backend phase 13 & frontend phase 6
This commit is contained in:
@@ -12,6 +12,29 @@ for awareness.
|
||||
- **Requests filed:** frontend/requests/for-backend.md (yes/no)
|
||||
-->
|
||||
|
||||
## frontend-phase-6-b7 — Search & discovery (find a verified, same-gender nurse) — 2026-07-09
|
||||
- **Shipped:** the family discovery slice — `services/search` (types/keys/constants/apis/hooks + a shared
|
||||
`filterParams.ts` C1↔C2 URL serializer) and screens **C1** `/search` (reused category grid + f3 region
|
||||
picker + prominent same-gender facet + Toman price + live-count CTA; `useSearchFilters` colocated
|
||||
controller with debounced price), **C2** `/search/results` (rating-sorted `NurseResultCard` list, all
|
||||
four states incl. "relax filters" empty, load-more), **C3** `/search/nurse/[nurseId]` (TrustBadge + نظام
|
||||
پرستاری badges, attribute chips, `ServicePriceRow` services, latest review, "درخواست رزرو" handoff).
|
||||
Two shared tested components: `NurseResultCard`, `ServicePriceRow`. `/bookings/request` = f7 handoff stub.
|
||||
i18n `search` (filled) + `booking` (seeded) in both locales. Reused f4 category grid, f5 TrustBadge, f3
|
||||
geo picker, f0 money util — none rebuilt.
|
||||
- **Headline caching:** the **filter object IS the query key** — reverting to a prior filter set is a cache
|
||||
hit with zero network (keepPreviousData avoids flashing); price input debounced.
|
||||
- **Consumes:** dev/contracts/domains/search.md (b7) + b6 trust badge / b5 variant reads.
|
||||
- **Mocked client-side:** `services/search` via `searchMockApi` (**USE_SEARCH_MOCK=true, primary**) — b7's
|
||||
index row + b5/b6 reads don't yet expose nurse name/avatar/distance or an aggregated profile
|
||||
(name/bio/specialties/services list/latest review). Real `searchClientApi` maps what exists; swap is one
|
||||
line once REQ-012 lands. Recorded in the phase report (not mocks-registry — that's for backend DI seams).
|
||||
- **Gate:** npm run check green · npm run test:ci green (165 tests, +8). `npm run build` compiles + types
|
||||
clean; prerender fails only on the pre-existing f5 `/nurse/verification` "Missing .env variable!" (needs
|
||||
env set — unrelated to f6).
|
||||
- **Requests filed:** frontend/requests/for-backend.md — yes (REQ-012: search row name/avatar/distance +
|
||||
`GET nurses/{id}/profile` aggregation).
|
||||
|
||||
## frontend-phase-5-b6 — Nurse verification flow (trust engine) — 2026-07-09
|
||||
- **Shipped:** `services/verification` domain (types/keys/constants/validation/apis[client+mock(primary)+seam]/
|
||||
hooks/index) — ONE cached `status()` query drives B3+B6, every mutation invalidates it. The nurse
|
||||
|
||||
@@ -150,3 +150,24 @@ delivers fixes in its own change. **Frontend never edits backend code to "fix" a
|
||||
- **Also (minor):** the contract's `VerificationStepDto` has no `isRequired` — the client treats **every**
|
||||
seeded step as required (the "X از Y" meter Y = `steps.length`). Confirm that holds, or add `isRequired`.
|
||||
- **Status:** open
|
||||
|
||||
## REQ-012 — Search result + nurse-profile enrichment for discovery (C2/C3) — filed by frontend-phase-6-b7 — 2026-07-09
|
||||
- **Need:** Two extra read surfaces the discovery UI renders but b7/b6/b5 don't yet expose:
|
||||
1. **On the `search/nurses` result row** (`NurseSearchResultDto`): the nurse's **display name** and
|
||||
**avatar URL** (the C2 card's identity) and a **distance** value (km from the searched area) — b7's
|
||||
index row today carries only ids + price/rating/gender/geo ids. Without the name/avatar the card falls
|
||||
back to a generic label + initials; distance is simply hidden.
|
||||
2. **An aggregated public nurse-profile endpoint** for C3 — proposed `GET api/v1/nurses/{id}/profile` →
|
||||
`{ nurseId, nurseName, avatarUrl, bio, yearsExperience, averageRating, totalReviews,
|
||||
totalCompletedBookings, isVerified, inoMembership, attributeChips: string[] (specialty codes),
|
||||
services: [{ variantId, displayName, priceIrr (string), priceUnit, sessionCount? }],
|
||||
latestReview?: { rating, body, authorMasked, createdAt } }`. Today only the b6 public **trust badge**
|
||||
(`nurses/{id}/trust_badge`, giving `isVerified` + `credentialTypes`) and the b5 single-variant read are
|
||||
public — there is no name/bio/specialties/**full services list**/latest-review aggregation.
|
||||
- **Why:** C2/C3 are the trust funnel — the family chooses a real, named, priced nurse here. The
|
||||
`services/search` domain is **mock-primary** (`USE_SEARCH_MOCK = true`) precisely because these fields
|
||||
aren't available; the real `searchClientApi` maps everything b7/b6 do provide and leaves the above blank.
|
||||
When both land, the swap is a single config flip (no hook/component change).
|
||||
- **Proposed shape:** enrich `NurseSearchResultDto` with `{ nurseName, avatarUrl, distanceKm? }`; add
|
||||
`GET api/v1/nurses/{id}/profile` returning the object above. `price`/`priceIrr` stay IRR digit-strings.
|
||||
- **Status:** open
|
||||
|
||||
Reference in New Issue
Block a user