# 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.
