frontend phase 14

This commit is contained in:
hamid
2026-07-10 18:46:16 +03:30
parent 85488bc25b
commit bc51cf59b4
73 changed files with 3582 additions and 13 deletions
+47
View File
@@ -0,0 +1,47 @@
/**
* 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 = true;
/** 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;
/**
* 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,
};