Commit Graph

69 Commits

Author SHA1 Message Date
Inna d612b7916c Fase 1 (isla 2): estado del servidor de la portada en React/TSX
Segunda isla de la home: la tabla de estado (nombre, online, login, hora,
dirección) pasa de plantilla Django a componente React.

- API: home_status_api -> /api/home/status/ (server_name, address, expansion,
  online_characters, status). Reutiliza check_server_status y
  get_online_characters_count de views/pages.
- React: ServerStatus.tsx (fetch + reloj en vivo con setInterval, mismas clases
  CSS). El entry home.tsx ahora monta dos islas: #home-news-app y #home-status-app.
- partials/noticias.html: la <table> de estado se sustituye por el contenedor.

Verificado: check OK, ambos endpoints 200, la home monta las dos islas.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 20:22:32 +00:00
Inna 98c3cbdbc6 Fase 0/1 migración a TSX: islas React con Vite + API JSON (piloto: noticias)
Arquitectura elegida: islas React/TSX montadas sobre las plantillas Django
existentes (django-vite), alimentadas por endpoints JSON bajo /api/. El backend,
las URLs y la auth por sesión se mantienen; se migra sección a sección.

Fase 0 (tooling):
- frontend/ con Vite + React 18 + TypeScript. Build a static/dist con manifest.
- django-vite 3.1 en INSTALLED_APPS + DJANGO_VITE (dev_mode=DEBUG,
  static_url_prefix='dist'). STATIC_URL pasa a '/static/' (absoluto) para que los
  assets no choquen con el <base href> de la plantilla. WhiteNoise sirve el bundle.
- .gitignore: frontend/node_modules y static/dist (artefactos de build).

Fase 1 (piloto: lista de noticias de la portada):
- API: home/views/api.py -> home_news_api (JsonResponse); ruta /api/home/news/
  montada en home/api_urls.py fuera de i18n_patterns.
- React: NewsList.tsx hace fetch de la API y renderiza las noticias (mismas clases
  CSS que el HTML original). Entry src/entries/home.tsx monta en #home-news-app.
- partials/noticias.html: el bucle {% for noticia %} se reemplaza por el contenedor
  de montaje + {% vite_asset %}.

Verificado en producción: manage.py check OK, /api/home/news/ 200, la home incluye
el mount y el <script> del bundle, y el bundle se sirve (200).

Build en deploy: cd frontend && npm run build && collectstatic (ver frontend/README.md).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 20:18:35 +00:00
Inna 1ee126a69f Despliegue en nightspire.gg: dominio real, estáticos y home resiliente
- settings: ALLOWED_HOSTS y CSRF_TRUSTED_ORIGINS a nightspire.gg /
  www.nightspire.gg (+ IP del servidor). Se retira el antiguo novawow.com.
- WhiteNoise para servir estáticos desde gunicorn (el reverse proxy Caddy
  corre como usuario 'caddy' y no puede leer /root): middleware +
  STORAGES con CompressedStaticFilesStorage. Añadido a requirements.txt.
- home: get_online_characters_count() ahora tolera que la BD de personajes
  (AzerothCore) no exista/esté vacía y devuelve 0 en vez de provocar un 500
  en la portada (mismo criterio que el context_processor get_server_info).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 20:01:43 +00:00
Inna 96ab91a82b Corrige ContentCreator.__str__ (self.titles -> self.title)
El campo se llama `title`; `self.titles` no existía y provocaba
AttributeError al representar el modelo (p. ej. en el admin de Django).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:16:22 +00:00
Inna 585285640d Divide home/models.py en el paquete home/models/ por secciones
El módulo (~310 líneas, 30 modelos) se convierte en un paquete cuyo
__init__.py re-exporta todos los modelos, de modo que `from home.models
import X`, el admin y el resto de consumidores siguen funcionando igual.

Módulos por sección: pricing (precios/costes de servicios + GuildRenameSettings),
store (Category, Item, StripeLog, Pedido), site (contenido/config del sitio),
recruit, accounts (activación, token de seguridad, LoginAttempt), voting
(VoteSite, VoteLog, HomeApiPoints) e history. Las claves foráneas por clase
directa quedan en el mismo módulo; cada submódulo importa solo lo que usa.

Se eliminan imports de cabecera muertos (ValidationError, uuid, secrets) y las
líneas de import duplicadas del original.

