# ADR 0006 — Observability, API docs, and runtime tuning

- Status: Accepted
- Date: 2026-08-19

## Context

Phase 8 hardens the service for operations: API documentation, correlated logs,
metrics, graceful shutdown, and pool/timeout tuning.

## Decisions

- **OpenAPI/Swagger via springdoc.** The spec is generated from the controllers
  and DTOs (so it cannot drift from reality). A `bearerAuth` HTTP/JWT scheme is
  declared once; protected controllers (`Items`, `Users`) opt in with
  `@SecurityRequirement`, while the public `/auth` endpoints do not — the document
  reflects the real authorization. `/v3/api-docs` and `/swagger-ui` are public.
- **Correlation id via a plain MDC filter**, not Micrometer tracing. Full
  distributed tracing (trace/span propagation, an exporter) is more than a
  single service needs; a first-order `CorrelationIdFilter` echoes/mints
  `X-Request-Id`, sanitizes any inbound value (length + charset, to prevent log
  injection), and puts it in the MDC. It runs at highest precedence so every log
  line and downstream filter shares the id.
- **Structured JSON logs in prod only.** `logging.structured.format.console=ecs`
  emits ECS JSON to stdout (MDC included automatically) under the `prod` profile;
  dev keeps human-readable logs with the id shown inline. Log collection is left
  to the platform (stdout), not the app.
- **Prometheus metrics, authenticated.** `micrometer-registry-prometheus` exposes
  `/actuator/prometheus` (and `/actuator/metrics`), both behind authentication —
  only `/health` and `/info` are public. A common `application` tag is added via a
  `MeterFilter`.
- **Graceful shutdown + pool/timeout tuning.** `server.shutdown=graceful` with a
  30s drain window; HikariCP sized conservatively (10 max, 2 idle) with sane
  connection/idle/lifetime timeouts; Tomcat connection/keep-alive timeouts and a
  bounded thread pool. JVM flags stay container-aware (`MaxRAMPercentage`,
  `ExitOnOutOfMemoryError`), documented in the README and Dockerfile.

## Consequences

- Endpoints, logs, and metrics are ready for a real deployment; the CD smoke
  tests (Phase 10) can assert on `/actuator/health` and an authenticated round
  trip, and Newman (Phase 12) can regenerate its collection from `/v3/api-docs`.
