Replace the day, timeline and life-event stubs with their implementations (#613) and drop the not-implemented helper, its error code and its OpenAPI response with the last stub. loadDay reads one local day for every reader: the readings live inside the record's own day window (never the UTC rollups), through the canonical-source engine the mood sheet already uses (resolveDayReadings in linked-context.ts), with the person's usual range over the 30 days before; the record sections from their own tables, each in the storage form it speaks (an instant in the local window, a date string with its own zone, a calendar date). A switched-off module's section is not read; a section the grant does not cover is named not_shared and not read. The day, the day index and the new visit preparation (GET /api/day/notable) are admitted on the readings and narrowed per section through actingDomainVisibility, so a scoped grant sees exactly its sections. The timeline and its readiness stay whole-record reads and narrow their lanes the same way. Notable days are deterministic keys: a three-month high or low with history behind it, a first reading, and in the visit preparation a regular reading that stopped. The timeline lays out spans and points from the owning tables, standing items without a date, and series by zoom: months from the rollup tier inside its five-year window and from one cached live query before it. The readiness inventory rates each lane with one link per gap. Life events are created, edited and soft-deleted as MANAGE verbs with audit rows, encrypted at rest, and join the sharing guard and the handler matrix. get_day reads a day for the Coach and the MCP endpoint without life events, notes or document names; its step carries the date it read.
src/app/
The Next.js App Router tree: the page surfaces a logged-in user sees and the REST API under api/. Server components are the default; "use client" is added only where a hook, state, or browser API needs it. Routing is file-based — a page.tsx is a page, a route.ts is an API endpoint.
API routes (api/)
Every endpoint wraps its handler in apiHandler (@/lib/api-handler), parses any body with Zod safeParse, narrows userId from the session or Bearer token (never from the body), and returns the { data, error, meta? } envelope. requireAdmin() is cookie-only, so api/admin/ is unreachable by Bearer token. Notable groups:
auth/— login, register, password, passkey (WebAuthn), refresh, Codex device-OAuth.measurements/,mood-entries/,medications/,sleep/— the core health-data CRUD + batch/bulk ingest.ingest/— external Bearer-token ingest surfaces.insights/,analytics/,dashboard/— AI insights, the Coach SSE stream, trend summaries, the first-paint dashboard snapshot.withings/,whoop/,fitbit/,integrations/,sync/— OAuth connect/sync/webhook surfaces and the offline delta feed.fhir/,share-links/,doctor-report/,export/,import/— clinician-facing FHIR R4 read API, shareable records, report + data export.notifications/,devices/,send/,telegram/— channel registration, device tokens, dispatch, webhook intake.admin/— operator panel APIs (cookie-only).health/,version/,meta/,internal/— health check, build-version probe, runtime metadata, worker-internal routes.
Page surfaces
measurements/, medications/, mood/, insights/, achievements/, notifications/, settings/, onboarding/, admin/, plus the public about/, privacy/, bugreport/, the share-record route c/, and the root dashboard (page.tsx). Shared shell + chrome lives in layout.tsx; error.tsx / global-error.tsx / not-found.tsx / loading.tsx cover the framework boundaries. layout.tsx holds the one nonce-bound dangerouslySetInnerHTML (theme bootstrap).
Conventions
See ../../CLAUDE.md. The request-flow walk in .planning/codebase/arch.md annotates each layer with file:line citations. Related dirs: handlers compose ../lib/; pages render ../components/.