frontend phase 5 & backend phase 12

This commit is contained in:
hamid
2026-07-09 03:05:14 +03:30
parent 465f75c29e
commit dc64472631
98 changed files with 11847 additions and 136 deletions
@@ -12,6 +12,24 @@ One block per completed backend phase. Newest at the top. Backend lane writes he
- **Notes for frontend:** <anything load-bearing>
-->
## backend-phase-12 — BNPL: provider-financed installments (mocked) — 2026-07-09
- **Shipped:** `payments.BnplTransactions` (1:1 with `payment_transaction`, `UNIQUE(payment_transaction_id)`,
settle-split CHECK, forward-only `BnplStatus` machine); `Features/Bnpl/*` (eligibility/initiate/verify/settle/
revert/callback/status); `CheckoutBnplController` (customer) + `WebhooksBnplController` (anon, signed) +
`AdminBnplController` (admin), all rate-limited; `LedgerPosting.BnplSettle` (net-of-fee group w/
`bnpl_fee_expense`); extracted shared `Features/Bookings/BookingConversion` (used by b10 card + b12 settle).
- **Contracts:** dev/contracts/domains/bnpl.md + openapi snapshot refreshed (yes).
- **Mocked:** `IBnplProvider` (per `provider_code` via `IBnplProviderResolver`) + `ICurrencyNormalizer` → 🟡
(configurable mock commission %, non-instant `settled_at`). See reports/mocks-registry.md.
- **Gate:** build clean (0 new code warnings) / tests green (314 pass: 4 identity + 214 foundation + 96 api;
+14 new). Migration `BnplTransactions` created (not applied to a live DB this session — SQLite
`EnsureCreated` builds it for tests).
- **Handoff:** backend/handoff/after-backend-phase-12.md
- **Notes for frontend:** f11-b12 = the "pay with installments" checkout (`checkout_bnpl/eligibility`
`initiate` → provider redirect; declined → fall back to card), the customer order view (`checkout_bnpl/{id}`),
and the admin BNPL revert path with the ~710-day ETA. Money is IRR digit-strings; `settledAt` is nullable
(not instant). A BNPL revert opens a `refund_channel='bnpl_revert'` refund (read via `refunds/{id}/status`).
## backend-phase-11 — Refunds, invoices & nurse clawbacks — 2026-07-09
- **Shipped:** the reversal leg via one migration in the **`payments`** schema — **3 tables** `Refunds`
(fee-leg decomposition + `refund_channel` + `amount = fee_leg + payout_leg` CHECK + **nullable `ticket_id`, no FK**