Files
baya-monorepo/mvp/fix-plan.md
T
2026-08-02 23:24:28 +03:30

9.3 KiB
Raw Blame History

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

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

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

  • Phase 08 closed the customer-facing refund surface only — the admin refund console stays mocked. AdminRefundsController only implements create-and-execute (POST admin_refunds, matching initiateRefund); there is no real read-only preview, no retry/approve, and no reject route. The phase doc's own read ("real server side is live and correct") only checked the customer half (RefundsController, CreateRefundCommand, GetCancellationPolicyPreviewQuery) — the admin gaps weren't called out and would have 404'd the console had the single mock flag been flipped wholesale. Split into two independently-selected flags instead (client/src/services/refunds/constants.ts): USE_CUSTOMER_REFUNDS_MOCK = false (real — closes the actual ×100 money-safety bug) and USE_ADMIN_REFUNDS_MOCK = true (stays mocked; the four admin methods are kept together rather than mixed, since a real initiateRefund executing against a mocked preview's numbers would be actively dangerous). Building the missing preview/retry/reject endpoints needs real design (retry semantics re-executing a channel call, what "reject" reverses) that isn't specified anywhere — filed as its own future phase, not guessed here.

  • 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.

  • Phase 12 closed everything except the medication/routine schema decision, which stays deliberately unresolved. Fixed: the silent data-wipe (patients/[id]/record/page.tsx's EditableTabs.save now always resends the full medications/routine/tasks triple, not just the tab being edited — the real UpsertCarePlanCommand fully replaces all three from the request, no server-side merge); the RecordAccess.deniedReason enum (client now matches the server's real 'not_authorized' | 'not_found', was 'no_access' | 'not_found'); and the visit-note taskResults mapper bug (clientApi.ts was hardcoding taskResults: [] on read and folding the checklist into free text on write, even though CareRecordDto already serves a structured TaskResults array and WriteCareRecordBody already accepts one — both sides now pass the array through directly). Also corrected the stale "no backend at all" comments in constants.ts/types.ts/clientApi.ts/mockApi.tsPatientCareRecordsController implements every route this domain needs. Still open, on purpose: the client's medication/routine shape (structured dose amount/unit, frequency preset codes, a multi-select timeOfDay) doesn't match the server's (one free-text dose, one required frequency string, no timeOfDay on either medications or routine items) — see phase 12's items #3/#4. Asked which side should change; the answer was to leave both as they are for now and just keep this note so it isn't lost. USE_PATIENT_RECORDS_MOCK therefore stays true, and the id-type mismatch (client string ids vs. the wire's long, phase 12 item #2) is left unfixed too — it can't be finished without first knowing the target field shape, since getFamilyRecord/updateFamilyRecord would need a real mapping function between the two, not just an id conversion.

  • ZarinPal-callback translator, latent until a real gateway is switched on. Phase 07 restored the mock-gateway harness and pointed MockPaymentProvider.InitPaymentAsync's redirectUrl at it (relative URL, no more dead mock-psp.local host) — the card-payment dead end (blockers.md § "Payments") is closed for the mock path, which is the only path reachable pre-e-namad (§B.5). Once a real acquirer is ever switched on, ZarinPal's callback redirects the browser with its own query params (Authority, Status) — nothing under Controllers/V1 today translates that into what checkout/return/page.tsx expects (request_id/transaction_id/outcome). Needs a translating endpoint/route before the real path can work; deliberately out of scope of the mock fix, and moot until §B.5 clears.

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.