# 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 = true` remains anywhere.** > **Track:** frontend · **Depends on:** Phases 2 & 4 · **Unlocks:** — (chain complete) > **Before you start, read [_shared/agent-operating-rules.md](../../phases/_shared/agent-operating-rules.md).** ## 1. Context — where this sits Fixes **H-16b, H-17** and retires the remaining flags from [issues.md](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](issues.md) H-16b/H-17; the refinement-phase-4 file + report (the mapper-fix lesson). - `client/CLAUDE.md` de-mock status block; `mocks-registry.md` frontend section. - The regenerated swagger in `dev/contracts/openapi/` for every DTO you map. ## 3. Scope — build this 1. **H-17 — patientRecords id reconciliation, then flip.** Client `Medication`/`RoutineItem`/ `CareTask.id` are `string` ('m1'/'r1'/'t1' seeds) vs the wire's `long` (`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; then `USE_PATIENT_RECORDS_MOCK=false`. The nurse visit-note half is already contract-real — don't disturb it. 2. **H-16b — partner reachability + gate.** - `Me` gains `administersPartnerCenterId` (REQ-038); `resolveRoleDestination` gains the partner branch (a partner admin lands on `/partner` after login; add the routing unit test). - Gate the portal at the **layout** level: a `PartnerAccessGuard` in `partner/layout.tsx` resolves `useMyPartnerCenter()` once and renders the non-leaking access-denied state on 403/404 before any child page mounts; `nurses`/`bookings`/`settlement` pages stop fetching before the gate resolves. - Flip `USE_PARTNER_MOCK=false` onto the `centers/me*` reads (REQ-032/033). 3. **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), `verification` admin half (REQ-034 — admin queue/case/decide/signed-URL onto real), `payouts` admin 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). 4. **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 the `client/CLAUDE.md` de-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:ci` green; 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](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.md` declaring the chain complete (or listing exactly what remains and why).