Family Authority, Payment, And Privacy Gap Mining
Family Authority, Payment, And Privacy Gap Mining
Section titled “Family Authority, Payment, And Privacy Gap Mining”Family membership is not payment authority. Reservation ownership is not payer identity. Care-delivery visibility is not financial visibility. Modern commands must freeze the actor, consumed grant revision, booking, product obligation, effective interval, and decision evidence at use time.
sequenceDiagram participant Sponsor as Family sponsor participant Backend as Backend command participant SpiceDB as SpiceDB participant Supabase as Supabase Sponsor->>Backend: Intent plus backend-issued grant reference Backend->>SpiceDB: Check booking and product-scoped capability SpiceDB-->>Backend: Relationship decision Backend->>Supabase: Consume grant revision and freeze actor snapshot Supabase-->>Backend: Revisioned command result Backend-->>Sponsor: Display-ready projection
Frontend never submits allowed, isMother, capability, or visibility booleans.
Supabase stores grant and use evidence; SpiceDB owns relationship decisions;
backend domain/application policies own effective-time and obligation scope.
New P0 Gaps
Section titled “New P0 Gaps”Sponsored booking contract acceptance
Section titled “Sponsored booking contract acceptance”Legacy service intake declares the mother as contracting party and binds booking to authenticated profile. Spouse data is emergency contact, not booking or contract authority. Evidence:
source-refs/sanmopia_web/application/views/service/step1.php:74-93source-refs/sanmopia_web/application/views/service/step1.php:193-209source-refs/sanmopia_web/application/controllers/api/Service.php:18-59
Implementation remains partial under
ADR-021.
FamilySponsorshipGrantorPolicy, ReservationSponsorshipGrant,
FamilySponsoredReservationDraft, SponsoredReservationContractAcceptance,
and one-time acceptance consumption bind the normalized request fingerprint,
contract version, sponsor and mother identities, grant revision, draft revision,
and authenticated actor evidence. Backend 109a717 adds HTTP/runtime
composition, Supabase transaction functions and RLS, generated database types,
and SpiceDB relationship outbox convergence. The changed slice passes 233 tests
plus exact Tach gates. Remaining proof is live migration application,
contract/client convergence, and the positive plus denial stage matrix.
Product-scoped delegated payment capabilities
Section titled “Product-scoped delegated payment capabilities”Legacy has distinct normal deposit, balance, pre-reservation, and payment-change routes:
source-refs/sanmopia_web/application/controllers/api/Payment.php:89-113source-refs/sanmopia_web/application/controllers/api/Payment.php:325-372source-refs/sanmopia_web/application/controllers/api/Payment.php:523-545source-refs/sanmopia_web/application/controllers/api/Payment.php:681-709
One pay_pre_reservation permission cannot express product, phase, adjustment,
amount ceiling, booking, grant revision, or validity window. Target
DelegatedPaymentCapability values:
pay_pre_reservation_deposit, pay_reservation_deposit,
pay_reservation_balance, and pay_reservation_change_adjustment, consumed by
AuthorizeDelegatedPaymentUseCommand and queried through
GetEffectiveDelegatedPaymentDecisionQuery.
Historical payer snapshot
Section titled “Historical payer snapshot”Current payment communication reconstructs payer from grants active when a later event is processed. Revocation or a new delegate can therefore rewrite historical payer and recipient meaning. Legacy also proves only owner access, then notifies mother:
source-refs/sanmopia_web/application/controllers/api/Payment.php:95-113source-refs/sanmopia_web/application/controllers/api/Payment.php:182-193
Target PaymentActorSnapshot, DelegatedPaymentGrantUse, and
PaymentCompletionRecipientDecision. Freeze payer, initiating actor, mother,
recipient, consumed grant revision, and decision time at handoff.
Financial visibility separate from booking visibility
Section titled “Financial visibility separate from booking visibility”Legacy reservation detail and receipt routes are owner-gated:
source-refs/sanmopia_web/application/controllers/MyReservation.php:117-175source-refs/sanmopia_web/application/controllers/MyReservation.php:329-349source-refs/sanmopia_web/application/views/mypage/reservation_receipt.php:121-127
Backend 871defb separates booking care visibility from financial visibility.
The booking graph now has authorized_payer, view_payment, view_refund, and
view_receipt; payment workflow reads and payment-change receipt/detail reads
use those permissions instead of broad booking view. Stage proof preserves
caregiver booking visibility while denying that caregiver payment, refund, and
receipt access. Mother, authorized payer, branch finance, and HQ finance passed
their respective financial checks.
Backend now exposes authenticated mother-only grant and revoke commands for a
reservation-scoped PaymentDelegation. The aggregate owns payment scopes,
effective interval, authority evidence, revision, and revocation reason.
Service-role-only Supabase RPCs persist the lifecycle and atomically enqueue
PGMQ touch/delete mutations; the bounded worker converges expiring SpiceDB
authorized_payer relationships. Stage E2E proved grant/replay, permission
appearance, revoke/replay, permission removal, and reaper cleanup.
Remaining gap: consume a product/phase/amount-scoped grant revision when a real
payment instruction is created and freeze that use into PaymentActorSnapshot.
Inventory every financial projection and prove authenticated HTTP reads; family
directory lifecycle proof alone does not complete participant visibility.
Booking-scoped care-history grants
Section titled “Booking-scoped care-history grants”Legacy validates ownership for each reservation and report:
source-refs/sanmopia_web/application/controllers/MyReservation.php:213-222source-refs/sanmopia_web/application/controllers/api/Report.php:40-52
Backend 903e68d now persists a booking-scoped
ReservationCareHistoryAccessGrant with
revision, scopes, effective interval, authority evidence, revocation actor and
reason, and separate grant/revoke idempotency keys. Service-role-only Supabase
RPCs atomically write the lifecycle and enqueue PGMQ touch or delete work;
the worker converges the exact SpiceDB care_history_viewer relationship.
Contract e4cc9ed publishes exact read, grant, and revoke routes. Public read
decision derives the grantee from the authenticated member
profile and derives the account mother from Supabase. Grant/revoke commands
derive the acting mother from the authenticated session. None of those request
bodies accepts motherMemberId. Daily-report review and rating mutation use a
separate submit_mother_daily_report_review permission plus a backend-owned
booking-to-mother authority reader. Legacy actor_is_reservation_mother, actor,
mother, and rating identities are canonicalized only after both checks pass;
they are never authorization evidence.
The 2026-07-12 authenticated stage smoke proved exact grant replay, delegated
read, cross-booking denial, rejection of a browser-supplied mother field,
mother readiness, forged family-delegate review/rating denial, exact revoke
replay, SpiceDB permission removal, post-revocation denial, and registered DB
plus SpiceDB cleanup. Booking 81af6692-7703-4da4-89cb-9300bfb5b769 used grant
b7d413de-894e-4ada-894a-457823e79815.
Backend a88326b and contract 0d576f2 now complete the content read boundary
described in ADR-024.
A later stage run created booking 9c3b61e4-e81e-424d-8d0e-a73b7f53775a
and grant e3c7ef7a-51c5-47e4-90e3-9486e8915c21, then proved mother and
delegate content reads, backend-resolved labels and notes, review-mutation
denial, revoke, post-revoke denial, and complete registered-data cleanup.
Effective-time revocation
Section titled “Effective-time revocation”Current policy treats any non-null revoked_at as inactive even when evaluating
a time before revocation. It has no operational revoke command or relationship
delete outbox. Target FamilyAuthorityEffectiveInterval,
FamilyAuthorityGrantLifecycle, RevokeFamilyAuthorityGrantCommand,
FamilyAuthorityGrantRevoked, and GetFamilyAuthorityAsOfQuery with invariant
granted_at <= used_at < revoked_at when revocation exists.
Backend 83fe291 establishes FamilyAuthorityEffectiveInterval as shared
domain authority for sponsor, delegated-payment, and care-history grants.
Payment communication evaluates delegation at payment event time, so later
revocation no longer changes historical payer resolution. The reservation
payment-delegation slice now persists lifecycle revisions, exposes an
operational revoke command, and retries the SpiceDB relationship-delete outbox.
Exact replay ignores the newly generated backend clock while rejecting changed
actor, reason, or revision facts. Remaining work is a persisted general
family-authority as-of query and equivalent lifecycle wiring for sponsorship and
care-history grants.
Grant-directory privacy
Section titled “Grant-directory privacy”Current family-account RLS allows a linked family member to list unrelated payment-delegation and care-history grant metadata. Legacy lists reservations by owner only:
source-refs/sanmopia_web/application/controllers/MyReservation.php:22-48source-refs/sanmopia_web/application/controllers/MyReservation.php:73-98
Target FamilyAuthorityGrantDirectoryVisibilityPolicy,
GetFamilyAuthorityDirectoryQuery, and mother-only
GetFamilyAuthorityAdministrationProjection. Backend bb4d6ee creates the
first projection boundary: own view returns only the authenticated member’s
grants, while administration requires mother domain authority and SpiceDB
administer on the family account. Direct Supabase family membership must not
imply authority-directory access. Backend 4477372 removes authenticated raw
grant-table reads for sponsorship, payment-delegation, legacy care-history, and
reservation care-history authority facts, leaving service-role backend reads.
Backend 13dc531 proves withdrawn Supabase member sessions and revoked family
members are denied at API/HTTP boundaries. Backend dde8177 closes the stage
HTTP proof by extending the care-history access smoke: booking
f175bd00-441f-4801-b21d-3081bfa75682 and grant
aecf7aa6-d034-407d-9148-74deb5f87d1c prove active own directory visibility,
hidden authority evidence, non-admin administration denial, revoke, and
post-revoke disappearance from the delegate’s own directory.
Completion Gate
Section titled “Completion Gate”This slice remains incomplete until:
- SpiceDB has product-scoped delegated-payer and financial-view relations;
- backend consumes a revisioned grant and freezes payer evidence atomically;
- care-history content reads continue consuming booking-scoped authorization while review mutation stays mother-only;
- payment-delegation and sponsorship revocation preserve historical facts and emit relationship outbox work;
- Supabase RLS no longer exposes unrelated family authority rows;
- stage E2E proves sponsor booking, mother acceptance, delegated payment, revocation, historical receipt visibility, and denied caregiver finance read.