create mvp path
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# nurse — nurse bank accounts
|
||||
|
||||
> Client seam `client/src/services/nurse/` · `USE_NURSE_BANK_MOCK = false` (**real**) · 4 server ops
|
||||
> Last verified: 2026-07-30 against commit `d3ec723` and swagger.v1.json (2026-07-29).
|
||||
|
||||
The nurse's payout destination. Narrow domain, high stakes: a payout cannot be paid to an unverified IBAN.
|
||||
|
||||
> The domain is named `nurse`, not `nurse-bank-accounts`, because that is the client folder name. The
|
||||
> nurse's *profile* lives in [profiles.md](profiles.md); coverage in
|
||||
> [service-areas.md](service-areas.md); verification in [verification.md](verification.md).
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Path | Rate limit | Verdict |
|
||||
| --- | --- | --- | --- |
|
||||
| GET | `/api/v1/nurse_bank_accounts/list` | — | wired |
|
||||
| POST | `/api/v1/nurse_bank_accounts/add` | `sensitive` 20/min | wired |
|
||||
| POST | `/api/v1/nurse_bank_accounts/set_primary/{id}` | — | wired |
|
||||
| POST | `/api/v1/nurse_bank_accounts/verify_ownership/{id}` | `sensitive` 20/min | wired |
|
||||
|
||||
All `[Authorize]`. No phantoms. The domain maps 1:1.
|
||||
|
||||
## Shape rules the JSON does not express
|
||||
|
||||
- **`iban_hash` is UNIQUE across the platform.** The same IBAN cannot be registered by two nurses; the
|
||||
second `add` returns a `409`. The uniqueness is enforced on a deterministic hash, not the encrypted
|
||||
column.
|
||||
- **The IBAN is encrypted at rest and returned masked** — `maskedIban` on every read model, including the
|
||||
admin-side `PayoutDto` and the nurse's own `NursePayoutHistoryDto`. **The full IBAN is never returned
|
||||
after the write that created it.** Write-then-masked is the pattern.
|
||||
- **`verify_ownership` is استعلام شبا** — a Shahkar-class inquiry that confirms the account holder's
|
||||
national id matches the nurse's. It is a seam: `Seams:BankOwnership:Provider` = `mock` (default) or
|
||||
`finnotech`. The mock returns a match for every IBAN **except** `Seams:BankOwnership:MismatchIban`
|
||||
(`IR000000000000000000000000`), which exists so the payout-gating path is testable.
|
||||
- **Ownership verification gates payouts, and the gate lives in the payout engine, not here.**
|
||||
`EligibleNurseEarningsDto.hasVerifiedPrimaryIban` is the flag the admin console reads before generating
|
||||
a batch — see [payouts.md](payouts.md). A nurse with earnings and no verified primary IBAN accrues a
|
||||
balance and is simply not paid.
|
||||
- Client-side IBAN handling (`iban.ts`) does checksum validation and formatting only. It is a UX
|
||||
affordance; the server re-validates.
|
||||
|
||||
## Enums
|
||||
|
||||
| Vocabulary | Values |
|
||||
| --- | --- |
|
||||
| `BankAccountStatus` | `pending` `verified` `mismatch` |
|
||||
|
||||
`mismatch` is a terminal, actionable state — the holder's national id did not match — and is distinct from
|
||||
`pending`, which only means the inquiry has not run.
|
||||
|
||||
## Open REQs
|
||||
|
||||
None.
|
||||
Reference in New Issue
Block a user