# Fix plan — how to close every item in blockers.md

An index into [`blocker-phases/`](blocker-phases/), an engineering-facing companion to
[blockers.md](blockers.md): one numbered file per fix, in a suggested working order. Each file has the exact
root cause (file:line), the proposed fix, and anywhere the fix depends on a business-rule decision that
shouldn't be guessed. Written from a full read of the current code (commit `fb58ca5`, 2026-08-02). Phases 01
and 02 are applied (see Status column); the rest are unapplied — work through them at your own pace, in
whatever order you prefer.

> **Two blockers already got a scope decision, recorded so it isn't re-litigated:** §B.4 (مودیان
> e-invoicing) gets a note in [forgotten-features.md](forgotten-features.md) instead of a build — no chosen
> provider to integrate against. §B.6 (bank-transfer payout rail) stays mocked — the seam already exists, see
> phase 11.

## Phases

| # | File | Blocker | Depends on | Status |
| --- | --- | --- | --- | --- |
| 01 | [admin-rbac](blocker-phases/01-admin-rbac.md) | Admin can't do anything (the #1 leverage item) | — | ✅ Done |
| 02 | [reviews-moderation](blocker-phases/02-reviews-moderation.md) | Reviews can never go live | 01 | ✅ Done (no separate fix needed — unblocked by 01) |
| 03 | [address-edit-bug](blocker-phases/03-address-edit-bug.md) | Editing an address wipes recipient name/phone | — | ✅ Done |
| 04 | [payment-timezone](blocker-phases/04-payment-timezone.md) | The 30-minute payment countdown can lie | — | ✅ Done (follow-up filed below) |
| 05 | [bnpl-setup](blocker-phases/05-bnpl-setup.md) | Installments (BNPL) don't work at all | — | — |
| 06 | [catalog-admin-page](blocker-phases/06-catalog-admin-page.md) | No admin page for service categories/pricing | — | — |
| 07 | [card-payment-redirect](blocker-phases/07-card-payment-redirect.md) | Card payment can never complete | — | — |
| 08 | [refunds-demock](blocker-phases/08-refunds-demock.md) | Refunds are demo-only, off by 100× | — | — |
| 09 | [nurse-verification-badge](blocker-phases/09-nurse-verification-badge.md) | Verification badge doesn't reflect reality | pairs with 10 | — |
| 10 | [search-dedup-and-trust](blocker-phases/10-search-dedup-and-trust.md) | Search isn't de-duplicated; trust info hardcoded | pairs with 09 | — |
| 11 | [nurse-payouts](blocker-phases/11-nurse-payouts.md) | Nurse pay/payouts are fake, no "process" action | benefits from 01 | — |
| 12 | [patient-records](blocker-phases/12-patient-records.md) | Patient records & visit notes are fake demo data | needs a product decision first | — |
| 13 | [booking-lifecycle](blocker-phases/13-booking-lifecycle.md) | Stuck bookings; "today's visits" unfiltered | pairs with 04 | — |
| 14 | [partner-center](blocker-phases/14-partner-center.md) | Partner/business-center accounts are fake | benefits from 01 | — |
| 15 | [debug-mode-production](blocker-phases/15-debug-mode-production.md) | Turn off dev mode on the live site (§B.2) | do last, deliberately | — |

## Follow-ups filed (not yet phases of their own)

- **Same timezone bug as 04, lower severity, not fixed.** Phase 04 fixed `BookingRequest.PaymentDeadlineAt`/
  `NurseResponseDeadlineAt` — a `DateTime` (not `DateTimeOffset`) read back from SQL Server's `datetime2`
  loses its `Kind` tag (comes back `Unspecified`), so JSON serialization drops the trailing `Z` and a client
  `Date.parse()` misreads it as local time. A grep for every other bare `DateTime`/`DateTime?` entity property
  found four more real instances, all on `Booking` (`server/src/Core/Baya.Domain/Entities/Booking/Booking.cs`):
  `DisputeWindowEndsAt` (:95, rendered via `formatShamsiDate` in
  `client/src/components/booking/BookingDetailView/BookingDetailView.tsx:444`), and `ConfirmedAt`/
  `CancelledAt`/`CompletedAt` (:73,74,91), booking timeline timestamps shown to the client. Lower severity than
  04 — nothing here drives a live countdown, so the failure mode is "can show the wrong calendar day near a
  Tehran (UTC+3:30) midnight boundary," not "actively expires while still showing time left." (Everything
  else with a bare `DateTime` — payout batches, webhook events, ASP.NET Identity tables — is internal/audit-only
  and never reaches a client, so it's excluded.) Fix is the same pattern phase 04 used: apply the existing
  `UtcDateTimeConverter` (`server/src/Infrastructure/Baya.Infrastructure.Persistence/ValueConversion/
  UtcDateTimeConverter.cs`) to these four properties in `BookingConfig.cs`. No migration needed. Deliberately
  left undone — pick up as its own small phase, or fold into whatever eventually addresses 13b's timezone
  decision (booking-lifecycle's "today's visits" fix), since both are the same missing
  `Asia/Tehran`/UTC-boundary discipline.

## Suggested order

1. **01 (admin RBAC)** — unlocks 02, and makes 09/10/11/14 independently testable via the seeded
   `super_admin`/`finance` accounts.
2. **Small, contained, no dependencies:** 03, 04, 05, 06.
3. **De-mock passes, each roughly self-contained:** 08, 09+10 together, 11.
4. **Needs a product decision before coding:** 12 (medication/routine schema), 13a (all-missed edge case).
5. **14 (partner center)** — the largest single phase, mostly new server surface.
6. **15 (debug mode)** — on its own, right before any real user is let near the site.
