backend phase 4: geography, addresses & nurse service areas
Adds the province -> city -> district reference hierarchy (geo schema, seeded with 31 provinces + capital cities + Tehran's 22 districts), nurse service areas (district_id NULL = whole city, filtered-index-pair uniqueness -> 409), and encrypted, geocoded customer addresses with a single-primary invariant. Introduces the IGeocoder seam (mocked) and 409 Conflict on the result envelope. Public cascading lookups are cached behind a generation-token scheme with invalidate-on-admin-write. One EF migration (GeographyAddressesServiceAreas, applied). Contract + swagger snapshot + handoff/report/registry updated. 103 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,28 @@ One block per completed backend phase. Newest at the top. Backend lane writes he
|
||||
- **Notes for frontend:** <anything load-bearing>
|
||||
-->
|
||||
|
||||
## backend-phase-4 — Geography, addresses & nurse service areas — 2026-07-02
|
||||
- **Shipped:** five tables via one migration (`GeographyAddressesServiceAreas`) — new **`geo`** schema
|
||||
`Provinces` 1:N `Cities` 1:N `Districts` (+ `NurseServiceAreas`) and `usr.CustomerAddresses`; seed
|
||||
(31 provinces + capital cities + Tehran's 22 مناطق via `HasData`); 20 CQRS slices across 4 controllers
|
||||
(`geo` public lookups incl. `/tree`, `admin_geo` CRUD + set_active, `nurse_service_areas`,
|
||||
`customer_addresses`); new **`IGeocoder`** seam (deterministic mock, `Seams:Geocoding`); per-domain
|
||||
repos on `IUnitOfWork`; enc value converters for the address PII columns; **`409 Conflict`** added to
|
||||
`OperationResult`/`BaseController`. Whole-city (`district_id NULL`) uniqueness via a **filtered-index
|
||||
pair**; single-primary address via filtered `UNIQUE(customer_id) WHERE is_primary=1`; geo reads cached
|
||||
behind a generation-token scheme with invalidate-on-admin-write.
|
||||
- **Contracts:** dev/contracts/domains/geography-addresses.md + openapi snapshot refreshed (yes — 20 new
|
||||
geo/service-area/address paths).
|
||||
- **Mocked:** `IGeocoder` → 🟡 (see reports/mocks-registry.md).
|
||||
- **Gate:** build clean (0 new code warnings) / tests green (103 pass: +16 `Baya.Test.Api` integration,
|
||||
+12 handler unit tests). Migration `GeographyAddressesServiceAreas` applies on startup; swagger exposes
|
||||
all b4 paths.
|
||||
- **Handoff:** backend/handoff/after-backend-phase-4.md
|
||||
- **Notes for frontend:** `districtId=null` means **whole city** (a real choice) everywhere. Duplicate
|
||||
service area → **409**. Addresses come back **decrypted for the owner** with `latitude`/`longitude`
|
||||
(nullable when ungeocoded — geocoding is mocked). Routes are action-style (`admin_geo/create_city`,
|
||||
`nurse_service_areas/add`, `customer_addresses/create`, …). Admin geo needs an admin token.
|
||||
|
||||
## backend-phase-3 — Identity: profiles, patients & nurse bank accounts — 2026-07-02
|
||||
- **Shipped:** four `usr` tables via one migration (`IdentityProfilesPatientsBankAccounts`) —
|
||||
`NurseProfiles` (1:1 `Users`; guarded `is_verified` **no public setter**; read-only aggregates;
|
||||
|
||||
Reference in New Issue
Block a user