Migración-neutral: `makemigrations home --dry-run` -> "No changes detected"
(app_label=home y nombres/tablas de modelo intactos). Definición de cada
modelo idéntica (extracción por AST). `manage.py check` sin incidencias.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:15:12 +00:00
Inna b3184fbdfe Divide home/views.py en el paquete home/views/ por secciones
El módulo monolítico (~3200 líneas) se convierte en un paquete cuyo
__init__.py re-exporta todas las vistas, de modo que `views.X`,
`from home.views import X` y la cadena 'home.views.not_found' (handler404)
siguen funcionando sin tocar urls.py.

Módulos por sección: _base (imports comunes + require_paid_stripe), auth,
pages, account, recruit, characters, store, points, guild, history,
players y payments. Cada submódulo hereda los imports con
`from ._base import *`; las dependencias entre secciones se resuelven con
imports explícitos (guild->auth, recruit/history->account).

Se eliminan dos definiciones duplicadas que quedaban muertas al cargar:
- get_character_image (primera copia, idéntica a la efectiva)
- store_novawow_success_view (stub sin SOAP, pisado por la versión real)

Validado con `manage.py check` (0 issues), resolución de las 100 rutas y
un chequeo estático de nombres no definidos por módulo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:09:40 +00:00
Inna 758435fe77 Corrige bugs de la revisión de home/views.py (dinero, bypass de pago, 500s)
Seguridad / dinero:
- store_novawow_view: recalcula precios y valida ítems contra la BD (Item) en vez
  de confiar en el precio/ítems que manda el cliente; guarda en sesión un carrito
  ya validado para la entrega
- *_success_view (x9): @require_paid_stripe verifica el pago real en Stripe por
  session_id (Stripe lo añade a la success_url) y marca StripeLog.fulfilled para
  evitar re-entregas; cierra el bypass de ir directo a la success-url sin pagar
- gold_character_view: deja de truncar el precio (int(4.99)->4); pasa el precio real

Correctitud / 500s:
- change_password_view: .get(...,'') evita AttributeError si falta un campo
- revive_character_view: lógica de éxito corregida (vacío=éxito, no vacío=error,
  None=fallo de comunicación) — antes marcaba error como éxito y caía a HTML
- store category y recruit_a_friend: guardas para Category.DoesNotExist y cuenta None

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:56:20 +00:00
Inna faa9aabdbf Corrige security_token_view: bug de indentación que impedía generar el token
- 'if not email:' estaba a 5 espacios, anidando todo el bloque bajo él: con un
  email válido se saltaba la generación del token (solo re-renderizaba) y el
  código de creación quedaba inalcanzable
- re-indentado para que la generación del token cuelgue de 'if request.method == POST'

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:44:26 +00:00
Inna b5d46fad5c Activa CSRF global en el portal (CsrfViewMiddleware)
- añade django.middleware.csrf.CsrfViewMiddleware a MIDDLEWARE (estaba ausente:
  el CSRF estaba desactivado en todo el sitio)
- head.html: $.ajaxSetup envía X-CSRFToken en todo POST AJAX de jQuery + expone
  window.CSRF_TOKEN (fuerza la cookie csrftoken en cada página)
- store_novawow.html: el fetch() nativo ahora manda X-CSRFToken (era el único que
  se rompía al activar el middleware)
- register.html: añade {% csrf_token %} al formulario
- retira @csrf_exempt de login/register/restore_character/restore_items
  (solo los webhooks stripe/sumup siguen exentos)
- auditoría previa: el resto de POST (AJAX jQuery + forms nativos con token) ya cubierto

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:42:34 +00:00
Inna 89ea16ba4d Foro: correcciones de la revisión de seguridad y correctitud
- CSRF real en las vistas mutadoras con @csrf_protect (el middleware global no
  estaba activo; verificado: POST sin token -> 403). Se documenta el hueco global.
- bloquea acceso a temas de foros ocultos/borrados por URL directa (view_topic y reply)
- conteo de posts respeta borrados para moderadores (paginación correcta)
- tema bloqueado impide editar/borrar posts a no-moderadores (_topic_locked_for)
- moderador ve el formulario de respuesta en temas bloqueados (can_reply)
- filtro forum_safe: sanea el HTML también al renderizar (defensa en profundidad)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:34:03 +00:00
Inna 071ba031a1 Foro: ocultar contador de visitas cuando la columna no existe
- corrige que se mostrara '1 visitas' sin la columna forum_topics.views:
  el incremento y la visualización solo ocurren si has_views_column() es true

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:25:53 +00:00
Inna eb93758c43 Foro: paginación en la búsqueda y contador de visitas por tema
- búsqueda paginada (count_search_topics + offset/limit) con controles en la plantilla
- contador de visitas: columna opcional forum_topics.views con detección automática
  (has_views_column), increment_views al ver el tema, mostrado en lista y cabecera
