# F-078 — Architect: Server log streaming via SSE in admin ## Goal Stream server-side logs in real-time to the admin UI via SSE (Server-Sent Events), like `docker logs -f`. Errors highlighted in red. ## Design ### Backend **1. `project/src/infrastructure/logging/log-broadcaster.ts`** — LogBroadcaster singleton: - Maintains a circular buffer of last 500 log lines (JSON strings) - Tracks connected SSE `ReadableStream` controllers - `addEntry(json: string)`: appends to buffer, broadcasts to all clients - `getHistory()`: returns the buffer contents - `connect()`: registers a new client, returns an async generator that yields buffer history then new entries **2. `project/src/infrastructure/logging/logger.ts`**: - Accept `broadcaster?: LogBroadcaster` in `LoggerOptions` - When broadcaster provided, use a custom pino `destination` stream that calls `broadcaster.addEntry()` for each serialized JSON log line **3. `project/src/infrastructure/http/server.ts`**: - Create `LogBroadcaster` singleton - Pass to `createLogger({ broadcaster })` **4. `project/src/modules/security/api/security.routes.ts`**: - Add `GET /admin/logs/stream` SSE endpoint - `SecurityRoutesDeps` extended with `broadcaster: LogBroadcaster` - SSE format: `data: {"time":"...","level":50,"msg":"...","err":{...}}\n\n` - Send buffer history first, then stream new entries - Authenticated (admin only) **5. `project/src/app/build-app.ts`**: - Pass `broadcaster` to `registerSecurityRoutes` ### Frontend (Admin) **6. `project/apps/admin/src/components/ServerLogViewer.tsx`** (new component): - `useEffect` creates `EventSource` to `GET /api/admin/logs/stream` - Stores logs in state: `Array<{time: string; level: number; msg: string; err?: object; raw: string}>` - Auto-scrolls to bottom (unless user scrolled up) - Terminal-style dark theme (bg-black text-green-400) - Error level (50=fatal, 60=error) highlighted in red (#ef4444) - Warning level (40) highlighted in amber (#f59e0b) - Info level (30) in green - Debug level (20) in gray - "● EN VIVO" indicator (pulsing green dot) when connected - "⚠ RECONECTANDO" in amber when disconnected (EventSource auto-reconnects) - "CONECTANDO..." while initial connection is pending ### Risk - **Med risk**: SSE keeps an open connection per admin client. In-memory buffer (500 lines) is bounded. - Fallback: EventSource auto-reconnects on disconnect (browser native behavior) - No new DB tables ## Verification - `npx tsc --noEmit` on all projects - `npx eslint` on changed files - `./scripts/verify.sh` green - Backend rebuild and restart - Manual: open audit page → see live server logs with errors in red