# 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).
