67 lines
3.5 KiB
TypeScript
67 lines
3.5 KiB
TypeScript
import { REFUND_ETA_MAX_BUSINESS_DAYS } from '@/constants';
|
||
import type { CancellationPolicyCode } from './types';
|
||
|
||
/**
|
||
* When true, the refunds domain is served by the in-memory mock (`apis/mockApi.ts`) behind the
|
||
* `RefundsApi` seam.
|
||
*
|
||
* **Mock is primary this phase.** b11 shipped the refund lifecycle **admin-only**: the only
|
||
* customer-visible surface is `GET refunds/{id}/status` (thin: status/channel/amount/ETA/masked ref).
|
||
* There is **no** customer cancel command, **no** cancellation-policy preview, **no** refund-by-booking
|
||
* lookup, and the customer status carries **no** fee-leg decomposition — all filed as REQ-019/020/021.
|
||
* So the whole cancel + policy-disclosure + fee-split surface is mocked behind this seam. The mock reads
|
||
* the shared f8 bookings store (lead time + per-session refundability), flips the booking to `cancelled`
|
||
* on confirm (so the booking-detail cache reflects it), and drives a refund through
|
||
* `submitted → on_its_way → completed` (card immediate; BNPL processing with an ETA). Flip to `false`
|
||
* once REQ-019/020/021 land — no hook/component change.
|
||
*/
|
||
export const USE_REFUNDS_MOCK = true;
|
||
|
||
/**
|
||
* The cancellation preview depends on `now` vs the booking start (the resolved tier moves as the visit
|
||
* approaches), so keep it short-lived — never serve a stale tier that under/over-states the fee.
|
||
*/
|
||
export const POLICY_PREVIEW_STALE_TIME = 10 * 1000;
|
||
|
||
/**
|
||
* Refund status is read-heavy and mostly stable between visits; a modest stale window avoids a refetch on
|
||
* re-entry, while the poll (below) keeps a non-terminal refund fresh.
|
||
*/
|
||
export const REFUND_STATUS_STALE_TIME = 15 * 1000;
|
||
export const REFUND_STATUS_GC_TIME = 5 * 60 * 1000;
|
||
|
||
/**
|
||
* The refund-status poll runs **only while the refund is non-terminal** (`requested`/`approved`/
|
||
* `processing`); it stops at `succeeded`/`failed`/`rejected`. A calm, fixed interval — a refund moves on
|
||
* the order of days (BNPL) or is already terminal (card), so there is no need for tight backoff.
|
||
*/
|
||
export const REFUND_STATUS_POLL_INTERVAL_MS = 5 * 1000;
|
||
|
||
/**
|
||
* Mock-only policy tiers. The product doc pins the shape (free > 24h = 100%/0%; partial < 24h ≈ 50%;
|
||
* customer no-show up to 100% charge) but flags the 50% as **illustrative/config**, so these are the
|
||
* mock's stand-in figures until the backend serves `cancellation_policies`. `refundFraction` is 0–1.
|
||
*/
|
||
export const MOCK_POLICY_TIERS: Record<
|
||
CancellationPolicyCode,
|
||
{ refundFraction: number; leadTimeLabel: 'gt_24h' | 'lt_24h' | 'started' }
|
||
> = {
|
||
free_24h: { refundFraction: 1, leadTimeLabel: 'gt_24h' },
|
||
partial_under_24h: { refundFraction: 0.5, leadTimeLabel: 'lt_24h' },
|
||
customer_no_show: { refundFraction: 0, leadTimeLabel: 'started' },
|
||
};
|
||
|
||
/**
|
||
* The admin decomposition preview depends on the booking's current payout/dispute state (a post-payout
|
||
* refund forks to a clawback), so keep it short-lived — the console must never initiate off a stale split.
|
||
*/
|
||
export const ADMIN_REFUND_PREVIEW_STALE_TIME = 10 * 1000;
|
||
|
||
/**
|
||
* The BNPL customer cash-back window the mock projects onto `expectedCustomerRefundEta` — the product's
|
||
* ~7–10 business-day truth, Fridays skipped (see `cancellation-and-payout.md`). Surface it honestly;
|
||
* never imply the money is back instantly. Sourced from the single policy-numbers file (`constants/policy.ts`)
|
||
* so the mock's projected date and `refunds.eta_business_days`'s displayed window can never drift apart.
|
||
*/
|
||
export const BNPL_REFUND_ETA_BUSINESS_DAYS = REFUND_ETA_MAX_BUSINESS_DAYS;
|