# Balinyaar phase roadmap

The build, as a dependency-ordered chain of agent prompts. Two tracks — **backend** and **frontend** —
that can run in parallel (two agents) coordinated only through [`../contracts/`](../contracts/README.md)
and [`../shared-working-context/`](../shared-working-context/README.md).

> **Every agent: read [`_shared/agent-operating-rules.md`](_shared/agent-operating-rules.md) first.**
> It carries the rules each phase file assumes (how to work, the gate, contracts, the handoff, reports,
> memory). The per-phase files stay focused on *what* to build.

## Naming

- Backend: `backend/backend-phase-N.md` — run in order, `N = 0…15`.
- Frontend: `frontend/frontend-phase-N-bM.md` — the **`bM` suffix is the highest backend phase that must
  be merged before this frontend phase starts** (earlier backend phases are implied; `frontend-phase-0`
  has no backend dependency). Within the frontend track, run in order `N = 0…15`.

## How to run a phase

Point a fresh agent at one file: *"Execute `dev/phases/backend/backend-phase-5.md` end to end."* The file
lists its required reading, scope, mocks, rules, Definition of Done, how-to-test, and close-out. It links
the prior phases whose work it builds on, so nothing is duplicated.

## Dependency graph

```mermaid
flowchart TD
  subgraph BACKEND
    b0[b0 Foundation·seams·cleanup·REST·rate-limit] --> b1[b1 Config & Reference]
    b1 --> b2[b2 Identity — auth/OTP/sessions]
    b2 --> b3[b3 Identity — profiles/patients/bank]
    b1 --> b4
    b3 --> b4[b4 Geography·addresses·service-areas]
    b3 --> b5[b5 Catalog & pricing]
    b4 --> b5
    b3 --> b6["b6 Nurse verification (mock)"]
    b5 --> b7[b7 Search & matching]
    b6 --> b7
    b5 --> b8[b8 Booking requests & lifecycle]
    b7 --> b8
    b8 --> b9[b9 Bookings·sessions·care·EVV]
    b9 --> b10[b10 Payments core: ledger·txn·webhook·capture]
    b1 --> b10
    b10 --> b11[b11 Refunds·invoices·clawbacks]
    b10 --> b12["b12 BNPL (mock)"]
    b11 --> b13["b13 Payouts (mock)"]
    b12 --> b13
    b9 --> b14[b14 Reviews & patient records]
    b3 --> b15[b15 Messaging·notifications·partner·admin backoffice]
    b11 --> b15
    b13 --> b15
    b14 --> b15
  end
  subgraph FRONTEND
    f0[f0 Foundations·shells·design-system·contracts client] --> f1[f1-b2 Auth & OTP]
    f1 --> f2[f2-b3 Onboarding & profiles]
    f2 --> f3[f3-b4 Addresses & geo]
    f3 --> f4[f4-b5 Catalog browse & service builder]
    f4 --> f5[f5-b6 Nurse verification flow]
    f5 --> f6[f6-b7 Search & discovery]
    f6 --> f7[f7-b8 Booking request flow]
    f7 --> f8[f8-b9 Booking detail·sessions·EVV]
    f8 --> f9[f9-b10 Checkout & payment]
    f9 --> f10[f10-b11 Refund & cancellation]
    f10 --> f11[f11-b12 BNPL checkout]
    f11 --> f12[f12-b13 Nurse earnings & payouts]
    f12 --> f13[f13-b14 Reviews & patient records]
    f13 --> f14[f14-b15 Messaging & notifications]
    f14 --> f15[f15-b15 Admin & partner consoles]
  end
  b2 -. contract .-> f1
  b3 -. contract .-> f2
  b4 -. contract .-> f3
  b5 -. contract .-> f4
  b6 -. contract .-> f5
  b7 -. contract .-> f6
  b8 -. contract .-> f7
  b9 -. contract .-> f8
  b10 -. contract .-> f9
  b11 -. contract .-> f10
  b12 -. contract .-> f11
  b13 -. contract .-> f12
  b14 -. contract .-> f13
  b15 -. contract .-> f14
  b15 -. contract .-> f15
```

## Backend track

