**Fase:** F3 · **Tamaño:** M · **Depende de:** #28 (F2-06) ### Objetivo Una API que arranca de forma segura, valida entradas y devuelve errores coherentes, preparada para estar expuesta a internet. ### Contexto Hoy el servidor escucha aunque Mongo falle, no hay manejador global de errores, ni límite de body, ni cabeceras de seguridad, ni logs estructurados. ### Alcance - Separar `createApp()` (`api/app.ts`) de `api/server.ts`. - `server.ts`: conectar a Mongo y Redis **antes** de escuchar; apagado ordenado con `SIGTERM`/`SIGINT`. - `helmet` con CSP que permita `img-src`/`media-src` del origen de almacenamiento. - `pino-http` con id de petición y `redact` de `authorization`, `cookie`, `apiKey`, `*.key`. - `express.json({ limit: '100kb' })`. - Middleware `validate(zodSchema)` para body, params y query. - Manejador global que responde `application/problem+json` (`type, title, status, detail, code`); 404 para rutas desconocidas. - `GET /healthz` (vivo) y `GET /readyz` (Mongo y Redis conectados). - Rutas nuevas bajo `/api/v1`. ### Criterios de aceptación - [ ] Con `MONGODB_URI` inválida, el proceso termina con código ≠ 0 en < 15 s y no abre el puerto. - [ ] `curl -i /ruta-inexistente` → 404 con `Content-Type: application/problem+json`. - [ ] Body de 200 KB → 413. - [ ] El log de una petición con cabecera `Authorization` muestra `[Redacted]`. - [ ] `kill -TERM` termina en < 10 s sin cortar una petición en curso (test de integración).
Activity