First half of Phase 5 P2 (the "structured backend logging" piece;
E2E-in-CI lands separately so the diff stays reviewable).
Adds `lib/logger.ts` exporting a singleton pino instance shared between
Fastify (via `loggerInstance`) and any non-request code path. One
configured logger across the backend means uniform formatting,
redaction, and log-level control:
- LOG_LEVEL env knob (defaults: debug in non-prod, info in prod when
NODE_ENV=production). Documented in `.env.example`.
- Built-in redaction for Authorization / Cookie headers and the
common secret-shaped field names (password, token, refreshToken,
accessToken, csrfToken, JWT_SECRET, CSRF_SECRET, ENCRYPTION_KEY,
COSMOS_KEY, AZURE_CLIENT_SECRET) so an accidental
`req.log.info(req.body)` or `logger.error({ err, config }, …)`
won't dump credentials. This is a backstop, not the primary
defense — call sites should still avoid logging raw config/req.
- JSON to stdout in every environment. Pipe through `pino-pretty`
locally if you want pretty output; we deliberately don't bundle
pino-pretty as a runtime dep.
- `childLogger(module)` helper tags log lines with their origin so
repositories/background workers don't have to repeat the module
name on every line.
Sweeps the runtime `console.error` sites that lose request context
(deployment orchestrator background fire-and-forget, system docker
stats/cleanup, backup CRUD, vm getAllContainers) onto the structured
logger. CLI-only modules (`scripts/run-migrations.ts`,
`migrations/index.ts`, `cosmos-init.ts` startup, `azure-keyvault.ts`,
`config.ts` env warnings, `lib/migrations.ts` no-op message) keep
`console.*` for now — they run before Fastify is up and are queued for
a separate cleanup pass.
Tests, typecheck, lint (0 errors), build green. Coverage gate still
passing (≥95% lines on every gated file).
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Closes the long-standing SSE TODO. The previous attempt with
`fastify-sse-v2 ^4` was incompatible with Fastify 5 and was never wired
in; the README/DEPLOYMENT.md kept advertising "real-time log streaming"
that didn't exist. The web client never used EventSource — `web/src/
lib/api.ts` already polls `/deployments/:id/logs` via the normal
`apiRequest` helper.
Resolution: remove the claim, not ship the feature.
- drop `fastify-sse-v2` dep from `backend/package.json` + lockfile
- delete the commented-out plugin import + register in `server.ts`,
replace with a NOTE explaining the JSON-polling decision and how
to add a stream later (`reply.raw`)
- remove the `TODO: Re-enable SSE` comment in `deployments/routes.ts`;
the endpoint already returns JSON, document that explicitly
- rewrite the README "Deployment Log Streaming" section as
"Deployment Logs" (JSON-polled, no SSE); fix the endpoint table
- flip the DEPLOYMENT.md bullet from "Real-time log streaming (SSE)"
to "Deployment log retrieval (JSON polling — no SSE)"
- mark REVIEW_ACTIONS #4 RESOLVED with the reasoning
- tick the roadmap checkbox
If a real-time stream is wanted later, ship it explicitly via
`reply.raw` and update README/DEPLOYMENT.md/the route comment in the
same change. Don't reintroduce a half-disabled plugin.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Add docker-compose.yml following trading web pattern
- Update web Dockerfile to use multi-stage build with metadata
- Add build metadata (commit SHA, branch, timestamp, author, message)
- Rewrite deploy.sh to use docker compose with build metadata
- Add hotcopy deployment script for quick updates
- Add comprehensive backend API with deployment orchestration
- Add health checks, service management, and monitoring endpoints
- Add CI/CD workflow configuration
- Add deployment documentation and guides
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>