# Foro integrado (app `forum`)

Foro de comunidad reimplementado en Django dentro de NovaWoW, con el **diseño
del propio sitio** (usa los `partials` head/header/footer). Portado desde la app
Symfony *NovaWeb-main*, contra las **mismas tablas** en la base de datos
`acore_web`.

## Arquitectura

- **BD**: `acore_web` (5ª conexión Django, `DB_NAME_WEB`). Acceso por SQL directo
  (`connections['acore_web']`), mismo estilo que el resto del proyecto.
- **Tablas**: `forum_categories`, `forums`, `forum_topics`, `forum_posts`,
  `forum_reads`. (La tabla legacy `forum_forums` NO se usa.)
- **Identidad del autor**: la cuenta de juego en sesión de NovaWoW
  (`session['account_id']` / `session['username']`). No usa las cookies del
  proyecto original.

## Funcionalidad (completa)

- Portada con categorías y foros (contadores de temas/mensajes, último tema).
- Ver foro: lista de temas paginada.
- Ver tema: posts paginados, con panel de autor (rol, registro, nº de mensajes).
- Crear tema, responder, editar y borrar el post propio.
- Moderación: fijar/desfijar, bloquear/desbloquear, mover, borrar/restaurar temas
  y posts.
- Buscador de temas (por título y contenido) **paginado** en `/es/forum/search`.
- Contador de **visitas** por tema (columna opcional `forum_topics.views`).
- Perfil público básico (`/es/profile/<usuario>`).
- El autor se muestra con un **nombre legible** (parte local del email de la
  cuenta) en vez de `<bnetId>#1`.

Rutas bajo `/es/forum...` (idénticas al original: `app_forum`, `forum_view`,
`forum_topic`, `forum_create_topic`, etc.).

## Modelo de permisos (simplificado)

En vez de la matriz `group_level`×`permission` del original (enrevesada y con
acciones que quedaban deshabilitadas por falta de filas), se usa un modelo claro
en `forum/permissions.py`:

- **Ver**: foros públicos (`visibility=1`, `deleted=0`) visibles para todos.
- **Publicar / responder / crear tema**: cualquier usuario con sesión iniciada y
  cuenta de juego seleccionada.
- **Editar / borrar** un post: su autor, o un moderador.
- **Moderar**: cuentas con `gmlevel >= FORUM_MOD_GMLEVEL` (por defecto **2**),
  leído de `acore_auth.account_access`.

## Seguridad

- El texto de los posts se **sanea con `nh3`** (allowlist de etiquetas) al
  guardar — `forum/sanitize.py` — evitando el XSS que tenía el original (que
  renderizaba HTML del editor sin filtrar). Se renderiza con `|safe` ya saneado.
- **Todas** las acciones que modifican datos (publicar, responder, editar, mover,
  bloquear/desbloquear, fijar, borrar/restaurar temas y posts) van por **POST**, y
  las vistas mutadoras llevan **`@csrf_protect`** (fuerza la validación CSRF por
  vista aunque el middleware global no esté activo).
- El HTML de los posts también se **sanea al renderizar** con el filtro
  `forum_safe` (defensa en profundidad frente a datos heredados sin sanear).
- Acceso a temas de foros ocultos/borrados bloqueado también por URL directa
  (no solo en los listados).

> ✅ **CSRF global activado** (todo el portal): `novawow/settings.py` ya incluye
> `django.middleware.csrf.CsrfViewMiddleware`. Las peticiones AJAX (jQuery) envían
> la cabecera `X-CSRFToken` automáticamente (`$.ajaxSetup` en `partials/head.html`),
> los formularios nativos llevan `{% csrf_token %}`, y solo los webhooks externos
> (`stripe_webhook`, `sumup_webhook`) mantienen `@csrf_exempt`.

## Editor

Los mensajes se escriben con **CKEditor 5** (el mismo editor que usa el resto de
NovaWoW), vía `forum/forms.py` (`TopicForm`, `ReplyForm`, `EditPostForm`). El
HTML que produce el editor se **sanea con nh3** al guardar, así que el rich text
es seguro.

## Despliegue

1. Crear/usar la BD `acore_web` y aplicar el esquema:
   ```bash
   mysql acore_web < sql/forum_schema.sql
   ```
   (Si ya existe la BD del portal Symfony con esas tablas, apunta `DB_NAME_WEB`
   a ella y omite este paso.)
   - Opcional (contador de visitas): `mysql acore_web < sql/forum_views.sql`.
     El foro detecta la columna automáticamente y funciona sin ella.
2. Configurar variables de entorno:
   ```
   DB_NAME_WEB=acore_web
   FORUM_MOD_GMLEVEL=2
   FORUM_TOPICS_PER_PAGE=20
   FORUM_POSTS_PER_PAGE=15
   ```
3. El enlace «FOROS» del menú COMUNIDAD ya apunta al foro interno (`/es/forum`).

## Notas / posibles mejoras

- Sistema de nicks propio del foro (ahora el nombre visible es la parte local del
  email de la cuenta).
- Avatares de usuario y firmas.
