backend phase 15 & frontend phase 8

This commit is contained in:
hamid
2026-07-10 03:22:29 +03:30
parent 93cc5ecb98
commit cd6c2591a6
154 changed files with 15335 additions and 37 deletions
@@ -12,6 +12,39 @@ for awareness.
- **Requests filed:** frontend/requests/for-backend.md (yes/no)
-->
## frontend-phase-8-b9 — Booking detail, sessions & nurse EVV — 2026-07-10
- **Shipped:** the post-payment engagement — a **new** `services/bookings` domain (the sibling of
`bookingRequests`, NOT a rename): types/keys/constants/apis[client(1:1 b9)+mock+serverApi]/8 hooks +
barrel, plus the `evv/locationProvider.ts` **ILocationProvider** GPS seam. Screens: customer **رزروها
list** `/bookings` + **booking detail** `/bookings/[id]` (BookingDetailView, customer view), nurse
**ویزیت امروز** `/nurse/visits` (today-sessions EVV feed) + **nurse booking detail** `/nurse/visits/[id]`
(EVV controls + gated care). Seven shared tested composites under `src/components/booking/`:
`BookingDetailView`, `BookingStatusTimeline` (server-truth 7-status), `SessionList``SessionCard`
(per-session schedule/status/EVV CTA), `EvvStatusBanner` (advisory in/out-of-range/no-gps), `CareInstructionsCard`,
`BookingMoneySummary`, + `useEvvController`. i18n `booking` extended (`bstatus_*`/`sstatus_*`/`evv_*`/`care_*`/
`money_*`/`list_*`) both locales; new icons (check_in/out, gps, clinical, medication, emergency, lock) +
`--bal-secondary-soft` token.
- **Load-bearing rules honored:** **two-stage disclosure is a UI gate**`useCareInstructions` is
`enabled` only for the assigned-nurse view on a `confirmed`+ booking; the customer NEVER fires it (proven
by test). **EVV mismatch/GPS-denial is advisory, never a block** — out-of-range check-in still succeeds
(warning-tokened banner, not error); denial still submits. **Timeline = server truth** (never advanced
client-side); **money display-only** (gross/commission/payout rendered as sent, never summed/re-split;
`payoutEligibleAt` never recomputed); single-visit renders one session row through the same card; EVV
mutations **invalidate** detail+sessionEvv+today+list.
- **Consumes:** dev/contracts/domains/bookings-evv.md (b9) + swagger `BookingDetailDto`/`BookingSessionSummaryDto`/
`VisitVerificationDto`/`CareInstructionsDto``services/bookings/types.ts` derives from these 1:1.
- **Mocked client-side:** `services/bookings` via `bookingsMockApi` (**USE_BOOKINGS_MOCK=true, primary**) —
seeds 2 confirmed bookings (one 3-session, one single-visit) + care + a check-in/out EVV state machine,
because a real booking only exists after `bookings/convert` runs on a paid request and both upstreams
(bookingRequests mock, card capture b10) aren't real client-side yet. Real `bookingsClientApi` maps the
routes 1:1; swap is one flag. Also the **ILocationProvider** GPS seam (`NEXT_PUBLIC_EVV_MOCK_GPS`
in_range|out_of_range|denied|off) — the first frontend seam recorded in mocks-registry.
- **Gate:** npm run check green · npm run test:ci green (195 tests, +22). Added a committed
`NEXT_PUBLIC_API_URL` default in `jest.setup.ts` (first test to render a service-hook component pulled
`@/config` at import).
- **Requests filed:** frontend/requests/for-backend.md — yes (REQ-015: confirm the booking/session/EVV enum
string codes + the `checkInAddressMatch` tri-state semantics the client unions assume).
## frontend-phase-7-b8 — Booking request flow (customer request + nurse inbox) — 2026-07-09
- **Shipped:** the money-free request phase — `services/bookingRequests` (types/keys/constants/apis[client+
mock]/hooks + barrel) and screens **C4** `/bookings/request` (patient/variant/address/date+time + a
@@ -195,3 +195,22 @@ delivers fixes in its own change. **Frontend never edits backend code to "fix" a
`variantLabel` on the row makes the inbox self-describing; a coarse age is a nice-to-have for triage.
- **Proposed shape:** `BookingRequestListItemDto { …, variantLabel: string, patientAge?: int }`.
- **Status:** open
## REQ-015 — Confirm the booking/session/EVV enum codes + `checkInAddressMatch` tri-state — filed by frontend-phase-8-b9 — 2026-07-10
- **Need:** Two confirmations so the f8 `services/bookings/types.ts` client unions stay wire-accurate:
1. **Enum string codes.** The b9 swagger types `status`/`evvStatus`/session `status` as bare `string`
(no enum constraint). Confirm the stable wire codes match the client unions: `BookingStatus`
= `pending_payment|confirmed|in_progress|completed|disputed|closed|cancelled`; `BookingSessionStatus`
= `scheduled|in_progress|completed|missed|cancelled`; `VisitVerificationStatus`
= `pending|checked_in|completed`. (They match the contract doc's "Enums used" — this just asks that the
serialized JSON emits these exact snake_case codes, not PascalCase/int.)
2. **`checkInAddressMatch` tri-state semantics.** The EVV banner keys off it as: `true` = in range
(«موقعیت تایید شد»), `false` = out-of-range/advisory-under-review («موقعیت خارج از محدوده»), `null` =
GPS unavailable/denied («موقعیت ثبت نشد»). Confirm the server returns `null` (not `false`) when the
nurse checked in **without** coordinates (GPS denied), so the UI can distinguish "flagged mismatch"
from "no position captured". A mismatch stays advisory server-side (support alert, never a block) — the
UI mirrors that.
- **Why:** f8 renders the status timeline, per-session chips, and the EVV banner strictly off these codes;
a casing/int drift or a `false`-vs-`null` conflation would mislabel a visit. Low-risk (mock-primary now),
but worth locking before f9/f13 consume the same shapes.
- **Status:** open