| # | Phase | Builds (entities / capabilities) | Seams introduced |
| --- | --- | --- | --- |
| b0 | Foundation, seams & cleanup | Delete `Order` + old migrations; add the REST controller surface + rate limiting; register `LoggingBehavior`; `ICurrentUser` + audit-field SaveChanges interceptor; define + DI-register the cross-cutting seams & their mocks; mock-report discipline | `ICacheService`, `IObjectStorage`, `IFieldEncryptor`, `IDateTimeProvider`, `INotificationDispatcher` (stub) |
| b1 | Config, reference & platform signals | `platform_configs` (+ typed cached accessor + seed keys), `audit_logs` (+ interceptor writes), `system_events`, `iranian_holidays` (+ seed), **`notifications`** (write + list/read + retention) and **`support_alerts`** (raise API; built early because verification/booking/payments/reviews all raise them); **first marketplace migration baseline**; admin config/holiday/audit endpoints | `IHolidayCalendar`, `IAnalyticsSink`, `INotificationDispatcher` (real in-app write) |
| b2 | Identity — auth | REST OTP login (`/auth/otp/request|verify`, `/auth/refresh`, `/auth/logout`, `/me`); `users` extensions (gender, national_id…), `user_sessions` (rotation + reuse detection), role selection; wire real SMS seam delivery | `ISmsSender` |
| b3 | Identity — profiles | `nurse_profiles`, `customer_profiles`, `patients` (CRUD + tenancy), `nurse_bank_accounts` (+ ownership-inquiry seam) | `IBankAccountOwnershipVerifier` |
| b4 | Geography & addresses | `provinces`/`cities`/`districts` (+ seed), `nurse_service_areas`, `customer_addresses` (+ geocode) | `IGeocoder` |
| b5 | Catalog & pricing | `service_categories`/`service_option_groups`/`service_option_values` (admin + seed), `nurse_service_variants`/`nurse_service_variant_options` (nurse builder, price units) | — |
| b6 | Nurse verification (mock) | `nurse_verifications`, `verification_step_types` (+seed), `verification_steps`, `verification_documents`, `nurse_credentials`; the guarded `is_verified` flip; admin review queue; bank-account verification step | `IShahkarVerifier`, `IIdentityKycProvider`, `ICredentialVerifier` |
| b7 | Search & matching | `nurse_search_index` (fan-out + maintenance hooks), the search query (category/city/district/gender/price, rating sort) behind a search seam | `INurseSearch` |
| b8 | Booking requests & lifecycle | `booking_requests` (create/accept/reject + expiry job), deadlines (config), same-gender + tenancy validation | — |
| b9 | Bookings, sessions, care & EVV | `bookings` (3-amount split, conversion command), `booking_sessions`, `booking_care_instructions` (two-stage disclosure), `visit_verifications` (EVV check-in/out), `cancellation_policies`; dispute-window set on completion | (reuses `IGeocoder` for GPS match) |
| b10 | Payments core | `payment_gateways`, `payment_transactions` (filtered uniques), `payment_webhook_events` (idempotency), `ledger_entries` (double-entry, 6 account types), card capture → confirm → convert booking, Redis lock on money path | `IPaymentProvider`, `ISettlementSplitProvider`, `IWebhookVerifier`, `IDistributedLock` |
| b11 | Refunds, invoices, clawbacks | `refunds` (1:N, fee/payout decomposition, channel-aware, ticket-linked), refund ledger postings, `nurse_clawbacks`, `invoices` (VAT on commission) | `IMoadianClient` |
| b12 | BNPL (mock) | `bnpl_transactions` (1:1, state machine), BNPL settle ledger (`bnpl_fee_expense`), revert/update path, callbacks via webhook idempotency | `IBnplProvider`, `ICurrencyNormalizer` |
| b13 | Payouts (mock) | `nurse_payout_batches`, `nurse_payouts`, `nurse_payout_booking_links` (booking_id UNIQUE), weekly batch, holiday-aware scheduling, clawback netting, eligibility gating | `IBankTransferProvider` |
| b14 | Reviews & patient records | `reviews` (1:1 booking, moderation, aggregate recompute), `review_tags_master`/`review_tag_links`, `patient_care_records` (encrypted, patient-scoped), low-rating → support alert | `IReviewModerationService` |
| b15 | Messaging, partner & admin backoffice | `tickets`/`ticket_participants`/`ticket_messages` (`is_internal`), the `support_alerts` admin worklist (table/raise from b1), `partner_centers` (merchant-of-record + sponsor), admin backoffice consolidation (verify/refund/payout/moderation/config worklists), refund↔ticket link; deferred tables stay inactive | `ILicenseVerificationService` |

