Files
mercadodevida/work/artifacts/F-054/architect.md
2026-08-19 13:15:30 +02:00

2.6 KiB

Architect — F-054

Diagnóstico

  • El backend (dist/infrastructure/http/server.js) muere sin dejar trazas de error en el log: el último msg es un request completed 200, y luego silencio.
  • Cuando el backend está caído, los proxies devuelven:
    • GET/POST /api/auth/login en admin (3004) → 502 (catch del proxy en [...path]/route.ts)
    • POST /api/auth/login en frontend (3003) → 500 (catch en src/app/api/auth/login/route.ts)
  • El frontend hardcodea http://127.0.0.1:3000 mientras el admin usa process.env.NEXT_PUBLIC_API_URL ?? 'http://127.0.0.1:3000'. Inconsistencia menor pero no causa de este ticket.

Causa raíz probable

El proceso fue terminado por SIGTERM/SIGKILL — posiblemente cuando el shell que lo lanzó (nohup ... &) fue reaped por el harness de Pi. nohup evita SIGHUP pero no SIGTERM/SIGKILL que pueda llegar desde el agente.

Diseño

  1. Watchdog en monolith.sh: nueva función ensure_alive() que verifica si el PID en <service>.pid sigue vivo (vía kill -0) y, si no, lo relanza con spawn_service. Se invoca al inicio de status y se ofrece como comando explícito monolith.sh prod watch.
  2. Frontend /api/auth/login: usar process.env.NEXT_PUBLIC_API_URL ?? 'http://127.0.0.1:3000' igual que el admin. Cambio defensivo (no causa el bug pero evita uno futuro si se despliega el frontend en otro host).
  3. Diagnóstico de la muerte del backend: añadir un handler de uncaughtException y unhandledRejection en server.ts que loguee el error antes de morir. No previene la muerte pero ayuda a diagnosticarla la próxima vez.
  4. monolith.sh prod status mejorado: ahora también dispara ensure_alive antes de imprimir la tabla, así el operador ve servicios vivos sin tener que reiniciar manualmente.

Alternativas descartadas

  • systemd / launchd: fuera del scope del proyecto (no se asume init del sistema).
  • PM2 / forever: añadiría una dependencia runtime al proyecto.

Acceptance

  1. Si el backend muere, ./project/scripts/monolith.sh prod status lo detecta y lo relanza automáticamente.
  2. frontend/src/app/api/auth/login/route.ts lee NEXT_PUBLIC_API_URL con fallback a 127.0.0.1:3000.
  3. server.ts loguea uncaughtException y unhandledRejection antes de morir.
  4. Smoke: matar backend manualmente (kill <pid>), esperar 5s, correr monolith.sh status, ver backend running de nuevo.

Riesgos

  • El watchdog añade latencia al status (1 ciclo de kill -0 por servicio, <1ms).
  • Ningún cambio en runtime de los handlers API; solo el catch ya existente sigue devolviendo 500/502 cuando el backend está realmente caído.