Files
baya-monorepo/dev/post-phase/hardening/hardening-phase-5-final-demock.md
T
2026-07-17 13:22:04 +03:30

97 lines
6.2 KiB
Markdown

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