73 lines
3.9 KiB
TypeScript
73 lines
3.9 KiB
TypeScript
/**
|
|
* When true, the tickets domain is served by the in-memory mock (`apis/mockApi.ts`) behind the `TicketsApi`
|
|
* seam.
|
|
*
|
|
* **Mock is primary this phase.** b15 serves the ticket endpoints (open / list / thread / message), and the
|
|
* real `clientApi.ts` maps them 1:1 — but the ticket screens depend on **inputs that are themselves
|
|
* mock-primary** (the f8 bookings a coordination ticket links to only exist client-side under the bookings
|
|
* mock), and the wire summary lacks `unreadCount`/`lastMessageAt` (**REQ-028**). So the mock is the primary
|
|
* source: it seeds realistic tickets/threads **with no internal messages** (mimicking the server's user-view
|
|
* `is_internal` stripping — it even stores an internal admin note that the user view drops, so the
|
|
* no-leak test is demonstrable), supports the optimistic append, and makes a booking-linked coordination
|
|
* ticket reachable. Flip to `false` once the upstreams are real — no hook/component change (only the seam
|
|
* selection in `apis/index.ts`).
|
|
*/
|
|
export const USE_TICKETS_MOCK = false;
|
|
|
|
/** Inbox page size (api-conventions `pageSize`, default 50 / max 100). */
|
|
export const TICKETS_PAGE_SIZE = 20;
|
|
|
|
/**
|
|
* The inbox list moves at human speed — a moderate `staleTime` avoids refetching on every revisit but a
|
|
* mutation (open ticket / post message) invalidates it so a new ticket / new activity shows without a manual
|
|
* refresh. The **thread is short-lived** (an active conversation) so it revalidates more eagerly.
|
|
*/
|
|
export const TICKETS_LIST_STALE_TIME = 30 * 1000;
|
|
export const TICKET_THREAD_STALE_TIME = 15 * 1000;
|
|
export const TICKETS_GC_TIME = 5 * 60 * 1000;
|
|
|
|
/**
|
|
* Poll the open thread while it's mounted (§3.2) — TanStack Query only polls while the query has an
|
|
* active observer, so this is automatically scoped to the thread screen. Proportionate to a support
|
|
* conversation, not a real-time chat; SSE can replace this later behind the same query.
|
|
*/
|
|
export const TICKET_THREAD_REFETCH_INTERVAL = 15 * 1000;
|
|
|
|
/**
|
|
* Photo-attachment affordance capability gate (§3.3) — the composer's attachment button is designed but
|
|
* renders only when this is on. Default **off**: the object-storage linkage for ticket messages is a
|
|
* backend gap (REQ-060); flip once that contract lands — no component change beyond this flag.
|
|
*/
|
|
export const TICKETS_ATTACHMENTS_ENABLED = false;
|
|
|
|
/** The admin global queue is a live worklist — a short stale window keeps it fresh without hammering. */
|
|
export const ADMIN_TICKETS_LIST_STALE_TIME = 20 * 1000;
|
|
|
|
/**
|
|
* Ticket lifecycle controls (close/reopen/assign) capability gate — mirrors the `TICKETS_ATTACHMENTS_ENABLED`
|
|
* pattern above. Default **off**: the backend has no close/reopen/assign routes yet (REQ-063), so the
|
|
* real-path controls stay hidden rather than pointing at a route that would 404. Flip once the endpoints
|
|
* land — no component change beyond this flag.
|
|
*/
|
|
export const TICKET_LIFECYCLE_ENABLED = false;
|
|
|
|
/**
|
|
* DEV-ONLY trigger for the optimistic-send **failure** path (phase §7 step 2): posting this exact message
|
|
* body makes the mock throw a `500` so a human can watch the bubble roll back, the draft stay in the
|
|
* composer, and the retry succeed. Never a product string.
|
|
*/
|
|
export const MOCK_SEND_FAIL_SENTINEL = '/fail';
|
|
|
|
/**
|
|
* Stable per-role "me" ids for the **mock** world (the real path uses the authenticated `/me` id). The mock
|
|
* seeds the customer's / nurse's / support's messages with these sender ids; `useTicket` passes
|
|
* `currentUser?.id ?? MOCK_VIEWER_USER_ID[actorRole]` so a message renders as **mine** in whichever app is
|
|
* viewing (customer app → the customer's bubbles are mine; nurse app → the nurse's are). The fallback only
|
|
* fires under mock auth (no `/me` id); on the real path the authenticated id wins and this is dead weight.
|
|
*/
|
|
export const MOCK_VIEWER_USER_ID: Record<'customer' | 'nurse' | 'admin', number> = {
|
|
customer: 7001,
|
|
nurse: 7015,
|
|
admin: 7003,
|
|
};
|