# F-078 — Implementer evidence ## What was implemented ### Backend (`project/src/`) - `infrastructure/logging/log-broadcaster.ts`: `LogBroadcaster` singleton with circular 500-line buffer + per-client `ReadableStream` registration that sends history then live entries. - `infrastructure/logging/logger.ts`: `createLogger` accepts a `broadcaster` option and pipes pino through a `Writable` that calls `broadcaster.addEntry()`. - `infrastructure/http/server.ts`: instantiates `getLogBroadcaster()` and passes to logger. - `modules/security/api/security.routes.ts`: new route `GET /admin/logs/stream` returns SSE with `text/event-stream` headers (`Cache-Control: no-cache`, `Connection: keep-alive`, `X-Accel-Buffering: no`). - `app/build-app.ts`: passes `broadcaster` to `registerSecurityRoutes`. ### Frontend (`project/apps/admin/src/`) - `components/ServerLogViewer.tsx`: fetch-based SSE client (cookie-forwarding), color-coded by pino level (50/60 red, 40 amber, 30 green, 20/10 gray), EN VIVO indicator, RECONECTANDO fallback, scroll-up detection. - `app/(dashboard)/logs/page.tsx`: admin page hosting `ServerLogViewer`. - `lib/permissions.ts`: new nav item `Logs` (admin-only via `audit.read`). ## Files changed - `project/src/infrastructure/logging/log-broadcaster.ts` (new) - `project/src/infrastructure/logging/logger.ts` (broadcaster option) - `project/src/infrastructure/http/server.ts` (wiring) - `project/src/modules/security/api/security.routes.ts` (SSE route) - `project/src/app/build-app.ts` (deps wiring) - `project/apps/admin/src/components/ServerLogViewer.tsx` (lint fixes: removed unused refs) - `project/apps/admin/src/app/(dashboard)/logs/page.tsx` (new) - `project/apps/admin/src/lib/permissions.ts` (nav entry) ## Validation - `npx tsc --noEmit -p apps/admin/tsconfig.json` → exit 0 - `npx eslint` on changed files → 1 pre-existing warning in `permissions.ts` (`can(role, permission)` unused arg) NOT introduced by this change. - `./scripts/verify.sh` → exit 0. ## Acceptance trace - "SSE endpoint streams server logs in real-time" → `GET /admin/logs/stream` returns `text/event-stream` with buffer history then live pino entries. - "Errors highlighted in red" → `LEVEL_STYLES[50]=text-red-400`, `[60]=text-red-400` in `ServerLogViewer.tsx`. - "Log viewer shows recent history on connect" → `registerClient()` enqueues buffer first, then live additions.