frontend phase 10

This commit is contained in:
hamid
2026-07-10 12:51:53 +03:30
parent 40cc1d163b
commit ccfa27aff6
32 changed files with 2151 additions and 3 deletions
@@ -12,6 +12,45 @@ for awareness.
- **Requests filed:** frontend/requests/for-backend.md (yes/no)
-->
## frontend-phase-10-b11 — Cancellation & refund status (customer) — 2026-07-10
- **Shipped:** the trust-first **exit** — a **new `services/refunds` domain** (types/constants/keys/
invalidations/apis[client+mock]/3 hooks + barrel) and two customer screens: the **cancellation flow**
`/bookings/[id]/cancel` (discloses the resolved policy tier + **refund % + fee %** + the Toman
refund-vs-fee split + the multi-session refundable/locked breakdown **before** confirm, gated behind an
explicit acknowledgement → `useCancelBooking` → refund status) and the read-only **refund status**
`/bookings/[id]/refund_status` (3-step **submitted → on-its-way → completed** stepper, the honest BNPL
**~710-business-day** ETA, `failed`=contact-support with **no retry**, empty state). The customer
booking detail now hangs a **Cancel** CTA / **refund section** (`CustomerBookingActions`, reuses the
cached booking query). Three shared tested composites: `CancellationPolicyDisclosure`, `RefundStatusCard`,
`RefundEtaBanner`. New `refunds` i18n namespace (71 keys, both locales).
- **Load-bearing rules honored:** refunds are **admin-approved — the customer never self-issues** (no
issue/approve/retry control anywhere; failed = contact-support); the fee/refund % is **disclosed +
acknowledged before confirm**; money = IRR digit-strings, **BigInt only** (integer parts-per-10000 —
refund+fee and the fee-leg split reconcile to the rial, `PriceBreakdown` dev-guarded); **BNPL surfaced
honestly** (the ~710-day window + `expected_customer_refund_eta`, money flows *through the provider*,
never instant, never Balinyaar→customer) — and **suppressed on a failed refund** (no success-framed
"money is on its way"); **per-session** — only un-started sessions refundable, completed-and-verified stay
locked; labels are i18n keys off the codes, **never raw enum codes**; polling **only while non-terminal**;
cancel invalidates booking detail/lists + **primes** the refund cache.
- **Consumes:** dev/contracts/domains/refunds-invoices.md (b11 — `refunds/{id}/status` shape + enums;
`refund_status`=requested|approved|processing|succeeded|failed|rejected, `refund_channel`=psp_card|
bnpl_revert|manual, `expected_customer_refund_eta` is a date). **Not served by the contract (admin-only):**
the customer cancel command, the pre-cancel policy preview + per-session flags, refund-by-booking, and the
fee-leg decomposition on the customer status → REQ-019/020/021.
- **Mocked client-side:** `services/refunds` via `refundsMockApi` (**USE_REFUNDS_MOCK=true, primary**) — it
reads the shared f8 bookings store to resolve the tier by lead time + per-session refundability, flips the
booking to `cancelled` (`mockMarkBookingCancelled` stamps the b9 snapshot), and drives card-immediate
(`succeeded`) / BNPL-`processing``succeeded` refunds with a real ETA + a seeded `failed` refund (5004) and
the outside-policy `409`. Added bookings-store seeds 5003 (mid-engagement mixed) + 5004 (cancelled) + two
non-seam exports. Real `refundsClientApi` maps `refunds/{id}/status` 1:1 and targets the proposed slugs for
the gaps; one flag flip when REQ-019/020/021 land.
- **Reviewed:** 4-dimension adversarial review + per-finding verify — 3 confirmed findings, all fixed
(failed-state ETA/amount suppression = BNPL-honesty; two missing `no_refund_*` i18n keys; a UTC/local
`daysUntil` mismatch that flipped the tier in +offset timezones).
- **Gate:** npm run check green · npm run test:ci green (**214 tests, +10**).
- **Requests filed:** frontend/requests/for-backend.md — yes (REQ-019 cancel command, REQ-020 policy
preview + per-session flags + canonical policy codes, REQ-021 refund-by-booking + customer decomposition).
## frontend-phase-9-b10 — Checkout, card payment & invoice — 2026-07-10
- **Shipped:** the money moment — a **new `services/payment` domain** (types/keys/constants/
apis[client+mock]/invalidations/5 hooks + barrel) and the customer checkout flow: **C6 خلاصه و پرداخت**