## Frontend track

| # | Phase (file) | Needs | Builds (screens / flows) |
| --- | --- | --- | --- |
| f0 | `frontend-phase-0.md` | — | Remove demo scaffolding; the three actor app shells (customer mobile + bottom nav, nurse, admin) & route groups; the `services/{domain}` + Query caching pattern; the contracts→types pattern; shared composite components (OTP input, cards, stepper, price-breakdown); i18n namespaces; RTL baseline |
| f1 | `frontend-phase-1-b2.md` | b2 | Phone login (A1), OTP (A2), customer/nurse login switch, role router; replace username/password with OTP; roles in `AuthContext` |
| f2 | `frontend-phase-2-b3.md` | b3 | "Who is care for" (A3), add/list/edit patient (A4), customer profile, nurse profile bootstrap, nurse bank-account settings |
| f3 | `frontend-phase-3-b4.md` | b4 | Address book + map picker + cascading province/city/district; nurse coverage-area editor |
| f4 | `frontend-phase-4-b5.md` | b5 | Customer home + category grid (A5), nurse "add a service" builder (B7 services), catalog browse |
| f5 | `frontend-phase-5-b6.md` | b6 | Nurse verification: status checklist (B3), identity submit (B4), credentials (B5), under-review (B6), document upload, trust badge |
| f6 | `frontend-phase-6-b7.md` | b7 | Search & filter (C1), results (C2), nurse profile (C3) |
| f7 | `frontend-phase-7-b8.md` | b8 | Request form (C4), awaiting-acceptance (C5) + status tracker; nurse request inbox (accept/reject) |
| f8 | `frontend-phase-8-b9.md` | b9 | Booking detail & sessions; nurse EVV check-in/out (E3 top); care-instructions (post-confirm); status timeline |
| f9 | `frontend-phase-9-b10.md` | b10 | Summary & pay (C6) w/ commission/tax/escrow notice; card payment (mock redirect); confirmation; invoice |
| f10 | `frontend-phase-10-b11.md` | b11 | Cancellation flow (policy fee disclosure); customer refund status (BNPL ETA) |
| f11 | `frontend-phase-11-b12.md` | b12 | BNPL: method (D1), plan (D2), eligibility (D3), contract/schedule (D4), wallet/installment status (D5) |
| f12 | `frontend-phase-12-b13.md` | b13 | Nurse earnings & payout history (pending/eligible/paid/clawback) |
| f13 | `frontend-phase-13-b14.md` | b14 | Leave a review; nurse profile reviews tab; patient record viewer (E2); nurse visit notes (E3 note); longitudinal history |
| f14 | `frontend-phase-14-b15.md` | b15 (+ b1 notifications) | Ticket inbox + thread (support); notification center/bell (polling unread count); emergency banner |
| f15 | `frontend-phase-15-b15.md` | b15 | Admin backoffice console (verification queue, refunds, payouts, moderation, config/holidays/audit, support alerts) + partner-center portal |

## Scope notes & deferrals (apply across phases)

- **MVP-only:** items the product docs tag DEFERRED stay out — availability hard-filtering, recurring
  schedules, surge/holiday pricing, two-way reviews, push/SMS notification channels, مودیان automation,
  org/employer model, ML fraud, customer national-ID KYC, in-house BNPL credit. Build the *seam/flag*,
  not the feature, where a phase calls for it.
- **Everything fake is a seam.** No phase ships a hidden stub; mocks live behind interfaces in the
  [mock registry](../shared-working-context/reports/mocks-registry.md).
- **Money correctness is sacred** across b9–b13: IRR `BIGINT`, the three-amount split, append-only
  balanced ledger, webhook idempotency, dispute-window gating, one-payout-per-booking. The
  [payments contract conventions](../contracts/conventions/money-and-types.md) bind both tracks.