- sql/forum_views.sql (ALTER opcional) + docs

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:22:05 +00:00
Inna fd49d6cd96 Foro: buscador de temas y nombre de autor legible
- forum_search: busca temas por título y contenido (foros visibles)
- db.get_display_name: nombre visible del autor = parte local del email de la cuenta
  (en vez de <bnetId>#1), usado en el panel de posts y la lista de temas
- buscador en la portada del foro + plantilla search.html
- docs/FORO.md actualizado

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:18:34 +00:00
Inna 874a0c1ad9 Foro: editor CKEditor 5 en los mensajes y moderación por POST+CSRF
- forum/forms.py: TopicForm/ReplyForm/EditPostForm con CKEditor5Widget (rich text)
- vistas crear/responder/editar pasan el form; el HTML del editor se sanea con nh3
- acciones de moderación (bloquear, fijar, mover, borrar/restaurar temas y posts)
  ahora exigen POST y van con CSRF; las plantillas usan formularios en vez de enlaces GET
- docs/FORO.md actualizado

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:15:35 +00:00
Inna 2c30844bf7 Añade foro de comunidad integrado (app forum) con el diseño de NovaWoW
- app 'forum': portada (categorías/foros), ver foro y tema (paginado), crear tema,
  responder, editar/borrar posts y moderación (fijar, bloquear, mover, borrar/restaurar)
- lee/escribe la BD acore_web (5ª conexión, DB_NAME_WEB) por SQL directo, tablas
  forum_categories/forums/forum_topics/forum_posts/forum_reads (portado de NovaWeb-main)
- identidad = cuenta de juego en sesión; permisos simplificados por gmlevel
  (FORUM_MOD_GMLEVEL) en vez de la matriz group_level×permission del original
- saneado del HTML de posts con nh3 (evita el XSS del original); POST+CSRF en formularios
- plantillas con los partials del sitio; enlace 'FOROS' del menú apunta al foro interno
- sql/forum_schema.sql y docs/FORO.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 17:10:55 +00:00
Inna 2162fe34d0 Muestra el email Battle.net como nombre visible en vez de <bnetId>#1
- header: saludo con bnet_email (fallback al username de juego)
- my-account: 'Cuenta (Battle.net)' = email y 'Cuenta de juego' = <bnetId>#1
- session['username'] se mantiene intacto para las consultas a la BD

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 16:52:45 +00:00
Inna 4edd08cd1a Mi cuenta: enlace a Battlepay y saldo de créditos bnet
- my_account: añade battlepay_credits (leído de battlenet_accounts.battlePayCredits)
- bnet.get_battlepay_credits() defensivo (0 si la columna no existe)
- partials/my-account.html: muestra 'Créditos Battlepay' y añade botón 'Tienda del cliente' que enlaza a /es/battlepay/

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 16:51:03 +00:00
Inna 0fef9ac35b Integra Battlepay con SumUp (órdenes battlepay_orders)
- pagos_sumup.py: crear_checkout_battlepay(reference,...) y obtener_checkout()
- battlepay_view: lista las órdenes PENDING de la cuenta de juego
- battlepay_pay_view: crea checkout SumUp para una orden concreta (checkout_reference=reference)
- sumup_webhook: marca la orden PAID (valida estado contra la API de SumUp si falta)
- plantillas account/battlepay.html y partials/pago_sumup.html
- sql/battlepay_sumup.sql (tablas battlepay_orders/battlepay_price) y docs actualizados

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 16:48:16 +00:00
Inna 215061776b Adapta el portal a 3.4.3 (cuentas Battle.net + selector de cuenta de juego)
- home/bnet.py: SRP6 v2 (PBKDF2-HMAC-SHA512) para battlenet_accounts y SRP6
  Grunt (SHA1) para las cuentas de juego, con helpers bnet<->game account
- login por email contra battlenet_accounts; selector de cuenta de juego
  cuando la cuenta bnet tiene varias (my_account redirige al selector)
- registro/activación crean battlenet_accounts + account enlazada (<bnetId>#1,
  battlenet_account/battlenet_index)
- cambio de contraseña sobre battlenet_accounts; cambio de email recalcula
  salt/verifier (el usuario SRP depende del email)
- AccountActivation: identidad por email (username/salt/verifier opcionales) + migración
- plantillas login/register por email + nueva plantilla del selector
- docs/MIGRACION_3.4.3.md con el detalle y los pasos de verificación

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 16:43:11 +00:00
Inna b43b888f53 Añade README de despliegue y soporte Docker
- README.md: guía de instalación (venv, .env, migraciones, gunicorn) y notas de producción/seguridad
- Dockerfile: imagen Python 3.14 con deps de sistema para mysqlclient/Pillow
- docker-compose.yml: servicios web (Django+gunicorn) y db (MySQL 8.4) con las 4 BBDD
- docker/entrypoint.sh: espera a MySQL, migra, collectstatic y arranca gunicorn
- docker/mysql-init.sql: crea django_wow + bases acore_*
- .dockerignore y gunicorn en requirements

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 16:16:29 +00:00
Inna f787b0d06e Mueve secretos a variables de entorno (.env)
- settings.py: SECRET_KEY, DEBUG, credenciales MySQL (x4 BBDD), SOAP,
  SumUp, Stripe y SMTP ahora se leen de variables de entorno via python-dotenv
- añade .env.example como plantilla y python-dotenv a requirements
- .gitignore: ignora .env
- verificado: manage.py check OK y settings cargan valores desde .env

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 16:01:57 +00:00
Inna e1c04a92e3 Actualiza dependencias a las últimas versiones (Django 6.0.7, Python 3.14)
- Django 4.2.17 -> 6.0.7
- stripe 11.4.1 -> 15.3.0, pillow 11 -> 12, django-extensions 3.2.3 -> 4.1
- resto de paquetes actualizados a su última versión
- verificado: manage.py check, makemigrations --check y arranque WSGI OK
- .gitignore: ignora .venv/

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 15:58:45 +00:00
adevopg 9c92778816 Producion 2025-03-14 19:03:51 +01:00
adevopg 6365624e25 Implementacion Inicial SumUP 2025-03-02 17:37:33 +01:00
adevopg 34eec87bf2 Implementdo Cookies de la Union Europea 2025-03-02 10:50:45 +01:00
adevopg 9a96fad61b Implementado Cambio de Nombre Hermandad de Stripe 2025-02-20 17:27:00 +01:00
adevopg 3f962f8368 Implementado Ban History, Restore Character, Restore Items 2025-02-19 22:12:22 +01:00
adevopg 137dc853f8 Implementado historial de transaciones 2025-02-18 12:00:22 +01:00
adevopg 0a650eb161 Implementado Logs de Pagos de Stripe y Historial de conexiones de seguridad 2025-02-18 11:42:46 +01:00
adevopg e94915e667 Actualizacion la compra con logs logs correspondientes 2025-02-18 11:11:47 +01:00
adevopg 162f4bf828 Ahora la descripcion del pago de Stripe se muestra correctamente 2025-02-16 19:02:46 +01:00
adevopg 45ab155153 Implementadas algunas rutas faltantes 2025-02-16 17:22:26 +01:00
adevopg c3fea2e0a2 Ya da los items al juego 2025-02-16 10:59:42 +01:00
adevopg 2a194d6e98 Arreglado un problema visual del precio 6.1000000000000005 tipo a si 2025-02-16 01:01:45 +01:00
adevopg 0d5a8f853a Cambio el texto a EUR 2025-02-16 00:46:45 +01:00
adevopg 4d0711236e Arreglado los precios de Articulos en cesta 2025-02-16 00:43:18 +01:00
adevopg e6f6abdc8b Fix Precios tienda 2025-02-16 00:13:15 +01:00
adevopg 41c3c6ae91 Implementacion Inicial de la Tienda 2025-02-15 23:36:48 +01:00
adevopg fa8a0e0891 Se a Eliminado de Head los script js para evitar su carga inecesaria cuando no hace falta 2025-02-15 17:53:52 +01:00
adevopg 4b83057131 A;adido Wotlk Futura Implementacion y Varios arreglos en js 2025-02-15 16:38:42 +01:00
adevopg 40f9b7b0a9 Fix Si no ay respuesta del servidor 2025-02-15 01:49:11 +01:00
adevopg 631fad7c5d Arreglado el Problema si la cuenta no tenia correo asociado 2025-02-14 21:58:52 +01:00
adevopg e489d1355d Error 404 Fix 2025-02-14 17:19:37 +01:00
root e9de3248c0 Ignorar la carpeta venv en Git 2024-12-29 03:11:45 +05:30
Inna a77cdf96b9 Implementado Https 2024-12-27 08:26:10 -08:00
Inna 7f1fc94fc9 Fix From 2024-12-26 15:56:37 -08:00
Inna cff4bc3328 Fix name Class 2024-12-26 15:50:36 -08:00
Inna 2d9b7502d8 Fix Formulario de Login 2024-12-26 15:46:46 -08:00
Inna 473164e0a7 Fix URL 2024-12-26 15:21:55 -08:00
Inna 89f6bace97 Fix Class button Server Selection 2024-12-26 15:07:06 -08:00