5bcf71a37bcc5092ee0f7c87e64cfba1b024f505
Los enlaces de wowhead se guardan con el locale de quien los postea (subdominio, domain y nombre), así que un ítem posteado en /es se veía en español aunque lo leyeras en /en, y al revés. Ahora siguen el idioma de QUIEN LEE. Al renderizar el tema (server component, conoce el locale del lector) se localizan los enlaces: se reescribe el subdominio y el domain del data-wowhead y se vuelve a resolver el nombre en el idioma del lector (lib/forum-wowhead + lib/wowhead-resolve, compartido con la API del editor y cacheado). Es solo de presentación: no cambia lo guardado ni añade parpadeo (el nombre llega ya resuelto del servidor). Verificado: un post guardado con nombre inglés y domain=wotlk se lee como «Bolsa de tejido de Escarcha» + es.wotlk en /es, y «Frostweave Bag» + www en /en. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nova WoW
Portal web para un servidor de World of Warcraft 3.4.3 basado en AzerothCore.
- Framework: Next.js 16 (App Router) + Tailwind, en
web-next/ - Idiomas: ES/EN con next-intl
- Bases de datos (MySQL):
django_wow(la del portal),acore_auth,acore_characters,acore_worldyacore_web(el foro)
La base del portal se sigue llamando
django_wowpor motivos históricos: el portal era una app Django, jubilada el 2026-07-15. Sus tablas llevaban el prefijohome_(el nombre de la app) y se renombraron sin él (home_stripelog→stripelog). Next las consulta con SQL directo, sin ORM.
1. Puesta en marcha (desarrollo)
git clone https://git.nightspire.gg/Inna/NovaWoW.git
cd NovaWoW/web-next
npm install
# crear .env.local con las variables de la sección 2
npm run dev # http://127.0.0.1:3000
2. Configuración (web-next/.env.local)
No se versiona (contiene secretos).
| Variable | Descripción |
|---|---|
DB_USER / DB_PASSWORD / DB_HOST / DB_PORT |
Credenciales MySQL (compartidas por las 5 BBDD) |
DB_NAME_DEFAULT |
BD del portal (django_wow) |
DB_NAME_AUTH / DB_NAME_CHARACTERS / DB_NAME_WORLD / DB_NAME_WEB |
BBDD de AzerothCore y del foro |
SESSION_SECRET |
Firma de la sesión |
SITE_URL |
Raíz pública del sitio. De aquí cuelgan todos los enlaces e imágenes de los correos, así que cambiar de dominio es tocar solo esta variable |
EMAIL_* |
SMTP (hoy Proton Mail, smtp.protonmail.ch:587 con STARTTLS). EMAIL_HOST_USER es además el remitente, y Proton exige que coincida con la dirección del token |
AC_SOAP_* |
Conexión SOAP a AzerothCore (envío de ítems, etc.) |
STRIPE_* / SUMUP_* |
Pasarelas de pago |
NEXT_PUBLIC_TURNSTILE_SITE_KEY / TURNSTILE_SECRET_KEY |
Captcha de Cloudflare |
ADMIN_EMAILS / ADMIN_GMLEVEL |
Acceso al panel de administración |
CRON_SECRET |
Protege el endpoint de reconciliación de SumUp |
NEXT_PUBLIC_GA_ID |
Google Analytics 4 (p. ej. G-XXXXXXXXXX). Vacío o sin poner = analítica desactivada, no se carga nada. Además, aunque esté puesta, solo se carga si el visitante acepta la categoría «Analíticas» del banner de cookies. Al ser NEXT_PUBLIC_* se incrusta en el build: activar o desactivar exige npm run build + reinicio |
MONETAG_SRC / MONETAG_ZONE |
Script de anuncios de Monetag (MultiTag). Salen del panel: Sites → canal → Get Tag; el src varía por zona. Cualquiera de las dos vacía = anuncios desactivados. Aunque estén puestas, solo se cargan si el visitante acepta la categoría «Marketing» del banner y pasa el filtro de lib/ads.ts. El push necesita además public/sw.js del panel. Se leen en el servidor: activar/desactivar sin rebuild |
ADSENSE_CLIENT_ID |
ID de editor de Google AdSense (ca-pub-...). Emite <meta name="google-adsense-account"> en el <head> de todas las páginas. Vacío o sin poner = etiqueta desactivada. No la ven ni los admins ni las cuentas de rango 2+ o que hayan pagado alguna vez (ver components/AdSense.tsx). Se lee en el servidor en cada petición: activar o desactivar es tocar el .env + reinicio, sin rebuild |
3. Producción
- Servicio:
novawow-next.service→next start -p 3001 - Proxy: Caddy.
nightspire.ggredirige awww.nightspire.gg, que va a127.0.0.1:3001;next.nightspire.ggapunta al mismo sitio. - Timer:
novawow-dpoints-reconcile.timerllama cada 2 min a/api/dpoints/reconcile(SumUp no manda webhooks, así que se reconcilia sondeando).
cd web-next && npm run build && systemctl restart novawow-next
4. Estructura
web-next/
app/[locale]/ páginas (una carpeta por ruta)
components/ componentes React
lib/ acceso a datos y lógica (SQL directo, sin ORM)
messages/ traducciones ES/EN
public/ estáticos, incluido el tema nw-ryu
sql/db2/ utilidades para leer los DB2 del cliente 3.4.3
docs/ documentación (foro, migración a 3.4.3)
sql/ esquemas y semillas (foro, precios, etc.)
5. Notas
- En 3.4.3 no existe
item_template: los datos de ítems salen de los.db2del cliente (verweb-next/sql/db2/). - La tienda vive en
/store-<realm>en minúsculas (p. ej./store-trinity);/storea secas da 404. - Los correos se construyen en
web-next/lib/emails.ts: una sola maqueta compartida por las 8 plantillas, con todas las URLs derivadas deSITE_URL.
6. Seguridad
- Los secretos que estuvieron hardcodeados en el historial de git deben rotarse: contraseña de MySQL/SOAP, credenciales SMTP y claves de Stripe/SumUp.
- Ni
.env.localni ningún fichero con secretos se versionan.
Description
Languages
TypeScript
86.2%
CSS
8.3%
Python
3.5%
JavaScript
2%