Observability
Logging
| Item | Detail |
|---|---|
| Logger | Pino via @sophia/platform |
| Format | JSON to stdout in containers (CloudWatch-friendly); pretty print locally when TTY allows |
| Level | LOG_LEVEL env (default info; deployed API/Lambdas typically info) |
| Identity | Each line includes service and version from env |
| Policy | No console.* in API; use structured logger.info({ … }, 'message') |
Correlation ID
| Item | Detail |
|---|---|
| Header | x-request-id on requests and responses |
| Generation | Client may send one; API uses inbound value or generates UUID |
| Logs | Pino mixin attaches requestId for the request/async context |
| SQS | Producers set requestId message attribute; Lambdas continue the same id when present |
| Errors | Every API error JSON includes requestId |
organizationId and userId are not automatically on every log line—only when call sites pass them explicitly.
PII
Redact paths for auth headers, tokens, email, phone, names, etc. Do not log full request bodies, resumes, or LLM prompts.
Errors
Single envelope: { error, code, requestId, details? }. Central handler maps AppError, validation, and unknown errors to status + code.
Health
| Route | Auth | Behavior |
|---|---|---|
GET /health | None | HTTP 200 always; status: ok if Mongo connected, else degraded with dependencies.mongo |
GET /v1/hello | None | Smoke: validation + envelope + correlation id in body |
Production API exits on startup if Mongo is unreachable. Non-production may start degraded until Mongo is up.
Cross-cutting events
Controlled LOG_EVENTS include request.started, request.completed, request.failed, Mongo connect/disconnect/failure, server start/stop. Filter alarms on event and structured fields, not free-text messages.