# Handoff — after refinement-phase-1 (Database: local-dev story, demo seed & migration hygiene)

**Date:** 2026-07-13 · **Track:** backend (+ DB) · **Unlocks:** real search/discovery/booking data for
[Refinement Phase 4](../../../post-phase/refinement/refinement-phase-4-frontend-de-mock.md).

## What the frontend can now do
- **A fresh Development DB is a populated marketplace, not an empty shell.** On boot (Development only) the API
  now seeds a coherent demo world *after* the reference/lookup seeds. Every real-path discovery/search/booking
  screen has data on the real path — no frontend change required to see it.
- **Log in as real demo accounts** (phone-OTP flow; read the code from the server console or
  `GET /api/v1/dev/last_otp/{phone}`). The accounts already hold the right role, so the role router lands them
  on the correct shell:

  | Phone | Role | Who | State |
  | --- | --- | --- | --- |
  | `09120000001` | nurse | زهرا عزیزی (female) | **verified**, accepting, 3 variants, whole-city + 2 districts |
  | `09120000002` | nurse | علی کریمی (male) | **verified**, accepting, 2 variants, 3 districts |
  | `09120000003` | nurse | مریم احمدی (female) | **unverified** (pending) — never surfaces in search |
  | `09120000010` | customer | سارا محمدی (female) | 2 patients, 1 Tehran address (coords) |
  | `09120000011` | customer | رضا حسینی (male) | 1 patient, 1 Tehran address (coords) |

- **Search returns real nurses.** `GET /api/v1/search/nurses?service_category_id=1&city_id=101` (Elderly Care in
  Tehran) returns the two verified nurses' priced variants. Categories offered only by the unverified nurse
  (Infant Care, `service_category_id=3`) return an empty page — the `is_searchable` invariant holds.
- **Trust badges are real.** `GET /api/v1/nurses/{id}/trust_badge` returns `isVerified=true` + credential types
  for the verified nurses, `false` for the unverified one.
- **The variant builder's required-option step renders on the real path.** The demo seeder adds one
  cross-category **required** option group — شیفت / *Shift Type* (`Daytime`/`Night`/`Live-in`) — so
  `GET /api/v1/catalog/...` option-group reads are non-empty in Development (the "categories but no option
  groups" data gap). This group is **Development-only demo data**, not a production catalog decision.

## What did NOT change (important)
- **No `USE_*_MOCK` flag was flipped** — de-mocking the client is still [Phase 4](../../../post-phase/refinement/refinement-phase-4-frontend-de-mock.md).
  This phase only makes the *backend* real path return data.
- **No new endpoints, no contract changes, no new migration.** The 17 migrations are unchanged and current;
  the reference `HasData` seeds are untouched. The demo seeder writes through the existing entities/handlers.
- **Nothing runs in Production/Staging.** The seeder is gated on `IsDevelopment()`.

## How to reset / re-seed
- `docker compose down -v` (wipe the DB volume) then `dotnet run` → migrate + reference seed + demo seed from
  scratch. Re-running `dotnet run` against an already-seeded DB is a **no-op** (guarded on each persona's phone).

## Gotchas
- **Money is IRR Rials** (e.g. per-24h live-in = `3500000`); on the wire variant prices are digit strings.
- The unverified nurse **has** a variant and a covered area but `is_verified=0`, so the search maintainer
  computes `is_searchable=0`. Do not treat "has a variant" as "is discoverable".
