16 KiB
Deferred — recorded, not re-decided
Last verified: 2026-08-02 against commit
cd8144e. Populated by phase 5 of the documentation clean-up chain.
51 items carry deferred status in backlog.md: the 43 in its dedicated
"Deferred" section (BL-220–BL-262), plus 8 more filed by severity
elsewhere in the same file whose Status column also reads deferred (BL-050, BL-075, BL-082, BL-096,
BL-163, BL-168, BL-201, BL-219). This file records them faithfully — it does not re-litigate any of
them. A deferral with a trigger is a decision; every row below has one, preserved in substance from its
source. Grouped by theme, as backlog.md itself groups its Deferred section.
How to read "size" below: this column is this document's own estimate (S / M / L / XL), not carried from any source file — backlog.md doesn't size deferred items, so sizing them is this phase's proposal, made to help a future reader triage, and open to revision.
The 8 unbuilt product tables
Named individually per the phase brief, cross-referenced from implemented.md:
| Table | Backs | BL-### | Pull-trigger |
|---|---|---|---|
organizations |
Employer/company account model | BL-224 | Product pulls it |
organization_nurses |
Employer↔nurse membership | BL-224 | Product pulls it |
fraud_flags |
ML-scored fraud signals | BL-225 | Product pulls it (manual suspension + support alerts cover this today) |
recurring_booking_schedules |
Recurring/subscription bookings | BL-226 | Product pulls it |
bnpl_settlement_entries |
Tranched BNPL settlement | BL-227 | Product pulls it, or a future BNPL provider tranches settlement (one settlement row covers today's provider) |
nurse_availability_slots |
Soft scheduling-guidance windows | BL-228 | Product pulls it |
nurse_availability_exceptions |
Time-off exceptions to the above | BL-228 | Product pulls it |
incidents |
First-class incident entity | BL-244 | Product pulls it (support alerts cover this today) |
All eight are, per refinement-phase-9's own framing (item 9.11 in that phase's handoff, distilled in decisions.md), pure additive migrations — nothing in the current schema needs to change first when one is pulled forward. The same source item 9.11 also grouped in customer national-ID KYC (BL-229) and geo bulk-import (BL-230) alongside the tables; backlog.md split those into their own rows below since neither is a table.
Scale-later infrastructure
Correct for a single instance / MVP load; each has a concrete, measurable trigger, not a date.
| Item | Why deferred | Pull-trigger | Size | Decided |
|---|---|---|---|---|
| BL-220 — Redis (shared cache, cross-instance scheduler/money lock) not deployed | Every current seam (the in-process scheduler, rate limiting) is correct only for one running instance | Running more than one instance | M | refinement-phase 7/8/9 handoffs |
BL-221 — Elasticsearch INurseSearch + outbox feeder not built |
SqlNurseSearch is real, correct, and sufficient at MVP scale |
SQL search shows real strain (latency/throughput on nurse_search_index) |
L | backend-phase-7 follow-up, refinement-phase 9.7 |
| BL-252 — no short-TTL cache over hot search-result pages | Shipped no-cache at MVP; premature to cache before there's a measured hot path | Search read latency becomes a real problem | S | backend-phase-7 follow-up |
Product-scope cuts (not building yet, by decision)
| Item | Why deferred | Pull-trigger | Size | Decided |
|---|---|---|---|---|
BL-222 — IAnalyticsSink / analytics warehouse not built |
Events write to ops.SystemEvents (real, queryable) fire-and-forget; no cross-event pipeline yet |
Product needs cross-event analytics beyond SQL queries | L | backend-phase-1, refinement-phase 9.8 |
| BL-223 — no real holiday-calendar feed | IHolidayCalendar reads a real, seeded, manually-maintained table; a yearly ops top-up is an acceptable MVP alternative to an automated feed |
Product pulls it (manual refresh becomes a burden) | M | backend-phase-1, refinement-phase 9.9 |
| BL-229 — customer national-ID KYC collection not built | Deliberate: never gate browsing/booking on it | Never, by design — informational only | — | backend-phase-3, refinement-phase-9, business/01 |
BL-230 — geography bulk-import feed (IGeoDataImporter) not built |
The idempotent seed + admin CRUD is sufficient for MVP | Product pulls it | M | backend-phase-4 follow-up |
| BL-231 — holiday/surge pricing, a distinct Companionship tier, tiered per-category commission | All explicitly out of MVP scope in business/03 | Product pulls it | M (pricing rule) / L (new tier) | backend-phase-5 follow-up, business/03 |
| BL-232 — GPS-radius "nurses near me" map discovery | Coverage stays named-district-only by design | None — permanent product decision | — | backend-phase 4/7, business/04 |
| BL-233 — automated MoH/INO license lookup + professional-liability-insurance step type | Manual verification is the MVP path; no B2B lookup API is confirmed to exist yet | A lookup portal is confirmed to exist, or product pulls the insurance step | M | backend-phase-6, business/02 |
| BL-239 — dedicated MoR center-settlement payout path (تسهیم split leg) | Per decision 6.6; the platform pays nurses directly today regardless of MoR | Product pulls it | M | refinement-phase 6/8 follow-ups |
| BL-241 — on-demand/instant nurse payout, per-nurse payout frequency | MVP is one fixed weekly cadence for everyone | Product pulls it | M | backend-phase-13, business/10 |
| BL-242 — automated clawback recovery beyond next-batch netting | Simple greedy netting covers MVP | Product pulls it | M | backend-phase-13 |
| BL-243 — two-way double-blind reviews with timed reveal | One-way customer review is MVP scope per business/11 | Product pulls it | L | backend-phase-14, business/11 |
| BL-246 — automated eNamad/MoH license verification for partner centers | Manual-approve is MVP scope per business/13 | Product pulls it | M | backend-phase-15 |
| BL-247 — no telephony seam for emergencies | The emergency contact is an out-of-platform tel: link, by deliberate design |
None — permanent product decision | — | backend-phase-15 |
| BL-248 — SMS/push notification channels not built | Only in-app notifications are real; deliberate MVP scope (business/14) | Notification UX demands out-of-app reach | M | refinement-phase-9, refinement-phase 9.10 |
| BL-251 — PWA/offline caching (Workbox) unbuilt | Marked "maybe" in the original product backlog — optional from the start | Product pulls it | M | product/notes/open-questions.md |
| BL-254 — partner dashboard's sponsored-nurse list capped at 50, no pagination | No center has exceeded 50 sponsored nurses yet | A center exceeds 50 sponsored nurses | S | backend-phase-15 follow-up |
| BL-257 — no true desktop search layout | The phone-width frame is the whole app's deliberate design; a full responsive pass was explicitly deferred post-chain | Product decides to support desktop | L | ui-phase-12 follow-up |
| BL-258 — Persian OG image is Latin-only (also BL-202) | Deliberate scope cut on /welcome and other share cards |
Persian social sharing becomes a priority | S | ui-phase-13 follow-up |
| BL-259 — no list-row EVV "currently checked in" indicator | Needs a product/API decision to avoid an N+1 read; not free to add | Product prioritizes a list-level EVV signal | S | ui-phase-5 follow-up |
| BL-260 — no web-push for new nurse booking requests | The 15-second poll is the only freshness mechanism today | Push infra (service worker + VAPID + dispatch rail) is built | L | ui-phase-7 follow-up, REQ-054 |
| BL-262 — no real payment-gateway/Shaparak logos near the pay CTA | No licensed assets yet; a generic lock-icon notice stands in | Licensed gateway assets obtained | S | ui-phase-6 follow-up |
Vendor / integration deferrals
| Item | Why deferred | Pull-trigger | Size | Decided |
|---|---|---|---|---|
| BL-235 — SMS.ir/Ghasedak adapters not built | Only Kavenegar's real-SMS path is wired; either alternative throws at startup by design rather than silently mocking | A second SMS vendor is needed | M | refinement-phase-8 follow-up |
| BL-236 — Finnotech/Moadian token-exchange refresh + signing certificate not wired | Both are deploy-time actions that need real credentials, which don't exist yet | Going to a real Moadian integration (pre-launch.md §5) | S once credentials exist | refinement-phase-8 handoff |
| BL-238 — per-provider-code BNPL revert incomplete (always drives SnappPay) | Only one BNPL provider is live today | A second BNPL provider goes live | S | refinement-phase-8 follow-up |
Scheduled-ops deferrals (manual today, by choice or by not-yet-built)
| Item | Why deferred | Pull-trigger | Size | Decided |
|---|---|---|---|---|
| BL-234 — credential-expiry scan + EVV no-show sweep are manual-only endpoints | No cron calls either yet | A scheduled-ops phase | S | backend-phase 6/9 follow-ups |
| BL-237 — Moadian reconciliation poll + refund-settlement poll are manual | No scheduled cron for either | A scheduled-ops phase | S | backend-phase-11, refinement 6/7/8 follow-ups |
| BL-240 — payout batch generation is automatic; processing a batch stays a deliberate, explicit admin action | Not a bug — moving real money should have a human in the loop at this scale | None — permanent product decision | — | refinement-phase-7, backend-phase-13 |
Cleanup-of-convenience and data-integrity hygiene
| Item | Why deferred | Pull-trigger | Size | Decided |
|---|---|---|---|---|
BL-219 — rename the SET_VIA_USER_SECRETS_OR_ENV placeholder sentinel |
The name is a load-bearing sentinel StartupSecretsGuard and the pre-commit hook both check for; renaming touches 7 files for a cosmetic gain |
None — cleanup-of-convenience | S | phase 2 (open-contradictions.md C-2) |
| BL-250 — the ESLint unused-vars gate is a repo-wide no-op | Config patches an export path that doesn't carry the rule; fixing it is a dedicated infra task, not a drive-by | A dedicated infra task | S | frontend-phase-13 follow-up |
| BL-253 — payment-webhook confirm path uses two DB commits instead of one transaction | Kept safe today via idempotency + a forward-only guard; a real fix needs IUnitOfWork to grow a transaction scope first |
IUnitOfWork grows a transaction scope |
M | backend-phase-10 follow-up |
BL-255 — Bookings/Invoices.partner_center_id have no DB-level FK |
Only nurse_profiles.partner_center_id got one, per that phase's own Definition of Done |
A data-integrity pass on partner-center columns | S | backend-phase 11/15 follow-ups |
| BL-256 — skeleton→content crossfade never retrofitted onto every list/detail page | Exists as a one-line-per-screen pattern; applying it everywhere is a dedicated visual pass, not a drive-by | A dedicated visual-polish pass | M | ui-phase-12 follow-up |
BL-249 — legacy UserRefreshTokens (gRPC auth path) still exists alongside real session-based REST auth |
Removing it means confirming nothing still depends on the gRPC path | gRPC moves to sessions, or is dropped | S | backend-phase-2 follow-up |
Deferred at the item level — gated behind a console that isn't prioritized yet
These 7 are filed by severity (major/minor) rather than in backlog.md's thematic Deferred section, because each is a specific, already-scoped gap rather than a standing product decision — but each is genuinely blocked on the same thing: an admin console this roadmap hasn't prioritized building yet. Recorded here for the same reason: each has a trigger, and none should be picked up piecemeal ahead of its console.
| Item | Why deferred | Pull-trigger | Size | Decided |
|---|---|---|---|---|
BL-050 — no preview/approve/reject route for admin refunds (POST admin_refunds creates+executes in one call) |
The three-step admin RefundPanel console has no real backend to call |
Admin refund console prioritized | M | phase 3 flow gap |
BL-075 — recordTransferReference targets a route that doesn't exist |
The payout batch-detail reconcile field would 404 on flip | Payout reconciliation console prioritized | S | phase 3 flow gap, REQ-036 |
BL-082 — approveVerification/rejectVerification/getDocumentSignedUrl target routes that don't exist |
The admin verification case page's approve/reject CTAs would 404 the moment BL-001 (RBAC) is fixed | Verification-admin console prioritized | M | phase 3 flow gap, REQ-034 |
| BL-096 — tier (c) of the public front door (guest search + public nurse profiles) unbuilt | Needs a backend phase (anonymous rate-limited search read, privacy-reviewed profile shape) and an explicit privacy sign-off on the nurse-profile field list — a decision, not a coding task | Privacy sign-off obtained and REQ-066/REQ-067 delivered | L | ui-phase-13, product/notes/open-questions.md |
BL-163 — POST tickets/{id}/assign is a phantom endpoint the client already targets |
Client-side assign UI exists; server route doesn't | Ticket assignment prioritized | S | phase 3 flow gap, REQ-063 |
| BL-168 / BL-261 — ticket attachments are fully designed/built client-side, gated off behind a flag | Waiting on the upload/signed-URL backend | Attachment backend delivered | M | phase 3 flow gap + REQ-060 (note: these are the same underlying fact filed as two BL-### by two different harvest passes — treat as one item when picking it up) |
| BL-201 — center self-onboarding (write-then-masked IBAN) never exercised on a real route | Deferred pending partner-center de-mock generally | Center self-service onboarding prioritized | M | phase 3 flow gap |
Verification note
BL-245 is not listed above: its own trigger was "phase 5 verification
pass," which this phase executed directly against the code rather than deferring further — see
decisions.md for the finding (2 of 3 admin actions confirmed built; only
FlagConcern is a genuine, small, unfiled gap).
What this file is not
This is a record, not a plan — nothing here is re-ranked or newly triggered by this phase. The proposed order of work that isn't deferred is next-up.md; what the deferrals above cost to keep deferring is partly covered in tech-debt.md where a deferral and a debt item are the same underlying fact (e.g. Redis/BL-220 appears in both, because "not built yet" and "costs more the longer it's not built" are two different questions about the same gap).