6.2 KiB
Hardening Phase 5 — Final de-mock & partner reachability (zero mocks left)
Flip the last mocked client domains to the Phase-4 backend, reconcile the patientRecords id-type mismatch that makes its PUT write-unsafe, and make the partner portal reachable from login and actually gated. Exit criteria for the whole chain: no
USE_*_MOCK = trueremains anywhere. Track: frontend · Depends on: Phases 2 & 4 · Unlocks: — (chain complete) Before you start, read _shared/agent-operating-rules.md.
1. Context — where this sits
Fixes H-16b, H-17 and retires the remaining flags from issues.md. After Phase 2 the
mocked surface is: refunds, bnpl, admin, partnerCenter, patientRecords, plus the admin
halves of verification/payouts. Phase 4 delivered (or explicitly re-deferred) their REQs — its
handoff note says exactly which flags may flip. This mirrors refinement-phase-4: a flip is never
assumed to be a pure flag flip — check each clientApi.ts mapper against the delivered DTOs first
(that phase's lesson: delivered fields were being null-overridden by stale mappers).
What already exists (do not rebuild): every domain's real clientApi.ts, the seam-split
mechanics from Phase 2, the partner portal screens, useMyPartnerCenter's access-denied pattern, the
Phase-0 auth gate.
2. Required reading (do this first)
- Phase 4's report + handoff note (which REQs landed; which were re-deferred — a re-deferred REQ means its domain stays mocked and you record why, you don't force it).
- issues.md H-16b/H-17; the refinement-phase-4 file + report (the mapper-fix lesson).
client/CLAUDE.mdde-mock status block;mocks-registry.mdfrontend section.- The regenerated swagger in
dev/contracts/openapi/for every DTO you map.
3. Scope — build this
- H-17 — patientRecords id reconciliation, then flip. Client
Medication/RoutineItem/CareTask.idarestring('m1'/'r1'/'t1' seeds) vs the wire'slong(CarePlanDtos.cs:11-15). Reconcile before flipping: existing items carry the server's numeric id (stringified is fine if the type stays string — but the PUT must send what the server accepts); new items omit the id and let the server assign. Update the mapper +useUpdateCareRecord's optimistic path; thenUSE_PATIENT_RECORDS_MOCK=false. The nurse visit-note half is already contract-real — don't disturb it. - H-16b — partner reachability + gate.
MegainsadministersPartnerCenterId(REQ-038);resolveRoleDestinationgains the partner branch (a partner admin lands on/partnerafter login; add the routing unit test).- Gate the portal at the layout level: a
PartnerAccessGuardinpartner/layout.tsxresolvesuseMyPartnerCenter()once and renders the non-leaking access-denied state on 403/404 before any child page mounts;nurses/bookings/settlementpages stop fetching before the gate resolves. - Flip
USE_PARTNER_MOCK=falseonto thecenters/me*reads (REQ-032/033).
- Flip the rest, mapper-checked, in dependency order:
refunds(REQ-019/020/021 — retire the Phase-2 mock-side preview),bnpl(REQ-022/023/024 — restore the checkout CTA derivation to enabled-when-real; delete the dev gateway-harness page if the real provider redirect replaces it),verificationadmin half (REQ-034 — admin queue/case/decide/signed-URL onto real),payoutsadmin half (REQ-036 — batch preview/run/retry/reference onto real),admin(REQ-029/030/031 — config/ audit/alerts/holidays/RBAC grid real; the RBAC grid consumes Phase 1's RolesController). - Cleanup + honesty pass. Delete now-unused mockApi modules and cross-mock helpers
(
mockGetBookingForRefund,mockInsertConvertedBooking,__mockApproveAll, …) unless a Testing path genuinely uses them (then say so in the registry). No dead code. Update theclient/CLAUDE.mdde-mock block (should read "22/22 real"),mocks-registry.md(frontend rows → 🟢), and the project-structure tree if files moved/died.
4. Mocks & seams in this phase
This phase retires the frontend mock seams. The seam pattern itself stays (it's the test/dev affordance); only the defaults flip. Any domain that must stay mocked (re-deferred REQ) keeps a registry row with the reason + pull-trigger.
5. Critical rules you must not get wrong
- Mapper-check every flip against the real swagger — the refinement-4 lesson. A delivered field a stale mapper drops is a silent regression.
- Money stays served IRR digit-strings; D5 wallet is provider-reported, never a Balinyaar ledger; the
BNPL confirmation reuses the card confirmation (
?method=bnpl). - Partner tenancy is server truth — the client guard is chrome; never pass a center id from the
client to the
me-scoped routes. - Published-only reviews, two-stage disclosure, nurse append-only records — unchanged invariants.
- Per flip: run the affected screen against the live server before moving to the next flag.
6. Definition of Done
grep -rn "USE_.*_MOCK = true" client/src/services→ empty (or each survivor justified in the registry + issues.md).- Journey A end-to-end on real data: login → search → request → accept → pay (card AND BNPL) → booking → cancel/refund path visible → review. Journey B: verification → publish → inbox → accept → EVV → earnings. Admin: verification decide, refund approve, payout run. Partner: login → auto-routed → own center only.
npm run check+npm run test:cigreen; no dead mock code.
7. How to test (human)
Run the two journeys + the admin/partner spot-checks above against the RUNBOOK setup. The demo world personas: customers 0912000000x, nurses (incl. unverified 09120000003), admins 0912000002x, plus the Phase-4 partner admin seed.
8. Hand off & document
- Tick H-16b/H-17 (and the flip checklist) in issues.md with commit hashes.
- Final updates:
client/CLAUDE.md,mocks-registry.md,for-backend.md(all REQs terminal). - Write
dev/shared-working-context/reports/hardening-phase-5-report.mddeclaring the chain complete (or listing exactly what remains and why).