# Refinement Phase 4 — Frontend de-mock (flip every domain to the real backend) > **Mission:** make the frontend actually call the backend. Today 21 of 22 client service domains default to an > in-browser mock (`USE_*_MOCK = true`), so the running app is almost entirely fake data. Each domain's real > `clientApi` already exists and maps the live routes 1:1 — the swap is a **one-line flag flip per domain**, > once that domain's REQ gaps ([Phase 3](refinement-phase-3-contract-batch.md)) are delivered and the demo data > ([Phase 1](refinement-phase-1-database-and-seed.md)) exists. This phase flips them, in dependency order, and > verifies each against the real API. > > **Track:** frontend · **Depends on:** [Phase 1](refinement-phase-1-database-and-seed.md), > [Phase 2](refinement-phase-2-auth-and-role-nav.md), [Phase 3](refinement-phase-3-contract-batch.md) · > **Unlocks:** a genuinely integrated app > **Before you start, read [../../phases/_shared/agent-operating-rules.md](../../phases/_shared/agent-operating-rules.md).** ## 1. Context — where this sits The frontend was deliberately built **mock-primary** so each phase could ship before its backend counterpart merged. Every domain follows the same seam: `services/{domain}/apis/index.ts` picks `mockApi` vs `clientApi` from a compile-time `USE_{DOMAIN}_MOCK` constant in `constants.ts`; the `clientApi` already wraps `clientFetch` and unwraps the `ApiResult` envelope. The design intent, recorded in every phase report and the mocks-registry, is: **deliver the REQ → flip the flag → the domain is real, with no hook/component change.** This phase executes that flip for every domain. The order matters because the domains form a funnel — a domain whose *inputs* are still mocked can't meaningfully go real (e.g. `bookingRequests` needs `search`/`patients`/ `addresses` real first). Auth is already real and is the template. **Note on flags:** the `USE_*_MOCK` constants are **hard-coded literals**, not env vars. Flipping means editing the `constants.ts` line to `false`. Consider (optional, small) refactoring each to read `process.env.NEXT_PUBLIC_USE_{DOMAIN}_MOCK` with a `false` default so environments can differ without code edits — but the minimum deliverable is the flags flipped to real. ## 2. Required reading (do this first) - **`dev/shared-working-context/reports/mocks-registry.md`** → the "Frontend client-side mocks" table. Every row lists the flag, the file, and the exact "Make it real →" precondition (which REQ + which upstream domain). This is your checklist. - `client/CLAUDE.md` → "services/" section (the per-domain descriptions + their REQ gaps). - `client/src/services/auth/` → the already-real template for how a flipped domain behaves. - Each domain's `apis/clientApi.ts` (verify the routes it maps against the regenerated `dev/contracts/openapi/swagger.v1.json` — especially the ones Phase 3 flagged: partner-center **kebab-case** routes, BNPL `provider_code`, cancellation-policy codes). - The [Phase 3](refinement-phase-3-contract-batch.md) hand-off (which REQs actually landed) — only flip a domain whose gaps are delivered. ## 3. Scope — flip these, in this order Flip each `USE_*_MOCK` to `false` **only after its precondition holds**, then run the domain's screens against the real backend and fix any real-path shape surprises. Group order mirrors the dependency funnel: ### Group 1 — identity & reference (few/no gaps) - `USE_GEOGRAPHY_MOCK` — reference lookups; b4 live, **no REQ needed**. Flip early. - `USE_PATIENTS_MOCK` — needs REQ-005 (relation/conditions). - `USE_PROFILES_MOCK` — needs REQ-006 (avatar) + REQ-007 (name/language). `uploadAvatar` currently throws 501 until REQ-006. - `USE_NURSE_BANK_MOCK` — b3 live, **no REQ**. Flip. - `USE_ADDRESSES_MOCK` — needs REQ-008 (pin) + REQ-009 (provinceId). - `USE_SERVICE_AREAS_MOCK` — b4 live, **no REQ**. Flip. ### Group 2 — catalog, verification, search (the discovery funnel) - `USE_CATALOG_MOCK` — b5 live; **data caveat**: a fresh backend has categories but **no option groups** until Phase 1 seeds them (or the f15 admin authors them). Flip only once option groups exist, or the variant builder's required-option step is empty. - `USE_VERIFICATION_MOCK` — needs REQ-011 (credential_details) + REQ-034 (admin queue/doc-URL/approve). - `USE_SEARCH_MOCK` — needs REQ-012 (name/avatar/distance + public profile). **The linchpin of the funnel.** ### Group 3 — booking funnel - `USE_BOOKING_REQUESTS_MOCK` — needs REQ-013/014 **and** search/patients/addresses real (Groups 1–2). - `USE_BOOKINGS_MOCK` — a booking only exists after a paid request converts, so needs booking-requests + payment real. Also set `NEXT_PUBLIC_EVV_MOCK_GPS=off` to use real `navigator.geolocation`. - `USE_PAYMENT_MOCK` — needs REQ-016 (checkout summary) + REQ-017 (outcome/bookingId) + REQ-018 (invoice) and the upstream request flow real. Delete the dev mock-gateway harness page once flipped. ### Group 4 — money reversal & post-booking - `USE_REFUNDS_MOCK` — needs REQ-019/020/021 (+ canonical cancellation codes) + REQ-035 (admin). - `USE_BNPL_MOCK` — needs REQ-022/023/024 (+ the `balinyaar` provider decision) + upstream real. Delete the BNPL gateway harness page once flipped. - `USE_PAYOUTS_MOCK` — needs REQ-025 (+ REQ-036 admin). - `USE_REVIEWS_MOCK` — needs REQ-026 (+ REQ-037 admin `tagCodes`). - `USE_PATIENT_RECORDS_MOCK` — the nurse visit-note half is already real (b14); the family-record half needs REQ-027 (**and the product decision** on whether it's a real entity). Flip only the parts that are backed; keep the family record mocked if the product defers it. ### Group 5 — comms & admin consoles - `USE_TICKETS_MOCK` — needs REQ-028 + bookings real. - `USE_NOTIFICATIONS_MOCK` — b1 live; real once upstream domains actually **dispatch** notifications (the mock exists because nothing dispatches while upstreams are mocked). Flip after Groups 3–4. - `USE_ADMIN_MOCK` — needs REQ-029/030/031. - `USE_PARTNER_MOCK` — needs REQ-032/033 **and** the route-casing reconciliation (verify the kebab-case routes bind before flipping). ### Cleanup - Remove the dev-only test harness pages once their domains are real: the payment mock-gateway (`…/checkout/gateway/page.tsx`) and the BNPL provider-handoff (`…/checkout/bnpl/gateway/page.tsx`) — on the real path the PSP/provider `redirectUrl` is an absolute URL, so these are never linked. - Remove the dev-only `__mock*` helpers (`__mockApproveAll`, `__mockPublishSubmittedReview`, `__mockPushNotification`, etc.) as their domains go real, or keep them behind a dev guard if still useful. ## 4. Mocks & seams in this phase This phase *retires* mocks. The one client seam that legitimately stays is `ILocationProvider` (EVV GPS capture) — set `NEXT_PUBLIC_EVV_MOCK_GPS=off` to select the real `navigator.geolocation`. The `AddressMapPicker` remains a canvas stand-in until a real map widget is inlined (that's a separate design task, not a data mock). ## 5. Critical rules you must not get wrong - **Don't flip a domain whose inputs are still mocked** — you'll get empty screens or shape errors. Follow the group order; a domain is only real if the whole chain beneath it is. - **Verify each `clientApi`'s routes against the regenerated swagger before flipping** — Phase 3 flagged three concrete casing/enum mismatches (partner-center kebab-case, BNPL `balinyaar`, cancellation codes). A wrong route silently 404s. - **The flip is a flag, not a rewrite.** If a screen needs a hook/component change to work on the real path, that's a Phase 3 gap that wasn't fully delivered — file/finish the REQ, don't hack the component. - **`npm run check` and `test:ci` stay green** after each flip; keep `en.json`/`fa.json` in sync (no new strings expected, but empty/error states may surface copy that was never exercised on the mock path). - **Real error/empty states now matter.** The mocks always returned tidy data; real endpoints 404/return empty. Verify each domain's empty, error, and loading states against the real backend — this is where mock-only apps break. ## 6. Definition of Done On top of the shared [definition-of-done.md](../../phases/_shared/definition-of-done.md): - [ ] Every domain whose REQ preconditions are met has `USE_*_MOCK = false` and is verified working against the real backend; any domain still mocked is because its REQ/product decision is explicitly outstanding (documented, not forgotten). - [ ] `npm run check` + `npm run test:ci` green; translations in sync. - [ ] The full happy path runs on real data end-to-end: log in → browse categories → search → open a nurse profile → request a booking → nurse accepts → checkout → confirmation → booking detail → review. - [ ] Dev test-harness pages + `__mock*` helpers for real domains removed or dev-guarded. - [ ] `client/CLAUDE.md` and the mocks-registry updated to reflect which domains are now real. ## 7. How to test (what a human can verify after this phase) 1. With client + server running on real data (Phases 0–3 done), open the app and confirm the **Network tab shows real `/api/v1/*` calls for every screen** (not just auth) — no domain is serving in-browser mock data. 2. Walk the customer funnel: home category grid → search (real seeded nurses) → nurse profile → request → (switch to the nurse account) accept → (customer) checkout → pay (mock gateway is gone; on a real PSP this is [Phase 8](refinement-phase-8-external-rails.md), but the request→booking conversion works) → confirmation → booking detail. 3. Nurse funnel: verification flow, services builder, coverage, requests inbox, visits/EVV, earnings — all on real data. 4. Admin: verification queue, refunds, payouts, moderation, config/holidays/audit, partner centers — on real data with role-gated nav (Phase 2). 5. Confirm empty/error states render correctly where the demo data is sparse (e.g. a nurse with no reviews). ## 8. Hand off & document (close the phase) - Update `client/CLAUDE.md` "services/" notes and `dev/shared-working-context/reports/mocks-registry.md` (frontend mocks table) to mark each flipped domain real. - Report the flip status of all 22 domains (real / still-mocked-because-X) and any real-path surprises found. Save a memory note on the de-mock order and any domain that needed a Phase-3 follow-up.