Files
NightSpire/README.md
T
Inna 3361f2e9e9 Etiqueta de verificación de AdSense, con interruptor y sin anuncios para quien paga
Se añade `<meta name="google-adsense-account">` al <head> de todas las páginas, que
es lo que pide Google para verificar la propiedad del sitio. OJO: esto NO muestra
anuncios ni carga adsbygoogle.js todavía; solo permite que Google confirme que el
dominio es nuestro y arranque la revisión.

TRES interruptores (ver components/AdSense.tsx):
1. `ADSENSE_CLIENT_ID` en el .env (no versionado). Vacío o sin poner = no se emite
   nada. Documentada en el README. NO lleva prefijo NEXT_PUBLIC_ a propósito: la
   etiqueta se pinta en el servidor, así que no hace falta exponerla al bundle ni
   rebuildear para activarla/desactivarla, al revés que NEXT_PUBLIC_GA_ID.
2. Admin (ADMIN_EMAILS o gmlevel de AzerothCore): sin etiqueta, para que la
   navegación del staff no cuente como tráfico con anuncios.
3. Rango de la cuenta (ns-ranks) Y pagos: solo ve anuncios el rango 1 (Newbie, el
   de por defecto) que ADEMÁS nunca ha pagado.

Los dos cortes del punto 3 son distintos a propósito y no basta con mirar el rango:
el mínimo de SumUp son 0,20 €, que a 100 PD/unidad son 20 PD, y eso sigue siendo
rango 1. Mirando solo el rango, quien pagara el mínimo seguiría viendo anuncios,
que es justo lo contrario de lo que queremos.

Para no duplicar el SQL, las consultas de saldo y de total donado salen de
getAccountDashboard a dos helpers (`getPoints`, `getDonatedPD`) que reutiliza el
nuevo `getAccountRankInfo`, con las dos consultas mínimas en vez del panel entero
(personajes, baneos, correo…). El criterio de rango es el mismo que ya usaba
/my-account: el máximo entre lo donado y el saldo actual.

Verificado contra la web real: anónimo y rango 1 sin pagos SÍ reciben la etiqueta;
rango 1 con 99 PD también; 100 PD de saldo (rango 2) no; rango 1 tras pagar 0,20 €
tampoco; admin tampoco; y con la variable vacía no la recibe nadie. Los dos últimos
casos no existían en la BD, así que se probaron con datos temporales en la cuenta
14 (fila en stripelog y en api_points), ya borrados. /my-account sigue pintando el
rango correcto tras mover las consultas.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 06:57:28 +00:00

4.2 KiB

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_world y acore_web (el foro)

La base del portal se sigue llamando django_wow por motivos históricos: el portal era una app Django, jubilada el 2026-07-15. Sus tablas llevaban el prefijo home_ (el nombre de la app) y se renombraron sin él (home_stripelogstripelog). 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
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.servicenext start -p 3001
  • Proxy: Caddy. nightspire.gg redirige a www.nightspire.gg, que va a 127.0.0.1:3001; next.nightspire.gg apunta al mismo sitio.
  • Timer: novawow-dpoints-reconcile.timer llama 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 .db2 del cliente (ver web-next/sql/db2/).
  • La tienda vive en /store-<realm> en minúsculas (p. ej. /store-trinity); /store a 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 de SITE_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.local ni ningún fichero con secretos se versionan.