Problem
The axios interceptors in src/lib/api.ts read x-correlation-id from responses (via normalizeApiError), but nothing generates or attaches a correlation id to outgoing requests. The backend (per the backend repo's correlation middleware) reads incoming X-Correlation-ID headers and generates its own when absent; without the client sending one, every request the browser makes gets a fresh server-side id. Consequences:
- A single user action cannot be traced end-to-end: the browser-side sequence (bootstrap, refresh, outages fetch, resolve mutation) produces N unrelated correlation ids; support cannot join them into one user story.
- The declared
correlationId on NormalizedApiError is response-only: when the server is unreachable (network error, no response), there is no id at all — the error the operator reports cannot be looked up.
- The app already has the plumbing to do this right:
logger declares correlationId, and the session provider logs events — but the id source (a per-session or per-request id generator) does not exist.
Root cause
The correlation feature was implemented on the response/error side only; the request side was never wired.
Why this is architecturally hard
- The id source needs a lifecycle: a per-request id (unique per network call, generated in the request interceptor) vs. a per-session id (stable across a session, propagated to every request) — or both (request id + session id headers). The backend's contract must be confirmed (which header names it reads).
- Ids must flow into
logger entries (companion issue) and be readable by error reporting; the interceptor is the single place to capture and stash them.
- Persisting the session id across hard refreshes (localStorage) would let a support agent follow a user across reloads — a privacy/retention decision (how long to keep it).
Proposed design
Generate a session correlation id (persisted) in the request interceptor, attach it (and a per-request id) to every outgoing call via headers the backend reads, surface the id on all errors including network failures, and log it via the logger context (companion issue). Add tests asserting the header on outgoing requests and on errors.
Acceptance criteria
Service
Tests
Out of scope
Backend-side tracing changes and the logger-context work (companion issues).
Getting started
npm test -- api-interceptor
Good first files to read: src/lib/api.ts, src/lib/errors.ts, src/lib/logger.ts.
Problem
The axios interceptors in
src/lib/api.tsreadx-correlation-idfrom responses (vianormalizeApiError), but nothing generates or attaches a correlation id to outgoing requests. The backend (per the backend repo's correlation middleware) reads incomingX-Correlation-IDheaders and generates its own when absent; without the client sending one, every request the browser makes gets a fresh server-side id. Consequences:correlationIdonNormalizedApiErroris response-only: when the server is unreachable (network error, no response), there is no id at all — the error the operator reports cannot be looked up.loggerdeclarescorrelationId, and the session provider logs events — but the id source (a per-session or per-request id generator) does not exist.Root cause
The correlation feature was implemented on the response/error side only; the request side was never wired.
Why this is architecturally hard
loggerentries (companion issue) and be readable by error reporting; the interceptor is the single place to capture and stash them.Proposed design
Generate a session correlation id (persisted) in the request interceptor, attach it (and a per-request id) to every outgoing call via headers the backend reads, surface the id on all errors including network failures, and log it via the logger context (companion issue). Add tests asserting the header on outgoing requests and on errors.
Acceptance criteria
Service
Tests
Out of scope
Backend-side tracing changes and the logger-context work (companion issues).
Getting started
npm test -- api-interceptorGood first files to read:
src/lib/api.ts,src/lib/errors.ts,src/lib/logger.ts.