frontend phase 12
This commit is contained in:
@@ -379,3 +379,37 @@ delivers fixes in its own change. **Frontend never edits backend code to "fix" a
|
||||
behind the `services/bnpl` seam (seeded plan + a plan pushed on each settled checkout). When it lands the
|
||||
swap is one config flip.
|
||||
- **Status:** open
|
||||
|
||||
## REQ-025 — Nurse-read earnings surface: four-bucket balance + per-booking earnings list + nurse payout detail — filed by frontend-phase-12-b13 — 2026-07-10
|
||||
- **Need:** b13 serves the nurse exactly one endpoint (`GET api/v1/nurse_payouts/history` → `NursePayoutHistoryDto`).
|
||||
The f12 earnings screen needs three more **nurse-scoped, read-only** reads (all tenancy-scoped to the caller):
|
||||
1. **Earnings balance (four buckets + signed net)** — proposed `GET api/v1/nurse_payouts/earnings_balance` →
|
||||
`{ pendingTotalIrr, eligibleTotalIrr, paidTotalIrr, clawbackOutstandingIrr, netPayableBalanceIrr }`.
|
||||
`netPayableBalanceIrr` is the **ledger-derived, SIGNED** payable balance (may be **negative** = "owed back";
|
||||
never clamp). `paidTotalIrr` is a lifetime total and does **not** enter the net balance.
|
||||
2. **Per-booking earnings list + money-state** — proposed
|
||||
`GET api/v1/nurse_payouts/earnings?state=&page=&pageSize=` → `PagedResult<NurseEarningsItem>` where
|
||||
`NurseEarningsItem = { bookingId, patientName, scheduledDate, grossPriceIrr, balinyaarCommissionIrr,
|
||||
nursePayoutAmount, state: 'pending'|'eligible'|'paid'|'clawback_applied', disputeWindowEndsAt?,
|
||||
payoutEligibleAt?, paidAt?, transferReference?, nursePayoutId?, batchId?, clawbackAppliedIrr?, netAmountIrr? }`.
|
||||
`state` is derived **server-side** from `bookings.status` + `dispute_window_ends_at < now` + the payout link +
|
||||
any clawback (the client must never compute eligibility). Filterable by `state`.
|
||||
3. **Nurse-readable payout detail (batch context + booking links)** — proposed
|
||||
`GET api/v1/nurse_payouts/{id}` → a nurse-scoped analogue of the admin `PayoutBatchDetailDto`/`PayoutDto`:
|
||||
`{ id, batchId, status, grossEarningsIrr, clawbackAppliedIrr, netAmountIrr, amountIrr, maskedIban,
|
||||
transferReference?, paidAt?, failureReason?, batch: { id, periodStart, periodEnd, processingDate, status,
|
||||
totalAmount, payoutCount, processedAt? }, bookings: PayoutBookingLinkDto[] }`. The admin `batches/{id}` detail
|
||||
is admin-only; a nurse needs to reach **their own** payout's batch window + covered bookings for reconciliation.
|
||||
4. **`failureReason` on the nurse history DTO** — `NursePayoutHistoryDto` has no `failureReason` (it's on the
|
||||
admin `PayoutDto`). A `failed` payout in the nurse history should carry its reason so the read-only failure
|
||||
banner can show it (the nurse cannot retry — retry stays an admin action).
|
||||
- **Why:** the f12 nurse earnings screen (`services/payouts`) renders the net payable balance + four-bucket
|
||||
breakdown, the state-segmented earnings list (pending/eligible/paid/clawback_applied), and the payout/batch
|
||||
reconciliation detail. Only `getNursePayoutHistory` maps a live route; the other three are mocked behind the
|
||||
`PayoutsApi` seam (real-shaped fixtures covering all four states + a negative net balance + a failed payout).
|
||||
`payoutsClientApi` already targets the proposed slugs — when these land the swap is a single
|
||||
`USE_PAYOUTS_MOCK=false` flip; no hook/component change.
|
||||
- **Note (money invariants the server owns):** `gross_price_irr = balinyaar_commission_irr + nurse_payout_amount`;
|
||||
`net_amount = gross_earnings − clawback_applied`; a payout's booking-link `payout_amount_irr` sum = its
|
||||
`gross_earnings_irr`; the nurse amount is **payment-method-invariant** (BNPL provider commission never deducted).
|
||||
- **Status:** open
|
||||
|
||||
Reference in New Issue
Block a user