Skip to content

ADR 024 Reservation Care-History Read Model

Legacy caregiver reports joined question labels, answers, and free text through controller-specific queries. Ownership checks differed by surface, ordering was unstable, and browser code interpreted option values. Family visibility and mother-only review mutation were not separate capabilities.

Member Management authorizes an active mother or an exact reservation-scoped family delegate. SpiceDB must also grant view_care_history; this permission never grants submit_mother_daily_report_review.

Care Delivery owns GetReservationCareHistoryQuery. Supabase returns submitted reports through one service-role RPC using stable keyset order: service date descending, caregiver handoff order ascending, submission id descending. Backend resolves definition order, option display labels, value types, notes, and summary counts. Frontend receives render-ready facts and performs no report calculation or authority inference.

Pagination cursor is opaque, versioned, URL-safe base64. Public responses expose no mother id, family grant id, revision, or authority evidence. Missing family authority, missing booking, and denied SpiceDB permission all return generic 404 to prevent booking enumeration. Invalid cursors return 400.

  • Domain shared kernel owns ReservationCareHistoryScope.
  • Member Management owns family reader authority.
  • Care Delivery owns report content projection.
  • Supabase owns canonical report rows, definitions, summary, and keyset page.
  • SpiceDB owns coarse reservation visibility.
  • Contract repository owns public OpenAPI, JSON Schema, and TypeScript types.

Backend a88326b adds DDD feature slices, strict Pydantic models, Supabase RPC, HTTP composition, opaque cursor, and authority/content separation. Contract 0d576f2 publishes route, schema, TypeScript types, and query validator.

Stage run on 2026-07-12 created booking 9c3b61e4-e81e-424d-8d0e-a73b7f53775a and grant e3c7ef7a-51c5-47e4-90e3-9486e8915c21. It proved service-role projection, mother read, delegated read, ordered fields, backend-resolved choice label, caregiver note, review-mutation denial, revocation, post-revoke 404, and DB plus SpiceDB cleanup. Supabase lint returned zero schema errors; focused backend tests, Ruff, and Tach passed. Contract gate passed 396 tests.

Form definitions may evolve without frontend branching. Additional report sections and service days paginate without fixed slots. Historical report content remains tied to submitted definition and policy evidence. Family read access can change without granting review or rating mutation.