Files
mercadodevida/work/artifacts/F-003/architect.md
rikrdo 41f144d7bd feat(F-003): HTTP foundation with request context and error envelope
- request_id generated or sanitized-propagated on every request (x-request-id)
- structured JSON logging (pino), one correlated line per request, injectable logger
- error envelope v2 { error: { statusCode, code, message, details? }, requestId }
- 5xx messages always generic; stack traces stay in server logs only
- explicit parseJson (zod) input validation hook at the API layer
- README HTTP contract section; deps justified in spec/tech.md
- all gates approved; verify.sh green
2026-08-14 22:13:28 +02:00

1.7 KiB

Architect — F-003 HTTP foundation and request context

done -> work/artifacts/F-003/architect.md

Deliverables

  • specs/F-003-http-foundation/SPEC.md
  • specs/F-003-http-foundation/DESIGN.md
  • specs/F-003-http-foundation/TASKS.md
  • specs/F-003-http-foundation/TESTS.md

Key decisions

  1. pino for JSON structured logging: Fastify ecosystem standard, fast, boring. Fastify's own logger stays OFF (logger: false); logging happens through explicit onRequest/onResponse hooks so there is exactly one log line per request and zero hidden log paths.
  2. zod for the input validation hook: explicit parseJson(schema, body) calls inside handlers. No decorators, no magic binding. F-003 ships the hook; first real consumer is F-005 identity.
  3. request_id policy: propagate incoming x-request-id only when it matches ^[A-Za-z0-9._-]{1,128}$ (header-injection defense); otherwise crypto.randomUUID(). Response header x-request-id on every response; error envelopes also embed requestId.
  4. Error envelope v2 (additive): { error: { statusCode, code, message }, requestId }. Codes: NOT_FOUND, VALIDATION_ERROR, INTERNAL_ERROR, or upstream Fastify error codes for known 4xx. >=500 always answers the generic Internal Server Error; stack goes to logs tagged with requestId, never to the client.
  5. Logger injection: buildApp({ logger? }) — tests capture logs through an in-memory destination. No transports, no env sniffing in tests.

Boundaries

  • Cross-cutting code lives in shared and infrastructure/logging; composition wiring only in src/app. Modules (health) untouched.

Open risks

  • Envelope change touches F-001 test expectations (additive; tests will be updated in build).