fix(tpv-dev-in-prod): tPV production is running next dev (HMR + React DevTools visible)

This commit is contained in:
Deploy
2026-08-27 23:13:10 +02:00
parent 42b0290dd2
commit 7ed78f96eb
13 changed files with 1144 additions and 244 deletions

View File

@@ -138,7 +138,7 @@ cd project
./scripts/monolith.sh prod start
```
Usa `npm ci`, aplica migraciones, construye backend/admin/frontend/storefront y arranca todo en `0.0.0.0`.
Usa `npm ci`, aplica migraciones, construye backend/admin/frontend/storefront y arranca todo en `0.0.0.0`. Al finalizar ejecuta un **smoke test post-arranque** que verifica que ninguno de los servicios Next está sirviendo modo dev (sin HMR, sin `react-refresh`, sin banner `(Turbopack)`). Si detecta un dev server activo, aborta el arranque con un mensaje claro.
### Redeploy / reinicio completo
@@ -149,6 +149,51 @@ cd project
Detiene únicamente PIDs registrados en `.runtime/prod/`; nunca usa `pkill` global. Si un puerto está ocupado por un proceso ajeno, falla y muestra el PID.
### 3.1 Errores comunes — jamás arranques `dev` en un host de producción
**Regla de oro:** en cualquier host expuesto al público (sea LAN, VPS o servidor de tienda), usa **siempre** `./scripts/monolith.sh prod`. El modo `dev` está reservado para desarrollo local en `127.0.0.1`.
#### Por qué `next dev` no es un atajo válido en producción
- **Expone internals:** el bundle del cliente incluye `react-refresh`, `__webpack_require__`, el cliente HMR y los mensajes "Download the React DevTools". Cualquier visitante ve el código fuente sin minificar.
- **Hackeable:** el endpoint `/_next/hmr` queda abierto y acepta WebSocket upgrades. Esto filtra nombres de archivos del servidor, permite lecturas no autenticadas del árbol de fuentes y rompe asunciones de seguridad (CSP, cookies Secure, CORS).
- **Rota el PWA:** Chrome exige un `manifest.webmanifest` válido. `next dev` no genera el manifest correctamente en algunos setups y dispara errores CORS cuando un auth-proxy (Authelia) intenta proteger la ruta.
- **Rendimiento ~10× peor:** Turbopack compila cada request bajo demanda y mantiene cachés en memoria que pueden llegar a GB. Sin monitorización, esto degrada el TPV hasta hacerlo inutilizable en horas punta.
- **Rompe el ciclo de release:** los artefactos `.next/` de dev no son válidos para `next start`. Si mezclas `dev` y `start` en el mismo árbol, los reinicios de prod fallan silenciosamente porque los PIDs no se registran.
#### Señales de que estás corriendo `dev` por accidente
- El log del servicio dice `▲ Next.js 16.3.1 (Turbopack)` — la coletilla `(Turbopack)` solo aparece en `next dev`.
- La consola del navegador muestra intentos de WebSocket a `/_next/hmr` y mensajes `[HMR] connected` repetidos.
- Verás `Download the React DevTools` al cargar cualquier página.
- `lsof -nP -iTCP:3002 -sTCP:LISTEN` muestra un PID de `node .../next/dist/bin/next dev` en lugar de `next start`.
#### Runbook de recuperación rápida (si ya estás sirviendo dev en prod)
```bash
# 1) Identificar el proceso dev en :3002 (TPV) y :3001 (admin)
lsof -nP -iTCP:3002 -sTCP:LISTEN
lsof -nP -iTCP:3001 -sTCP:LISTEN
# 2) Detenerlo (sustituye <PID> por el del paso anterior)
kill -TERM <PID>
# 3) Confirmar que el puerto queda libre
lsof -nP -iTCP:3002 -sTCP:LISTEN # debe devolver nada
# 4) Limpiar runtime stale (incluye dev huérfano)
rm -f project/.runtime/dev/*.pid
# 5) Arrancar prod (con smoke test post-arranque)
cd project && ./scripts/monolith.sh prod start
# 6) Confirmar: el log dirá "▲ Next.js 16.3.1" SIN "(Turbopack)"
tail project/.runtime/prod/tpv.log
# debe terminar con la línea de Ready y NADA de WebSocket /_next/hmr
```
Si el smoke test falla igualmente, abre un ticket: hay otro proceso (posiblemente externo al script) ocupando el puerto y `monolith.sh` no puede broad-kill por seguridad.
### Estado, logs y stop
```bash
@@ -279,6 +324,22 @@ curl -fsS -o /dev/null http://127.0.0.1:3004/
curl -fsS -o /dev/null http://127.0.0.1:3005/
```
Comprobaciones adicionales anti-dev (TPV-DEV-IN-PROD):
```bash
# 1) El log del TPV NO debe contener "(Turbopack)"
! grep -F '(Turbopack)' project/.runtime/prod/tpv.log
# 2) /_next/hmr debe devolver 404 o 426 (no 200/101/405)
code=$(curl -sS -o /dev/null -w '%{http_code}' http://127.0.0.1:3002/_next/hmr)
[[ "$code" == "404" || "$code" == "426" ]]
# 3) El HTML inicial NO debe contener marcadores de dev
! curl -fsS http://127.0.0.1:3002/ | grep -qE '/__next_hmr|react-refresh|Download the React DevTools'
```
Repetir para `:3001` (admin), `:3003` (frontend) y `:3004` (storefront) si también están en producción. Si cualquiera falla, sigue el runbook de §3.1 antes de continuar.
---
## 7. Problemas frecuentes