5839b3508f
Add the discovery layer: the denormalized nurse_search_index read model (one row per bookable variant x covered service area), maintained inline inside each source write's transaction, plus the single public search query behind the INurseSearch seam. - Entity + EF config + migration (search schema): covering search index, filtered-unique (variant_id, city_id, district_id) pair with NULL district participating, nurse_id index, soft-delete. - ISearchIndexMaintainer (write seam) + SearchIndexMaintainer: reindex variant / nurse / fan-out / remove-area / full rebuild, staged in the owning source write's unit of work; wired into the b3/b4/b5/b6 handlers. - INurseSearch (read seam) + SqlNurseSearch (real MVP backend): reads only is_searchable=1, category/city/district(NULL-aware)/gender/price filters, rating sort, pagination. Elasticsearch deferred (config Search:Backend). - SearchNursesQuery (+ validator) and RebuildSearchIndexCommand; public SearchController (GET search/nurses) + admin AdminSearchController (POST admin_search/rebuild_index). - Tests: 9 DB-backed maintainer/search + 4 WebApplicationFactory; updated affected b3/b4/b5/b6 handler tests. Build clean, 167 tests green. - Docs: server CLAUDE.md project map, contract search.md, swagger refresh, handoff, report, mocks-registry rows, STATUS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase reports — template
Every phase writes a report here when it finishes (operating-rules §7, Definition of Done). The report is the durable answer to "what did this phase do, what can I test now, and what's still fake?" — saved to a file, not left in chat.
File name: backend-phase-N-report.md or frontend-phase-N-bM-report.md.
# <Backend|Frontend> Phase N — <Title> — Report (<YYYY-MM-DD>)
## What was built
- Bullet list of concrete deliverables (entities/migrations/endpoints, or screens/services/components).
## What is now testable (and exactly how)
- Step-by-step for a human: e.g. "Swagger → POST /api/v1/auth/otp/request with {phone} → 200; the OTP is
logged to the console; POST /api/v1/auth/otp/verify with that code → returns access+refresh tokens."
- For the frontend: which screen, which route, what to click, expected result, how mock data shows up.
## What is mocked / waiting on a real service
- Each seam touched: interface + file, what's faked, and a link to its entry in `mocks-registry.md`.
## Contracts
- Produced (backend): which `contracts/domains/*.md` + openapi snapshot.
- Consumed (frontend): which contract/version; any request filed in `frontend/requests/for-backend.md`.
## Docs updated
- Which CLAUDE.md / product doc / conventions were updated and why.
## Follow-ups for later phases
- Anything intentionally deferred, with the phase that should pick it up.