kaafil-react-uikit 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/dist/admin/index.cjs +471 -363
- package/dist/admin/index.cjs.map +1 -1
- package/dist/admin/index.d.cts +4 -4
- package/dist/admin/index.d.ts +4 -4
- package/dist/admin/index.js +116 -8
- package/dist/admin/index.js.map +1 -1
- package/dist/{chunk-2OWH2KDY.cjs → chunk-2JNB5A6Z.cjs} +90 -84
- package/dist/chunk-2JNB5A6Z.cjs.map +1 -0
- package/dist/{chunk-S53XNHRU.cjs → chunk-4TTDAOOG.cjs} +18 -4
- package/dist/chunk-4TTDAOOG.cjs.map +1 -0
- package/dist/{chunk-AFWZFFEM.js → chunk-4WXIR6FD.js} +5 -5
- package/dist/{chunk-AFWZFFEM.js.map → chunk-4WXIR6FD.js.map} +1 -1
- package/dist/{chunk-NCHZLGEE.cjs → chunk-6MD4QTZZ.cjs} +9 -9
- package/dist/{chunk-NCHZLGEE.cjs.map → chunk-6MD4QTZZ.cjs.map} +1 -1
- package/dist/{chunk-7V2XJIXD.js → chunk-7CLYTDSC.js} +18 -4
- package/dist/chunk-7CLYTDSC.js.map +1 -0
- package/dist/{chunk-AJE2RNOR.cjs → chunk-DRUTYOTN.cjs} +4 -4
- package/dist/{chunk-AJE2RNOR.cjs.map → chunk-DRUTYOTN.cjs.map} +1 -1
- package/dist/{chunk-K5Z6N2FY.js → chunk-DTVRWYVN.js} +5 -5
- package/dist/{chunk-K5Z6N2FY.js.map → chunk-DTVRWYVN.js.map} +1 -1
- package/dist/{chunk-VCROLPO3.js → chunk-EGEVXI5K.js} +3 -3
- package/dist/{chunk-VCROLPO3.js.map → chunk-EGEVXI5K.js.map} +1 -1
- package/dist/{chunk-7752B4NM.js → chunk-F6SN6CEC.js} +3 -3
- package/dist/{chunk-7752B4NM.js.map → chunk-F6SN6CEC.js.map} +1 -1
- package/dist/{chunk-KV7ODN2X.js → chunk-HC4PLK4E.js} +3 -3
- package/dist/{chunk-KV7ODN2X.js.map → chunk-HC4PLK4E.js.map} +1 -1
- package/dist/{chunk-F4GGHUMX.cjs → chunk-KY752BBA.cjs} +55 -55
- package/dist/{chunk-F4GGHUMX.cjs.map → chunk-KY752BBA.cjs.map} +1 -1
- package/dist/chunk-PMXQQFQN.cjs +12 -0
- package/dist/{chunk-ZZK7USFC.cjs.map → chunk-PMXQQFQN.cjs.map} +1 -1
- package/dist/{chunk-TGP4GTIY.js → chunk-RK3CWJ56.js} +10 -4
- package/dist/chunk-RK3CWJ56.js.map +1 -0
- package/dist/{chunk-64R4ZJTA.cjs → chunk-UG4Z23IJ.cjs} +12 -12
- package/dist/{chunk-64R4ZJTA.cjs.map → chunk-UG4Z23IJ.cjs.map} +1 -1
- package/dist/{chunk-UUID3H4R.js → chunk-VWFNUQDH.js} +3 -3
- package/dist/{chunk-UUID3H4R.js.map → chunk-VWFNUQDH.js.map} +1 -1
- package/dist/{chunk-3AF2M2JD.cjs → chunk-W63ZEIC2.cjs} +17 -17
- package/dist/{chunk-3AF2M2JD.cjs.map → chunk-W63ZEIC2.cjs.map} +1 -1
- package/dist/core/index.cjs +107 -107
- package/dist/core/index.d.cts +5 -5
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +10 -10
- package/dist/index.css +1 -1
- package/dist/manager/index.cjs +256 -256
- package/dist/manager/index.d.cts +4 -4
- package/dist/manager/index.d.ts +4 -4
- package/dist/manager/index.js +6 -6
- package/dist/tokens.json +4 -1
- package/dist/traveller/index.cjs +35 -35
- package/dist/traveller/index.js +5 -5
- package/dist/{useAgencyTrip-gZB0NILH.d.ts → useAgencyTrip-BgQ4gkyy.d.ts} +1 -1
- package/dist/{useAgencyTrip-C1YmfuQq.d.cts → useAgencyTrip-CtUMpC-J.d.cts} +1 -1
- package/dist/{useNotifications-D262i5BQ.d.ts → useNotifications-B9t5jUQc.d.ts} +1 -1
- package/dist/{useNotifications-BZW1Z_ur.d.cts → useNotifications-xn08Oypa.d.cts} +1 -1
- package/dist/{useVendors-DXOuZWhZ.d.cts → useVendors-B827YIDs.d.cts} +20 -0
- package/dist/{useVendors-DXOuZWhZ.d.ts → useVendors-B827YIDs.d.ts} +20 -0
- package/package.json +2 -2
- package/dist/chunk-2OWH2KDY.cjs.map +0 -1
- package/dist/chunk-7V2XJIXD.js.map +0 -1
- package/dist/chunk-S53XNHRU.cjs.map +0 -1
- package/dist/chunk-TGP4GTIY.js.map +0 -1
- package/dist/chunk-ZZK7USFC.cjs +0 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/errors/catalog.ts","../src/core/errors/classify.ts","../src/core/internal/ensureTripPulled.ts","../src/core/hooks/useSnapshotList.ts","../src/core/internal/createDomainHook.ts","../src/core/hooks/useChecklists.ts","../src/core/hooks/useCloseout.ts","../src/core/hooks/useCollections.ts","../src/core/hooks/useExpenses.ts","../src/core/hooks/useFiles.ts","../src/core/hooks/useFloat.ts","../src/core/hooks/useForms.ts","../src/core/hooks/useItinerary.ts","../src/core/hooks/useManagers.ts","../src/core/hooks/useManagerToday.ts","../src/core/hooks/useParties.ts","../src/core/hooks/usePickups.ts","../src/core/hooks/useRooming.ts","../src/core/hooks/useSeating.ts","../src/core/hooks/useTravellerProfile.ts","../src/core/hooks/useVendors.ts"],"names":["UnsatisfiableSchemeError","isKaafilError","useContext","OfflineEngineContext","KaafilClientContext","useState","useRef","useCallback","useEffect","useCapabilityRows","UNKNOWN_CAPABILITY_TRIPLE","deriveCapabilityTriple","darkReasonFor","client","useKaafilClient","useOfflineMutation","engine","SyncOpMethod","normalizeDateTimeInput","usePersona","isDevelopment","useOfflineEvent"],"mappings":"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","file":"chunk-2JNB5A6Z.cjs","sourcesContent":["// The master error catalog, keyed to ONE handling path each — `architecture/\n// 10-conventions.md §7` is the catalog's home (24 cross-cutting codes; cited,\n// never restated here beyond the code string itself) and\n// `architecture/06-offline-first.md §7` is the home for the TRANSIENT /\n// CONFLICT / FATAL outbox classification this table is built from. This file\n// does not re-pair a code with a status the catalog already assigns — it\n// only adds the fourth axis the catalog doesn't carry: which of the four\n// UIKit-level handling paths (`ErrorClassification.path` in `./classify.ts`)\n// a hook should take for it.\n//\n// `journey`/`checklists`/etc. also mint MODULE-LOCAL codes beyond this\n// table's 24 (`10-conventions.md §7`: \"follow the same discipline... must not\n// re-pair a code this table already assigns\") — that set is open, the same\n// way `journey.capabilities()`'s `capability` string is (`09-registries.md\n// §1`). `classifyError()` in `./classify.ts` therefore falls back to a\n// status-only classification for any code not in this table, rather than\n// exhaustively switching on the 24 here and breaking the day a 25th\n// cross-cutting code (or a 40th module-local one) ships.\n\n/** The four handling paths a `/core` hook ever takes for a classified error. */\nexport type ErrorHandlingPath = 'retryable' | 'parked' | 'surface-to-user' | 're-auth';\n\n/**\n * Exactly the 24 codes `architecture/10-conventions.md §7` lists, each\n * mapped to exactly one `ErrorHandlingPath`:\n *\n * - `re-auth` (1 code): `UNAUTHENTICATED` — the SDK's own credential\n * resolver already attempted one silent refresh before this ever reaches\n * `/core` (`10 §7`'s \"*SDK attempts one token refresh first\"); a hook\n * seeing this classification is seeing a refresh that already failed, so\n * the one correct action left is surfacing `session.expired`.\n * - `retryable` (3 codes): the three the offline table (`06 §7`) marks\n * TRANSIENT — `RATE_LIMITED`, `INTERNAL_ERROR`, `TENANT_SCOPE_MISSING`.\n * - `parked` (3 codes): the closed three-code subset `07-offline-and-sync.md\n * §10` names explicitly as \"never retried\" — `PLAN_FEATURE_DISABLED`,\n * `FILE_PURGED`, `LOCKED`. (`UnsatisfiableSchemeError` — not a wire code,\n * thrown locally by `kaafil-js`'s credential resolver before any request —\n * is the fourth member of that same closed set; `./classify.ts` handles it\n * by `instanceof`, not through this table, because it never carries a\n * `KaafilErrorCode`.)\n * - `surface-to-user` (the remaining 17 codes): every code that is neither\n * retryable, parked, nor a re-auth signal — a human needs to see it and,\n * in most cases, act on it (fix a validation error, resolve a conflict via\n * `useConflicts()`, request a fresh share link). `CONFLICT_VERSION` and\n * `SECRET_NOT_REPLAYABLE` land here too: both ARE surfaced to a human, just\n * through the one shared `ConflictResolver` shape (`07-offline-and-sync.md\n * §6`) rather than a generic toast — that richer shape is `useConflicts()`'s\n * job, not this classifier's.\n */\nexport const ERROR_HANDLING_PATH: Readonly<Record<string, ErrorHandlingPath>> = {\n // re-auth\n UNAUTHENTICATED: 're-auth',\n // retryable (TRANSIENT, `06-offline-first.md §7`)\n RATE_LIMITED: 'retryable',\n INTERNAL_ERROR: 'retryable',\n TENANT_SCOPE_MISSING: 'retryable',\n // parked (the closed never-retried set, `07-offline-and-sync.md §10`)\n PLAN_FEATURE_DISABLED: 'parked',\n FILE_PURGED: 'parked',\n LOCKED: 'parked',\n // surface-to-user (everything else in the 24-code catalog)\n VALIDATION_ERROR: 'surface-to-user',\n RESOURCE_NOT_FOUND: 'surface-to-user',\n CONFLICT_VERSION: 'surface-to-user',\n STOP_HAS_PENDING: 'surface-to-user',\n RESPONSE_CLOSED: 'surface-to-user',\n BUSINESS_RULE_VIOLATION: 'surface-to-user',\n OUT_OF_TRIP_WINDOW: 'surface-to-user',\n UPLOAD_MISMATCH: 'surface-to-user',\n FILE_ORPHANED: 'surface-to-user',\n CAPABILITY_UNAVAILABLE: 'surface-to-user',\n READ_ONLY_ROLE: 'surface-to-user',\n SUBJECT_REQUIRED: 'surface-to-user',\n IDEMPOTENCY_KEY_REUSED: 'surface-to-user',\n SECRET_NOT_REPLAYABLE: 'surface-to-user',\n NOT_IMPLEMENTED: 'surface-to-user',\n SHARE_TOKEN_EXPIRED: 'surface-to-user',\n SHARE_TOKEN_REVOKED: 'surface-to-user',\n};\n","// The one error classifier every /core hook funnels a caught SDK error\n// through — `02-architecture.md §2` (\"error classification\" lives in\n// `src/core/` exactly once) and `02-architecture.md §3a` (a family that\n// re-derives this itself is the exact anti-pattern the invariant forbids).\n// This is also the one file outside `./errors.ts`'s re-export that imports\n// `kaafil-js`'s error hierarchy — `hard rule #1: kaafil-js only from\n// src/core/`.\n\nimport { isKaafilError, UnsatisfiableSchemeError } from 'kaafil-js/client';\nimport { ERROR_HANDLING_PATH, type ErrorHandlingPath } from './catalog';\n\n/** The normalised shape every `/core` hook's `'error'` branch carries. */\nexport interface ErrorClassification {\n readonly path: ErrorHandlingPath;\n /** The catalog code, when the failure reached a real response\n * (`kind: 'api'`). `undefined` for a transport failure (network, timeout,\n * abort) or for `UnsatisfiableSchemeError`, neither of which ever carries\n * one (`kaafil-js/src/http/errors.ts`, verified: `KaafilTransportError`\n * fixes `code: undefined`). */\n readonly code: string | undefined;\n readonly status: number | undefined;\n /** `true` when the SDK's own credential resolver refused the call locally,\n * before any request was built — `UnsatisfiableSchemeError`\n * (`kaafil-js/src/auth/credentials.ts`, verified). A hook surfacing this\n * to a composite renders it as a structural \"this persona cannot do that\",\n * never a transient failure worth retrying. */\n readonly unsatisfiableScheme: boolean;\n /** The original error, for a caller that needs more than the\n * classification (support escalation, a `details` field a specific hook\n * knows how to read). */\n readonly cause: unknown;\n}\n\n/**\n * Codes this classifier treats as retryable even absent a catalog entry —\n * a raw transport failure (network/timeout, `status: null`) never reached a\n * response and so never got a code at all, but is exactly as retryable as\n * `INTERNAL_ERROR`/`RATE_LIMITED` (`06-offline-first.md §7`'s TRANSIENT row\n * also lists \"5xx, network error, timeout, 429\" together).\n */\nfunction pathForStatusOnly(status: number | undefined): ErrorHandlingPath {\n if (status === undefined || status === null) {\n // No HTTP response reached the client at all — a network error or\n // timeout. TRANSIENT per `06-offline-first.md §7`.\n return 'retryable';\n }\n if (status === 401) {\n return 're-auth';\n }\n if (status === 429 || status >= 500) {\n return 'retryable';\n }\n if (status === 402 || status === 410 || status === 423) {\n return 'parked';\n }\n // Every other 4xx this classifier has no catalog entry for (a module-local\n // code not yet added to `./catalog.ts`, or a code this build doesn't know)\n // gets the honest default: put it in front of a human rather than\n // guessing it is safe to retry or safe to hide.\n return 'surface-to-user';\n}\n\n/**\n * Turns any caught value into the shape every `/core` hook's error branch\n * needs. Never throws — an unrecognised shape (a bare `Error`, a rejected\n * promise from something outside the SDK) still classifies, conservatively,\n * as `surface-to-user` with no code and no status, rather than propagating\n * an uncaught exception up through a hook that promised a `{ status:\n * 'error' }` branch instead.\n */\nexport function classifyError(error: unknown): ErrorClassification {\n if (error instanceof UnsatisfiableSchemeError) {\n return {\n path: 'parked',\n code: undefined,\n status: undefined,\n unsatisfiableScheme: true,\n cause: error,\n };\n }\n\n if (isKaafilError(error)) {\n const catalogPath = error.code !== undefined ? ERROR_HANDLING_PATH[error.code] : undefined;\n const path = catalogPath ?? pathForStatusOnly(error.status);\n return {\n path,\n code: error.code,\n status: error.status,\n unsatisfiableScheme: false,\n cause: error,\n };\n }\n\n // Not a KaafilError at all — never reached the transport in a shape the\n // SDK recognises. Conservative default: put it in front of a human.\n return {\n path: 'surface-to-user',\n code: undefined,\n status: undefined,\n unsatisfiableScheme: false,\n cause: error,\n };\n}\n","'use client';\n\n// `07-offline-and-sync.md §10.1`: \"`sync.pullTrip` is internal to `/core`'s\n// offline engine and appears in no component's `Backed by` field anywhere in\n// this tree, by design\" — the engine is supposed to drive the consolidated\n// pull itself, not a component. But nothing in `kaafil-js`'s own\n// `OfflineEngine` schedules a trip's FIRST pull automatically (verified —\n// `createPullCoordinator` only computes `since` off already-cached lists; it\n// never decides on its own that a new tripRef needs pulling at all), so\n// without this seam every `useSnapshotList()` read stays permanently cold —\n// `rows: []`, `syncedAt: undefined` — for a trip the engine has never been\n// told to pull. This is that seam: internal to `/core` (a hook file, never a\n// component), calling `engine.pull.pullTrip()` — the one call §10.1 says a\n// component must never name — exactly once per (engine, tripRef) pair.\n\nimport type { OfflineEngine } from 'kaafil-js/client';\n\nconst pulledTrips = new WeakMap<OfflineEngine, Set<string>>();\n\n/**\n * Triggers this trip's first consolidated pull, once, the first time any\n * `/core` hook asks for it. Idempotent across every `useSnapshotList()`\n * instance mounted for the same trip (rooming alone mounts two, for\n * `'rooming'` and `'stayWindows'`) — only the first caller actually pulls.\n * A failed pull clears its own `seen` entry so the next render's mount\n * (a remount, a tab revisit) gets a fresh attempt — never an automatic\n * retry loop this function itself schedules.\n *\n * VERIFIED THIS PASS: `syncPullTrip` accepts `[managerAuth, apiKeyAuth]`\n * only (`kaafil-js/src/generated/security.ts`) — an `agencyAdmin` session\n * gets `UnsatisfiableSchemeError` from every call this makes. That is the\n * real, structural reason every admin composite built on\n * `useSnapshotList()` (expenses, float, checklists, collections, forms,\n * pickups, seating, bookings) reads as permanently empty today — not a bug\n * in this seam, and not something widening a credential allowlist fixes:\n * the admin persona is not meant to run an offline pull cycle at all. The\n * silent catch above is exactly the right behavior for that case, not a\n * masked failure.\n */\nexport function ensureTripPulled(engine: OfflineEngine, tripRef: string): void {\n let seen = pulledTrips.get(engine);\n if (seen === undefined) {\n seen = new Set();\n pulledTrips.set(engine, seen);\n }\n if (seen.has(tripRef)) {\n return;\n }\n seen.add(tripRef);\n void engine.pull.pullTrip({ tripRef }).catch(() => {\n seen?.delete(tripRef);\n });\n}\n","'use client';\n\n// `08-core-hooks.md §2.2`. The cache-first read of one snapshot list —\n// `SnapshotStore.list()`, re-rendering on the store's own `snapshot.updated`\n// event, filtered to this `tripRef`/`listName` pair.\n//\n// ── THE LIVE LANE, AND WHY IT LIVES HERE ──────────────────────────────────\n//\n// Cache-first assumes a cache. `OfflineShell` mounts only when the host\n// passes `storage`, which the FIELD personas do and a DESK console does not,\n// so on the desk `engine` is null and this hook returns `{rows: [],\n// syncedAt: undefined}` — permanently, and indistinguishably from \"genuinely\n// cold\". A composite reading it renders an empty list for a trip that has\n// rows, which is not a degraded read: it is a confident wrong answer, the\n// same false-empty that made `useExpenses` unusable on the desk.\n//\n// So a caller MAY supply `live`: the same list, fetched straight from the\n// SDK. With an engine, nothing changes — the snapshot wins and `live` is\n// never called. With none and a `live`, this fetches once per\n// (`tripRef`, `listName`) and reports what came back. With none and no\n// `live`, it returns `[]` exactly as before, which stays right for a domain\n// only a field persona reads.\n//\n// This is the read-side twin of `useOfflineMutation`'s own `direct` lane,\n// and it is here for the same reason its header gives: one adaptive rule in\n// the one hook §2.2 owns, rather than the same branch re-derived in every\n// domain hook that a desk surface happens to reach for.\n//\n// It is NOT a second sync engine (hard rule #3). Nothing is cached, nothing\n// is reconciled, no cursor is kept, and no event is subscribed to — it is a\n// plain read of the SDK's own endpoint on a surface that has no store to put\n// the answer in.\n\nimport type { KaafilClient, SnapshotRow } from 'kaafil-js/client';\nimport { useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { KaafilClientContext, OfflineEngineContext } from '../internal/contexts';\nimport { ensureTripPulled } from '../internal/ensureTripPulled';\n\nexport interface SnapshotListOptions<TRow> {\n /**\n * The same list, read live, for a surface with no `OfflineShell`. Resolve\n * the rows AND the server's own time — `syncedAt` means the same thing on\n * both lanes (\"what this reading is as of\"), and deriving it from a device\n * clock would make the two disagree.\n */\n readonly live?: (\n client: KaafilClient,\n tripRef: string,\n ) => Promise<{ readonly rows: readonly TRow[]; readonly syncedAt: string | undefined }>;\n}\n\nexport interface SnapshotListResult<TRow> {\n readonly rows: readonly TRow[];\n readonly syncedAt: string | undefined;\n /**\n * Re-reads the live lane. A NO-OP on the snapshot lane, where the store's\n * own `snapshot.updated` event already drives re-render and a manual\n * refetch would be a second sync path.\n */\n readonly refreshLive: () => Promise<void>;\n}\n\n/**\n * At-least-once delivery is the CALLER's problem to absorb structurally\n * (`07-offline-and-sync.md §4`) — this hook returns exactly what\n * `SnapshotStore.list()` holds and does not de-duplicate beyond what the\n * store itself already guarantees.\n */\nexport function useSnapshotList<TRow extends Record<string, unknown>>(\n tripRef: string,\n listName: string,\n options?: SnapshotListOptions<TRow>,\n): SnapshotListResult<TRow> {\n // NOT `useOfflineEngine()` (its throwing form) — called from inside a\n // domain hook's `build()`, which runs unconditionally on every render\n // (`createDomainHook.ts`), including the render(s) before `OfflineShell`\n // has opened an engine. A momentarily-absent engine is indistinguishable\n // from \"genuinely cold, no pull has ever completed\" below — `syncedAt:\n // undefined` with `rows: []` already means exactly that, never a crash.\n const engine = useContext(OfflineEngineContext);\n // The raw context, not `useKaafilClient()`'s throwing form — same reasoning\n // as the engine read above. A client is needed only on the live lane.\n const client = useContext(KaafilClientContext);\n const [rows, setRows] = useState<readonly SnapshotRow[]>(() =>\n engine === null ? [] : engine.snapshot.list(tripRef, listName),\n );\n const [liveRows, setLiveRows] = useState<readonly TRow[] | undefined>(undefined);\n const [liveSyncedAt, setLiveSyncedAt] = useState<string | undefined>(undefined);\n\n // A REF, NOT A DEPENDENCY — and this is load-bearing, not tidiness. Callers\n // pass `live` as an inline arrow (`usePickups` does), so its identity\n // changes on every render. Naming it in `readLive`'s dependency array made\n // `readLive` new every render, which re-fired the effect below, which set\n // state, which re-rendered, which built a new arrow: an infinite loop that\n // pegged the CPU and froze the tab. The same `enqueueRef`/`directRef`\n // pattern `useOfflineMutation` already uses, for the same reason.\n //\n // Assigned on every render, so the closure invoked is always the latest —\n // a ref costs nothing in staleness here because it is only ever read inside\n // an async callback, never during render.\n const liveRef = useRef(options?.live);\n liveRef.current = options?.live;\n const hasLive = options?.live !== undefined;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: naming `options.live` here is the infinite loop this lane already shipped once — callers pass it as an inline arrow, so it is a new object on every render, and depending on it re-fires the effect below forever. `liveRef` holds the latest closure; `hasLive` carries the only part of it that is a stable fact.\n const readLive = useCallback(async (): Promise<void> => {\n const live = liveRef.current;\n if (engine !== null || live === undefined || client === null) {\n return;\n }\n try {\n const result = await live(client, tripRef);\n setLiveRows(result.rows);\n setLiveSyncedAt(result.syncedAt);\n } catch {\n // Deliberately NOT `setLiveRows([])`. A failed read is not an empty\n // list, and the whole reason this lane exists is that the two must not\n // look alike. `liveRows` stays `undefined` until something lands, which\n // reads as \"still nothing to show\" rather than as \"there is nothing\".\n }\n // `hasLive` rather than `live` itself: whether a live lane EXISTS is a\n // stable fact about the caller, while the function is a new object each\n // render. This is what re-runs the read when a caller starts or stops\n // supplying one, without re-running it because a closure was rebuilt.\n }, [engine, client, tripRef, hasLive]);\n\n useEffect(() => {\n void readLive();\n }, [readLive]);\n\n useEffect(() => {\n if (engine === null) {\n setRows([]);\n return;\n }\n // §10.1's own seam, not a second sync engine — see `ensureTripPulled`'s\n // header for why this call has to live here rather than nowhere at all.\n ensureTripPulled(engine, tripRef);\n setRows(engine.snapshot.list(tripRef, listName));\n const unsubscribe = engine.events.on('snapshot.updated', (event) => {\n if (event.tripRef === tripRef && event.lists.includes(listName)) {\n setRows(engine.snapshot.list(tripRef, listName));\n }\n });\n return unsubscribe;\n }, [engine, tripRef, listName]);\n\n if (engine === null) {\n return {\n rows: liveRows ?? (rows as readonly TRow[]),\n syncedAt: liveSyncedAt,\n refreshLive: readLive,\n };\n }\n\n // `syncedAt` is per-entity in `SnapshotStore` (`kaafil-js/src/offline/\n // snapshot.ts`, verified) — a LIST has no single cursor timestamp of its\n // own beyond the most recent entity it holds, which is the honest reading\n // of \"as of 14:02\" for the list as a whole, for a POPULATED list.\n //\n // A genuinely-empty list has no entity to derive that reading from, so\n // this used to leave `syncedAt` permanently `undefined` — indistinguishable\n // from \"the first pull hasn't landed yet\" (a real bug: `FloatFlow`'s\n // `NoFloatYet` story got stuck on its loading skeleton forever). `cursor()`\n // is the list's own pull-level timestamp — stamped from `applyPull`'s\n // `serverTime` regardless of how many rows that pull returned — so it is\n // `undefined` only while genuinely cold (no pull has ever completed), and\n // a real timestamp the instant a pull succeeds even with zero rows. Used\n // only as the empty-list fallback; a populated list keeps the per-entity\n // reading above, unchanged.\n let syncedAt: string | undefined;\n for (const row of rows) {\n const stamp = engine.snapshot.syncedAt(tripRef, listName, row.id);\n if (stamp !== undefined && (syncedAt === undefined || stamp > syncedAt)) {\n syncedAt = stamp;\n }\n }\n if (syncedAt === undefined && rows.length === 0) {\n syncedAt = engine.snapshot.cursor(tripRef, listName);\n }\n\n return { rows: rows as readonly TRow[], syncedAt, refreshLive: readLive };\n}\n","'use client';\n\n// The factory every §3 domain hook in `../hooks/` is written from\n// (`08-core-hooks.md §0`: \"every domain hook is capability-gated internally\n// ... resolves the trip's capability triple for its own module key before\n// doing any fetch; on a dark module it returns a `{ status: 'dark', reason\n// }` shape rather than throwing or returning an empty success\"). Carries\n// exactly the three concerns a domain hook needs, once: the capability gate,\n// the cache-first read (via §2.2/§2.3, inside `build`), and mutation helpers\n// (via §2.5, also inside `build`) — `useRooming()` is the exemplar built\n// from this; the other seventeen domain hooks either use it too (once\n// authored) or are `NotImplementedError` stubs that don't call it yet.\n\nimport type { DomainHookResult } from '../types/domain.types';\nimport {\n darkReasonFor,\n deriveCapabilityTriple,\n UNKNOWN_CAPABILITY_TRIPLE,\n} from './deriveCapabilityTriple';\nimport { useCapabilityRows } from './useCapabilityRows';\n\n/**\n * `build` is called UNCONDITIONALLY, every render, regardless of whether the\n * module is lit or dark — it is where a domain hook calls `useSnapshotList`/\n * `useOfflineMutation`/etc., and the Rules of Hooks require those calls to\n * happen on every render, not only when the module happens to be lit. What\n * changes with the capability triple is only which branch of\n * `DomainHookResult` this factory RETURNS to the caller — `build`'s own\n * subscriptions stay live either way, so a module that lights up mid-session\n * (a fresh journey build landing) starts reflecting real data on its very\n * next render with no remount.\n */\nexport function createDomainHook<TReady extends object>(\n moduleKey: string,\n build: (tripRef: string) => TReady,\n): (tripRef: string) => DomainHookResult<TReady> {\n return function useDomainHook(tripRef: string): DomainHookResult<TReady> {\n const { rows, loaded } = useCapabilityRows(tripRef);\n const ready = build(tripRef);\n\n if (!loaded) {\n return { status: 'loading' };\n }\n\n const row = rows.find((candidate) => candidate.capability === moduleKey);\n const triple = row === undefined ? UNKNOWN_CAPABILITY_TRIPLE : deriveCapabilityTriple(row);\n\n if (triple.status !== 'lit') {\n const reason = darkReasonFor(triple);\n // `darkReasonFor` only returns `undefined` for `'lit'`, which this\n // branch has already excluded — the assertion documents that instead\n // of threading an impossible-per-types `undefined` through the public\n // `DomainHookResult` union.\n return { status: 'dark', reason: reason as NonNullable<typeof reason> };\n }\n\n return { status: 'ready', ...ready };\n };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useChecklists(tripRef)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/checklists.ts` +\n// `generated/security.ts`): `checklists.read`, `checklists.items.\n// {get,add,patch,remove,toggle}`, `checklists.templates.{list,pull}` (the\n// trip-side pull of the agency's library, `RULES:checklists R1c`'s \"COPY,\n// never a live link\"), `checklists.agencyTemplates.{list,create,patch,\n// remove,publish}` (the agency's own library CRUD — `publish` is the\n// `DRAFT` → `PUBLISHED` transition, invisible to `templates.list`/`.pull`\n// until it fires). PERSONALIZED mode-dark (`06-capability-and-personas.md\n// §3`), gated via `createDomainHook()` exactly like `useRooming()`.\n//\n// READ MODEL — SPLIT, same shape `useFloat()`/`useRooming()` already\n// document for their own hybrid reads. `items[]` IS a genuine delta feed\n// (`ChecklistAggregateResponse.items[]` — a live row or a `_tombstone`,\n// each carrying `id`/`version`, `07-checklists.md`'s own spec text, and\n// `'checklist'` is a registered `SYNC_PULL_SECTIONS` entry per `useTreks\n// .ts`'s own verified header) — cache-first via `useSnapshotList()`.\n// `sections[]`/`progress`/`hasOpenMandatoryByPhase`/`availableTemplates`/\n// `title`/`subtitle`, by contrast, are the REST of `ChecklistAggregateResponse`\n// — always sent in full on every read regardless of `?since=`\n// (`ReadChecklistOptions`'s own doc comment: \"sections[] and the two\n// progress figures are always full regardless; only items[] narrows\") and\n// carry no per-row id/version array for `extractSectionRows()` to key on.\n// This hook therefore exposes that remainder as `aggregate`, a live-fetched,\n// explicitly-refreshed state — the identical `unassignedPool`/`summary`\n// shape `useRooming.ts`/`useFloat.ts` already establish — refreshed on\n// mount and again after every write below that could have moved it\n// (an item add/patch/remove/toggle changes `progress`/\n// `hasOpenMandatoryByPhase`; a template pull replaces the whole aggregate).\n//\n// TOGGLE'S GUARD IS `expectedStatus`, NOT `version` — `07-offline-and-sync\n// .md §6`'s named exception, restated here because every OTHER write on\n// this resource (`patch`/`remove`) carries the usual required `version` →\n// `If-Match`. A stale toggle still answers `409 CONFLICT_VERSION`, but with\n// `details.currentStatus`, never `details.currentStatus`'s sibling\n// `details.currentVersion` — a caller inspecting the conflict reads\n// whichever field the response actually carries, this hook does not\n// normalise the two into one shape.\n//\n// DELETE HAS NO FORCE OVERRIDE. Unlike `pickups.remove`/`rooming`'s room\n// removal, `DeleteChecklistItemOptions` carries no `force` query param at\n// all — deleting a `COMPLETE` item is refused outright,\n// `422 BUSINESS_RULE_VIOLATION` / `details.rule: 'item_complete_delete_\n// blocked'` (`RULES R6`), un-toggle first. `removeItem` below sends exactly\n// the SDK's own `tripRef`/`itemId`/`version` triple; a caller (`ChecklistBoard`)\n// is the one that must disable the affordance ahead of time rather than\n// letting this request fire and showing the 422 as a toast.\n//\n// TEMPLATES.LIST IS A PLAIN LIVE CALL, NOT AN AUTO-FETCHED HOOK STATE —\n// `07-checklists.md`'s own `ChecklistTemplatePicker` Offline row: \"fetched\n// fresh when the picker opens,\" not eagerly on every `useChecklists()`\n// mount. `listTemplates` below is exposed the same way `usePickups\n// .manifestByPickup` is — a plain async function a composite calls on its\n// own trigger (the sheet opening), never a value this hook resolves by\n// itself.\n//\n// AGENCY TEMPLATE CRUD IS OUT OF THIS FAMILY'S OWN SCOPE\n// (`families/manager/07-checklists.md`'s own framing note: authoring the\n// agency's template library has \"no manager-family equivalent\" — that is\n// `admin/07-checklists.md`'s `ChecklistTemplateLibrary`/\n// `ChecklistTemplateEditor`/`TemplateAuthoringFlow`) but this hook is\n// persona-agnostic `/core` surface shared by both families\n// (`02-architecture.md §3a`), so the four `agencyTemplates.*` methods are\n// still wired here for whichever admin composite eventually calls them. No\n// manager composite in this build ever calls them. `agencyRef` is NOT\n// auto-resolved from session context below (this hook's own header\n// documents that as a real, narrow scope gap): `AgencyChecklistTemplatesResource`'s\n// options each require an explicit `agencyRef: string`, and this build has\n// no admin-scoped \"which agency\" resolution plumbed into `/core` yet for a\n// manager-signature hook to reach — the caller supplies `agencyRef` on the\n// input itself, same as any other explicit field.\n//\n// WRITES. `addItem`/`patchItem`/`removeItem`/`toggleItem`/`pullTemplate`\n// each enqueue via `OfflineEngine.enqueue()` with a raw path/method/\n// operationId/body — `OperationId` is not exported from `kaafil-js/client`'s\n// public surface (verified, the same gap `useRooming.ts`/`useFloat.ts`\n// document for their own literal operationId casts); every literal below is\n// checked against `kaafil-js`'s own exported `OperationId` enum\n// (`dist/vocabulary-*.d.ts`, verified this session, even though that named\n// export itself does not cross the `kaafil-js/client` subpath boundary).\n// `pullTemplate` never applies an optimistic local shape — `07-checklists\n// .md`'s own Offline row: \"applying optimistically is not attempted —\n// pull-template replaces the whole aggregate atomically\" — this hook\n// re-fetches `aggregate` after enqueueing exactly like every other write\n// below, and the composite's own `onPulled` fires off THAT refreshed\n// `aggregate`, never a value invented from the enqueue call alone.\n\nimport type {\n AddChecklistItemOptions,\n ChecklistItemDeltaRow,\n ChecklistItemsResource,\n ChecklistsResource,\n ChecklistTemplatesResource,\n DeleteChecklistItemOptions,\n KaafilClient,\n ListChecklistTemplatesOptions,\n OutboxOp,\n PatchChecklistItemOptions,\n PullChecklistTemplateOptions,\n ToggleChecklistItemOptions,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\n/** `Awaited<ReturnType<...>>` off the resource methods, never imported by\n * name — `ChecklistAggregateResponse`/`ChecklistItemResponse`/\n * `ToggleResponse`/`TemplatesListResponse`/`DeleteItemResponse` are not\n * individually re-exported from `kaafil-js/client`'s public surface\n * (verified — only `ChecklistItemDeltaRow` and the `*Options` input types\n * are), the identical gap `usePickups.ts`'s own header documents for its\n * resource's response shapes. */\nexport type ChecklistReadResult = Awaited<ReturnType<ChecklistsResource['read']>>;\nexport type ChecklistToggleResult = Awaited<ReturnType<ChecklistItemsResource['toggle']>>;\nexport type ChecklistAddItemResult = Awaited<ReturnType<ChecklistItemsResource['add']>>;\nexport type ChecklistPatchItemResult = Awaited<ReturnType<ChecklistItemsResource['patch']>>;\nexport type ChecklistRemoveItemResult = Awaited<ReturnType<ChecklistItemsResource['remove']>>;\nexport type ChecklistTemplatesListResult = Awaited<ReturnType<ChecklistTemplatesResource['list']>>;\nexport type ChecklistPullTemplateResult = Awaited<ReturnType<ChecklistTemplatesResource['pull']>>;\n\n/** One row of `ChecklistReadResult['sections']` — always the full set,\n * never narrowed by `?since=` (this file's header). */\nexport type ChecklistSectionRow = ChecklistReadResult['sections'][number];\n\n/** `ChecklistItemDeltaRow` narrowed to the LIVE shape — a tombstone carries\n * only `id`/`version`/`deletedAt` and has none of the fields an optimistic\n * row has to fill in. Declared here rather than imported from a composite's\n * `.types.ts`: `/core` cannot depend on a family. */\nexport type ChecklistItemLiveRow = Exclude<ChecklistItemDeltaRow, { readonly _tombstone: true }>;\n\n/** One row of `ChecklistReadResult['availableTemplates']` — the agency's\n * templates this trip hasn't pulled yet, as returned inline on the\n * aggregate (a smaller shape than `listTemplates()`'s own\n * `TemplatesListResponse`, which additionally carries `itemCount`/\n * `lastUsedAt`). */\nexport type ChecklistAvailableTemplateRow = ChecklistReadResult['availableTemplates'][number];\n\nexport type AddChecklistItemInput = Omit<\n AddChecklistItemOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\nexport type PatchChecklistItemInput = Omit<PatchChecklistItemOptions, 'tripRef' | 'signal'>;\nexport type RemoveChecklistItemInput = Omit<DeleteChecklistItemOptions, 'tripRef' | 'signal'>;\nexport type ToggleChecklistItemInput = Omit<\n ToggleChecklistItemOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\nexport type ListChecklistTemplatesInput = Omit<ListChecklistTemplatesOptions, 'tripRef' | 'signal'>;\nexport type PullChecklistTemplateInput = Omit<\n PullChecklistTemplateOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\n\n// `client.checklists.agencyTemplates` resolves, at RUNTIME, to\n// `BoundAgencyChecklistTemplatesResource` — the agency-bound variant\n// `KaafilClient`'s own `get checklists()` accessor returns (verified,\n// `kaafil-js/dist/client-entry.d.ts`), NOT the plain\n// `AgencyChecklistTemplatesResource` its options types are individually\n// exported under. Neither the bound resource interface nor its five\n// `Bound*Options` input types cross the `kaafil-js/client` subpath's named\n// export boundary (verified) — every type below is therefore derived\n// structurally off `KaafilClient['checklists']['agencyTemplates']` itself\n// (the one type this hook file DOES import), the same \"derive off the one\n// exported anchor, never off an unexported sibling name\" discipline\n// `usePickups.ts`'s own `ReassignInput` comment documents.\ntype BoundAgencyChecklistTemplates = KaafilClient['checklists']['agencyTemplates'];\nexport type ListAgencyChecklistTemplatesInput = Parameters<\n BoundAgencyChecklistTemplates['list']\n>[0];\nexport type CreateAgencyChecklistTemplateInput = Parameters<\n BoundAgencyChecklistTemplates['create']\n>[0];\nexport type PatchAgencyChecklistTemplateInput = Parameters<\n BoundAgencyChecklistTemplates['patch']\n>[0];\nexport type RemoveAgencyChecklistTemplateInput = Parameters<\n BoundAgencyChecklistTemplates['remove']\n>[0];\nexport type PublishAgencyChecklistTemplateInput = Parameters<\n BoundAgencyChecklistTemplates['publish']\n>[0];\n\n/**\n * The live-fetched remainder of `ChecklistAggregateResponse` — everything\n * that isn't `items[]` (this file's header explains the split). Same\n * `loaded`/`lastFetchFailed`/`fetchedAt`/`refresh` contract\n * `RoomingUnassignedPool`/`FloatManagerSummaryState` already establish.\n */\nexport interface ChecklistAggregateState {\n readonly title: string | undefined;\n readonly subtitle: string | undefined;\n readonly progress: { readonly total: number; readonly complete: number } | undefined;\n readonly hasOpenMandatoryByPhase:\n | { readonly PRE_DEPARTURE: boolean; readonly IN_TRIP: boolean; readonly POST_TRIP: boolean }\n | undefined;\n readonly sections: readonly ChecklistSectionRow[];\n /** The aggregate's OWN `items[]`, in the identical live-row-or-tombstone\n * union the snapshot list holds. Kept because a desk console mounts no\n * `OfflineShell`, so the snapshot list is permanently empty there and\n * this fetch is the only place a desk's rows come from — see\n * `ChecklistsReady.items`. */\n readonly items: readonly ChecklistItemDeltaRow[];\n readonly availableTemplates: readonly ChecklistAvailableTemplateRow[];\n /** `true` once at least one `client.checklists.read()` call has settled\n * (success or failure) — distinguishes \"never fetched yet\" from \"fetched\n * and genuinely empty.\" */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. */\n readonly lastFetchFailed: boolean;\n readonly fetchedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n}\n\nexport interface ChecklistsReady {\n /** Cache-first — `SnapshotStore`'s `'checklist'` list. */\n readonly items: readonly ChecklistItemDeltaRow[];\n readonly syncedAt: string | undefined;\n readonly aggregate: ChecklistAggregateState;\n /** `null` rather than an `OutboxOp` when the write took the DESK lane —\n * a direct call has no outbox row to hand back. A field surface with an\n * `OfflineShell` still gets its op. */\n readonly addItem: (input: AddChecklistItemInput) => Promise<OutboxOp | null>;\n readonly patchItem: (input: PatchChecklistItemInput) => Promise<OutboxOp | null>;\n readonly removeItem: (input: RemoveChecklistItemInput) => Promise<OutboxOp | null>;\n readonly toggleItem: (input: ToggleChecklistItemInput) => Promise<OutboxOp | null>;\n /** Live, on-demand — see this file's header for why this is a plain\n * function rather than auto-fetched hook state. */\n readonly listTemplates: (\n input?: ListChecklistTemplatesInput,\n ) => Promise<ChecklistTemplatesListResult>;\n readonly pullTemplate: (input: PullChecklistTemplateInput) => Promise<OutboxOp | null>;\n /** Out of THIS family's own scope (this file's header) — wired for the\n * future admin-family template-authoring composite. */\n readonly listAgencyTemplates: (\n input: ListAgencyChecklistTemplatesInput,\n ) => ReturnType<BoundAgencyChecklistTemplates['list']>;\n readonly createAgencyTemplate: (\n input: CreateAgencyChecklistTemplateInput,\n ) => ReturnType<BoundAgencyChecklistTemplates['create']>;\n readonly patchAgencyTemplate: (\n input: PatchAgencyChecklistTemplateInput,\n ) => ReturnType<BoundAgencyChecklistTemplates['patch']>;\n readonly removeAgencyTemplate: (\n input: RemoveAgencyChecklistTemplateInput,\n ) => ReturnType<BoundAgencyChecklistTemplates['remove']>;\n readonly publishAgencyTemplate: (\n input: PublishAgencyChecklistTemplateInput,\n ) => ReturnType<BoundAgencyChecklistTemplates['publish']>;\n}\n\n/**\n * The row painted for an item added out of signal, until the server's own\n * arrives.\n *\n * TYPED AS THE LIVE ROW ON PURPOSE. `enqueue`'s `optimistic` parameter is\n * `SnapshotRow` — `id` plus `version` plus anything — so nothing would have\n * caught a field with the wrong type here, and the first version of this\n * shipped three: `key` and `updatedAt` as `null` where the row declares\n * `string`, and `gate` as `null` where it declares an enum. The last one was\n * user-visible: `deriveChecklist` treats `gate !== 'NONE'` as a phase\n * blocker, so a brand-new item rendered as something holding the trip back.\n * The annotation is what makes the compiler check the shape.\n */\nfunction optimisticChecklistItem(\n input: AddChecklistItemInput,\n sections: readonly ChecklistSectionRow[],\n fetchedAt: string | undefined,\n): ChecklistItemLiveRow {\n return {\n // Replaced by the id the engine mints — this hook never invents identity.\n id: 'pending',\n // Cannot beat any server row in the snapshot's version-guarded merge.\n version: 0,\n // The write addresses a section by KEY; the board groups rows by ID. An\n // unknown section leaves the row ungrouped rather than filing it under a\n // heading that does not exist.\n sectionId: sections.find((section) => section.key === input.sectionKey)?.id ?? '',\n // The server derives the key from the title when one is not sent. Blank\n // rather than a guessed slug: a key that disagrees with the server's is\n // worse than an obviously-absent one, and nothing renders it.\n key: input.key ?? '',\n title: input.title,\n subLine: null,\n status: 'OPEN',\n // `=== true`, never `?? false` (hard rule #5): an omitted `mandatory` is\n // the SERVER's default to apply, not this hook's to guess.\n isMandatory: input.mandatory === true,\n // `'NONE'`, never null. The add request carries no `gate` at all — the\n // engine derives it from `phase` — and `'NONE'` is the one value that\n // cannot make a pending item look like it is blocking the trip.\n gate: 'NONE',\n dayOffset: null,\n // Appended. The server's own ordering arrives with the canonical row.\n sortOrder: Number.MAX_SAFE_INTEGER,\n completedByManagerId: null,\n performedByKind: null,\n performedById: null,\n completedAt: null,\n // The last reading the SERVER gave this hook, never a device clock (hard\n // rule #6). Blank when nothing has been fetched yet, which is the only\n // honest answer and which the board already prefers `fetchedAt` over.\n updatedAt: fetchedAt ?? '',\n };\n}\n\n/**\n * The aggregate's rows, plus any snapshot row the aggregate has never heard\n * of — which is what a create queued offline looks like from here.\n *\n * Matched by ABSENCE from the aggregate rather than by any property of the\n * id itself: the temporary-id format is the engine's business, and a hook\n * that pattern-matched on it would break silently the day that format\n * changed. The moment the write lands, the server's own row arrives in the\n * aggregate under its canonical id and the local one is purged by the\n * drainer, so this union empties itself.\n */\nfunction appendPendingRows(\n fromAggregate: readonly ChecklistItemDeltaRow[],\n fromSnapshot: readonly ChecklistItemDeltaRow[],\n): readonly ChecklistItemDeltaRow[] {\n if (fromSnapshot.length === 0) {\n return fromAggregate;\n }\n const known = new Set(fromAggregate.map((row) => row.id));\n const pending = fromSnapshot.filter((row) => !known.has(row.id));\n return pending.length === 0 ? fromAggregate : [...fromAggregate, ...pending];\n}\n\nconst useChecklistsInternal = createDomainHook<ChecklistsReady>('checklists', (tripRef) => {\n const client = useKaafilClient();\n const engine = useContext(OfflineEngineContext);\n const { rows: snapshotItems, syncedAt } = useSnapshotList<ChecklistItemDeltaRow>(\n tripRef,\n 'checklist',\n );\n\n // The aggregate carries this module's PROJECTIONS — `sections`, `title`,\n // `progress`, `availableTemplates` — which are recomputed per read and\n // therefore have no delta identity and no snapshot list of their own.\n // `items` is the only delta-shaped part, and it is already cache-first\n // above.\n //\n // That split used to mean the screen was unusable offline even with every\n // item cached: the surface groups items UNDER their section, so an empty\n // `sections` rendered the \"No checklist yet\" empty state over ten rows it\n // was holding. A confident wrong answer, which is the one outcome this\n // hook's own failure handling exists to avoid.\n //\n // So the whole aggregate gets a last-known-good copy in the engine's\n // durable read cache (`kaafil-js`'s `engine.reads` — see its header for why\n // a non-delta response cannot live in the snapshot store). Same key space,\n // same credential scope, same rule: `meta.serverTime` is the age, never a\n // device clock.\n const aggregateCacheKey = `checklists.read:${tripRef}`;\n\n const [aggregate, setAggregate] = useState<Omit<ChecklistAggregateState, 'refresh'>>(() => {\n const cached =\n engine?.reads?.get<Omit<ChecklistAggregateState, 'refresh' | 'loaded' | 'lastFetchFailed'>>(\n aggregateCacheKey,\n );\n if (cached !== undefined) {\n return { ...cached.value, loaded: true, lastFetchFailed: false };\n }\n return {\n title: undefined,\n subtitle: undefined,\n progress: undefined,\n hasOpenMandatoryByPhase: undefined,\n sections: [],\n items: [],\n availableTemplates: [],\n loaded: false,\n lastFetchFailed: false,\n fetchedAt: undefined,\n };\n });\n\n const refreshAggregate = useCallback(async (): Promise<void> => {\n try {\n const response = await client.checklists.read({ tripRef });\n const value = {\n title: response.title,\n subtitle: response.subtitle,\n progress: response.progress,\n hasOpenMandatoryByPhase: response.hasOpenMandatoryByPhase,\n sections: response.sections,\n items: response.items,\n availableTemplates: response.availableTemplates,\n fetchedAt: response.meta.serverTime,\n };\n void engine?.reads?.set(aggregateCacheKey, value, response.meta.serverTime).catch(() => {\n // Costs the next reload's first paint, never this one's correctness.\n });\n setAggregate({ ...value, loaded: true, lastFetchFailed: false });\n } catch {\n // Honest failure, not a fabricated empty aggregate — `loaded` stays\n // whatever it already was, only `lastFetchFailed` flips (the same\n // reasoning `useRooming.ts`'s `refreshUnassignedPool` documents).\n //\n // A previously-seen copy is promoted here for the case the initial\n // state could not cover: `OfflineShell` opens its engine in an effect,\n // so the first render of a trip screen has no engine to read one from.\n setAggregate((previous) => {\n if (previous.loaded) {\n return { ...previous, lastFetchFailed: true };\n }\n const cached =\n engine?.reads?.get<\n Omit<ChecklistAggregateState, 'refresh' | 'loaded' | 'lastFetchFailed'>\n >(aggregateCacheKey);\n return cached === undefined\n ? { ...previous, lastFetchFailed: true }\n : { ...cached.value, loaded: true, lastFetchFailed: true };\n });\n }\n }, [client, tripRef, engine, aggregateCacheKey]);\n\n useEffect(() => {\n void refreshAggregate();\n }, [refreshAggregate]);\n\n // A write's own `mutate()` resolves once the op is DURABLE (write-ahead),\n // not once the drainer has actually sent it — `OfflineEngine.enqueue()`'s\n // own header. Calling `refreshAggregate()` immediately after therefore\n // races the drainer's own POST for this same write: against a real\n // backend both requests are ordinary HTTP calls with no guaranteed\n // ordering, and the GET can genuinely land first and read the\n // PRE-write aggregate — verified live against the sample app, not a mock\n // artifact. The immediate refresh stays (the common, fast-network case\n // still repaints instantly); this additionally re-refreshes once after\n // the NEXT `sync.drained` — the drainer's own \"I just sent a batch\"\n // signal `useOfflineMutation.ts` already uses for the identical reason —\n // so a lost race still self-corrects without a full remount.\n const refreshAggregateAfterDrain = useCallback((): void => {\n if (engine === null) {\n return;\n }\n const unsubscribe = engine.events.on('sync.drained', () => {\n unsubscribe();\n void refreshAggregate();\n });\n }, [engine, refreshAggregate]);\n\n const addItemMutation = useOfflineMutation<AddChecklistItemInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/checklist/items`,\n operationId: 'addChecklistItem' as never,\n body: input,\n // ── THE OPTIMISTIC CREATE ──────────────────────────────────────\n // Without this the item a manager adds out of signal does not\n // appear until it syncs. It was queued, durable and landed on\n // reconnect the whole time — and from where the manager is\n // standing, work that does not show up is work that was lost, so\n // they add it again.\n //\n // `creates` makes the ENGINE mint the row's temporary id (this\n // hook never invents identifiers) and swap it for the server's\n // canonical row the moment the write lands, in one\n // `snapshot.updated`, so the item is never rendered twice.\n creates: true,\n entity: { listName: 'checklist' },\n // Shaped as a real `ChecklistItemDeltaRow` so the board renders it\n // through the same path as every other row rather than a special\n // \"pending\" branch. `id` is a placeholder the engine replaces with\n // the id it mints; `version: 0` cannot beat any server row in the\n // snapshot's version-guarded merge.\n //\n // The write addresses a section by its `sectionKey`, but the board\n // groups rows by `sectionId`, so the id is resolved from the sections\n // this hook already holds. Adding to a section that does not exist\n // yet resolves to `''` and the row sits ungrouped until the write\n // lands — correct rather than clever: inventing a section id would\n // put the item under a heading that does not exist.\n optimistic: optimisticChecklistItem(input, aggregate.sections, aggregate.fetchedAt),\n }),\n // ── THE DESK LANE ─────────────────────────────────────────────────\n // All five checklist writes take the admin triple, and a desk console\n // mounts no `OfflineShell` — without this the write has no transport\n // at all and every attempt fails as an unclassified error.\n // `idempotencyKey` is OPTIONAL on these SDK options, so no lane here\n // mints one (hard rule #4); `linkExpenseReceipt`, whose key is\n // required, is the one write in this package that CANNOT have a desk\n // lane for exactly that reason.\n direct: (liveClient, input) => liveClient.checklists.items.add({ tripRef, ...input }),\n });\n\n const patchItemMutation = useOfflineMutation<PatchChecklistItemInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { itemId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/checklist/items/${itemId}`,\n operationId: 'patchChecklistItem' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.checklists.items.patch({ tripRef, ...input }),\n });\n\n const removeItemMutation = useOfflineMutation<RemoveChecklistItemInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { itemId, version } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/checklist/items/${itemId}`,\n operationId: 'deleteChecklistItem' as never,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.checklists.items.remove({ tripRef, ...input }),\n });\n\n const toggleItemMutation = useOfflineMutation<ToggleChecklistItemInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { itemId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/checklist/items/${itemId}/toggle`,\n // `expectedStatus`, not `version`/`ifMatch` — this file's header,\n // quirk 1.\n operationId: 'toggleChecklistItem' as never,\n body,\n });\n },\n direct: (liveClient, input) => liveClient.checklists.items.toggle({ tripRef, ...input }),\n });\n\n const pullTemplateMutation = useOfflineMutation<PullChecklistTemplateInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/checklist/templates/pull`,\n operationId: 'pullChecklistTemplate' as never,\n body: input,\n }),\n direct: (liveClient, input) => liveClient.checklists.templates.pull({ tripRef, ...input }),\n });\n\n const addItemMutate = addItemMutation.mutate;\n const addItem = useCallback(\n async (input: AddChecklistItemInput): Promise<OutboxOp | null> => {\n const op = await addItemMutate(input);\n void refreshAggregate();\n refreshAggregateAfterDrain();\n return op;\n },\n [addItemMutate, refreshAggregate, refreshAggregateAfterDrain],\n );\n\n const patchItemMutate = patchItemMutation.mutate;\n const patchItem = useCallback(\n async (input: PatchChecklistItemInput): Promise<OutboxOp | null> => {\n const op = await patchItemMutate(input);\n void refreshAggregate();\n refreshAggregateAfterDrain();\n return op;\n },\n [patchItemMutate, refreshAggregate, refreshAggregateAfterDrain],\n );\n\n const removeItemMutate = removeItemMutation.mutate;\n const removeItem = useCallback(\n async (input: RemoveChecklistItemInput): Promise<OutboxOp | null> => {\n const op = await removeItemMutate(input);\n void refreshAggregate();\n refreshAggregateAfterDrain();\n return op;\n },\n [removeItemMutate, refreshAggregate, refreshAggregateAfterDrain],\n );\n\n const toggleItemMutate = toggleItemMutation.mutate;\n const toggleItem = useCallback(\n async (input: ToggleChecklistItemInput): Promise<OutboxOp | null> => {\n const op = await toggleItemMutate(input);\n // A toggle changes both `progress` and `hasOpenMandatoryByPhase` —\n // re-request the live aggregate rather than leaving it stale.\n void refreshAggregate();\n refreshAggregateAfterDrain();\n return op;\n },\n [toggleItemMutate, refreshAggregate, refreshAggregateAfterDrain],\n );\n\n const pullTemplateMutate = pullTemplateMutation.mutate;\n const pullTemplate = useCallback(\n async (input: PullChecklistTemplateInput): Promise<OutboxOp | null> => {\n const op = await pullTemplateMutate(input);\n // Never applied optimistically (this file's header) — the composite's\n // `onPulled` reads the freshly re-fetched `aggregate`, not a value\n // invented from `op` alone.\n void refreshAggregate();\n refreshAggregateAfterDrain();\n return op;\n },\n [pullTemplateMutate, refreshAggregate, refreshAggregateAfterDrain],\n );\n\n // MEMOISED, not inline. `createDomainHook`'s `build()` re-runs on every\n // render, so an arrow written straight into the returned object is a NEW\n // function each time — and a composite that puts one in a `useEffect`\n // dependency array gets an effect that re-fires every render, sets state,\n // and re-renders. That froze a browser tab once\n // (`usePickups.spec.tsx` carries the incident and the invariant).\n const listTemplates = useCallback(\n (input?: ListChecklistTemplatesInput) =>\n client.checklists.templates.list({ tripRef, ...input }),\n [client, tripRef],\n );\n const listAgencyTemplates = useCallback(\n (input: ListAgencyChecklistTemplatesInput) => client.checklists.agencyTemplates.list(input),\n [client],\n );\n const createAgencyTemplate = useCallback(\n (input: CreateAgencyChecklistTemplateInput) => client.checklists.agencyTemplates.create(input),\n [client],\n );\n const patchAgencyTemplate = useCallback(\n (input: PatchAgencyChecklistTemplateInput) => client.checklists.agencyTemplates.patch(input),\n [client],\n );\n const removeAgencyTemplate = useCallback(\n (input: RemoveAgencyChecklistTemplateInput) => client.checklists.agencyTemplates.remove(input),\n [client],\n );\n const publishAgencyTemplate = useCallback(\n (input: PublishAgencyChecklistTemplateInput) =>\n client.checklists.agencyTemplates.publish(input),\n [client],\n );\n\n // ── WHICH ITEM SOURCE WINS ────────────────────────────────────────────\n // The snapshot list is the cache-first lane and stays authoritative\n // wherever it is actually running. On a DESK there is no `OfflineShell`,\n // so it never syncs and returns `[]` forever — while `checklists.read()`\n // has been fetching the very same rows all along and this hook was\n // throwing them away, leaving an admin board permanently empty.\n //\n // The switch is `syncedAt`, NOT the hook's status: a snapshot lane that\n // has never synced reports ready with `[]`, so `[]` alone cannot tell\n // \"genuinely no items\" from \"no sync engine here\" — the same\n // syncedAt-not-status rule the Suppliers usage column needed.\n //\n // EXCEPT for rows the aggregate cannot know about. An item created while\n // offline lives only in the snapshot, under an id this device minted, and\n // `checklists.read()` will not return it until it syncs — so on the\n // aggregate lane it was being dropped on the floor, which is precisely the\n // \"I added it and it vanished\" the optimistic create exists to end. Those\n // rows are unioned in rather than switched to: the aggregate stays the\n // source for everything the server knows, and a pending create is appended\n // until the server knows it too, at which point it arrives through the\n // normal path and this filter stops matching it.\n const items =\n syncedAt === undefined ? appendPendingRows(aggregate.items, snapshotItems) : snapshotItems;\n\n return {\n items,\n syncedAt,\n aggregate: { ...aggregate, refresh: refreshAggregate },\n addItem,\n patchItem,\n removeItem,\n toggleItem,\n listTemplates,\n pullTemplate,\n listAgencyTemplates,\n createAgencyTemplate,\n patchAgencyTemplate,\n removeAgencyTemplate,\n publishAgencyTemplate,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'checklists'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useChecklists(tripRef: string): DomainHookResult<ChecklistsReady> {\n return useChecklistsInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useCloseout(tripRef)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/closeout.ts`): `closeout.get`,\n// `closeout.saveHandover`, `closeout.lock`, `closeout.unlock`,\n// `closeout.exportPdf`. PERSONALIZED mode-dark (`04-closing-day.md`\n// `Gating`) — routed through `createDomainHook()` exactly like\n// `useRooming()`/`useFloat()`.\n//\n// READ MODEL — LIVE, NOT CACHE-FIRST, AND DELIBERATELY SO. `closeout.get()`'s\n// own doc comment (`kaafil-js/src/resources/closeout.ts`, verified this\n// session): \"the aggregate is fully DERIVED — `blockers[]` is recomputed\n// from ten modules on every read and stored nowhere, so there is no\n// `updatedAt` to window and no tombstone to emit.\" There is therefore no\n// delta-shaped list for `useSnapshotList()` to cache — the identical\n// reasoning `useItinerary.ts`'s header already documents for its own live\n// read, one layer further out (that hook's section is merely un-splittable\n// by `extractSectionRows()`; this one was never pull-shaped to begin with —\n// `'closeout'` does not appear in `SYNC_PULL_SECTIONS`). This hook reads via\n// `client.closeout.get()` and refreshes explicitly rather than subscribing\n// to `snapshot.updated`.\n//\n// WRITE MODEL — NOT ROUTED THROUGH `OfflineEngine.enqueue()`, DELIBERATELY.\n// Two independent reasons, the same shape as `useRooming()`'s own\n// `autoAssign` exception (that hook's header, cited): (1) both\n// `saveHandover` and `lock` re-derive the WHOLE aggregate server-side —\n// `canLock`/`lockDisabledReason`/`blockers[]` all move on `lock()` even\n// though only `handover`/`lockedAt` were the intent of the call — and the\n// spec's own Offline note for `ClosingDayFlow` (`04-closing-day.md`) is\n// explicit that the working→locked transition is \"driven by the\n// server-confirmed `stage`/`lockedAt`, never a locally guessed one\"; an\n// outbox round-trip can only hand back an `OutboxOp`, never the re-derived\n// aggregate a lock decision needs synchronously. (2) `expectedVersion` here\n// is a REQUEST BODY field, not an `If-Match` header (`closeout.ts`'s own\n// header, verified) — `useOfflineMutation`'s `ifMatch` plumbing has nowhere\n// to attach it that would actually reach the wire the way this resource\n// expects. Both writes therefore call `client.closeout.*()` directly. This\n// is a real, load-bearing consequence: a `saveHandover`/`lock` attempted\n// while offline throws (network error) rather than queuing durably the way\n// every other write in this package does — flagged as a genuine gap in this\n// worker's final report, not silently smoothed over.\n//\n// `unlock` IS APIKEYAUTH-ONLY (verified against `security.ts` /\n// `OPERATION_SECURITY.unlockCloseout`) — calling it from this hook, itself\n// only ever mounted under a `manager`/`agencyAdmin` session, throws\n// `UnsatisfiableSchemeError` locally, before any request leaves the device.\n// This hook still exposes it (matching the catalog's literal `useCloseout()`\n// table row and the SDK's own uniform `CloseoutResource` shape) because the\n// method exists on `KaafilClient.closeout` for every persona to call — but\n// `ClosingDayFlow`'s own `UnlockForm` never calls it (`04-closing-day.md\n// §ClosingDayFlow`'s `onSubmitUnlockRequest` note: \"this screen makes no\n// `kaafil-js` call of its own here or anywhere else\" — the host's own\n// backend is the only route). Do not add a second, browser-reachable unlock\n// path anywhere — none exists, by design (hard rule #21).\n//\n// `exportPdf` is implemented here for catalog completeness (the SDK exposes\n// it uniformly on `CloseoutResource`) but no composite in this build's\n// `closing-day` module calls it — `04-closing-day.md §ClosingDayScreen`'s\n// own `Does NOT`: \"Does not surface the PDF export action... out of this\n// file's scope for this pass.\"\n\nimport type {\n CloseoutResource,\n ExportCloseoutPackOptions,\n KaafilBinaryResponse,\n LockCloseoutOptions,\n SaveCloseoutHandoverOptions,\n UnlockCloseoutOptions,\n} from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\n\ntype CloseoutGetResult = Awaited<ReturnType<CloseoutResource['get']>>;\n\n/** The whole closing-day aggregate, verbatim off the wire\n * (`CloseoutAggregateResponse`, `kaafil-js/src/generated/schema.d.ts`) plus\n * the envelope's own `meta`. Indexed-access off the real SDK return type\n * rather than restated, per this file's own convention (`useItinerary.ts`'s\n * `ItineraryReadResult`, `useRooming.ts`'s `RoomingStayWindowRow`). */\nexport type CloseoutAggregate = CloseoutGetResult;\n\n/** One row of `CloseoutAggregate['blockers']` — what is still open, and\n * which screen clears it (`actionKey`). The inventory is closed at eleven\n * keys; a twelfth is a spec change, not a release. */\nexport type CloseoutBlockerRow = CloseoutAggregate['blockers'][number];\n\nexport type SaveCloseoutHandoverInput = Omit<\n SaveCloseoutHandoverOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\nexport type LockCloseoutInput = Omit<LockCloseoutOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\nexport type UnlockCloseoutInput = Omit<\n UnlockCloseoutOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\nexport type ExportCloseoutPackInput = Omit<ExportCloseoutPackOptions, 'tripRef' | 'signal'>;\n\nexport interface CloseoutReady {\n /** `undefined` until the first `closeout.get()` has settled — never a\n * fabricated empty aggregate (`RoomingReady.unassignedPool`'s own\n * discipline, applied here). */\n readonly aggregate: CloseoutAggregate | undefined;\n /** `true` once the first `closeout.get()` has settled (success or\n * failure) — distinguishes \"never fetched yet\" from \"fetched, and this\n * trip is genuinely clean\" (`ItineraryReady.loaded`'s own contract). */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. `loaded`/`aggregate` stay\n * whatever they already were; only this flips (mirrors\n * `RoomingReady.unassignedPool.lastFetchFailed`). */\n readonly lastFetchFailed: boolean;\n readonly syncedAt: string | undefined;\n /** Re-runs the live read. Every write below already calls this on its own\n * success (`recordChangedSince`'s own header note: a write's response is\n * already the freshest possible aggregate, but `refresh()` still exists\n * for a caller that wants to re-poll independently of a write, e.g. after\n * a deep-linked blocker screen clears one elsewhere). */\n readonly refresh: () => Promise<void>;\n /** `expectedVersion` REQUIRED (`SaveCloseoutHandoverRequest`) — read it\n * off `aggregate.handover.version`. A stale one is answered `409\n * CONFLICT_VERSION`. Not offline-queued — see this file's header. */\n readonly saveHandover: (input: SaveCloseoutHandoverInput) => Promise<CloseoutAggregate>;\n /** `expectedVersion` optional — `canLock` is re-derived inside the request\n * regardless, so a stale client-side `true` never wins. Not\n * offline-queued — see this file's header. */\n readonly lock: (input?: LockCloseoutInput) => Promise<CloseoutAggregate>;\n /** `apiKeyAuth`-only on the wire — see this file's header. Calling it from\n * any browser persona this hook serves throws `UnsatisfiableSchemeError`\n * before any request is sent. No composite in this build calls it. */\n readonly unlock: (input: UnlockCloseoutInput) => Promise<CloseoutAggregate>;\n /** Returns bytes, not an envelope — see `CloseoutResource.exportPdf`'s own\n * doc comment. No composite in this build's `closing-day` module calls\n * this (`04-closing-day.md §ClosingDayScreen`'s own `Does NOT`). */\n readonly exportPdf: (input?: ExportCloseoutPackInput) => Promise<KaafilBinaryResponse>;\n}\n\nconst useCloseoutInternal = createDomainHook<CloseoutReady>('closing-day', (tripRef) => {\n const client = useKaafilClient();\n\n const [aggregate, setAggregate] = useState<CloseoutAggregate | undefined>(undefined);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n const [syncedAt, setSyncedAt] = useState<string | undefined>(undefined);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.closeout.get({ tripRef });\n setAggregate(response);\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated clean aggregate — `loaded` stays\n // whatever it already was; only `lastFetchFailed` flips (mirrors\n // `ItineraryReady`'s own catch block).\n setLastFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const saveHandover = useCallback(\n async (input: SaveCloseoutHandoverInput): Promise<CloseoutAggregate> => {\n const response = await client.closeout.saveHandover({ tripRef, ...input });\n setAggregate(response);\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n return response;\n },\n [client, tripRef],\n );\n\n const lock = useCallback(\n async (input: LockCloseoutInput = {}): Promise<CloseoutAggregate> => {\n const response = await client.closeout.lock({ tripRef, ...input });\n setAggregate(response);\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n return response;\n },\n [client, tripRef],\n );\n\n const unlock = useCallback(\n async (input: UnlockCloseoutInput): Promise<CloseoutAggregate> => {\n const response = await client.closeout.unlock({ tripRef, ...input });\n setAggregate(response);\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n return response;\n },\n [client, tripRef],\n );\n\n const exportPdf = useCallback(\n (input: ExportCloseoutPackInput = {}): Promise<KaafilBinaryResponse> =>\n client.closeout.exportPdf({ tripRef, ...input }),\n [client, tripRef],\n );\n\n return {\n aggregate,\n loaded,\n lastFetchFailed,\n syncedAt,\n refresh,\n saveHandover,\n lock,\n unlock,\n exportPdf,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'closing-day'` capability triple isn't `lit`\n * (`04-closing-day.md`'s own `Gating`). `manager`/`agencyAdmin` both call\n * this same hook — the spec's `COORDINATOR`-role read-only resolution\n * happens on the open session server-side, never as a UIKit prop or a\n * second hook (`useItinerary.ts`'s identical note for its own module).\n */\nexport function useCloseout(tripRef: string): DomainHookResult<CloseoutReady> {\n return useCloseoutInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useCollections(tripRef)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/collections.ts`):\n// `collections.list`, `collections.eligible`, `collections.record`,\n// `collections.void`. PERSONALIZED mode-dark module\n// (`06-capability-and-personas.md §3`) — gated via `createDomainHook()`,\n// following `useRooming()`'s own exemplar pattern (`08-core-hooks.md §0`).\n//\n// `collections` IS a real `SYNC_PULL_SECTIONS` entry (verified,\n// `kaafil-js/src/offline/pull.ts`) and `CollectionDeltaResponse` is a proper\n// delta row — a live row or a `{ _tombstone: true }` tombstone, both keyed\n// on `id`/`version` — so the recorded-collections list is cache-first via\n// `useSnapshotList`, exactly like `RoomingReady.rooms`.\n//\n// `eligible()` is a DIFFERENT shape, deliberately NOT folded into the\n// cache-first list — same reasoning `RoomingReady.unassignedPool`'s own doc\n// comment gives for `unassigned[]`: `EligibleRowResponse` (verified,\n// `kaafil-js/src/generated/schema.d.ts`) carries no `id`/`version`/\n// tombstone branch at all — it is a live, DERIVED-per-read ranking of\n// travellers by outstanding balance, never a durable per-row delta feed a\n// `SnapshotStore` could rebase against. It is also parameterized by\n// `status` (`'due' | 'settled' | 'all'`, the engine's own `?status=` enum),\n// which a snapshot list has no seam for. So `eligible` here is its own\n// live-fetch pool, refetched whenever `status` changes or `refresh()` is\n// called explicitly — the same `loaded`/`lastFetchFailed`/`fetchedAt`\n// honesty triple `RoomingUnassignedPool` uses, for the identical reason:\n// \"no `Balance` row yet, genuinely empty\" must never look the same as\n// \"haven't fetched yet\" or \"last fetch failed.\"\n//\n// `record()` enqueues through `useOfflineMutation` (idempotent — verified\n// `recordCollection: true` in `kaafil-js/src/generated/security.ts`'s\n// idempotency table — `OfflineEngine.enqueue()` mints the key once,\n// internally, per `useOfflineMutation`'s own header comment). A successful\n// enqueue also re-triggers the eligible pool's live refresh, the same\n// \"this write changes who shows up in the OTHER read\" pattern\n// `RoomingReady.assign` already uses for `refreshUnassignedPool`.\n//\n// `void()` carries a mandatory `If-Match: <version>` — the SDK method\n// signature makes forgetting it impossible (`VoidCollectionOptions.version`\n// is required, not optional; see `collections.ts`'s own doc comment) — so\n// this hook's `void` input keeps `version` required too, threaded straight\n// into `engine.enqueue()`'s `ifMatch`, the same shape\n// `removeRoomMutation`/`patchRoomMutation` already use in `useRooming()`.\n\nimport type {\n CollectionsResource,\n ListEligibleCollectionsOptions,\n OutboxOp,\n RecordCollectionOptions,\n VoidCollectionOptions,\n} from 'kaafil-js/client';\nimport { normalizeDateTimeInput, SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\n// `CollectionsResource['list']`/`['eligible']` both resolve to\n// `KaafilResponse<readonly T[]>` = `T[] & { meta }` (`kaafil-js/src/types/\n// meta.ts`'s own header comment: \"the transport attaches `meta` onto the\n// array in place\" — never a `{ data: T[] }` envelope). The resolved\n// response IS the array itself; `[number]` below reaches its element type\n// the same way `useRooming()`'s own `RoomingStayWindowRow` does.\ntype CollectionDeltaRow = Awaited<ReturnType<CollectionsResource['list']>>[number];\ntype EligibleRow = Awaited<ReturnType<CollectionsResource['eligible']>>[number];\n// Not exported from `kaafil-js/client`'s public surface (verified) — derived\n// off the options type the same way this hook derives every other shape it\n// needs rather than restating the `'due' | 'settled' | 'all'` literal union\n// by hand.\nexport type EligibleCollectionsStatus = NonNullable<ListEligibleCollectionsOptions['status']>;\n\nexport type { CollectionDeltaRow, EligibleRow };\n\ntype RecordCollectionInput = Omit<RecordCollectionOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype VoidCollectionInput = Omit<VoidCollectionOptions, 'tripRef' | 'signal'>;\n\n/**\n * The eligible-balance roster — `collections.eligible()`, ranked \"who owes\n * money,\" the manager family's own p90 read (`families/manager/\n * 01-collections.md`'s own header prose). Its own live-fetch state,\n * deliberately not a `SnapshotList` — see this file's header comment.\n */\nexport interface CollectionsEligiblePool {\n readonly rows: readonly EligibleRow[];\n /** The `status` this pool's current `rows` were fetched with. */\n readonly status: EligibleCollectionsStatus;\n /** `true` once at least one `client.collections.eligible()` call has\n * settled (success or failure) for the CURRENT `status` — distinguishes\n * \"never fetched yet\" from \"fetched and genuinely empty\" (everyone\n * settled, or nobody has a `Balance` row at all). */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw — rendered distinctly from\n * `rows: [], loaded: true`, never collapsed into the same empty state. */\n readonly lastFetchFailed: boolean;\n /** The server time (`meta.serverTime`) of the last successful fetch. */\n readonly fetchedAt: string | undefined;\n /** Re-runs the live read. Passing a `status` switches the pool's own\n * filter and refetches under it; omitting it re-runs the CURRENT\n * `status`. `record()` already calls this on its own success (a payment\n * can move a traveller from `'due'` to `'settled'`) — a composite calls\n * it again after any other action that changes who is eligible. */\n readonly refresh: (status?: EligibleCollectionsStatus) => Promise<void>;\n}\n\nexport interface CollectionsReady {\n /** Recorded collections, cache-first — `collections.list()`'s own delta\n * feed. Includes tombstones for a row's own soft-void is NOT a tombstone\n * (`void()` corrects a live row in place, `CollectionResponse.voidedAt`\n * flips, the row is never removed) — a tombstone here means the\n * collection itself was deleted at the source, which this API surface\n * has no path to cause; the branch exists only because\n * `CollectionDeltaResponse`'s own generated union carries one. */\n readonly collections: readonly CollectionDeltaRow[];\n readonly syncedAt: string | undefined;\n /** Re-reads the desk lane after a write. A NO-OP on a field device, where\n * the outbox drain emits `snapshot.updated` and the cache-first read\n * re-renders itself — a composite need not know which lane it is on. */\n readonly refreshLive: () => Promise<void>;\n readonly eligible: CollectionsEligiblePool;\n /** Records one customer payment. The overpay guard is server-authoritative\n * (`collections.ts`'s own header comment) — this method does not\n * pre-validate `amountMinor` against anything; a `422\n * BUSINESS_RULE_VIOLATION` surfaces through the outbox op's own\n * `parkReason`, same as any other refused write. */\n readonly record: (input: RecordCollectionInput) => Promise<OutboxOp | null>;\n /** Voids a collection — a correction, never an edit or hard delete.\n * `version` is required (mirrors `VoidCollectionOptions`, which makes a\n * missing `If-Match` impossible to construct, not merely discouraged). */\n readonly void: (input: VoidCollectionInput) => Promise<OutboxOp | null>;\n}\n\n/** `CollectionDeltaRow` narrowed to the live shape — a tombstone has none of\n * the fields an optimistic row fills in. */\ntype CollectionLiveRow = Exclude<CollectionDeltaRow, { readonly _tombstone: true }>;\n\n/**\n * The row painted for a payment recorded out of signal.\n *\n * Typed as the live row so the COMPILER checks the shape, rather than\n * `enqueue`'s own `SnapshotRow` parameter, which would accept a wrong-typed\n * field silently.\n *\n * This is a MONEY row, so what it does not claim matters as much as what it\n * does. `outstandingMinor` — what the traveller still owes after this payment\n * — is the server's arithmetic over every other collection on the booking,\n * and it is left `null`, which the row's own type allows and which reads as\n * \"not worked out yet\" rather than as a balance. Showing a figure this\n * device computed would be the one kind of wrong a money surface must never\n * be, and `expenses.log` is left with no optimistic row at all for the same\n * family of reasons (see its own note).\n *\n * `collectedAt` is only ever the caller's own value. The request treats it as\n * optional and the SERVER stamps it when absent; a device clock here would\n * put a receipt time on a payment that the server will disagree with, so an\n * omitted one stays empty until the canonical row arrives.\n */\nfunction optimisticCollection(\n input: RecordCollectionInput,\n syncedAt: string | undefined,\n): CollectionLiveRow {\n const collectedAt =\n input.collectedAt === undefined ? '' : normalizeDateTimeInput(input.collectedAt, 'collectedAt');\n return {\n // Replaced by the id the engine mints.\n id: 'pending',\n version: 0,\n travellerId: input.travellerId,\n amountMinor: input.amountMinor,\n // The request's own default, restated: this tenant's money unit.\n currency: input.currency ?? 'INR',\n mode: input.mode,\n reference: input.reference ?? null,\n note: input.note ?? null,\n collectedByManagerId: null,\n performedByKind: null,\n performedById: null,\n collectedAt,\n reportedAt: null,\n voidedAt: null,\n voidReason: null,\n // The server's arithmetic, deliberately not guessed — see above.\n outstandingMinor: null,\n // The last reading the SERVER gave this list, never a device clock\n // (hard rule #6).\n createdAt: syncedAt ?? '',\n updatedAt: syncedAt ?? '',\n };\n}\n\nconst useCollectionsInternal = createDomainHook<CollectionsReady>('collections', (tripRef) => {\n const client = useKaafilClient();\n // CACHE-FIRST WITH A LIVE FALLBACK. A field device reads its own snapshot\n // exactly as before; a DESK console mounts no `OfflineShell` and has no\n // snapshot at all, so without this the ledger would render \"no payments\n // taken\" for a trip that has collected plenty — and on a MONEY surface a\n // confident zero is the one failure that must never ship.\n // `useSnapshotList`'s own header carries the full argument, including why\n // the `live` callback must never reach a dependency array.\n const {\n rows: collections,\n syncedAt,\n refreshLive,\n } = useSnapshotList<CollectionDeltaRow>(tripRef, 'collections', {\n live: async (liveClient, ref) => {\n const response = await liveClient.collections.list({ tripRef: ref });\n return { rows: response, syncedAt: response.meta.serverTime };\n },\n });\n\n // The eligible pool's own live-fetch state — see `CollectionsEligiblePool`'s\n // doc comment for why this is a `client.collections.eligible()` call and\n // never a snapshot subscription. Defaults to `'due'`, matching the SDK's\n // own default (`collections.ts`'s header comment: \"matching the engine's\n // own default so an existing caller's response never changes underneath\n // it\") and the family spec's p90 read.\n const [eligibleStatus, setEligibleStatus] = useState<EligibleCollectionsStatus>('due');\n const [eligibleRows, setEligibleRows] = useState<readonly EligibleRow[]>([]);\n const [eligibleLoaded, setEligibleLoaded] = useState(false);\n const [eligibleFetchFailed, setEligibleFetchFailed] = useState(false);\n const [eligibleFetchedAt, setEligibleFetchedAt] = useState<string | undefined>(undefined);\n\n const refreshEligible = useCallback(\n async (status?: EligibleCollectionsStatus): Promise<void> => {\n const nextStatus = status ?? eligibleStatus;\n if (status !== undefined && status !== eligibleStatus) {\n setEligibleStatus(status);\n }\n try {\n const response = await client.collections.eligible({ tripRef, status: nextStatus });\n setEligibleRows(response);\n setEligibleLoaded(true);\n setEligibleFetchFailed(false);\n setEligibleFetchedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated empty roster — `loaded` stays\n // whatever it already was, only `lastFetchFailed` flips (mirrors\n // `RoomingReady.unassignedPool.refresh`'s own catch block).\n setEligibleFetchFailed(true);\n }\n },\n [client, tripRef, eligibleStatus],\n );\n\n useEffect(() => {\n // `refreshEligible` is only ever recreated when `client`/`tripRef`/\n // `eligibleStatus` themselves change (its own `useCallback` deps\n // above), so depending on it alone here already re-fetches exactly\n // when any of those three change — no wider dep list needed.\n void refreshEligible(eligibleStatus);\n }, [refreshEligible, eligibleStatus]);\n\n const recordMutation = useOfflineMutation<RecordCollectionInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/collections`,\n // `OperationId` is not exported from `kaafil-js/client`'s public\n // surface (the same gap `useRooming()`'s own comment names) —\n // hardcoded literal, verified against\n // `kaafil-js/src/generated/security.ts` this session.\n operationId: 'recordCollection' as never,\n body: input,\n // A payment recorded out of signal appears at once — see\n // `optimisticCollection` for what it deliberately does not claim.\n creates: true,\n entity: { listName: 'collections' },\n optimistic: optimisticCollection(input, syncedAt),\n }),\n // The desk lane. `recordCollection` takes the admin triple, and a desk\n // console mounts no `OfflineShell` — without this the write has no\n // transport at all and every attempt fails as an unclassified error.\n direct: (liveClient, input) => liveClient.collections.record({ tripRef, ...input }),\n });\n\n const recordMutate = recordMutation.mutate;\n const record = useCallback(\n async (input: RecordCollectionInput): Promise<OutboxOp | null> => {\n const op = await recordMutate(input);\n // A recorded payment can move this traveller out of the current\n // `status` filter (e.g. `'due'` → fully settled) — re-request the\n // live pool rather than leaving it stale (`CollectionsEligiblePool\n // .refresh`'s own doc comment).\n void refreshEligible();\n return op;\n },\n [recordMutate, refreshEligible],\n );\n\n const voidMutation = useOfflineMutation<VoidCollectionInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { collectionId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/collections/${collectionId}/void`,\n operationId: 'voidCollection' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.collections.void({ tripRef, ...input }),\n });\n\n const voidMutate = voidMutation.mutate;\n const voidCollection = useCallback(\n async (input: VoidCollectionInput): Promise<OutboxOp | null> => {\n const op = await voidMutate(input);\n // A voided collection restores outstanding balance — same\n // re-request rationale as `record` above.\n void refreshEligible();\n return op;\n },\n [voidMutate, refreshEligible],\n );\n\n return {\n collections,\n syncedAt,\n refreshLive,\n eligible: {\n rows: eligibleRows,\n status: eligibleStatus,\n loaded: eligibleLoaded,\n lastFetchFailed: eligibleFetchFailed,\n fetchedAt: eligibleFetchedAt,\n refresh: refreshEligible,\n },\n record,\n void: voidCollection,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'collections'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useCollections(tripRef: string): DomainHookResult<CollectionsReady> {\n return useCollectionsInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useExpenses(tripRef)`. Primary SDK\n// surface (verified this session, `kaafil-js/src/resources/expenses.ts` +\n// `generated/security.ts`): `expenses.list`, `expenses.read`, `expenses.log`,\n// `expenses.linkReceipt`, `expenses.void`, `expenses.claims.{submit,\n// withdraw}`. PERSONALIZED mode-dark module (`06-capability-and-personas.md\n// §3`) — gated via `createDomainHook()`, following `useRooming()`'s own\n// exemplar shape (`useRooming.ts`).\n//\n// STRUCTURAL ABSENCE (load-bearing, verified — no such endpoint exists for\n// any credential, for any persona): this hook has NO `approveClaim`/\n// `rejectClaim`/`payClaim` method, and does not expose `expenses.claims.\n// ingest` either — that method is `apiKeyAuth`-only (the CRM's own decision,\n// mirrored inbound) and is never callable from any browser persona this\n// hook serves (`generated/security.ts`: `claimStatusIngest` carries no\n// `managerAuth`/`agencyAdminAuth` scheme at all). Do not add any of these.\n//\n// TRIP-SCOPED, NOT MANAGER-IMPLICIT: `tripRef` is a required, explicit\n// argument here — same shape as `useRooming(tripRef)` — so every write below\n// goes through `expenses.ts`'s trip-scoped surface\n// (`/api/v1/trips/{ref}/expenses...`), never `manager-expenses.ts`'s\n// trip-implicit `/manager/expenses...` reads. `kaafil-engine`'s\n// `manager-expenses.service.ts` header (cited by `manager-expenses.ts`'s own\n// file header) documents WHY: the close-out lock is wired through a path\n// parameter the trip-implicit surface structurally has none of, so\n// `managerExpenses` ships read-only this wave (`list`/`read`/`logMeta`) with\n// no `log`/`void`/`linkReceipt`/`duplicate` counterpart at all. A caller\n// mounting this hook already holds a `tripRef` (from `managerMe.listTrips()`\n// or the trip workspace it's mounted inside), so this hook never needs to\n// resolve one implicitly.\n//\n// GAP (documented, not fabricated): `ManagerExpenseLogMetaResponse` —\n// `GET /manager/expenses/log/meta`'s category/payment-mode vocabularies,\n// resolved float balance, and trip list — is NOT part of this hook's\n// contract. `08-core-hooks.md §3`'s own row for this hook names exactly six\n// SDK methods, none of them `logMeta`; `LogExpenseForm`'s composite (this\n// worker's own build) reads the fixed `ExpenseCategory`/`ExpensePaymentMode`\n// enums directly instead (`families/manager/02-expenses.md §LogExpenseForm`'s\n// own \"Does NOT\": \"does not accept `paymentMode` values from\n// `CollectionMode` — the option list is hardcoded\"), and reads the receipt\n// threshold via `useResolvedSetting('expenses.receipt.thresholdMinor')`\n// exactly as `ReceiptRequirementHint`'s own spec entry requires. `useFloat.ts`\n// is fully implemented, but the negative-float guard it fronts is\n// server-authoritative advisory-locked (a `422` with\n// `details.currentBalanceMinor`, never a version conflict) — `LogExpenseForm`\n// still omits a client-side negative-float banner, matching the same\n// \"server remains the actual authority, no client pre-check\" posture this\n// SDK already takes for collections' overpay guard, not because `useFloat`\n// is unsafe to call.\n\nimport type {\n ExpensesResource,\n LinkExpenseReceiptOptions,\n LogExpenseOptions,\n OutboxOp,\n SubmitExpenseClaimOptions,\n VoidExpenseOptions,\n WithdrawExpenseClaimOptions,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\n/** One row of `ExpensesReady['expenses']` — a live expense (the full\n * `ExpenseResponse` shape) or the tombstone for one voided-and-purged since\n * the last cursor. Structurally identical split to `RoomingRoomDeltaRow`\n * (`useRooming.ts`) — `ExpenseListResponse.items[]` is `anyOf` the two,\n * verified against `kaafil-js/openapi/openapi.json`. */\nexport type ExpenseDeltaRow = Awaited<ReturnType<ExpensesResource['list']>>['items'][number];\n\n/** `ExpenseDeltaRow`, narrowed to the live shape — a voided-and-purged row\n * carries no `category`/`paymentMode`/etc. at all. Composites built on this\n * hook (`manager/composite/expenses/*`) filter to this narrowed type before\n * rendering, the same `isLive*` pattern `useRooming.ts`'s consumers use. */\nexport type ExpenseLiveRow = Exclude<ExpenseDeltaRow, { readonly _tombstone: true }>;\n\n/** Derived structurally off the live row shape rather than imported from\n * `kaafil-js/client` by name (hard rule #1: no file outside `src/core/` may\n * import the SDK, even for a type) — `manager/composite/expenses/*`'s fixed\n * category-chip vocabulary is typed against this alias so a schema drift\n * fails that composite's own typecheck instead of silently going stale. */\nexport type ExpenseCategoryKey = ExpenseLiveRow['category'];\nexport type ExpensePaymentModeKey = ExpenseLiveRow['paymentMode'];\nexport type ExpenseClaimStatus = NonNullable<ExpenseLiveRow['claimStatus']>;\nexport type ExpensePerformedByKind = NonNullable<ExpenseLiveRow['performedByKind']>;\n\n// Exported (not just local aliases) — every manager/admin composite built on\n// this hook types its own write-path props off these rather than reaching\n// past the hook into `kaafil-js/client` itself (hard rule #1).\nexport type LogExpenseInput = Omit<LogExpenseOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\nexport type LinkExpenseReceiptInput = Omit<\n LinkExpenseReceiptOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\nexport type VoidExpenseInput = Omit<VoidExpenseOptions, 'tripRef' | 'signal'>;\nexport type SubmitExpenseClaimInput = Omit<\n SubmitExpenseClaimOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\nexport type WithdrawExpenseClaimInput = Omit<WithdrawExpenseClaimOptions, 'tripRef' | 'signal'>;\n\ntype LogInput = LogExpenseInput;\ntype LinkReceiptInput = LinkExpenseReceiptInput;\ntype VoidInput = VoidExpenseInput;\ntype SubmitClaimInput = SubmitExpenseClaimInput;\ntype WithdrawClaimInput = WithdrawExpenseClaimInput;\n\nexport interface ExpensesReady {\n readonly expenses: readonly ExpenseDeltaRow[];\n readonly syncedAt: string | undefined;\n /** Re-reads the desk lane after a write. A NO-OP on a field device, where\n * the outbox drain emits `snapshot.updated` and the cache-first read\n * re-renders itself — a composite need not know which lane it is on. */\n readonly refreshLive: () => Promise<void>;\n /** Live read (`client.expenses.read()`), not cache-first — for a detail\n * screen that wants the freshest single row rather than whatever the last\n * pull cached. The list above stays the cache-first source for every list\n * view. */\n readonly read: (expenseId: string) => ReturnType<ExpensesResource['read']>;\n readonly log: (input: LogInput) => Promise<OutboxOp | null>;\n /** FIELD-ONLY — see the mutation's own note: its route requires a\n * client-minted idempotency key, which hard rule #4 forbids this layer\n * from supplying, so there is no desk lane and a desk must not offer it. */\n readonly linkReceipt: (input: LinkReceiptInput) => Promise<OutboxOp>;\n readonly void: (input: VoidInput) => Promise<OutboxOp | null>;\n readonly submitClaim: (input: SubmitClaimInput) => Promise<OutboxOp>;\n readonly withdrawClaim: (input: WithdrawClaimInput) => Promise<OutboxOp>;\n /**\n * The SERVER's own spend rollup for this trip — `spendTotalMinor` and the\n * per-category breakdown, straight off `expenses.list()`'s envelope.\n *\n * Its own live state rather than a field on the snapshot list, for the\n * reason `useFloat.summary` and `useCollections.eligible` are: these are\n * DERIVED figures with no `id`/`version`, so there is nothing for\n * `SnapshotStore` to key on, and `useSnapshotList`'s `live` contract\n * returns `{rows, syncedAt}` with no slot for an envelope.\n *\n * Exposed because summing the rows in the browser is the wrong answer\n * twice over: it would miss anything outside the page and it would put a\n * money figure's correctness in the client. `deriveOverview.ts` wanted\n * exactly this and said so (\"wants a server-side rollup … until it lands\n * this card states the two numbers it can stand behind\").\n */\n readonly totals: ExpenseTotalsState;\n // NO `approveClaim`/`rejectClaim`/`payClaim`, no `ingestClaimStatus` —\n // structurally absent, see this file's header.\n}\n\n/** The server's spend rollup, and whether it could be read at all. */\nexport interface ExpenseTotalsState {\n /** `undefined` until a read lands — NEVER 0. A money figure the surface\n * could not read must not be drawn as zero. */\n readonly spendTotalMinor: number | undefined;\n readonly categoryTotals: Readonly<Record<string, number>> | undefined;\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly refresh: () => Promise<void>;\n}\n\nconst useExpensesInternal = createDomainHook<ExpensesReady>('expenses', (tripRef) => {\n const client = useKaafilClient();\n // CACHE-FIRST WITH A LIVE FALLBACK. A field device reads its own snapshot\n // exactly as before; a DESK console mounts no `OfflineShell` and has no\n // snapshot at all, so without this every desk surface that reads expenses\n // would render a confident empty list for a trip that has plenty — which\n // is worse than showing nothing, because a count of zero reads as a fact.\n // `useSnapshotList`'s own header carries the full argument, including why\n // the `live` callback must never reach a dependency array.\n const {\n rows: expenses,\n syncedAt,\n refreshLive,\n } = useSnapshotList<ExpenseDeltaRow>(tripRef, 'expenses', {\n live: async (liveClient, ref) => {\n const response = await liveClient.expenses.list({ tripRef: ref });\n return { rows: response.items, syncedAt: response.meta.serverTime };\n },\n });\n\n // The server's own rollup — see `ExpenseTotalsState`. Read from the SAME\n // endpoint the live lane uses, because that endpoint already returns both;\n // this is a second call rather than a shared one only because\n // `useSnapshotList`'s `live` contract has no slot for an envelope.\n const [spendTotalMinor, setSpendTotalMinor] = useState<number | undefined>(undefined);\n const [categoryTotals, setCategoryTotals] = useState<\n Readonly<Record<string, number>> | undefined\n >(undefined);\n const [totalsLoaded, setTotalsLoaded] = useState(false);\n const [totalsFailed, setTotalsFailed] = useState(false);\n\n const refreshTotals = useCallback(async (): Promise<void> => {\n try {\n const response = await client.expenses.list({ tripRef });\n setSpendTotalMinor(response.spendTotalMinor);\n setCategoryTotals(response.categoryTotals);\n setTotalsLoaded(true);\n setTotalsFailed(false);\n } catch {\n // Honest failure, not a fabricated ₹0 — the figures stay whatever they\n // were, and `lastFetchFailed` is what a caller renders.\n setTotalsFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshTotals();\n }, [refreshTotals]);\n\n // The rollup is a PLAIN READ, so nothing re-runs it when a queued expense\n // finally reaches the server: the item list re-syncs on its own\n // `snapshot.updated`, while the spend total stays at whatever it was when\n // this hook mounted. Out of signal that gap is arbitrarily long, and the\n // screen contradicts itself — the expense is listed, the total does not\n // include it.\n //\n // `sync.drained` is the drainer's own \"I just sent a batch\" signal; one\n // re-read per drain, for as long as this hook is mounted. Same shape and\n // same reason as `useItinerary`'s `refreshAfterDrain` and\n // `useChecklists`'s `refreshAggregateAfterDrain` — a standing subscription\n // rather than a one-shot, because totals go stale on EVERY drain, not only\n // the one that follows a write this hook issued.\n const engine = useContext(OfflineEngineContext);\n useEffect(() => {\n if (engine === null) {\n return;\n }\n const unsubscribe = engine.events.on('sync.drained', () => {\n void refreshTotals();\n });\n return unsubscribe;\n }, [engine, refreshTotals]);\n\n // DECISION (matching `useRooming.ts`'s identical choice for its own\n // room/window writes): every write below enqueues via\n // `OfflineEngine.enqueue()` with a hand-built path/operationId literal\n // rather than calling `client.expenses.*` directly, WITHOUT an `entity`/\n // `optimistic` pairing. `ExpenseListResponse.items[]` IS delta-shaped (this\n // file's own `ExpenseDeltaRow` doc comment), so an optimistic row is not\n // structurally impossible the way `RoomingBoardResponse.unassigned[]` was —\n // but a locally-fabricated `ExpenseResponse` would need to guess\n // server-assigned fields no client can compute (whether `FLOAT_CASH`\n // clears the negative-float guard, the paired `floatMovementId`,\n // `receiptRequired` against the agency's own resolved threshold). Guessing\n // any of those risks a wrong local paint a later pull then has to silently\n // correct — the same risk `useRooming.ts`'s header names for its own case.\n // The write is still durable, outbox-backed and idempotent either way; the\n // UI re-syncs on the next `snapshot.updated` for the `'expenses'` list.\n const logMutation = useOfflineMutation<LogInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/expenses`,\n // Hardcoded literal, not imported: `OperationId` is not exported\n // from `kaafil-js/client`'s public surface (verified — same gap\n // `useRooming.ts` documents). Value verified against\n // `kaafil-js/src/generated/security.ts` this session.\n operationId: 'logExpense' as never,\n body: input,\n }),\n // The desk lane. `log`, `linkReceipt` and `void` each additionally\n // accept an agency-admin session (the SDK's own header says so), and a\n // desk console mounts no `OfflineShell` — without these the writes have\n // no transport at all. `submitClaim`/`withdrawClaim` deliberately get\n // NONE: those are `['manager', 'apiKey']`, a manager claiming their own\n // reimbursement, and an admin has no business standing in for them.\n direct: (liveClient, input) => liveClient.expenses.log({ tripRef, ...input }),\n });\n\n const linkReceiptMutation = useOfflineMutation<LinkReceiptInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { expenseId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/receipt`,\n operationId: 'linkExpenseReceipt' as never,\n body,\n });\n },\n // NO DESK LANE, AND IT CANNOT HAVE ONE. `LinkExpenseReceiptOptions`\n // declares `idempotencyKey` as REQUIRED — the route \"addresses no\n // client-held version\", so the key is its only replay guard — and hard\n // rule #4 forbids any hook here from minting one or accepting one in its\n // signature. The outbox path is unaffected: `OfflineEngine.enqueue()`\n // mints the key itself, which is exactly the arrangement rule #4 exists\n // to preserve. So this write is FIELD-ONLY in practice, and a desk\n // surface must not offer it rather than offering a control that throws.\n // Widening it would mean either breaking rule #4 or making the key\n // optional on the wire, neither of which belongs in a UIKit pass.\n });\n\n const voidMutation = useOfflineMutation<VoidInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { expenseId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/void`,\n operationId: 'voidExpense' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.expenses.void({ tripRef, ...input }),\n });\n\n const submitClaimMutation = useOfflineMutation<SubmitClaimInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { expenseId } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/claim`,\n operationId: 'submitExpenseClaim' as never,\n body: {},\n });\n },\n });\n\n const withdrawClaimMutation = useOfflineMutation<WithdrawClaimInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { expenseId, version } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/expenses/${expenseId}/claim/withdraw`,\n operationId: 'withdrawExpenseClaim' as never,\n body: {},\n ifMatch: version,\n });\n },\n });\n\n // MEMOISED, not inline. `createDomainHook`'s `build()` re-runs on every\n // render, so an arrow written straight into the returned object is a NEW\n // function each time — and a composite that puts one in a `useEffect`\n // dependency array gets an effect that re-fires every render, sets state,\n // and re-renders. That froze a browser tab once\n // (`usePickups.spec.tsx` carries the incident and the invariant).\n const read = useCallback(\n (expenseId: string) => client.expenses.read({ tripRef, expenseId }),\n [client, tripRef],\n );\n\n return {\n expenses,\n syncedAt,\n refreshLive,\n totals: {\n spendTotalMinor,\n categoryTotals,\n loaded: totalsLoaded,\n lastFetchFailed: totalsFailed,\n refresh: refreshTotals,\n },\n read,\n log: logMutation.mutate,\n linkReceipt: linkReceiptMutation.mutate,\n void: voidMutation.mutate,\n submitClaim: submitClaimMutation.mutate,\n withdrawClaim: withdrawClaimMutation.mutate,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'expenses'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useExpenses(tripRef: string): DomainHookResult<ExpensesReady> {\n return useExpensesInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useFiles(context)`. Primary SDK surface\n// (verified this session, `kaafil-js/src/resources/files.ts` +\n// `generated/security.ts`): `files.request`, `files.confirm`, `files.meta`,\n// `files.url`, `files.list`, `files.managerView` — all six `managerAuth` +\n// `apiKeyAuth` + `agencyAdminAuth`.\n//\n// `purpose` IS GATED PER CREDENTIAL server-side, and this line used to say\n// `booking_voucher` was \"the one value no manager/agencyAdmin-issued\n// `request()` may pass\". Half of that is now wrong. Today:\n//\n// apiKey `booking_voucher` | `trip_document`\n// manager `expense_receipt` | `form_attachment`\n// agencyAdmin ALL FOUR\n//\n// A refused purpose answers **404, no capability hint** — it looks like a\n// missing trip, which is deliberate and worth knowing when debugging one.\n// The engine enforces it; this hook does not re-check.\n//\n// NO INDEPENDENT CAPABILITY GATE — BY CHOICE, NOT BECAUSE THERE IS NO ROW.\n//\n// CORRECTION (re-verified against the engine this session): this header used\n// to claim \"no `'files'` row exists anywhere in the capability catalog\". That\n// was WRONG, and it mattered — `TAB_CAPABILITY.documents = 'files'` in the\n// admin tab rail reads as a typo if you believe it. `files` is a real\n// capability: `flag-catalog.ts` carries `files: { default: false, parent:\n// null, label: 'Uploads, attachments and retention' }`, `files.constants.ts`\n// exports `filesCapability` (`key: 'files'`, `sortOrder: 90`), it is in\n// `tier-catalog.ts`'s permitted set, and every one of the six routes runs\n// `assertFilesCapability` before doing anything.\n//\n// The hook is still ungated, and the spec's reasoning is the surviving one\n// (`families/manager/07-files.md`'s \"Gating\" row: \"no independent gate;\n// entirely inherited from whichever consumer composite mounts this flow\").\n// A host composite applies whatever gate it already holds before mounting\n// this — `'expenses'` for receipt capture, `'forms'` for a field editor,\n// `'files'` itself for the admin Documents tab, which reads the triple\n// through `useCapabilityStatuses()` and renders the darkness itself.\n//\n// Every OTHER domain hook in this file wraps\n// its build function in `createDomainHook(moduleKey, build)`, which resolves\n// a capability triple keyed by that exact module string and returns\n// `{ status: 'dark' }` when the row is missing/unknown — for a module that\n// genuinely has no such row, that gate does not \"pass through\", it goes\n// permanently dark (`UNKNOWN_CAPABILITY_TRIPLE`), which would make this hook\n// unusable from any host. This hook is therefore built the same UNGATED\n// shape `useServerTime()`/`useCapabilities()` use: a plain function\n// returning `FilesReady` directly, never a `DomainHookResult` union. A host\n// composite (`LogExpenseForm`, a form field's `SIGNATURE`/`FILE_UPLOAD`\n// editor) applies whatever OWN capability gate it already holds\n// (`'expenses'`, `'forms'`) before ever mounting `FileAttachmentFlow` — this\n// hook does not re-gate on top of that, matching the spec row above exactly.\n//\n// BLOB LANE, DELIBERATELY NOT USED HERE (documented choice, not an\n// oversight): `kaafil-js/src/offline/blob.ts`'s `BlobLane.enqueue()` needs a\n// `backfill` (the parent record's own PATCH target) supplied at enqueue\n// time — `FileAttachmentFlow`'s own spec \"Does NOT\" row says it \"does not\n// attach the resulting `fileId` to any consumer record\" and \"does not\n// decide what a parent record's write looks like\". Only the HOST composite\n// knows that backfill shape, so wiring a blob permanently to the FIFO\n// lane's automatic back-fill is that host's own opt-in integration, built on\n// `useOfflineEngine().blobs` directly — outside this hook's contract. What\n// this hook (and `FileAttachmentFlow`, built on it) provides instead is the\n// foreground presign → PUT → confirm sequence, run directly against\n// `client.files.*`, with the same \"a 15-minute window expiring mid-retry is\n// routine, never surfaced as an error\" tolerance the spec asks for — see\n// `requestUploadWithRetry` below.\n\nimport type { FilesResource } from 'kaafil-js/client';\nimport { useCallback } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\nexport interface FilesContext {\n readonly tripRef: string;\n}\n\ntype RequestOptions = Omit<Parameters<FilesResource['request']>[0], 'tripRef'>;\ntype ConfirmOptions = Omit<Parameters<FilesResource['confirm']>[0], 'signal'>;\ntype ListOptions = Omit<Parameters<FilesResource['list']>[0], 'tripRef'>;\n\n// `KaafilResponse<T> = T & { meta }` — a flat intersection, never a `{\n// data, meta }` envelope (verified, `kaafil-js/src/types/meta.ts`'s own\n// header + `http/client.ts`'s `Object.assign(data as object, { meta })`).\n// Every alias below reads the resolved value directly, with no `.data`\n// unwrap — the same convention `fakeKaafilRuntime.ts`'s own header comment\n// documents for `journey.capabilities()`.\nexport type FileMeta = Awaited<ReturnType<FilesResource['meta']>>;\nexport type FileUrl = Awaited<ReturnType<FilesResource['url']>>;\nexport type FileListItem = Awaited<ReturnType<FilesResource['list']>>['items'][number];\nexport type ManagerFileView = Awaited<ReturnType<FilesResource['managerView']>>;\nexport type FileStatus = FileMeta['status'];\nexport type FilePurpose = FileMeta['purpose'];\n\nexport interface FilesReady {\n /** `POST /api/v1/files` — mints a `pending` row + a presigned `PUT`. */\n readonly request: (input: RequestOptions) => ReturnType<FilesResource['request']>;\n /** `POST /api/v1/files/{id}/confirm` — verifies what landed, flips\n * `pending` → `ready`. `422 UPLOAD_MISMATCH` leaves the file `pending`;\n * the caller re-`PUT`s and re-confirms (`FileAttachmentFlow` does this\n * itself, see its own file). */\n readonly confirm: (input: ConfirmOptions) => ReturnType<FilesResource['confirm']>;\n /** `GET /api/v1/files/{id}` — the metadata skeleton; `200` even once\n * `purged` — the one read that never 404s on a gone file. */\n readonly meta: (fileId: string) => Promise<FileMeta>;\n /** `GET /api/v1/files/{id}/url` — a fresh 5-minute signed GET, minted on\n * every call, never cached across calls. `410 FILE_PURGED` once the\n * bytes are gone. */\n readonly url: (fileId: string) => Promise<FileUrl>;\n /** `GET /api/v1/files?tripRef=…` — every file for this trip, newest\n * first, optionally narrowed by `purpose`/`status`. Needs no `fileId`. */\n readonly list: (query?: ListOptions) => Promise<readonly FileListItem[]>;\n /** `GET /api/v1/files/{id}/manager-view` — `meta()` + `url()` composed\n * server-side into one manager-doc-viewer-shaped response. Never refuses\n * on a non-`ready` file the way `url()` does — `url`/`urlExpiresAt` come\n * back `null` instead. */\n readonly managerView: (fileId: string) => Promise<ManagerFileView>;\n /**\n * `DELETE /api/v1/files/{id}` — withdraw a `trip_document` and DESTROY THE\n * STORED OBJECT. The only call here that removes bytes rather than reading\n * or adding them.\n *\n * `version` is the one from the file as last read, and is required: a\n * missing `If-Match` and a stale one both answer `409`, so the signature\n * refuses to let a caller forget it.\n *\n * Refuses with `422 BUSINESS_RULE_VIOLATION` on any other purpose\n * (`file.deleteRestrictedToTripDocument`) — a receipt, attachment or\n * voucher is evidence owned by its parent record, and leaves through that\n * — and on a `financial`/`consent_evidence` retention class\n * (`file.deleteBlockedByRetention`).\n *\n * Afterwards `meta(fileId)` answers `404` rather than the `200` skeleton a\n * purged file returns: a withdrawn document is indistinguishable from one\n * that never existed.\n */\n readonly remove: (fileId: string, version: number) => Promise<void>;\n /**\n * The full presign → direct-`PUT` → confirm sequence for one local\n * `File`, run in the foreground. On a `422 UPLOAD_MISMATCH` OR a presign\n * window that lapsed mid-`PUT` (the underlying `PUT`/`confirm` answering\n * a plain network failure once the 15-minute signature has expired) this\n * re-requests a fresh slot and retries silently, up to `maxAttempts` —\n * `07-files.md`'s own \"must never surface as an error\" contract for the\n * routine case. Bytes never pass through this SDK or the Kaafil API\n * itself; only the presign/confirm calls do.\n */\n readonly upload: (input: {\n readonly file: File;\n readonly purpose: FilePurpose;\n /** REQUIRED for `trip_document`, refused (422) for every other purpose —\n * nothing else names that file. */\n readonly title?: string;\n /** Only for `trip_document`. Omit and the document belongs to the whole\n * trip; name a traveller and only they see it on their own share link.\n * It also decides retention (scoped → `TRAVELLER_PII`). */\n readonly travellerRef?: string;\n readonly maxAttempts?: number;\n readonly signal?: AbortSignal;\n }) => Promise<FileMeta>;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3;\n\nexport function useFiles(context: FilesContext): FilesReady {\n const client = useKaafilClient();\n const { tripRef } = context;\n\n // MEMOISED, not inline. An arrow written straight into the returned object\n // is a NEW function on every render, and a consumer that puts one in a\n // `useEffect` dependency array gets an effect that re-fires forever —\n // fetch, set state, re-render, fetch. That froze a browser tab once; see\n // `usePickups.spec.tsx` for the incident and the invariant it now guards.\n const request = useCallback(\n (input: RequestOptions) => client.files.request({ ...input, tripRef }),\n [client, tripRef],\n );\n const confirm = useCallback((input: ConfirmOptions) => client.files.confirm(input), [client]);\n const meta = useCallback((fileId: string) => client.files.meta({ fileId }), [client]);\n const url = useCallback((fileId: string) => client.files.url({ fileId }), [client]);\n const list = useCallback(\n async (query?: ListOptions) => (await client.files.list({ ...query, tripRef })).items,\n [client, tripRef],\n );\n const managerView = useCallback(\n (fileId: string) => client.files.managerView({ fileId }),\n [client],\n );\n const remove = useCallback(\n async (fileId: string, version: number) => {\n await client.files.remove({ fileId, version });\n },\n [client],\n );\n const upload = useCallback(\n async ({\n file,\n purpose,\n title,\n travellerRef,\n maxAttempts = DEFAULT_MAX_ATTEMPTS,\n signal,\n }: {\n readonly file: File;\n readonly purpose: FilePurpose;\n readonly title?: string;\n readonly travellerRef?: string;\n readonly maxAttempts?: number;\n readonly signal?: AbortSignal;\n }) => {\n let lastError: unknown;\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n const created = await client.files.request({\n tripRef,\n purpose,\n contentType: file.type as never,\n sizeBytes: file.size,\n // Conditional spreads, not `title: title` — the engine rejects a\n // present-but-undefined key on the wrong purpose the same way it\n // rejects a real one, and \"absent\" is the only thing that means\n // \"no title\"/\"the whole trip\".\n ...(title !== undefined ? { title } : {}),\n ...(travellerRef !== undefined ? { travellerRef } : {}),\n ...(signal !== undefined ? { signal } : {}),\n });\n try {\n const put = await fetch(created.uploadUrl, {\n method: 'PUT',\n headers: { 'Content-Type': file.type },\n body: file,\n ...(signal !== undefined ? { signal } : {}),\n });\n if (!put.ok) {\n lastError = new Error(`Upload PUT failed with status ${put.status}`);\n continue;\n }\n } catch (putError) {\n lastError = putError;\n continue;\n }\n try {\n return await client.files.confirm({\n fileId: created.fileId,\n ...(signal !== undefined ? { signal } : {}),\n });\n } catch (confirmError) {\n // A mismatch (or an expired-window failure) is the routine case\n // this method exists to absorb — request a fresh slot and retry\n // rather than surfacing it as an error on the first attempt.\n lastError = confirmError;\n }\n }\n throw lastError instanceof Error\n ? lastError\n : new Error('File upload did not confirm after retrying.');\n },\n [client, tripRef],\n );\n\n return { request, confirm, meta, url, list, managerView, upload, remove };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useFloat(tripRef)`. Primary SDK surface\n// (verified, `kaafil-js/src/resources/float.ts` + `generated/schema.d.ts`):\n// `float.readSummary`, `float.readLedger`, `float.issue`, `float.return`,\n// `float.adjust`. PERSONALIZED mode-dark.\n//\n// THE LEDGER (`movements`) IS CACHE-FIRST; THE BALANCE (`summary`) IS A LIVE\n// READ — same split `useRooming()` draws between `rooms`/`stayWindows` (both\n// delta-shaped, cache-first) and `unassignedPool` (derived, live). `'float'`\n// is a registered consolidated-pull section (`kaafil-js/src/offline/\n// pull.ts`'s `SYNC_PULL_SECTIONS`) whose `data` is, verbatim, the same shape\n// `client.float.readLedger()` returns for the calling manager's own\n// movements — an append-only array of rows each carrying `id`/`version`, so\n// `extractSectionRows()` takes it as a genuine delta feed. `readSummary()`'s\n// rows, by contrast, are ENTIRELY DERIVED (`issuedMinor`/`returnedMinor`/\n// `spentMinor`/`adjustmentsMinor`/`balanceMinor` — nothing here is stored,\n// per that resource file's own header) and carry no `id`/`version` at\n// all — there is nothing for `SnapshotStore`/`mergeDeltaRows` to key on, the\n// identical reasoning `useRooming.ts` documents for why `unassignedPool` is\n// a live `client.rooming.read()` call rather than a cached list. `summary`\n// below follows that same shape: a live-fetched, explicitly-refreshed\n// state, not a snapshot subscription.\n//\n// NO TOMBSTONE VARIANT MODELLED FOR MOVEMENTS. `FloatResource` (verified)\n// exposes no delete/void method for a movement — every movement is\n// immutable and additive (the file's own \"append-only, appends commute\"\n// framing, `families/manager/03-float.md`'s \"no ConflictResolver, ever\"\n// section) — so `FloatMovementRow` below is typed as the live row shape\n// alone, never a `Row | Tombstone` union. If a future build ever needs to\n// reverse a movement it does so with a NEW corrective row\n// (`reversesMovementId`), never a tombstone on the original.\n//\n// THE NEGATIVE-FLOAT GUARD HAS NO VERSION TO RACE ON. Unlike `rooming`'s\n// room/window writes, none of `issue`/`return`/`adjust` below send an\n// `ifMatch` — `FloatSummaryResponse` (the derived balance) carries no\n// `version` field, and the guard itself runs server-side under an advisory\n// lock rather than an optimistic one (`float.ts`'s own header comment: \"so\n// two concurrent `OUT`s can never both pass the same stale read\"). A\n// refusal is `422 BUSINESS_RULE_VIOLATION` with `details.currentBalanceMinor`\n// — never a `409`, matching `families/manager/03-float.md`'s own framing\n// note that this module renders no `ConflictResolver` anywhere.\n//\n// NO `source` FIELD. The reference boilerplate's `FloatAdjustPayload`\n// carries a `source` key (`admin_disbursed`/`self_topup`/`other`) with its\n// own topup-meta picker endpoint. Neither exists on this build's real\n// wire — `IssueFloatRequest`/`ReturnFloatRequest`/`AdjustFloatRequest`\n// (`generated/schema.d.ts`, verified) carry `managerId`/`amountMinor`/\n// `note`/`clientRef` only, and there is no `GET .../float/topup-meta`\n// operation in `FloatResource` at all. Composites built on this hook must\n// not invent a source picker — \"absence leaves no trace.\"\n\nimport type {\n AdjustFloatOptions,\n FloatResource,\n IssueFloatOptions,\n OutboxOp,\n ReturnFloatOptions,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\n/** One row of the calling manager's own float ledger — verified against\n * `FloatLedgerResponse.data[number]` (`generated/schema.d.ts`). See this\n * file's header for why no tombstone variant is modelled. */\nexport type FloatMovementRow = Awaited<ReturnType<FloatResource['readLedger']>>['data'][number];\n\n/** One row of `FloatSummaryResponse.data[]` — entirely derived, never\n * delta-mergeable. See this file's header. */\nexport type FloatSummaryRow = Awaited<ReturnType<FloatResource['readSummary']>>['data'][number];\n\nexport type IssueFloatInput = Omit<IssueFloatOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\nexport type ReturnFloatInput = Omit<ReturnFloatOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\nexport type AdjustFloatInput = Omit<AdjustFloatOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\n\n/**\n * The live-fetched balance/breakdown state — `readSummary()`'s own rows,\n * refreshed explicitly rather than subscribed to `snapshot.updated`. Carries\n * every manager row the calling credential is entitled to see (a manager\n * session is answered its own row only, per `float.ts`'s own header — this\n * hook does not re-filter that, since it has no independent way to verify\n * which row is \"self\" beyond what the server already scoped the response\n * to); a composite that needs \"my own row\" specifically matches on the\n * `managerRef`/`managerId` it was itself handed as a prop.\n */\nexport interface FloatManagerSummaryState {\n readonly rows: readonly FloatSummaryRow[];\n /** `true` once at least one `client.float.readSummary()` call has settled\n * (success or failure) — distinguishes \"never fetched yet\" from \"fetched\n * and genuinely empty,\" the same contract `RoomingUnassignedPool.loaded`\n * documents. */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. */\n readonly lastFetchFailed: boolean;\n /** The server time (`meta.serverTime`) of the last successful fetch. */\n readonly fetchedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n}\n\nexport interface FloatReady {\n /** The calling manager's own movement history, cache-first — see this\n * file's header for why this is the one cache-first field on this hook. */\n readonly movements: readonly FloatMovementRow[];\n readonly syncedAt: string | undefined;\n readonly summary: FloatManagerSummaryState;\n /**\n * ONE NAMED MANAGER's movement history — `GET .../float/{managerId}/ledger`.\n *\n * Distinct from `movements` above, and the distinction matters on a desk:\n * `movements` is the CALLING MANAGER's own ledger, read from the `'float'`\n * pull section, which is scoped that way. An agency admin has no `Manager`\n * row, so there is no \"own ledger\" for them to read and no live lane that\n * could sensibly fill one — a desk asks \"show me THIS manager's\n * movements\", which is what this is for. `summary` names every manager who\n * has ever had a movement on the trip, so a caller always has an id to\n * pass.\n */\n readonly readLedger: (managerId: string) => ReturnType<FloatResource['readLedger']>;\n /** `POST .../float/issue` — `type=ISSUE`, `direction=IN`, never\n * negative-float guarded. */\n readonly issue: (input: IssueFloatInput) => Promise<OutboxOp | null>;\n /** `POST .../float/return` — `type=RETURN`, `direction=OUT`,\n * negative-float guarded. A manager, an API key OR an agency admin may\n * call it: this comment previously claimed `managerAuth`-only and that an\n * admin \"gets refused by the server\", which is wrong —\n * `float.routes.ts` declares the admin triple on it and its route\n * description calls the parity a deliberate owner decision. An office\n * reconciling a returned cash box is the case it exists for. */\n readonly return: (input: ReturnFloatInput) => Promise<OutboxOp | null>;\n /** `POST .../float/adjust` — `type=ADJUSTMENT`; `direction: 'OUT'` is\n * negative-float guarded identically to `return`, `direction: 'IN'`\n * never is. `note` is required by the wire request type itself. */\n readonly adjust: (input: AdjustFloatInput) => Promise<OutboxOp | null>;\n}\n\nconst useFloatInternal = createDomainHook<FloatReady>('float', (tripRef) => {\n const client = useKaafilClient();\n const { rows: movements, syncedAt } = useSnapshotList<FloatMovementRow>(tripRef, 'float');\n\n const [summaryRows, setSummaryRows] = useState<readonly FloatSummaryRow[]>([]);\n const [summaryLoaded, setSummaryLoaded] = useState(false);\n const [summaryFetchFailed, setSummaryFetchFailed] = useState(false);\n const [summaryFetchedAt, setSummaryFetchedAt] = useState<string | undefined>(undefined);\n\n const refreshSummary = useCallback(async (): Promise<void> => {\n try {\n const response = await client.float.readSummary({ tripRef });\n setSummaryRows(response.data);\n setSummaryLoaded(true);\n setSummaryFetchFailed(false);\n setSummaryFetchedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated empty summary — `loaded` stays\n // whatever it already was; only `lastFetchFailed` flips. Same\n // reasoning as `useRooming.ts`'s `refreshUnassignedPool`.\n setSummaryFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshSummary();\n }, [refreshSummary]);\n\n const issueMutation = useOfflineMutation<IssueFloatInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/float/issue`,\n // `OperationId` is not exported from `kaafil-js/client`'s public\n // surface (verified, same gap `useRooming.ts` documents for its own\n // literal operationId casts).\n operationId: 'issueFloat' as never,\n body: input,\n }),\n // The desk lane. All three float writes take the admin triple — `return`\n // included, contrary to what this file used to claim — and a desk\n // console mounts no `OfflineShell`, so without these the writes have no\n // transport at all.\n direct: (liveClient, input) => liveClient.float.issue({ tripRef, ...input }),\n });\n\n const returnMutation = useOfflineMutation<ReturnFloatInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/float/return`,\n operationId: 'returnFloat' as never,\n body: input,\n }),\n direct: (liveClient, input) => liveClient.float.return({ tripRef, ...input }),\n });\n\n const adjustMutation = useOfflineMutation<AdjustFloatInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/float/adjust`,\n operationId: 'adjustFloat' as never,\n body: input,\n }),\n direct: (liveClient, input) => liveClient.float.adjust({ tripRef, ...input }),\n });\n\n const issueMutate = issueMutation.mutate;\n const issue = useCallback(\n async (input: IssueFloatInput): Promise<OutboxOp | null> => {\n const op = await issueMutate(input);\n // A movement changes the derived balance — re-request the live\n // summary rather than leaving it stale until some unrelated remount\n // (`RoomingReady.assign`'s own precedent for `unassignedPool`).\n void refreshSummary();\n return op;\n },\n [issueMutate, refreshSummary],\n );\n\n const returnMutate = returnMutation.mutate;\n const returnFloat = useCallback(\n async (input: ReturnFloatInput): Promise<OutboxOp | null> => {\n const op = await returnMutate(input);\n void refreshSummary();\n return op;\n },\n [returnMutate, refreshSummary],\n );\n\n const adjustMutate = adjustMutation.mutate;\n const adjust = useCallback(\n async (input: AdjustFloatInput): Promise<OutboxOp | null> => {\n const op = await adjustMutate(input);\n void refreshSummary();\n return op;\n },\n [adjustMutate, refreshSummary],\n );\n\n // MEMOISED, not inline — `createDomainHook`'s `build()` re-runs every\n // render, and a composite that puts an unstable callback in a `useEffect`\n // dependency array is the infinite loop that froze a browser tab once\n // (`usePickups.spec.tsx` carries the incident).\n const readLedger = useCallback(\n (managerId: string) => client.float.readLedger({ tripRef, managerId }),\n [client, tripRef],\n );\n\n return {\n movements,\n syncedAt,\n readLedger,\n summary: {\n rows: summaryRows,\n loaded: summaryLoaded,\n lastFetchFailed: summaryFetchFailed,\n fetchedAt: summaryFetchedAt,\n refresh: refreshSummary,\n },\n issue,\n return: returnFloat,\n adjust,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'float'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useFloat(tripRef: string): DomainHookResult<FloatReady> {\n return useFloatInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useForms(tripRef | formRef)`. This build\n// resolves the SIGNATURE AMBIGUITY the prior stub's own header comment\n// flagged: the manager/agencyAdmin trip-scoped surface\n// (`ui-kit/families/manager/05-forms.md §FormFillFlow`, `§TripFormsPanel`) —\n// \"which forms are open on this trip, fill/capture one, read what was\n// already answered\" — never needs a `formRef`-only entry point of its own;\n// every real call site threads a `tripRef` (`FormFillFlow`'s own prop\n// table). The admin-only AUTHORING surface (`forms.create`/`.patch`/\n// `.sections.*`/`.fields.*`/`.publish`/…) belongs to\n// `admin/05-forms.md §FormsAuthoringFlow` — explicitly NOT this family\n// (`manager/05-forms.md`'s own framing note: \"a manager only fills forms; a\n// manager never authors them\") — and is left unimplemented here rather than\n// bolted onto a hook this session's manager composites never call it\n// through; see this worker's final report for the concrete gap.\n//\n// Primary SDK surface (verified this session, `kaafil-js/src/resources/\n// forms.ts` + `generated/security.ts`): `forms.trip.list` (`ListTripForms`),\n// `forms.get` (`GetForm`), `forms.responses.get` (`GetFormResponse`),\n// `forms.trip.travellerResponses.list` (`ListTravellerFormResponses`),\n// `forms.trip.responses.create` (`ManagerCreateFormResponse`). SDK MISMATCH\n// (inherited from the prior stub, still true): the catalog's shorthand\n// `forms.tripForms.*` names `forms.trip.*` on the real `FormsResource`.\n//\n// CORRECTED THIS PASS — `forms` IS A LIVE FETCH, NOT A SNAPSHOT-LIST READ.\n// The prior build of this hook read `forms` via `useSnapshotList(tripRef,\n// 'forms')`, on the assumption it rides the consolidated pull the way\n// `checklist`/`rooming`/`expenses` do. Verified false against the vendored\n// spec this pass: `kaafil-js/src/offline/pull.ts`'s own `SYNC_PULL_SECTIONS`\n// constant — \"every section the vendored spec CAN send\" — has no `forms`\n// entry, and the generated `SyncPullResponse['sections']` type (`generated/\n// schema.d.ts`) has no `forms` key either. A `useSnapshotList('forms')` read\n// is therefore not \"eventually populated on the next pull\" — it is\n// PERMANENTLY empty, because the consolidated pull the offline engine\n// actually runs has no code path that could ever fill it, live backend or\n// mock alike (confirmed live against a real seeded mock server this pass —\n// `/sync`'s own `forms` section arrived over the wire and was still never\n// read). `forms.trip.list({tripRef})` (`ListTripForms`) is the real,\n// already-correct live endpoint for this exact data — `forms`/`syncedAt`\n// below are now a plain live-fetched, explicitly-refreshed state (refreshed\n// on mount and again after `submitResponse` succeeds), the identical\n// `unassignedPool`/`aggregate` shape `useRooming.ts`/`useChecklists.ts`\n// already establish for their own live-fetched halves — not cache-first,\n// same as those.\n//\n// AUTHORING SURFACE ADDED THIS SESSION (`admin/05-forms.md\n// §FormBuilder/§FormLifecycleControls/§BindingCatalogBrowser/\n// §FormLocaleSiblingManager`) — the gap the comment above (inherited from\n// the manager-family build) flagged as its own follow-up. `forms.{create,\n// list,patch,publish,close,reopen,archive,unarchive,clone,reorder}`,\n// `forms.sections.{create,patch,delete}`, `forms.fields.{create,patch,\n// delete}` and `forms.bindings.list` all accept `agencyAdminAuth` (verified,\n// `generated/security.ts`) — this is the admin family's own authoring door,\n// so it is wired here rather than left a stub a second worker over. These\n// calls are direct, ONLINE-ONLY `client.forms.*` calls, never routed through\n// `useOfflineMutation`'s outbox — the identical resolved choice\n// `useChecklists.ts`'s own `agencyTemplates.*` methods already make for the\n// same class of agency-wide, desk-only authoring write (\"authoring is a\n// desk, online-first workflow\", this family's own Offline row) — an outbox\n// op's fire-and-forget shape has no way to hand a diff-syncing `FormBuilder`\n// the real, patched row it needs back to reconcile local ids/locked flags\n// against, the same reasoning `ChecklistTemplateLibrary.tsx`'s own header\n// gives for its sibling choice one domain over.\n//\n// `forms.create`/`forms.list` are AGENCY-BOUND on the browser client\n// (`kaafil-js/dist/client-entry.d.ts`'s own `BoundFormsResource`: \"create/\n// list agencyRef-bound... every other member is untouched\") — this hook\n// therefore never asks a caller for an `agencyRef` on those two calls,\n// matching `useChecklists.ts`'s corrected note for its own identically-bound\n// `agencyTemplates.list`/`.create` (its header's older claim that\n// `agencyRef` must be supplied explicitly is stale for those two methods;\n// the wire/type reality wins, same correction `ChecklistTemplateLibrary.tsx`\n// already documents once for its own sibling pair).\n//\n// THE TRIP-SCOPED CREDENTIAL WALL IS GONE — AND THIS HOOK CALLED IT.\n//\n// The block that stood here recorded the wall in detail and left it: seven\n// trip-scoped reads were `apiKeyAuth`/`managerAuth` only, and it argued\n// they were nonetheless *good* candidates to widen, because\n// `forms.service.ts`'s `assertManagerAssignedToTrip` is a no-op for any\n// non-manager principal — an `agencyAdmin`/`apiKey` caller is already\n// scoped by tenancy alone. Its reason for stopping was that widening the\n// SDK's allowlist alone would 401 at the engine, so it needed \"a\n// coordinated `forms.routes.ts` + `security.ts` change, outside this\n// repo's own boundary\".\n//\n// That coordinated change has now been made. `listTripForms`,\n// `dispatchForm`, trip `responses.list`, `responses.get`, `completion`,\n// `answers`, `export` and `consentReceipt` accept `agencyAdmin` in\n// `forms.routes.ts`, and `security.ts` regenerates from the same OpenAPI\n// document, so the two halves cannot drift. The analysis above was right\n// on every point; only its conclusion was temporary.\n//\n// What it unblocks is the asymmetry it did not name: `responses.create`\n// — a form filled out ON BEHALF of a traveller — already accepted an\n// agency admin, so a desk could write a response and could not read the\n// trip's responses to know one was missing. `TripFormsSection` is the\n// surface that gap was blocking.\n//\n// STILL DARK, deliberately: `getFormAggregate` is `apiKey` ALONE. No\n// browser persona reaches it, which is why nothing here wraps it and the\n// admin family's `FormAggregateDashboard` stays unbuilt.\n//\n// `forms` is NOT in the frozen PERSONALIZED mode-dark set\n// (`manager/05-forms.md`'s own framing note) — `createDomainHook`'s generic\n// gate still applies (every darkness this trip's `'forms'` capability row\n// can report is data- or flag-shaped in practice, never mode-shaped), same\n// mechanism every other domain hook uses, no per-module special case.\n\nimport type {\n BoundCreateFormOptions,\n CloneFormOptions,\n CreateFormFieldOptions,\n CreateFormSectionOptions,\n DeleteFormFieldOptions,\n DeleteFormSectionOptions,\n DispatchFormOptions,\n ExportFormResponsesOptions,\n FormsResource,\n KaafilBinaryResponse,\n ManagerCreateFormResponseOptions,\n OutboxOp,\n PatchFormFieldOptions,\n PatchFormOptions,\n PatchFormSectionOptions,\n ReadFormConsentReceiptOptions,\n ReorderFormOptions,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\n\n/** One row of `GET /api/v1/trips/{ref}/forms` — `TripFormsListResponse.items[]`\n * (verified, `kaafil-js/src/generated/schema.d.ts`). Carries `id`/`version`\n * like a delta row, but is NOT one — `SYNC_PULL_SECTIONS` has no `forms`\n * entry (this file's own header, corrected this pass), so this is a live\n * fetch (`forms.trip.list`), never a snapshot-list read. */\nexport type TripFormRow = Awaited<ReturnType<FormsResource['trip']['list']>>['items'][number];\n\n/** One row of `GET /api/v1/trips/{ref}/forms/completion` — PER FORM, not\n * per traveller. See `completion()`'s own note. */\nexport type FormCompletionRow = Awaited<\n ReturnType<FormsResource['trip']['completion']>\n>['items'][number];\n\nexport type DispatchFormInput = Omit<DispatchFormOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\nexport type ExportFormResponsesInput = Omit<ExportFormResponsesOptions, 'signal'>;\nexport type ConsentReceiptInput = Omit<ReadFormConsentReceiptOptions, 'signal'>;\n\n/** `GET /api/v1/forms/{formId}` — `FormDetailResponse`: sections + fields +\n * resolved options, the definition `FormFillRenderer` renders. A live read\n * (mirrors `useShareForms.renderForm`'s own \"live call, not cached\" note) —\n * there is no per-form definition slot in the trip snapshot's `'forms'`\n * section, only the summary row list. */\nexport type FormDefinitionDetail = Awaited<ReturnType<FormsResource['get']>>;\n\n/** The SDK schema's own `FormFieldKind` value for a single instant-effect\n * boolean field, re-exported by value (not just by type) so a persona\n * composite matching `field.kind` never has to spell the schema's literal\n * out itself — only `src/core` may reference the SDK's generated union at\n * all (hard rule #1, `no-restricted-imports` in `eslint.config.mjs`). Named\n * by shape, not by the schema string, since the rendered control for this\n * kind is `Switch` (an instant, self-contained toggle), never `Checkbox`\n * (a staged-for-save boolean) — `05-forms-and-inputs.md`'s own boundary\n * between the two primitives. */\nexport const FORM_FIELD_KIND_SINGLE_BOOLEAN: FormDefinitionDetail['fields'][number]['kind'] =\n 'CHECKBOX';\n\n/** `GET /api/v1/forms/{formId}/responses/{responseId}` —\n * `ResponseDetailResponse`: the full answer set plus staleness flags against\n * the current form version. */\nexport type FormResponseDetail = Awaited<ReturnType<FormsResource['responses']['get']>>;\n\n/** One row of `GET /api/v1/trips/{ref}/travellers/{travellerRef}/forms/\n * responses` — this traveller's `FormResponse` rows across every form on the\n * trip (the per-traveller cross-form read `TripFormResponsesResource.list`,\n * scoped to one `formId`, cannot give). Used to resolve \"has this filler\n * already got a response for this form, and what's its id/status\" without a\n * second per-form list call per row. */\nexport type TravellerFormResponseRow = Awaited<\n ReturnType<FormsResource['trip']['travellerResponses']['list']>\n>['items'][number];\n\n/** One row of `GET /api/v1/trips/{ref}/forms/{formId}/responses` — EVERY\n * respondent's row for one form (the per-form cross-traveller read\n * `TripFormResponsesResource.list`, the other axis from\n * `travellerResponses` above — same underlying `ResponsesListResponse`\n * shape, verified identical, just a different URL/fixed axis). `managerAuth`\n * is allowed (`generated/security.ts`, verified) — this is what a manager\n * needs to browse \"who has answered this form\" for a `TRAVELLER`-audience\n * form, never a browsable-all-travellers index of its own (that stays out\n * of scope, `manager/05-forms.md`'s own boundary). */\nexport type TripFormResponseRow = Awaited<\n ReturnType<FormsResource['trip']['responses']['list']>\n>['items'][number];\n\n/** `POST /api/v1/trips/{ref}/forms/{formId}/responses` body — a manager\n * self-fill (`travellerRef` omitted) or on-behalf capture\n * (`travellerRef` set), `submit: false` for a draft save and `true` for a\n * final submit. No `clientToken` on this route (unlike the share-surface's\n * `save`/`submit`, `useShareForms.ts`'s own header note) — the standard\n * `Idempotency-Key` header `OfflineEngine.enqueue()` mints once per op is\n * this route's only de-dupe key. */\nexport type SubmitFormResponseInput = Omit<\n ManagerCreateFormResponseOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\n\n/** `GET /api/v1/agencies/{ref}/forms` row — `FormListResponse.items[]`, the\n * agency's whole catalog (every locale/status/scope), `FormsCatalogScreen`'s\n * own read. Structurally identical to `FormDefinitionResponse`; named\n * separately here because it is reached through a different call\n * (`forms.list`, not `forms.get`). */\nexport type FormAgencyRow = Awaited<ReturnType<FormsResource['list']>>['items'][number];\n\n/** The patch-transition family's own return shape — `forms.patch`/\n * `.publish`/`.close`/`.reopen`/`.archive`/`.unarchive`/`.clone` all answer\n * `FormDefinitionResponse`, the metadata-only row (no `sections`/`fields`) —\n * distinct from `FormDefinitionDetail`, which only `.get`/`.create` return. */\nexport type FormDefinitionSummary = Awaited<ReturnType<FormsResource['patch']>>;\n\nexport type FormSectionDetail = FormDefinitionDetail['sections'][number];\nexport type FormFieldDetail = FormDefinitionDetail['fields'][number];\n\n/** `GET /api/v1/forms/bindings` row — the closed 16-key binding registry\n * `BindingCatalogBrowser` browses. */\nexport type BindingEntry = Awaited<ReturnType<FormsResource['bindings']['list']>>['items'][number];\n\n/** `forms.create`'s own body, `agencyRef` dropped (browser-bound, see this\n * file's own header) and the request-plumbing fields excluded — the exact\n * shape `FormBuilder` composes from its metadata/section/field draft. */\nexport type CreateFormInput = Omit<BoundCreateFormOptions, 'idempotencyKey' | 'signal'>;\nexport type PatchFormInput = Omit<PatchFormOptions, 'signal'>;\nexport type CloneFormInput = Omit<CloneFormOptions, 'idempotencyKey' | 'signal'>;\nexport type ReorderFormInput = Omit<ReorderFormOptions, 'signal'>;\nexport type CreateFormSectionInput = Omit<CreateFormSectionOptions, 'signal'>;\nexport type PatchFormSectionInput = Omit<PatchFormSectionOptions, 'signal'>;\nexport type DeleteFormSectionInput = Omit<DeleteFormSectionOptions, 'signal'>;\nexport type CreateFormFieldInput = Omit<CreateFormFieldOptions, 'signal'>;\nexport type PatchFormFieldInput = Omit<PatchFormFieldOptions, 'signal'>;\nexport type DeleteFormFieldInput = Omit<DeleteFormFieldOptions, 'signal'>;\n\nexport interface FormsReady {\n /** This trip's applicable forms, each with its resolved `window` and\n * `dispatched`/`submitted` counts — `TripFormsPanel`'s own read. Live-\n * fetched and explicitly refreshed (this file's header, corrected this\n * pass) — NOT a cache-first snapshot-list read. */\n readonly forms: readonly TripFormRow[];\n /** The last successful live fetch's own `meta.serverTime` — `undefined`\n * before the first fetch settles. */\n readonly syncedAt: string | undefined;\n /** Live read of one form's definition (sections + fields). */\n readonly getDefinition: (formId: string) => Promise<FormDefinitionDetail>;\n /** Live read of one response's full answer set + staleness flags. */\n readonly getResponse: (formId: string, responseId: string) => Promise<FormResponseDetail>;\n /** Live read of one traveller's responses across every form on the trip —\n * how `FormFillFlow` resolves \"already submitted\" / prefill without a\n * per-form response list call. */\n readonly travellerResponses: (\n travellerRef: string,\n ) => Promise<readonly TravellerFormResponseRow[]>;\n /** Live read of EVERY respondent's row for one form — how a manager\n * browses \"who has answered this `TRAVELLER`-audience form\" (the other\n * axis from `travellerResponses`). */\n readonly formResponses: (formId: string) => Promise<readonly TripFormResponseRow[]>;\n /** Save (`submit: false`) or finalize (`submit: true`) a response —\n * self-fill or on-behalf, same endpoint, same outbox-backed write. */\n /** `null` rather than an `OutboxOp` when the write took the DESK lane —\n * a direct call has no outbox row to hand back. */\n readonly submitResponse: (input: SubmitFormResponseInput) => Promise<OutboxOp | null>;\n\n // ── Authoring surface (agencyAdmin-only door, see this file's own header) ──\n\n /** `forms.list` — the agency's whole catalog, browser-bound (no\n * `agencyRef` to supply). */\n /** `getFormsCompletionMatrix` — one row PER FORM, not a traveller grid.\n * See the callback's own note. */\n /** Re-reads the live trip forms list. Exposed because a composite\n * showing a failed read needs a retry, and `forms`/`syncedAt` are\n * fetched, not subscribed. */\n readonly refresh: () => Promise<void>;\n readonly completion: () => Promise<readonly FormCompletionRow[]>;\n /** `dispatchForm` — sends a form to travellers and refreshes the list,\n * since it moves `dispatched`. */\n readonly dispatch: (input: DispatchFormInput) => Promise<void>;\n readonly exportResponses: (input: ExportFormResponsesInput) => Promise<KaafilBinaryResponse>;\n readonly consentReceipt: (input: ConsentReceiptInput) => Promise<KaafilBinaryResponse>;\n readonly listAgencyForms: () => Promise<readonly FormAgencyRow[]>;\n /** `forms.create` — authors a fresh `DRAFT`, browser-bound. */\n readonly createForm: (input: CreateFormInput) => Promise<FormDefinitionDetail>;\n readonly patchForm: (input: PatchFormInput) => Promise<FormDefinitionSummary>;\n readonly publishForm: (formId: string) => Promise<FormDefinitionSummary>;\n readonly closeForm: (formId: string) => Promise<FormDefinitionSummary>;\n readonly reopenForm: (formId: string) => Promise<FormDefinitionSummary>;\n readonly archiveForm: (formId: string) => Promise<FormDefinitionSummary>;\n readonly unarchiveForm: (formId: string) => Promise<FormDefinitionSummary>;\n readonly cloneForm: (input: CloneFormInput) => Promise<FormDefinitionSummary>;\n /** `forms.reorder` — one idempotent transaction over every section's and\n * field's `sortOrder`, never one call per row (this spec entry's own\n * `Does NOT`). */\n readonly reorderForm: (input: ReorderFormInput) => Promise<void>;\n readonly createSection: (input: CreateFormSectionInput) => Promise<FormSectionDetail>;\n readonly patchSection: (input: PatchFormSectionInput) => Promise<FormSectionDetail>;\n readonly deleteSection: (input: DeleteFormSectionInput) => Promise<void>;\n readonly createField: (input: CreateFormFieldInput) => Promise<FormFieldDetail>;\n readonly patchField: (input: PatchFormFieldInput) => Promise<FormFieldDetail>;\n readonly deleteField: (input: DeleteFormFieldInput) => Promise<void>;\n /** `forms.bindings.list` — the closed 16-key registry; `apiKeyAuth`/\n * `agencyAdminAuth`/`managerAuth` all accepted (`generated/security.ts`). */\n readonly listBindings: () => Promise<readonly BindingEntry[]>;\n}\n\nconst useFormsInternal = createDomainHook<FormsReady>('forms', (tripRef) => {\n const client = useKaafilClient();\n const engine = useContext(OfflineEngineContext);\n const [forms, setForms] = useState<readonly TripFormRow[]>([]);\n const [syncedAt, setSyncedAt] = useState<string | undefined>(undefined);\n\n const refreshForms = useCallback(async (): Promise<void> => {\n try {\n const response = await client.forms.trip.list({ tripRef });\n setForms(response.items);\n setSyncedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated empty list — whatever `forms`\n // already held stays, same reasoning `useRooming.ts`'s own\n // `refreshUnassignedPool` documents for its sibling live-fetched half.\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshForms();\n }, [refreshForms]);\n\n // `submitResponse`'s own `mutate()` resolves once the op is DURABLE\n // (write-ahead), not once the drainer has actually sent it —\n // `OfflineEngine.enqueue()`'s own header. Refreshing `forms` immediately\n // after therefore races the drainer's own POST for this same write\n // (verified live against the real sample app this pass — the exact same\n // class of bug `useChecklists.ts`'s own `refreshAggregateAfterDrain`\n // documents and fixes). The immediate refresh stays (the common,\n // fast-network case still repaints instantly); this additionally\n // re-refreshes once after the NEXT `sync.drained` so a lost race still\n // self-corrects without a full remount.\n const refreshFormsAfterDrain = useCallback((): void => {\n if (engine === null) {\n return;\n }\n const unsubscribe = engine.events.on('sync.drained', () => {\n unsubscribe();\n void refreshForms();\n });\n }, [engine, refreshForms]);\n\n const getDefinition = useCallback(\n async (formId: string): Promise<FormDefinitionDetail> => client.forms.get({ formId }),\n [client],\n );\n\n const getResponse = useCallback(\n async (formId: string, responseId: string): Promise<FormResponseDetail> =>\n client.forms.responses.get({ formId, responseId }),\n [client],\n );\n\n const travellerResponses = useCallback(\n async (travellerRef: string): Promise<readonly TravellerFormResponseRow[]> => {\n const response = await client.forms.trip.travellerResponses.list({ tripRef, travellerRef });\n return response.items;\n },\n [client, tripRef],\n );\n\n const formResponses = useCallback(\n async (formId: string): Promise<readonly TripFormResponseRow[]> => {\n const response = await client.forms.trip.responses.list({ tripRef, formId });\n return response.items;\n },\n [client, tripRef],\n );\n\n const submitMutation = useOfflineMutation<SubmitFormResponseInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { formId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/forms/${formId}/responses`,\n // Hardcoded literal, not imported: `OperationId` is not exported\n // from `kaafil-js/client`'s public surface (same reasoning\n // `useRooming.ts` documents). Verified against\n // `kaafil-js/src/generated/security.ts` this session:\n // `OperationId.ManagerCreateFormResponse === 'managerCreateFormResponse'`.\n operationId: 'managerCreateFormResponse' as never,\n body,\n });\n },\n // THE DESK LANE. On-behalf capture is exactly what an office does when\n // a traveller phones in an answer, and a desk console mounts no\n // `OfflineShell` — without this the write has no transport at all.\n // `idempotencyKey` is OPTIONAL on `ManagerCreateFormResponseOptions`,\n // so nothing here mints one (hard rule #4).\n direct: (liveClient, input) => {\n const { formId, ...body } = input;\n return liveClient.forms.trip.responses.create({ tripRef, formId, ...body });\n },\n });\n\n const submitMutate = submitMutation.mutate;\n const submitResponse = useCallback(\n async (input: SubmitFormResponseInput): Promise<OutboxOp | null> => {\n const op = await submitMutate(input);\n // A submit/save changes `dispatched`/`submitted` on the affected\n // row — re-request the live list rather than leaving it stale\n // (same reasoning `useChecklists.ts`'s own writes document for their\n // `refreshAggregate()` call).\n void refreshForms();\n refreshFormsAfterDrain();\n return op;\n },\n [submitMutate, refreshForms, refreshFormsAfterDrain],\n );\n\n // ── WHAT THE WIDENING UNLOCKED ────────────────────────────────────────\n //\n // These four were `manager`/`apiKey` only and refused an agency admin,\n // while `responses.create` beside them already took the triple — a desk\n // could write a response on somebody's behalf and could not read the\n // trip's responses to know one was missing. The engine closed that this\n // pass; these are the desk's half of it. All live, all memoised.\n\n /** `completion` is ONE ROW PER FORM (`{formId, formKey, audience,\n * dispatched, submitted, total}`), NOT a traveller grid — the name\n * suggests otherwise and it is worth stating. `trip.list` already\n * carries `dispatched`/`submitted`; the only thing this adds is the\n * denominator `total`, which is what turns \"12 submitted\" into\n * \"12 of 18\". */\n const completion = useCallback(async (): Promise<readonly FormCompletionRow[]> => {\n const response = await client.forms.trip.completion({ tripRef });\n return response.items;\n }, [client, tripRef]);\n\n const dispatch = useCallback(\n async (input: DispatchFormInput): Promise<void> => {\n const { formId, ...body } = input;\n await client.forms.trip.dispatch({ tripRef, formId, ...body });\n void refreshForms();\n },\n [client, tripRef, refreshForms],\n );\n\n // NOT trip-scoped, unlike everything else on this hook: both live on\n // `forms.responses.*` and their paths carry no `{ref}` at all\n // (`/api/v1/forms/{formId}/responses/export`, and the receipt route takes\n // only a `responseId`). Exposed here anyway because the trip Forms tab is\n // the only surface that reaches for them.\n const exportResponses = useCallback(\n (input: ExportFormResponsesInput) => client.forms.responses.export(input),\n [client],\n );\n\n const consentReceipt = useCallback(\n (input: ConsentReceiptInput) => client.forms.responses.consentReceipt(input),\n [client],\n );\n\n const listAgencyForms = useCallback(async (): Promise<readonly FormAgencyRow[]> => {\n const response = await client.forms.list({});\n return response.items;\n }, [client]);\n\n const createForm = useCallback(\n async (input: CreateFormInput): Promise<FormDefinitionDetail> => client.forms.create(input),\n [client],\n );\n const patchForm = useCallback(\n async (input: PatchFormInput): Promise<FormDefinitionSummary> => client.forms.patch(input),\n [client],\n );\n const publishForm = useCallback(\n async (formId: string): Promise<FormDefinitionSummary> => client.forms.publish({ formId }),\n [client],\n );\n const closeForm = useCallback(\n async (formId: string): Promise<FormDefinitionSummary> => client.forms.close({ formId }),\n [client],\n );\n const reopenForm = useCallback(\n async (formId: string): Promise<FormDefinitionSummary> => client.forms.reopen({ formId }),\n [client],\n );\n const archiveForm = useCallback(\n async (formId: string): Promise<FormDefinitionSummary> => client.forms.archive({ formId }),\n [client],\n );\n const unarchiveForm = useCallback(\n async (formId: string): Promise<FormDefinitionSummary> => client.forms.unarchive({ formId }),\n [client],\n );\n const cloneForm = useCallback(\n async (input: CloneFormInput): Promise<FormDefinitionSummary> => client.forms.clone(input),\n [client],\n );\n const reorderForm = useCallback(\n async (input: ReorderFormInput): Promise<void> => {\n await client.forms.reorder(input);\n },\n [client],\n );\n const createSection = useCallback(\n async (input: CreateFormSectionInput): Promise<FormSectionDetail> =>\n client.forms.sections.create(input),\n [client],\n );\n const patchSection = useCallback(\n async (input: PatchFormSectionInput): Promise<FormSectionDetail> =>\n client.forms.sections.patch(input),\n [client],\n );\n const deleteSection = useCallback(\n async (input: DeleteFormSectionInput): Promise<void> => {\n await client.forms.sections.delete(input);\n },\n [client],\n );\n const createField = useCallback(\n async (input: CreateFormFieldInput): Promise<FormFieldDetail> =>\n client.forms.fields.create(input),\n [client],\n );\n const patchField = useCallback(\n async (input: PatchFormFieldInput): Promise<FormFieldDetail> =>\n client.forms.fields.patch(input),\n [client],\n );\n const deleteField = useCallback(\n async (input: DeleteFormFieldInput): Promise<void> => {\n await client.forms.fields.delete(input);\n },\n [client],\n );\n const listBindings = useCallback(async (): Promise<readonly BindingEntry[]> => {\n const response = await client.forms.bindings.list();\n return response.items;\n }, [client]);\n\n return {\n forms,\n syncedAt,\n getDefinition,\n getResponse,\n travellerResponses,\n formResponses,\n submitResponse,\n refresh: refreshForms,\n completion,\n dispatch,\n exportResponses,\n consentReceipt,\n listAgencyForms,\n createForm,\n patchForm,\n publishForm,\n closeForm,\n reopenForm,\n archiveForm,\n unarchiveForm,\n cloneForm,\n reorderForm,\n createSection,\n patchSection,\n deleteSection,\n createField,\n patchField,\n deleteField,\n listBindings,\n };\n});\n\n/**\n * Not mode-dark (`manager/05-forms.md`'s own framing note) — a dark result\n * from this trip's `'forms'` capability row is always data- or flag-shaped\n * in practice. Returns `{ status: 'dark', reason }` before any fetch when\n * that row isn't `lit`.\n */\nexport function useForms(tripRef: string): DomainHookResult<FormsReady> {\n return useFormsInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useItinerary(tripRef)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/itinerary.ts`):\n// `itinerary.read`, `itinerary.days.patch`,\n// `itinerary.items.{add,patch,remove,reorder}`, `itinerary.changeLog.list`.\n//\n// NOT CAPABILITY-GATED — DELIBERATELY, UNLIKE `useRooming()`. Verified\n// against `kaafil-product-docs/ui-kit/families/manager/02-itinerary.md`:\n// \"Itinerary is structurally ungated — `FRD:itinerary` states plainly that\n// the module carries no capability manifest entry, no plan-flag key, and no\n// mode gate (`D-136`)... No composite below composes a `CapabilityGate` or\n// accepts any capability-dark view prop.\" `createDomainHook()`\n// (`../internal/createDomainHook.ts`) resolves an absent capability row to\n// `UNKNOWN_CAPABILITY_TRIPLE` (`../internal/deriveCapabilityTriple.ts`),\n// which is `mode-dark` — \"render nothing\" — FOREVER, since `itinerary` will\n// never appear in `journey.capabilities()`'s row set at all. Routing this\n// hook through `createDomainHook()` the way every other §3 domain hook is\n// would therefore make the itinerary composites permanently blank, which is\n// the opposite of the ungated behaviour the spec requires. This hook\n// intentionally does NOT use that factory; it returns `'loading'`/`'ready'`/\n// `'error'` only and never `'dark'`.\n//\n// READ MODEL — LIVE, NOT CACHE-FIRST, and the reason has changed.\n//\n// It used to be that it COULD not be cache-first: `'itinerary'`'s section\n// `data` is `ItineraryReadResponse` verbatim, carrying two id-bearing arrays\n// (`days[]` and `items[]`), and `extractSectionRows()` resolved any object\n// with more than one qualifying array to `undefined` rather than picking the\n// likelier — so the section was silently skipped by every pull and there was\n// no snapshot list to read. That is fixed: the SDK now DECLARES the row key\n// per section (`SECTION_ROW_KEY` in `kaafil-js/src/offline/pull.ts`), and\n// `'itinerary'` resolves to `items[]`, with `days[]` correctly treated as the\n// derived projection it is.\n//\n// So the section IS cached now, and this hook could move to\n// `useSnapshotList()`. It has not, deliberately and for the moment: the\n// screen renders the DAY projection, not a flat item list, and rebuilding\n// `days[]` from cached items means re-deriving the engine's own day\n// bucketing and its computed `'LIVE'` status client-side — which is the\n// class of duplication that makes a cached read disagree with a live one.\n// Moving it is a real piece of work with a real correctness question in it,\n// not a comment change, and it is tracked rather than done here.\n//\n// `status` (`ItineraryItemResponse.status`, verified against\n// `openapi/openapi.json`) already includes the computed `'LIVE'` value —\n// \"the state to render right now, including LIVE when the clock falls\n// inside [startTime, endTime) — a value the stored row never actually\n// holds.\" The engine computes this SERVER-SIDE, on every read. This hook\n// therefore never recomputes a live window client-side (the FRD's own\n// language for the offline case) — the freshest read already carries the\n// answer, and a stale cached read would only be wrong until the next\n// live re-read, never silently mispromoted.\n//\n// WRITE MODEL — TWO LANES, ONE PER SURFACE. Every write enqueues via\n// `OfflineEngine.enqueue()` with a raw path/method/operationId/body, the same\n// `useRooming()`/`useCollections()` idiom (`OperationId` is not exported from\n// `kaafil-js/client`'s public surface — every operationId below is a\n// hardcoded literal, verified against `kaafil-js/src/generated/\n// security.ts` this session). `patchItem`/`removeItem`/`patchDay` carry\n// `ifMatch: version` (required `If-Match`, per each SDK method's own doc\n// comment); `reorderItem` and `addItem` carry none, matching the SDK's own\n// \"no version, no If-Match, deliberately\" note on reorder and the\n// server-assigned-id note on add.\n//\n// EACH ALSO SUPPLIES A `direct` CALLBACK, because this hook is read AND\n// WRITTEN by both families: the manager tab on the ground and the office's\n// own day-by-day plan tab. `OfflineShell` mounts only when the host passes\n// `storage`, so a desk console has no engine and the outbox lane throws\n// there. `useOfflineMutation`'s own header carries the full argument for why\n// that fallback lives in the shared §2.5 hook rather than being forked per\n// domain; here it means one `useItinerary()` serves both surfaces with one\n// signature, as hard rule #2 requires, instead of an `useAdminItinerary()`.\n//\n// The two lanes hit the SAME endpoints with the same bodies — the outbox one\n// replays a raw request the engine assembled, the direct one goes through the\n// SDK resource method. Neither mints an idempotency key: `OfflineEngine\n// .enqueue()` does on one lane and `kaafil-js`'s own http client does on the\n// other (`OPERATION_ACCEPTS_IDEMPOTENCY_KEY` → `crypto.randomUUID()`), which\n// is precisely why rule #4 forbids a hook from doing it.\n//\n// A write therefore resolves `OutboxOp | null` — `null` on the direct lane,\n// where there is nothing queued to hand back. After every mutation this hook\n// calls its own `refresh()` — the same \"mutate, then re-request the live read\"\n// idiom `useCollections()`'s `record`/`voidCollection` already use for a\n// non-delta-shaped resource — AND arms `refreshAfterDrain()`, which re-reads\n// once the outbox next drains. That second half is what makes an offline\n// write appear: the immediate `refresh()` fails along with the write when\n// there is no signal, and without the drain-triggered re-read the block a\n// tour leader added stayed invisible until they happened to reload the page,\n// long after it had actually reached the server.\n//\n// What this hook still does NOT do is paint the write before it lands. There\n// is no client-side optimistic patch, so between submitting offline and\n// reconnecting, the day looks unchanged. True optimistic reflection needs an\n// `entity`/`optimistic` pairing on `enqueue()` writing into a snapshot list\n// keyed the way this screen reads — and this screen reads the DAY projection,\n// not a flat item list, so it would mean re-deriving the engine's own day\n// bucketing client-side (see the READ MODEL note above). Tracked, not done.\n\nimport type {\n AddItineraryItemOptions,\n DeleteItineraryItemOptions,\n ItineraryResource,\n ListItineraryChangeLogOptions,\n OutboxOp,\n PatchItineraryDayOptions,\n PatchItineraryItemOptions,\n ReorderItineraryItemOptions,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\n\ntype ItineraryReadResult = Awaited<ReturnType<ItineraryResource['read']>>;\n\n/** One row of `ItineraryReadResponse.days[]` — no tombstone branch (this\n * section is never delta-pulled; see this file's header). */\nexport type ItineraryDayRow = ItineraryReadResult['days'][number];\n\n/** `ItineraryReadResponse.items[]`'s generated shape is `anyOf` a live item\n * or a tombstone — the same shared shape the delta (`?since=`) mode uses,\n * even though a full/no-`since` read (the only mode this hook ever calls)\n * has nothing to report a tombstone against. This hook filters the\n * tombstone variant out in `refresh()` below rather than exposing the raw\n * union, so every `ItineraryItemRow` a composite reads is unconditionally\n * live — the same `isLiveRoom`/`Exclude<..., {_tombstone:true}>` pattern\n * `useRooming.ts`'s own consumers use, applied inside the hook here since\n * this hook, unlike `useRooming()`, has no separate delta-row type the spec\n * asks composites to narrow themselves. */\ntype ItineraryItemUnion = ItineraryReadResult['items'][number];\nexport type ItineraryItemRow = Exclude<ItineraryItemUnion, { readonly _tombstone: true }>;\n\nfunction isLiveItineraryItem(row: ItineraryItemUnion): row is ItineraryItemRow {\n return !('_tombstone' in row);\n}\n\nexport type ItineraryTripSummary = ItineraryReadResult['trip'];\n\nexport type ItineraryChangeLogRow = Awaited<\n ReturnType<ItineraryResource['changeLog']['list']>\n>[number];\n\nexport type AddItineraryItemInput = Omit<AddItineraryItemOptions, 'tripRef' | 'signal'>;\nexport type PatchItineraryItemInput = Omit<PatchItineraryItemOptions, 'tripRef' | 'signal'>;\nexport type RemoveItineraryItemInput = Omit<DeleteItineraryItemOptions, 'tripRef' | 'signal'>;\nexport type ReorderItineraryItemInput = Omit<ReorderItineraryItemOptions, 'tripRef' | 'signal'>;\nexport type PatchItineraryDayInput = Omit<PatchItineraryDayOptions, 'tripRef' | 'signal'>;\nexport type LoadItineraryChangeLogInput = Omit<ListItineraryChangeLogOptions, 'tripRef' | 'signal'>;\n\nexport interface ItineraryReady {\n readonly trip: ItineraryTripSummary | undefined;\n /** Server's own pick of which day the itinerary screen should land on\n * (today → first future day → Day 1, `FRD:itinerary §5`) — never\n * computed client-side. */\n readonly initialDayIso: string | undefined;\n readonly canAddItems: boolean;\n readonly canAddItemsReason: string | null;\n readonly days: readonly ItineraryDayRow[];\n readonly items: readonly ItineraryItemRow[];\n /** `true` once the first `itinerary.read()` has settled (success or\n * failure) — distinguishes \"never fetched yet\" from \"fetched, trip has\n * zero days,\" the same discipline `RoomingReady.unassignedPool.loaded`\n * documents. */\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly syncedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n readonly changeLog: readonly ItineraryChangeLogRow[];\n readonly changeLogLoaded: boolean;\n readonly changeLogFetchFailed: boolean;\n readonly loadChangeLog: (input?: LoadItineraryChangeLogInput) => Promise<void>;\n readonly patchDay: (input: PatchItineraryDayInput) => Promise<OutboxOp | null>;\n readonly addItem: (input: AddItineraryItemInput) => Promise<OutboxOp | null>;\n readonly patchItem: (input: PatchItineraryItemInput) => Promise<OutboxOp | null>;\n readonly removeItem: (input: RemoveItineraryItemInput) => Promise<OutboxOp | null>;\n readonly reorderItem: (input: ReorderItineraryItemInput) => Promise<OutboxOp | null>;\n}\n\nexport type ItineraryResult =\n | { readonly status: 'loading' }\n | ({ readonly status: 'ready' } & ItineraryReady)\n | { readonly status: 'error' };\n\n/**\n * Ungated (see this file's header) — never returns `{status:'dark'}`.\n * `manager`/`agencyAdmin` both call this same hook (`FRD:itinerary`'s\n * `COORDINATOR`-role read-only resolution happens on the OPEN SESSION,\n * server-side, never as a UIKit prop or a second hook).\n */\nexport function useItinerary(tripRef: string): ItineraryResult {\n const client = useKaafilClient();\n\n const [trip, setTrip] = useState<ItineraryTripSummary | undefined>(undefined);\n const [initialDayIso, setInitialDayIso] = useState<string | undefined>(undefined);\n const [canAddItems, setCanAddItems] = useState(false);\n const [canAddItemsReason, setCanAddItemsReason] = useState<string | null>(null);\n const [days, setDays] = useState<readonly ItineraryDayRow[]>([]);\n const [items, setItems] = useState<readonly ItineraryItemRow[]>([]);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n const [syncedAt, setSyncedAt] = useState<string | undefined>(undefined);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.itinerary.read({ tripRef });\n setTrip(response.trip);\n setInitialDayIso(response.initialDayIso);\n setCanAddItems(response.canAddItems);\n setCanAddItemsReason(response.canAddItemsReason);\n setDays(response.days);\n setItems(response.items.filter(isLiveItineraryItem));\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated empty itinerary — `loaded` stays\n // whatever it already was; only `lastFetchFailed` flips (mirrors\n // `RoomingReady.unassignedPool.refresh`'s own catch block).\n setLastFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n // ── WHY A WRITE ALSO REFRESHES ON THE NEXT DRAIN ──────────────────────\n //\n // This hook's read is LIVE, so `refresh()` is the only thing that repaints\n // it. Every write below already calls one — but a write made out of signal\n // is queued rather than sent, and that `refresh()` fails along with it.\n // Nothing re-ran when the outbox finally drained, so a block added offline\n // stayed invisible until the tour leader happened to reload: the write had\n // reached the server and the screen still showed the day as empty. From\n // where they are standing that is indistinguishable from having lost it,\n // so they add it again.\n //\n // `sync.drained` is the drainer's own \"I just sent a batch\" signal. One\n // re-read after the next one, then unsubscribe — the same shape, and the\n // same reason, as `useChecklists`'s `refreshAggregateAfterDrain`.\n const engine = useContext(OfflineEngineContext);\n const refreshAfterDrain = useCallback((): void => {\n if (engine === null) {\n return;\n }\n const unsubscribe = engine.events.on('sync.drained', () => {\n unsubscribe();\n void refresh();\n });\n }, [engine, refresh]);\n\n const [changeLog, setChangeLog] = useState<readonly ItineraryChangeLogRow[]>([]);\n const [changeLogLoaded, setChangeLogLoaded] = useState(false);\n const [changeLogFetchFailed, setChangeLogFetchFailed] = useState(false);\n\n const loadChangeLog = useCallback(\n async (input?: LoadItineraryChangeLogInput): Promise<void> => {\n try {\n const response = await client.itinerary.changeLog.list({ tripRef, ...input });\n setChangeLog(response);\n setChangeLogLoaded(true);\n setChangeLogFetchFailed(false);\n } catch {\n setChangeLogFetchFailed(true);\n }\n },\n [client, tripRef],\n );\n\n const patchDayMutation = useOfflineMutation<PatchItineraryDayInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { dayIndex, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/itinerary/days/${dayIndex}`,\n operationId: 'patchItineraryDay' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (client, input) => client.itinerary.days.patch({ tripRef, ...input }),\n });\n const patchDayMutate = patchDayMutation.mutate;\n const patchDay = useCallback(\n async (input: PatchItineraryDayInput): Promise<OutboxOp | null> => {\n const op = await patchDayMutate(input);\n void refresh();\n refreshAfterDrain();\n return op;\n },\n [patchDayMutate, refresh, refreshAfterDrain],\n );\n\n const addItemMutation = useOfflineMutation<AddItineraryItemInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/itinerary/items`,\n operationId: 'addItineraryItem' as never,\n body: input,\n }),\n direct: (client, input) => client.itinerary.items.add({ tripRef, ...input }),\n });\n const addItemMutate = addItemMutation.mutate;\n const addItem = useCallback(\n async (input: AddItineraryItemInput): Promise<OutboxOp | null> => {\n const op = await addItemMutate(input);\n void refresh();\n refreshAfterDrain();\n return op;\n },\n [addItemMutate, refresh, refreshAfterDrain],\n );\n\n const patchItemMutation = useOfflineMutation<PatchItineraryItemInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { itemId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}`,\n operationId: 'patchItineraryItem' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (client, input) => client.itinerary.items.patch({ tripRef, ...input }),\n });\n const patchItemMutate = patchItemMutation.mutate;\n const patchItem = useCallback(\n async (input: PatchItineraryItemInput): Promise<OutboxOp | null> => {\n const op = await patchItemMutate(input);\n void refresh();\n refreshAfterDrain();\n return op;\n },\n [patchItemMutate, refresh, refreshAfterDrain],\n );\n\n const removeItemMutation = useOfflineMutation<RemoveItineraryItemInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { itemId, version } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}`,\n operationId: 'deleteItineraryItem' as never,\n ifMatch: version,\n });\n },\n direct: (client, input) => client.itinerary.items.remove({ tripRef, ...input }),\n });\n const removeItemMutate = removeItemMutation.mutate;\n const removeItem = useCallback(\n async (input: RemoveItineraryItemInput): Promise<OutboxOp | null> => {\n const op = await removeItemMutate(input);\n void refresh();\n refreshAfterDrain();\n return op;\n },\n [removeItemMutate, refresh, refreshAfterDrain],\n );\n\n const reorderItemMutation = useOfflineMutation<ReorderItineraryItemInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { itemId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/itinerary/items/${itemId}/reorder`,\n operationId: 'reorderItineraryItem' as never,\n body,\n });\n },\n direct: (client, input) => client.itinerary.items.reorder({ tripRef, ...input }),\n });\n const reorderItemMutate = reorderItemMutation.mutate;\n const reorderItem = useCallback(\n async (input: ReorderItineraryItemInput): Promise<OutboxOp | null> => {\n const op = await reorderItemMutate(input);\n void refresh();\n refreshAfterDrain();\n return op;\n },\n [reorderItemMutate, refresh, refreshAfterDrain],\n );\n\n if (!loaded && !lastFetchFailed) {\n return { status: 'loading' };\n }\n if (!loaded && lastFetchFailed) {\n return { status: 'error' };\n }\n\n return {\n status: 'ready',\n trip,\n initialDayIso,\n canAddItems,\n canAddItemsReason,\n days,\n items,\n loaded,\n lastFetchFailed,\n syncedAt,\n refresh,\n changeLog,\n changeLogLoaded,\n changeLogFetchFailed,\n loadChangeLog,\n patchDay,\n addItem,\n patchItem,\n removeItem,\n reorderItem,\n };\n}\n","'use client';\n\n// Not a `08-core-hooks.md §3` table row (verified: no `useManagers` entry\n// exists there) — added this session to close a real gap `VehicleManagerLink`\n// documented rather than papered over: linking a manager to a vehicle needs\n// a real roster to pick from, and no hook exposed one.\n//\n// Primary SDK surface (verified, `kaafil-js/src/resources/trips.ts`):\n// `trips.managers.list({ tripRef })` — `GET /api/v1/trips/{ref}/managers`,\n// reachable from a `manager`/`agencyAdmin` session (`client-entry.ts`'s own\n// header: `trips.managers.list`/`.patch` accept `managerAuth`/\n// `agencyAdminAuth` alongside `apiKeyAuth`, unlike most of `trips`, which is\n// `apiKeyAuth`-only).\n//\n// NOT CAPABILITY-GATED, ON PURPOSE: unlike `useVendors`/`useRooming`/etc,\n// there is no \"managers\" row in `journey.capabilities()` — a trip's manager\n// roster is core trip metadata every manager/agencyAdmin session on the trip\n// can see, not a feature a plan/mode can turn off. This hook therefore\n// mirrors `useJourney.ts`'s own shape (a plain fetch-on-mount live read with\n// a loading/ready/error tri-state), never `createDomainHook()`, which exists\n// specifically for the capability-gated case.\n//\n// NOT A SNAPSHOT-LIST READ: `SYNC_PULL_SECTIONS` does not include a managers\n// section — same \"live, explicitly-refreshed read\" posture `useVendors.ts`\n// documents for `vendors.list`, never claimed as offline-cached.\n//\n// VALUE CHOICE FOR CONSUMERS (e.g. `VehicleManagerLink`'s manager picker):\n// use each row's `managerId` (Kaafil's own internal id, always present) as\n// the value a caller submits back to a write like `seating.linkManager`,\n// never `managerRef` (the CRM's own external id, `null` for a\n// Kaafil-provisioned manager). This is safe and correct, not a workaround:\n// `kaafil-engine`'s `resolveRef()` (`shared/ingest/external-ref.resolver.ts`)\n// tries the given string as the entity's OWN INTERNAL id FIRST, falling back\n// to an external-ref mapping only if that fails — so a write that only ever\n// sends `managerId` still resolves correctly server-side, and sidesteps the\n// `managerRef: null` case entirely rather than needing a per-row fallback.\n\nimport type { TripManagersResource } from 'kaafil-js/client';\nimport { useEffect, useState } from 'react';\nimport { classifyError, type ErrorClassification } from '../errors/classify';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useKaafilClient } from './useKaafilClient';\nimport { usePersona } from './usePersona';\n\n/** One row of `trips.managers.list`'s result — derived structurally off the\n * resource's own return type (`useJourney.ts`'s identical precedent for\n * `JourneyReadResponse`), so this can never drift from what the SDK\n * actually returns. */\nexport type TripManagerRow = Awaited<ReturnType<TripManagersResource['list']>>[number];\n\nexport type ManagersResult =\n | { readonly status: 'loading' }\n | { readonly status: 'ready'; readonly managers: readonly TripManagerRow[] }\n | { readonly status: 'error'; readonly error: ErrorClassification };\n\n/**\n * A trip's manager roster — every live manager assigned to the trip,\n * lead first (`trips.managers.list`'s own doc comment). `manager`/\n * `agencyAdmin` only, matching `useJourney()`'s identical persona\n * restriction and identical dev-only throw on misuse.\n */\nexport function useManagers(tripRef: string): ManagersResult {\n const client = useKaafilClient();\n const persona = usePersona();\n const [result, setResult] = useState<ManagersResult>({ status: 'loading' });\n\n useEffect(() => {\n if (persona === 'share') {\n if (isDevelopment()) {\n throw new Error(\n 'useManagers() was called from a share session — it is manager/agencyAdmin only.',\n );\n }\n return;\n }\n let cancelled = false;\n setResult({ status: 'loading' });\n // `Promise.resolve().then(…)` rather than calling straight into the SDK:\n // a SYNCHRONOUS throw (a host whose client does not carry this resource)\n // happens before any promise exists, so a bare `.catch` never attaches\n // and the error escapes the effect and unmounts the whole tree. A read\n // that cannot be made is this hook's `error` state, not a crash — that\n // is the difference between one picker degrading and a workspace going\n // blank, and it was exactly that blank workspace that found this.\n void Promise.resolve()\n .then(() => client.trips.managers.list({ tripRef }))\n .then((managers) => {\n if (!cancelled) {\n setResult({ status: 'ready', managers });\n }\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n setResult({ status: 'error', error: classifyError(error) });\n }\n });\n return () => {\n cancelled = true;\n };\n }, [client, persona, tripRef]);\n\n return result;\n}\n","'use client';\n\n// `families/manager/12-office.md §TripHomeScreen` (per this session's\n// explicit product-decision override — the spec's own \"nav-only, no\n// aggregation\" TripHomeScreen was overridden in favour of a real\n// `ManagerTodaySection` composite reading the new phase-and-day-aware\n// aggregate). This hook is the ONE `/core` read that composite is built\n// on, per hard rule #2 (\"capability gating, the snapshot read, and the\n// outbox write ... flow through the one hook in `/core`\") and\n// `02-architecture.md §3a` (\"a manager screen NEVER calls kaafil-js\n// directly — only through a /core hook\").\n//\n// GAP THIS FILE CLOSES, NOTED RATHER THAN HIDDEN: at the time this\n// composite was authored, `kaafil-js/src/resources/manager-today.ts`\n// (`GET /trips/{ref}/manager/today`) already existed as a real, generated,\n// wire-verified SDK resource (`client.managerToday.read()`), but NO hook\n// in this directory wrapped it yet — `ManagerTodaySection` would otherwise\n// have had to call `kaafil-js` directly, which is the one thing every\n// composite in this package is forbidden to do. Authoring the full\n// offline-list/outbox machinery every OTHER hook in this file carries is\n// explicitly out of this build pass's scope (this endpoint is a pure,\n// read-only, phase-aware aggregate — it has no mutation of its own to\n// queue), so this hook is deliberately the SAME minimal shape\n// `useJourney.ts`'s own `read` field already uses for an analogous\n// \"live GET, not part of the offline snapshot store\" read: a plain\n// `client.managerToday.read()` call behind `useEffect`/`useState`, no\n// caching layer, no capability gate (`06-capability-and-personas.md`\n// doesn't name one single capability key for this composed aggregate —\n// each of `itinerary`/`checklist`/`pickups`/`rooming`/`transport` is\n// independently `null` on the WIRE ITSELF when that domain's own\n// capability is dark, per this endpoint's own doc comment — so per-field\n// nullability IS this endpoint's capability signal, not a separate\n// `useCapability()` triple this hook would need to read).\n//\n// Should this hook graduate to needing retry/offline-replay semantics, that\n// is a follow-up to `08-core-hooks.md`'s own catalog, not a reason to block\n// `ManagerTodaySection` on it — the composite already treats every partial\n// domain (`null`) and the whole read (`'error'`) as first-class, non-crashing\n// states (`ManagerTodaySection.tsx`'s own per-section guards).\n\nimport type { ManagerTodayResponse } from 'kaafil-js/client';\nimport { useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\nexport interface ManagerTodayLoading {\n readonly status: 'loading';\n}\n\nexport interface ManagerTodayError {\n readonly status: 'error';\n}\n\n// An intersection, not `interface ... extends ManagerTodayResponse` — that\n// response type is a discriminated UNION (`kind: 'trip' | 'trek' | 'idle'`)\n// and TypeScript cannot extend an interface from a union\n// (TS2312: \"An interface can only extend an object type or intersection of\n// object types with statically known members\"). The intersection form\n// below distributes over the union correctly, so `ManagerTodayReady` stays\n// a 3-member discriminated union itself (verified: `ManagerTodaySection.\n// types.ts`'s `Extract<ManagerTodayReady, { kind: 'trip' } | { kind:\n// 'trek' }>` narrows on it exactly as `RoomingBoard.types.ts` narrows on\n// `RoomingReady`).\nexport type ManagerTodayReady = ManagerTodayResponse & {\n readonly status: 'ready';\n /** The server timestamp this read landed with (`meta.serverTime`) —\n * never a local clock read (hard rule #6). */\n readonly syncedAt: string;\n};\n\nexport type ManagerTodayResult = ManagerTodayLoading | ManagerTodayError | ManagerTodayReady;\n\n/**\n * `client.managerToday.read({ tripRef })` behind a plain fetch-on-mount/\n * fetch-on-`tripRef`-change effect. Re-fetches whenever `tripRef` changes;\n * never re-fetches on an interval or a focus event of its own — a caller\n * that wants \"refresh now\" re-mounts this hook's owning component or (once\n * this hook grows one) calls a future `refresh()` return field.\n */\nexport function useManagerToday(tripRef: string): ManagerTodayResult {\n const client = useKaafilClient();\n const [result, setResult] = useState<ManagerTodayResult>({ status: 'loading' });\n\n useEffect(() => {\n let cancelled = false;\n setResult({ status: 'loading' });\n client.managerToday\n .read({ tripRef })\n .then((response) => {\n if (cancelled) {\n return;\n }\n const { meta, ...data } = response;\n setResult({ status: 'ready', ...data, syncedAt: meta.serverTime });\n })\n .catch(() => {\n if (!cancelled) {\n setResult({ status: 'error' });\n }\n });\n return () => {\n cancelled = true;\n };\n }, [client, tripRef]);\n\n return result;\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useParties(tripRef)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/trips.ts`):\n// `trips.parties.{list,add,patch,remove}`. Wire schemas are `Party*`\n// (`PartyResponse`, `CreatePartyRequest`, …), never `TravellerParty` (the\n// Prisma model name only — `families/manager/06-parties.md`'s own header).\n//\n// NO CAPABILITY GATE (load-bearing, verified against\n// `families/manager/06-parties.md`'s own \"Gating\" row on every one of its\n// five components: \"capability key: **none** — parties carries no separate\n// flag/data gate; this composite performs no capability read at all and\n// renders identically on GROUP and PERSONALIZED trips\"). This is why this\n// file does NOT go through `createDomainHook()` (`../internal/\n// createDomainHook.ts`) the way every other §3 domain hook does — that\n// factory looks up the module's own row in `journey.capabilities()` and\n// returns `{ status: 'dark' }` for any key with no row, which would make an\n// always-lit module intermittently dark on a trip whose capability table\n// simply never mentions `'parties'`. `PartiesResult` below is therefore its\n// own union, `'loading' | 'ready' | 'error'` only — no `'dark'` member\n// exists to reach.\n//\n// OFFLINE MISMATCH (flagged, verified): `06-parties.md §PartyRoster`'s own\n// \"Offline\" row claims \"cache-first from the snapshot's party list,\n// delta-synced with the trip's other lists\" — but `SYNC_PULL_SECTIONS`\n// (`kaafil-js/src/offline/pull.ts`, verified) lists exactly `rooming,\n// stayWindows, pickups, seating, bookings, expenses, checklist, float,\n// collections, itinerary, closeout` — no `parties` entry. There is no\n// `SnapshotStore` list this hook could subscribe `useSnapshotList` to.\n// `list` below is therefore a LIVE, explicitly-refreshed read, the same\n// \"not every array in a read is a cached delta feed\" shape `useTreks.ts`'s\n// `board`/`walkIns` and `useRooming.ts`'s `unassignedPool` already document\n// for the identical reason — refreshed on mount and again after any write\n// that could have changed it, never claimed as offline-cached. A genuine\n// spec/SDK gap, not an oversight; see this worker's final report. Because\n// there is no persisted delta cursor to round-trip, `list` is called\n// without `since` every time — every row it returns is live, so this hook's\n// public `parties` array is typed as the live half of `PartyDeltaRow`, with\n// no tombstone member for a composite to have to narrow away.\n//\n// TRAVELLER-SEARCH MISMATCH (flagged, verified): `06-parties.md\n// §PartyEditor`'s own prop table cites a member `Combobox` whose search\n// \"uses the required-`q`, ≥2-char, cursor-paginated shape directly\" — but\n// the only trip-scoped traveller read the SDK exposes is\n// `travellers.listForTrip` (`kaafil-js/src/resources/travellers.ts`,\n// verified), a flat, non-paginated, `q`-less manifest fetch; the real\n// `q`-parameterised cursor search (`travellers.listForAgency`/\n// `searchTravellerDirectory`) is agency-wide, not trip-scoped, and CANNOT\n// be what \"must already be a live member of this trip's manifest\"\n// (`CreatePartyRequest.travellerRefs`'s own description) means. `tripRoster`\n// below fetches the trip's manifest once (live, same `loaded`/\n// `lastFetchFailed`/`refresh` shape as `list`) and `PartyEditor` filters it\n// client-side for its ≥2-character search — the closest honest match to the\n// spec's intent given what this build's SDK actually offers. Owned HERE,\n// not a second undocumented hook and not a direct `kaafil-js` import from\n// the composite (hard rule #1) — `useParties()` is the one hook\n// `PartyEditor`'s own spec row names, the same way `useRooming()` owns\n// `unassignedPool` even though a bed's occupant pool is \"traveller data\" in\n// the same sense.\n//\n// WRITES. `add`/`patch`/`remove` all enqueue via `useOfflineMutation` (spec:\n// \"`add` is idempotency-key-only\", \"`patch` is versioned (`If-Match`)\",\n// \"idempotency-key-guarded\" remove) and each re-runs `list` on success so a\n// composite never has to remember to refresh itself after a party write —\n// same \"the write already re-requests its own read\" contract\n// `useRooming.ts`'s `assign` documents for `refreshUnassignedPool`.\n\nimport type {\n AddPartyOptions,\n OutboxOp,\n PartyDeltaRow,\n PatchPartyOptions,\n RemovePartyOptions,\n TravellersResource,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { classifyError, type ErrorClassification } from '../errors/classify';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\n\n/** The live half of `PartyDeltaRow` — this hook never sends `since`, so no\n * tombstone member is ever returned; see this file's header. */\nexport type PartyRow = Exclude<PartyDeltaRow, { readonly _tombstone: true }>;\n\n/** One row of `travellers.listForTrip()` — the trip's manifest, the search\n * space `PartyEditor`'s member picker filters client-side. See this file's\n * header for why this is not a `q`-parameterised search. */\nexport type PartiesTripRosterRow = Awaited<ReturnType<TravellersResource['listForTrip']>>[number];\n\nexport type AddPartyInput = Omit<AddPartyOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\nexport type PatchPartyInput = Omit<PatchPartyOptions, 'tripRef' | 'signal'>;\nexport type RemovePartyInput = Omit<RemovePartyOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\n\n/** The live-fetched party list — see this file's header for why this is a\n * live read rather than a snapshot subscription. Same `loaded`/\n * `lastFetchFailed`/`fetchedAt`/`refresh` contract `RoomingUnassignedPool`\n * and `TrekBoardState` already establish for this shape. */\nexport interface PartiesListState {\n readonly rows: readonly PartyRow[];\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly fetchedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n}\n\n/** The trip's traveller manifest — the member picker's search space. */\nexport interface PartiesTripRosterState {\n readonly rows: readonly PartiesTripRosterRow[];\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly fetchedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n}\n\nexport interface PartiesReady {\n readonly list: PartiesListState;\n readonly tripRoster: PartiesTripRosterState;\n readonly add: (input: AddPartyInput) => Promise<OutboxOp>;\n readonly patch: (input: PatchPartyInput) => Promise<OutboxOp>;\n readonly remove: (input: RemovePartyInput) => Promise<OutboxOp>;\n}\n\n/**\n * `parties` has no capability triple to resolve, so this union carries no\n * `'dark'` member (contrast `DomainHookResult`, `../types/domain.types.ts`,\n * which every OTHER §3 domain hook returns). `'loading'` covers the window\n * before the first `list` fetch settles; `'error'` is reserved for that\n * first fetch failing outright (a later `refresh()` failure instead flips\n * `list.lastFetchFailed`/`tripRoster.lastFetchFailed`, matching the \"loaded\n * once, stay usable\" contract those two states already carry elsewhere in\n * this package).\n */\nexport type PartiesResult =\n | { readonly status: 'loading' }\n | ({ readonly status: 'ready' } & PartiesReady)\n | {\n readonly status: 'error';\n readonly error: ErrorClassification;\n /** Re-runs the failed initial fetch — a composite's only retry\n * affordance while `status` is `'error'` (there is no `list.refresh`\n * to reach for yet, since the `'ready'` branch hasn't happened). */\n readonly retry: () => Promise<void>;\n };\n\nfunction isLiveParty(row: PartyDeltaRow): row is PartyRow {\n return !('_tombstone' in row);\n}\n\nexport function useParties(tripRef: string): PartiesResult {\n const client = useKaafilClient();\n\n const [rows, setRows] = useState<readonly PartyRow[]>([]);\n const [listLoaded, setListLoaded] = useState(false);\n const [listFetchFailed, setListFetchFailed] = useState(false);\n const [listFetchedAt, setListFetchedAt] = useState<string | undefined>(undefined);\n const [firstLoadError, setFirstLoadError] = useState<ErrorClassification | undefined>(undefined);\n\n const refreshList = useCallback(async (): Promise<void> => {\n try {\n const response = await client.trips.parties.list({ tripRef });\n setRows(response.filter(isLiveParty));\n setListLoaded(true);\n setListFetchFailed(false);\n setListFetchedAt(response.meta.serverTime);\n setFirstLoadError(undefined);\n } catch (error) {\n // Honest failure, not a fabricated empty roster — `loaded` stays\n // whatever it already was (`RoomingUnassignedPool`'s own doc comment\n // states the identical contract), only `lastFetchFailed` flips. The\n // classified error is only ever surfaced through `status: 'error'`\n // for the very first load, below.\n setListFetchFailed(true);\n setFirstLoadError((previous) => previous ?? classifyError(error));\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshList();\n }, [refreshList]);\n\n const [rosterRows, setRosterRows] = useState<readonly PartiesTripRosterRow[]>([]);\n const [rosterLoaded, setRosterLoaded] = useState(false);\n const [rosterFetchFailed, setRosterFetchFailed] = useState(false);\n const [rosterFetchedAt, setRosterFetchedAt] = useState<string | undefined>(undefined);\n\n const refreshRoster = useCallback(async (): Promise<void> => {\n try {\n const response = await client.travellers.listForTrip({ tripRef });\n setRosterRows(response);\n setRosterLoaded(true);\n setRosterFetchFailed(false);\n setRosterFetchedAt(response.meta.serverTime);\n } catch {\n setRosterFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshRoster();\n }, [refreshRoster]);\n\n const addMutation = useOfflineMutation<AddPartyInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/parties`,\n operationId: 'createParty' as never,\n body: input,\n }),\n });\n\n const patchMutation = useOfflineMutation<PatchPartyInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { partyId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/parties/${partyId}`,\n operationId: 'patchParty' as never,\n body,\n ifMatch: version,\n });\n },\n });\n\n const removeMutation = useOfflineMutation<RemovePartyInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { partyId } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/parties/${partyId}`,\n operationId: 'deleteParty' as never,\n });\n },\n });\n\n const addMutate = addMutation.mutate;\n const add = useCallback(\n async (input: AddPartyInput): Promise<OutboxOp> => {\n const op = await addMutate(input);\n void refreshList();\n return op;\n },\n [addMutate, refreshList],\n );\n\n const patchMutate = patchMutation.mutate;\n const patch = useCallback(\n async (input: PatchPartyInput): Promise<OutboxOp> => {\n const op = await patchMutate(input);\n void refreshList();\n return op;\n },\n [patchMutate, refreshList],\n );\n\n const removeMutate = removeMutation.mutate;\n const remove = useCallback(\n async (input: RemovePartyInput): Promise<OutboxOp> => {\n const op = await removeMutate(input);\n void refreshList();\n return op;\n },\n [removeMutate, refreshList],\n );\n\n if (!listLoaded && !listFetchFailed) {\n return { status: 'loading' };\n }\n\n if (!listLoaded && listFetchFailed) {\n // `firstLoadError` is always set in the same `catch` that flips\n // `listFetchFailed` (above) — this fallback only exists so the\n // compiler sees a total `ErrorClassification`, never because the two\n // can actually diverge at runtime.\n return {\n status: 'error',\n error: firstLoadError ?? {\n path: 'surface-to-user',\n code: undefined,\n status: undefined,\n unsatisfiableScheme: false,\n cause: undefined,\n },\n retry: refreshList,\n };\n }\n\n return {\n status: 'ready',\n list: {\n rows,\n loaded: listLoaded,\n lastFetchFailed: listFetchFailed,\n fetchedAt: listFetchedAt,\n refresh: refreshList,\n },\n tripRoster: {\n rows: rosterRows,\n loaded: rosterLoaded,\n lastFetchFailed: rosterFetchFailed,\n fetchedAt: rosterFetchedAt,\n refresh: refreshRoster,\n },\n add,\n patch,\n remove,\n };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `usePickups(tripRef)` — built from the\n// `useRooming()` exemplar (`useRooming.ts`'s own header comment), the same\n// one-hook-layer proof: this file is the ONLY place `client.pickups` is\n// called from anywhere in this package (hard rule #1/#2). Primary SDK\n// surface (verified, `kaafil-js/src/resources/pickups.ts` +\n// `generated/security.ts`): `pickups.list` (cache-first via the `'pickups'`\n// snapshot section — `kaafil-js/src/offline/pull.ts`'s `SYNC_PULL_SECTIONS`),\n// `pickups.create/patch/remove/reorder`, `pickups.assign/reassign`,\n// `pickups.board` (manager-only origination), `pickups.correctBoardStatus`\n// (manager/apiKey/agencyAdmin — never a relaxed `board`),\n// `pickups.close/reopen`, `pickups.manifestByPickup`. PERSONALIZED\n// mode-dark (`06-capability-and-personas.md §3`).\n//\n// `reassign` (`pickups.reassign` — the bulk, stop-level \"move every\n// live, not-yet-boarded traveller off this stop\" sibling of `assign`) is\n// exposed here as a direct passthrough, the same pattern `useRooming.ts`\n// uses for `autoAssign`: `ReassignPickupStopTravellersOptions` is not\n// re-exported by name from `kaafil-js/client`'s public surface (verified —\n// only the OTHER nine `*Options` types on this resource are), so its input\n// type below is derived structurally off `PickupsResource['reassign']`\n// rather than imported, never invented.\n//\n// `manifestByPickup` is ALSO a direct passthrough, not a cache-first\n// snapshot read — `ManifestByPickupResponse` (per-traveller board rows,\n// grouped by stop) has no `SYNC_PULL_SECTIONS` entry of its own (only the\n// stop-level `'pickups'` section, `PickupStopDeltaRow[]`, is delta-cached);\n// the per-traveller roster this response carries is therefore a LIVE read,\n// the same \"not every array in a read is a cached delta feed\" reasoning\n// `useRooming.ts`'s own `RoomingUnassignedPool` doc comment states for\n// `unassigned[]`. `ManifestByPickupViewer`'s own spec entry (`05-pickup-\n// points.md`) says this read is cache-first with a head-count computed\n// locally from cached `BoardStatus` rows — that claim assumes a\n// per-traveller board-status cache this build's `SYNC_PULL_SECTIONS` does\n// not carry; documented here rather than silently reinterpreted, and the\n// calling composite's own header repeats this gap.\n\nimport type {\n AssignPickupTravellerOptions,\n BoardPickupTravellerOptions,\n ClosePickupStopOptions,\n CorrectPickupBoardStatusOptions,\n CreatePickupStopOptions,\n DeletePickupStopOptions,\n OutboxOp,\n PatchPickupStopOptions,\n PickupStopDeltaRow,\n PickupsResource,\n ReadManifestByPickupOptions,\n ReopenPickupStopOptions,\n ReorderPickupStopsOptions,\n} from 'kaafil-js/client';\nimport { normalizeDateTimeInput, SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback } from 'react';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\n// Re-exported by name (wasn't before) so a persona composite can type its\n// own `stops[]` state without importing `kaafil-js/client` directly (hard\n// rule #1) — the same re-export every sibling hook's own delta-row type\n// already gets (`ChecklistItemDeltaRow`, `TripFormRow`, etc).\nexport type { PickupStopDeltaRow };\n\ntype CreateStopInput = Omit<CreatePickupStopOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype PatchStopInput = Omit<PatchPickupStopOptions, 'tripRef' | 'signal'>;\ntype RemoveStopInput = Omit<DeletePickupStopOptions, 'tripRef' | 'signal'>;\ntype ReorderStopsInput = Omit<ReorderPickupStopsOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype AssignInput = Omit<AssignPickupTravellerOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\n/** Derived off the resource method, not imported — see this file's header. */\ntype ReassignInput = Omit<\n Parameters<PickupsResource['reassign']>[0],\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\ntype BoardInput = Omit<BoardPickupTravellerOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype CorrectBoardStatusInput = Omit<CorrectPickupBoardStatusOptions, 'tripRef' | 'signal'>;\ntype CloseStopInput = Omit<ClosePickupStopOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype ReopenStopInput = Omit<ReopenPickupStopOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype ManifestInput = Omit<ReadManifestByPickupOptions, 'tripRef' | 'signal'>;\n\n/** `Awaited<ReturnType<...>>` off the resource method — `ManifestByPickup\n * Response`/`ReassignResponse`/`BoardResponse`/`AssignResponse`/\n * `CloseResponse`/`ReopenResponse` are not individually re-exported by name\n * from `kaafil-js/client`'s public surface (only the nine `*Options` input\n * types and `PickupStopDeltaRow` are — verified), so every result type below\n * is derived structurally off `PickupsResource`, the one type that IS\n * exported, rather than invented or widened to `unknown`. */\nexport type PickupManifestResult = Awaited<ReturnType<PickupsResource['manifestByPickup']>>;\nexport type PickupAssignResult = Awaited<ReturnType<PickupsResource['assign']>>;\nexport type PickupReassignResult = Awaited<ReturnType<PickupsResource['reassign']>>;\nexport type PickupBoardResult = Awaited<ReturnType<PickupsResource['board']>>;\nexport type PickupCloseResult = Awaited<ReturnType<PickupsResource['close']>>;\nexport type PickupReopenResult = Awaited<ReturnType<PickupsResource['reopen']>>;\n\nexport interface PickupsReady {\n readonly stops: readonly PickupStopDeltaRow[];\n readonly syncedAt: string | undefined;\n /**\n * Re-reads the live lane after a write. A NO-OP on a field device, where\n * the outbox drain already emits `snapshot.updated` and the cache-first\n * read re-renders itself — calling it there costs nothing and means a\n * composite does not have to know which lane it is on.\n */\n readonly refreshLive: () => Promise<void>;\n // `OutboxOp | null` on the five stop writes below AND on\n // `correctBoardStatus`: each carries a desk `direct` lane, and `null` is\n // what it resolves to there — committed, with no outbox row to hand back.\n // `board`, `close` and `reopen` keep the narrow `Promise<OutboxOp>`,\n // because they are `managerAuth`-only, have no direct lane, and can never\n // take one.\n readonly create: (input: CreateStopInput) => Promise<OutboxOp | null>;\n readonly patch: (input: PatchStopInput) => Promise<OutboxOp | null>;\n readonly remove: (input: RemoveStopInput) => Promise<OutboxOp | null>;\n readonly reorder: (input: ReorderStopsInput) => Promise<OutboxOp | null>;\n readonly assign: (input: AssignInput) => Promise<OutboxOp | null>;\n /** `pickups.reassign` — moves every live, not-yet-boarded traveller off\n * one stop onto a sibling stop of the same kind in one call\n * (`FRD §8`'s \"delete a stop with travellers on it\" flow). Not enqueued\n * through the outbox like the other writes here — its response\n * (`movedCount`/`skippedBoardedCount`/both rebased stops) is needed\n * synchronously by the calling composite to render the outcome, the same\n * `autoAssign`-shaped exception `useRooming.ts`'s header documents. */\n readonly reassign: (input: ReassignInput) => Promise<PickupReassignResult>;\n /** Manager-only origination — an eyewitness statement\n * (`06-capability-and-personas.md §7`'s canonical `✏️` case). */\n readonly board: (input: BoardInput) => Promise<OutboxOp>;\n /** manager/apiKey/agencyAdmin correction of an existing board record —\n * never a relaxed version of `board`, and refused\n * `422 pickups.correctionRequiresObservation` on a still-`PENDING` row.\n * Not `If-Match`-guarded on the wire (`pickups.ts`'s own doc comment) —\n * no `version`/`ifMatch` on this input, unlike the other stop writes. */\n readonly correctBoardStatus: (input: CorrectBoardStatusInput) => Promise<OutboxOp | null>;\n readonly close: (input: CloseStopInput) => Promise<OutboxOp>;\n readonly reopen: (input: ReopenStopInput) => Promise<OutboxOp>;\n /** Live read, not cache-first — see this file's header. */\n readonly manifestByPickup: (input?: ManifestInput) => Promise<PickupManifestResult>;\n}\n\n/** `PickupStopDeltaRow` narrowed to the live shape — a tombstone has none of\n * the fields an optimistic row fills in. */\ntype PickupStopLiveRow = Exclude<PickupStopDeltaRow, { readonly _tombstone: true }>;\n\n/**\n * The row painted for a stop added out of signal.\n *\n * Typed as the live row so the COMPILER checks the shape — `enqueue`'s\n * `optimistic` parameter is `SnapshotRow` (`id`, `version`, anything else),\n * which would happily accept a field of the wrong type and let a composite\n * discover it at runtime.\n *\n * Every value here is one the client genuinely knows. The counts are the\n * honest reading for a stop that exists and has nobody assigned to it yet:\n * `expectedCount: 0` is not a placeholder, it is true until a traveller is\n * put on this stop, and `rollup: 'not_started'` follows from it. That is why\n * pickups gets an optimistic create and rooming rooms and seating vehicles do\n * not — their rows carry a server-GENERATED `beds[]`/`seats[]` map, and\n * inventing one would mean re-deriving the engine's own layout rules.\n */\nfunction optimisticPickupStop(\n input: CreateStopInput,\n syncedAt: string | undefined,\n): PickupStopLiveRow {\n return {\n // Replaced by the id the engine mints.\n id: 'pending',\n version: 0,\n // The request's own default, restated rather than guessed: the SDK's\n // `kind` is optional and the engine treats an absent one as a pickup.\n kind: input.kind ?? 'PICKUP',\n name: input.name,\n locationLabel: input.locationLabel ?? null,\n lat: input.lat ?? null,\n lng: input.lng ?? null,\n scheduledTime: normalizeDateTimeInput(input.scheduledTime, 'scheduledTime'),\n // Appended; the server's ordering arrives with the canonical row.\n sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,\n status: 'OPEN',\n closedAt: null,\n closedByManagerId: null,\n performedByKind: null,\n performedById: null,\n rollup: 'not_started',\n boardedCount: 0,\n expectedCount: 0,\n // The last reading the SERVER gave this list, never a device clock\n // (hard rule #6).\n updatedAt: syncedAt ?? '',\n };\n}\n\nconst usePickupsInternal = createDomainHook<PickupsReady>('pickup-points', (tripRef) => {\n const client = useKaafilClient();\n // CACHE-FIRST WITH A LIVE FALLBACK. `'pickups'` is a real\n // `SYNC_PULL_SECTIONS` entry, so a field device reads it out of its own\n // snapshot exactly as before. A DESK console mounts no `OfflineShell` and\n // therefore has no snapshot at all — without this the read would return\n // `[]` forever and the office would be told a trip has no pickup points\n // when it has several. `useSnapshotList`'s own header carries the full\n // argument for why the fallback lives there rather than here.\n const {\n rows: stops,\n syncedAt,\n refreshLive,\n } = useSnapshotList<PickupStopDeltaRow>(tripRef, 'pickups', {\n live: async (liveClient, ref) => {\n const response = await liveClient.pickups.list({ tripRef: ref });\n return { rows: response, syncedAt: response.meta.serverTime };\n },\n });\n\n const createMutation = useOfflineMutation<CreateStopInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/pickups`,\n // `OperationId` is not exported from `kaafil-js/client`'s public\n // surface (verified, same gap `useRooming.ts` documents) — every\n // literal below is checked against `kaafil-js/src/generated/\n // security.ts`'s own operation-id table.\n operationId: 'createPickupStop' as never,\n body: input,\n // A stop added out of signal appears at once, keyed on an id the\n // ENGINE mints and swapped for the server's row when the write lands\n // — see `optimisticPickupStop` for why every field here is one the\n // client can honestly know.\n creates: true,\n entity: { listName: 'pickups' },\n optimistic: optimisticPickupStop(input, syncedAt),\n }),\n // The desk lane. `board`, `close` and `reopen` below deliberately get\n // NONE — they are `managerAuth`-only on the wire, so a direct call from\n // an agency-admin session would be refused by `CredentialResolver`\n // before it left the process. See this file's own persona note.\n direct: (liveClient, input) => liveClient.pickups.create({ tripRef, ...input }),\n });\n\n const patchMutation = useOfflineMutation<PatchStopInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { pointId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/pickups/${pointId}`,\n operationId: 'patchPickupStop' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.pickups.patch({ tripRef, ...input }),\n });\n\n const removeMutation = useOfflineMutation<RemoveStopInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { pointId, version, force } = input;\n const query = force === true ? '?force=true' : '';\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/pickups/${pointId}${query}`,\n operationId: 'deletePickupStop' as never,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.pickups.remove({ tripRef, ...input }),\n });\n\n const reorderMutation = useOfflineMutation<ReorderStopsInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/pickups/reorder`,\n operationId: 'reorderPickupStops' as never,\n body: input,\n }),\n direct: (liveClient, input) => liveClient.pickups.reorder({ tripRef, ...input }),\n });\n\n const assignMutation = useOfflineMutation<AssignInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { pointId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/pickups/${pointId}/assign`,\n operationId: 'assignPickupTraveller' as never,\n body,\n });\n },\n direct: (liveClient, input) => liveClient.pickups.assign({ tripRef, ...input }),\n });\n\n const boardMutation = useOfflineMutation<BoardInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { pointId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/pickups/${pointId}/board`,\n operationId: 'boardPickupTraveller' as never,\n body,\n });\n },\n });\n\n const correctBoardStatusMutation = useOfflineMutation<CorrectBoardStatusInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { pointId, travellerId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/pickups/${pointId}/board/${travellerId}`,\n operationId: 'correctPickupBoardStatus' as never,\n body,\n });\n },\n // The office's ONE door onto the board table, so it needs the desk lane\n // as much as the five stop writes do — `board`/`close`/`reopen` below\n // still get none, because they are `managerAuth`-only.\n direct: (liveClient, input) => liveClient.pickups.correctBoardStatus({ tripRef, ...input }),\n });\n\n const closeMutation = useOfflineMutation<CloseStopInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { pointId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/pickups/${pointId}/close`,\n operationId: 'closePickupStop' as never,\n body,\n });\n },\n });\n\n const reopenMutation = useOfflineMutation<ReopenStopInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { pointId } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/pickups/${pointId}/reopen`,\n operationId: 'reopenPickupStop' as never,\n });\n },\n });\n\n // MEMOISED, not inline. `createDomainHook`'s `build()` re-runs on every\n // render, so an arrow written straight into the object below is a NEW\n // function each time. Every other member here is already stable — the\n // mutations come off `useOfflineMutation`'s own `useCallback` — and these\n // two were the exceptions.\n //\n // That is not a tidiness point. A consumer that calls one of these from a\n // `useCallback`, and puts THAT in a `useEffect` dependency array (the\n // obvious way to load a roster when a view opens), gets an effect that\n // re-fires every render: fetch, set state, re-render, new arrow, fetch.\n // It froze the browser tab. `useSnapshotList`'s own `liveRef` comment\n // records the same failure from the other direction.\n const reassign = useCallback(\n (input: ReassignInput) => client.pickups.reassign({ tripRef, ...input }),\n [client, tripRef],\n );\n const manifestByPickup = useCallback(\n (input?: ManifestInput) => client.pickups.manifestByPickup({ tripRef, ...input }),\n [client, tripRef],\n );\n\n return {\n stops,\n syncedAt,\n refreshLive,\n create: createMutation.mutate,\n patch: patchMutation.mutate,\n remove: removeMutation.mutate,\n reorder: reorderMutation.mutate,\n assign: assignMutation.mutate,\n reassign,\n board: boardMutation.mutate,\n correctBoardStatus: correctBoardStatusMutation.mutate,\n close: closeMutation.mutate,\n reopen: reopenMutation.mutate,\n manifestByPickup,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'pickup-points'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function usePickups(tripRef: string): DomainHookResult<PickupsReady> {\n return usePickupsInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useRooming(tripRef)` — the EXEMPLAR every\n// other §3 domain hook is written from. Primary SDK surface (verified this\n// session, `kaafil-js/src/resources/rooming.ts` + `generated/security.ts`):\n// `rooming.read`, `rooming.assign`, `rooming.autoAssign`,\n// `rooming.stayWindows.{list,create,patch,remove}`,\n// `rooming.rooms.{create,patch,remove}`. PERSONALIZED mode-dark module\n// (`06-capability-and-personas.md §3`) — gated via `createDomainHook()`.\n//\n// SDK MISMATCH (flagged): the catalog calls the sub-resource\n// `rooming.windows`; the real SDK names it `rooming.stayWindows`\n// (`RoomingStayWindowsResource`, verified). This hook's own returned shape\n// uses `stayWindows` throughout, matching the SDK rather than the catalog's\n// shorthand.\n//\n// DECISION: of this hook's writes, only `stayWindows.create` carries an\n// optimistic row. The others enqueue WITHOUT an `entity`/`optimistic`\n// pairing, and the split is about what a client can honestly know rather\n// than about effort.\n//\n// A stay window is a label, two dates and an order — every field of the row\n// is either given by the caller or genuinely absent, so\n// `optimisticStayWindow` paints one the instant it is added and the engine\n// swaps it for the server's row when the write lands.\n//\n// `rooms.create` cannot do the same. `RoomingRoomResponse` carries a\n// server-GENERATED `beds[]` derived from `capacity` and `roomType`, so a\n// local row would either show a room with no beds in it — which reads as a\n// failed create — or re-derive the engine's own bed-labelling rules in the\n// client, which is the duplication that makes a cached view disagree with a\n// live one. A bed ASSIGNMENT is worse still: its \"entity\" is neither a room\n// nor a traveller in isolation.\n//\n// `RoomingBoardResponse` (the 'rooming' pull section) exposes exactly one\n// array-valued, id-bearing property — `rooms[]` (verified against\n// `openapi/openapi.json`: `windows[]` items key on `stayWindowId`, not `id`;\n// `unassigned[]` items key on `travellerId`, not `id`). Those writes are\n// still durable, outbox-backed and idempotent; the UI re-syncs on the next\n// `snapshot.updated` for the `'rooming'` list, which is honest given the\n// ambiguity rather than fabricated.\n//\n// DECISION: `autoAssign` calls `client.rooming.autoAssign(options)` DIRECTLY\n// — the one write in this hook that does NOT go through\n// `OfflineEngine.enqueue()`. Two independent reasons: (1) `dryRun: true`\n// writes nothing at all, so there is no write to enqueue; (2) even\n// `dryRun: false`'s response — the computed plan, `perRule` outcomes, the\n// reasoned `unassigned[]` — cannot be recovered from `OutboxOp`, the only\n// value `useOfflineMutation`/`engine.enqueue()` can hand back, and the\n// calling composite needs that payload synchronously to render the\n// preview/apply result. This is a deliberate, narrow exception to\n// `07-offline-and-sync.md`'s write-ahead default, not an oversight — see\n// this worker's final report.\n\nimport type {\n AssignRoomingBedOptions,\n AutoAssignRoomingOptions,\n CreateRoomingRoomOptions,\n CreateRoomingStayWindowOptions,\n DeleteRoomingRoomOptions,\n DeleteRoomingStayWindowOptions,\n OutboxOp,\n PatchRoomingRoomOptions,\n PatchRoomingStayWindowOptions,\n RoomingOccupant,\n RoomingResource,\n RoomingRoomDeltaRow,\n} from 'kaafil-js/client';\nimport { normalizeDateTimeInput, SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\ntype RoomingStayWindowRow = Awaited<ReturnType<RoomingResource['stayWindows']['list']>>[number];\n\ntype AssignBedInput = Omit<AssignRoomingBedOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype AutoAssignInput = Omit<AutoAssignRoomingOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\n\n/** What `autoAssign` resolves to — `plan`, `perRule`, `unassigned`, `deltas`.\n * Derived structurally off the resource method rather than imported by name:\n * `RoomingAutoAssignResponse` is not re-exported from `kaafil-js/client`'s\n * public surface, and a composite rendering a plan needs to name this type. */\nexport type RoomingAutoAssignResult = Awaited<ReturnType<RoomingResource['autoAssign']>>;\ntype CreateWindowInput = Omit<\n CreateRoomingStayWindowOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\ntype PatchWindowInput = Omit<PatchRoomingStayWindowOptions, 'tripRef' | 'signal'>;\ntype RemoveWindowInput = Omit<DeleteRoomingStayWindowOptions, 'tripRef' | 'signal'>;\ntype CreateRoomInput = Omit<CreateRoomingRoomOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype PatchRoomInput = Omit<PatchRoomingRoomOptions, 'tripRef' | 'signal'>;\ntype RemoveRoomInput = Omit<DeleteRoomingRoomOptions, 'tripRef' | 'signal'>;\n\n/**\n * The unassigned-traveller roster — `RoomingBoardResponse.unassigned[]`\n * (`kaafil-js/openapi/openapi.json`, verified). Its own state, deliberately\n * NOT folded into `rooms`/`stayWindows`'s cache-first shape, so a consumer\n * can never mistake one for the other.\n */\nexport interface RoomingUnassignedPool {\n readonly travellers: readonly RoomingOccupant[];\n /** `true` once at least one `client.rooming.read()` call has settled\n * (success or failure) — distinguishes \"never fetched yet\" from \"fetched\n * and genuinely empty.\" */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw (offline, network, server\n * error) — a consumer must render this differently from `travellers: []`\n * with `loaded: true`; those two states are never the same thing. */\n readonly lastFetchFailed: boolean;\n /** The server time (`meta.serverTime`) of the last successful fetch —\n * `undefined` before any fetch has ever succeeded. Never a locally-minted\n * timestamp (hard rule #6). */\n readonly fetchedAt: string | undefined;\n /** Re-runs the live read, optionally scoped to one stay window.\n *\n * `stayWindowId` matters: the engine's own `readBoard` (`kaafil-engine`\n * `rooming.service.ts#unassignedCountForWindow`'s doc comment) computes\n * \"unassigned\" PER WINDOW deliberately — \"a trip-wide unassigned count\n * would have to decide whether a traveller with a bed on night 1 and none\n * on night 2 is assigned, and there is no answer to that a subscriber\n * could use.\" Passing the board's currently-active window here is what\n * makes the pool answer \"who still needs a bed IN THIS WINDOW,\" which is\n * the only question a manager looking at one window's board is actually\n * asking. Omitting it (this hook's own initial mount-time fetch, before\n * any window is known) falls back to the engine's unscoped trip-wide\n * read — genuinely ambiguous, per the same comment, so a caller that\n * knows the active window should always pass it.\n *\n * `assign` already calls this on its own success (a bed assignment\n * changes who is unassigned); a composite calls it again after any OTHER\n * action that can move someone in or out of the pool. */\n readonly refresh: (stayWindowId?: string) => Promise<void>;\n}\n\nexport interface RoomingReady {\n readonly rooms: readonly RoomingRoomDeltaRow[];\n readonly stayWindows: readonly RoomingStayWindowRow[];\n readonly syncedAt: string | undefined;\n /**\n * LIVE-READ, NOT cache-first — deliberately. `RoomingBoardResponse`\n * (`openapi/openapi.json`) carries three arrays; only `rooms[]` is\n * delta-shaped (`anyOf` a live row or a `_tombstone`, with `id`/\n * `version`). `unassigned[]` is a plain object keyed on `travellerId`\n * with no tombstone branch and no version — a DERIVED projection the\n * engine recomputes per read, not a durable delta feed\n * (`kaafil-js/src/offline/pull.ts`'s `extractSectionRows` docstring,\n * verified this session). Caching it as a delta row would be a real bug:\n * no tombstone can ever arrive for a traveller who GETS a bed, and\n * `SnapshotStore.applyPull` rebases by id rather than replacing, so a\n * cached pool would grow monotonically and never shrink. This field is\n * therefore sourced from its own `client.rooming.read()` call, refreshed\n * explicitly rather than subscribed to `snapshot.updated`.\n */\n readonly unassignedPool: RoomingUnassignedPool;\n /** Re-reads both desk lanes after a write. A NO-OP on a field device,\n * where the outbox drain emits `snapshot.updated` and the cache-first\n * reads re-render themselves — a composite need not know which lane it is\n * on. */\n readonly refreshLive: () => Promise<void>;\n // `OutboxOp | null` on all seven writes: each carries a desk `direct`\n // lane, and `null` is what it resolves to there — committed, with no\n // outbox row to hand back. Unlike `usePickups`, there is no member here\n // that lacks a direct lane, because every rooming route takes the admin\n // triple.\n readonly assign: (input: AssignBedInput) => Promise<OutboxOp | null>;\n readonly autoAssign: (input: AutoAssignInput) => ReturnType<RoomingResource['autoAssign']>;\n readonly createStayWindow: (input: CreateWindowInput) => Promise<OutboxOp | null>;\n readonly patchStayWindow: (input: PatchWindowInput) => Promise<OutboxOp | null>;\n readonly removeStayWindow: (input: RemoveWindowInput) => Promise<OutboxOp | null>;\n readonly createRoom: (input: CreateRoomInput) => Promise<OutboxOp | null>;\n readonly patchRoom: (input: PatchRoomInput) => Promise<OutboxOp | null>;\n readonly removeRoom: (input: RemoveRoomInput) => Promise<OutboxOp | null>;\n}\n\n// ── THE RENDER CANON, RE-EXPORTED THROUGH THIS LAYER ──────────────────────\n//\n// A rooming board and an auto-assign result cannot be rendered without them:\n// `HEURISTIC_SEVERITY` says how loudly each relaxed rule reads,\n// `TONE_FAMILIES`/`parseRoomingTone` turn the wire's `tone` TOKEN (`male.3`\n// — \"the engine never owns brand colours\") into something a palette can map,\n// and `FALLBACK_GLYPH` is what stands in when a traveller has no glyph.\n//\n// They are deliberately NOT on the wire, so `kaafil-js`'s own client entry is\n// the only source — and hard rule #1 forbids any file outside `src/core/`\n// importing from it. Re-exported here so a composite reaches them through\n// the one hook layer, exactly as `RoomingRoomDeltaRow` already is.\n\nexport type { RoomingHeuristicSeverity, RoomingTone } from 'kaafil-js/client';\nexport {\n FALLBACK_GLYPH,\n HEURISTIC_SEVERITY,\n isRoomingHeuristicKey,\n parseRoomingTone,\n roomingHeuristicSeverity,\n SHADES_PER_FAMILY,\n TONE_FAMILIES,\n UNKNOWN_TONE_FAMILY,\n} from 'kaafil-js/client';\n\nexport type { RoomingRoomDeltaRow, RoomingStayWindowRow };\n\n/**\n * The row painted for a stay window added out of signal.\n *\n * Typed as the row itself so the COMPILER checks the shape — `enqueue`'s\n * `optimistic` parameter is `SnapshotRow` and would accept a wrong-typed\n * field silently, which is how the first optimistic row in this package\n * shipped with three.\n *\n * A stay window is the one rooming create that CAN be painted honestly: its\n * whole shape is a label, two dates and an order. `createRoom` is not, and\n * deliberately has no optimistic row — `RoomingRoomResponse` carries a\n * server-GENERATED `beds[]` built from `capacity` and `roomType`, so a local\n * row would either show a room with no beds in it or re-derive the engine's\n * own bed-labelling. Both are worse than the row arriving a moment later.\n */\nfunction optimisticStayWindow(\n input: CreateWindowInput,\n syncedAt: string | undefined,\n): RoomingStayWindowRow {\n return {\n // Replaced by the id the engine mints.\n id: 'pending',\n version: 0,\n label: input.label,\n startDate: normalizeDateTimeInput(input.startDate, 'startDate'),\n endDate: normalizeDateTimeInput(input.endDate, 'endDate'),\n // Appended; the server's ordering arrives with the canonical row.\n sortOrder: input.sortOrder ?? Number.MAX_SAFE_INTEGER,\n // A window created by hand has no CRM segment behind it. This is a fact\n // about the write, not a placeholder.\n sourceSegmentRef: null,\n sourceUpdatedAt: null,\n // The last reading the SERVER gave this list, never a device clock.\n updatedAt: syncedAt ?? '',\n };\n}\n\nconst useRoomingInternal = createDomainHook<RoomingReady>('rooming', (tripRef) => {\n const client = useKaafilClient();\n // CACHE-FIRST WITH A LIVE FALLBACK, on BOTH lists. A field device reads its\n // own snapshot exactly as before; a DESK console mounts no `OfflineShell`\n // and has no snapshot at all, so without these the board would render \"no\n // rooms, no stay windows\" for a trip that has both.\n // `useSnapshotList`'s own header carries the full argument, including why\n // the `live` callback must never reach a dependency array.\n const {\n rows: rooms,\n syncedAt: roomsSyncedAt,\n refreshLive: refreshRoomsLive,\n } = useSnapshotList<RoomingRoomDeltaRow>(tripRef, 'rooming', {\n live: async (liveClient, ref) => {\n // The board read carries the rooms whole, so the desk needs no second\n // call for them — and it is the same endpoint the pool already uses.\n const response = await liveClient.rooming.read({ tripRef: ref });\n return { rows: response.rooms, syncedAt: response.meta.serverTime };\n },\n });\n const {\n rows: stayWindows,\n syncedAt: windowsSyncedAt,\n refreshLive: refreshWindowsLive,\n } = useSnapshotList<RoomingStayWindowRow>(tripRef, 'stayWindows', {\n live: async (liveClient, ref) => {\n const response = await liveClient.rooming.stayWindows.list({ tripRef: ref });\n return { rows: response, syncedAt: response.meta.serverTime };\n },\n });\n\n /** Re-reads both desk lanes. A no-op on a field device. */\n const refreshLive = useCallback(async (): Promise<void> => {\n await Promise.all([refreshRoomsLive(), refreshWindowsLive()]);\n }, [refreshRoomsLive, refreshWindowsLive]);\n\n const assignMutation = useOfflineMutation<AssignBedInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/rooming/assign`,\n // Hardcoded literal, not imported: `OperationId` is not exported from\n // `kaafil-js/client`'s public surface (verified — see this worker's\n // final report). Value verified against\n // `kaafil-js/src/generated/security.ts` this session.\n operationId: 'assignRoomingBed' as never,\n body: input,\n // `RoomingAssignDto.rooms` is every room this write touched, whole —\n // up to two, on a swap. `arrayKey` is this hook's multi-row rebase\n // (`OutboxEntityRef.arrayKey`), the reason the room grid now\n // repaints the instant an assign lands rather than waiting for the\n // next full pull.\n entity: { listName: 'rooming', arrayKey: 'rooms' },\n }),\n // The desk lane. Every rooming write takes the admin triple, so unlike\n // `usePickups` there is no member here that deliberately lacks one.\n direct: (liveClient, input) => liveClient.rooming.assign({ tripRef, ...input }),\n });\n\n // The unassigned pool's own live-fetch state — see `RoomingUnassignedPool`'s\n // doc comment for why this is a `client.rooming.read()` call and never a\n // snapshot subscription.\n const [poolTravellers, setPoolTravellers] = useState<readonly RoomingOccupant[]>([]);\n const [poolLoaded, setPoolLoaded] = useState(false);\n const [poolFetchFailed, setPoolFetchFailed] = useState(false);\n const [poolFetchedAt, setPoolFetchedAt] = useState<string | undefined>(undefined);\n // The most recently REQUESTED scope, so `assign`'s own auto-refresh (below)\n // can re-fetch in the SAME window a composite is currently looking at,\n // rather than silently falling back to the engine's ambiguous unscoped\n // read every time a write settles. Not component state — updating it must\n // never itself trigger a render.\n const lastRequestedStayWindowIdRef = useRef<string | undefined>(undefined);\n\n const refreshUnassignedPool = useCallback(\n async (stayWindowId?: string): Promise<void> => {\n lastRequestedStayWindowIdRef.current = stayWindowId;\n try {\n const response = await client.rooming.read({ tripRef, stayWindowId });\n setPoolTravellers(response.unassigned);\n setPoolLoaded(true);\n setPoolFetchFailed(false);\n setPoolFetchedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated empty roster — `loaded` stays\n // whatever it already was (a previously-successful fetch's rows are\n // still the best available answer), only `lastFetchFailed` flips.\n setPoolFetchFailed(true);\n }\n },\n [client, tripRef],\n );\n\n useEffect(() => {\n void refreshUnassignedPool();\n }, [refreshUnassignedPool]);\n\n // The pool is a PLAIN READ, so nothing re-runs it when queued rooming\n // writes finally reach the server — the room rows re-sync on their own\n // `snapshot.updated` while the pool keeps listing travellers who have since\n // been given a bed. Out of signal that gap is arbitrarily long and the\n // screen contradicts itself. One re-read per drain, for as long as this\n // hook is mounted — same shape and reason as `useItinerary`'s\n // `refreshAfterDrain`. Re-requests the SAME stay window the caller last\n // asked for, never a reset to the default one.\n const engine = useContext(OfflineEngineContext);\n useEffect(() => {\n if (engine === null) {\n return;\n }\n const unsubscribe = engine.events.on('sync.drained', () => {\n void refreshUnassignedPool(lastRequestedStayWindowIdRef.current);\n });\n return unsubscribe;\n }, [engine, refreshUnassignedPool]);\n\n const assignMutate = assignMutation.mutate;\n const assign = useCallback(\n async (input: AssignBedInput): Promise<OutboxOp | null> => {\n const op = await assignMutate(input);\n // A bed assignment changes who is unassigned — re-request the live\n // pool rather than leaving it to go stale until some unrelated\n // remount (`RoomingUnassignedPool.refresh`'s own doc comment).\n // Reuses whichever scope was last REQUESTED (typically the board's\n // active stay window), not an unscoped fetch — an unscoped re-fetch\n // here would silently widen the pool back to the engine's ambiguous\n // trip-wide read right after every single assignment, undoing\n // whatever window-scoped `refresh(stayWindowId)` call got the pool\n // correct in the first place.\n void refreshUnassignedPool(lastRequestedStayWindowIdRef.current);\n return op;\n },\n [assignMutate, refreshUnassignedPool],\n );\n\n const createWindowMutation = useOfflineMutation<CreateWindowInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/rooming/stay-windows`,\n operationId: 'createRoomingStayWindow' as never,\n body: input,\n // A window added out of signal appears at once. Every field of a\n // stay window is either given by the caller or genuinely absent —\n // which is exactly what `createRoom` below cannot say, and why only\n // this one of the two gets an optimistic row.\n creates: true,\n entity: { listName: 'stayWindows' },\n optimistic: optimisticStayWindow(input, windowsSyncedAt),\n }),\n direct: (liveClient, input) => liveClient.rooming.stayWindows.create({ tripRef, ...input }),\n });\n\n const patchWindowMutation = useOfflineMutation<PatchWindowInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { windowId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/rooming/stay-windows/${windowId}`,\n operationId: 'patchRoomingStayWindow' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.rooming.stayWindows.patch({ tripRef, ...input }),\n });\n\n const removeWindowMutation = useOfflineMutation<RemoveWindowInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { windowId, version, force } = input;\n const query = force === true ? '?force=true' : '';\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/rooming/stay-windows/${windowId}${query}`,\n operationId: 'deleteRoomingStayWindow' as never,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.rooming.stayWindows.remove({ tripRef, ...input }),\n });\n\n const createRoomMutation = useOfflineMutation<CreateRoomInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/rooming/rooms`,\n operationId: 'createRoomingRoom' as never,\n body: input,\n }),\n direct: (liveClient, input) => liveClient.rooming.rooms.create({ tripRef, ...input }),\n });\n\n const patchRoomMutation = useOfflineMutation<PatchRoomInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { roomId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/rooming/rooms/${roomId}`,\n operationId: 'patchRoomingRoom' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.rooming.rooms.patch({ tripRef, ...input }),\n });\n\n const removeRoomMutation = useOfflineMutation<RemoveRoomInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { roomId, version, force } = input;\n const query = force === true ? '?force=true' : '';\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/rooming/rooms/${roomId}${query}`,\n operationId: 'deleteRoomingRoom' as never,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.rooming.rooms.remove({ tripRef, ...input }),\n });\n\n const syncedAt =\n roomsSyncedAt === undefined\n ? windowsSyncedAt\n : windowsSyncedAt === undefined\n ? roomsSyncedAt\n : roomsSyncedAt > windowsSyncedAt\n ? roomsSyncedAt\n : windowsSyncedAt;\n\n // MEMOISED, not inline. `createDomainHook`'s `build()` re-runs on every\n // render, so an arrow written straight into the returned object is a NEW\n // function each time — and a composite that puts one in a `useEffect`\n // dependency array gets an effect that re-fires every render, sets state,\n // and re-renders. That froze a browser tab once\n // (`usePickups.spec.tsx` carries the incident and the invariant).\n const autoAssign = useCallback(\n (input: AutoAssignInput) => client.rooming.autoAssign({ tripRef, ...input }),\n [client, tripRef],\n );\n\n return {\n rooms,\n stayWindows,\n syncedAt,\n refreshLive,\n unassignedPool: {\n travellers: poolTravellers,\n loaded: poolLoaded,\n lastFetchFailed: poolFetchFailed,\n fetchedAt: poolFetchedAt,\n refresh: refreshUnassignedPool,\n },\n assign,\n autoAssign,\n createStayWindow: createWindowMutation.mutate,\n patchStayWindow: patchWindowMutation.mutate,\n removeStayWindow: removeWindowMutation.mutate,\n createRoom: createRoomMutation.mutate,\n patchRoom: patchRoomMutation.mutate,\n removeRoom: removeRoomMutation.mutate,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'rooming'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useRooming(tripRef: string): DomainHookResult<RoomingReady> {\n return useRoomingInternal(tripRef);\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useSeating(tripRef)`. Written from\n// `useRooming()`, this catalog's own EXEMPLAR (`useRooming.ts`'s header\n// comment) — same shape, same reasoning, this module's own specifics noted\n// inline. Primary SDK surface (verified, `kaafil-js/src/resources/\n// seating.ts`): `seating.read`, `seating.assign`, `seating.autoAssign`,\n// `seating.vehicles.{create,patch,remove}`,\n// `seating.vehicles.manager.{link,unlink}` (SDK MISMATCH flagged: the\n// catalog calls this `vehicles.managers.{link,unlink}`, plural; the real SDK\n// member is singular, `vehicles.manager` — this hook follows the SDK).\n// PERSONALIZED mode-dark module (`06-capability-and-personas.md §3`) —\n// gated via `createDomainHook()`.\n//\n// DECISION: `vehicles[]` is this module's one delta-shaped, id-bearing\n// array (`SeatingBoardResponse`, `openapi/openapi.json`, verified) — a live\n// row or a `{ _tombstone, id, version, deletedAt }` row, exactly the same\n// two-branch shape `rooming.rooms[]` uses. `unassignedPool[]` items key on\n// `travellerId`, not `id`, and carry no tombstone/version branch — a\n// DERIVED projection the engine recomputes per read\n// (`kaafil-js/src/offline/pull.ts`'s `extractSectionRows` docstring, which\n// names this exact module as its second worked example). So `vehicles` is\n// read cache-first via `useSnapshotList(tripRef, 'seating')` and\n// `unassignedPool` is its own live `client.seating.read()` call, refreshed\n// explicitly — identical split to `useRooming`'s `rooms` vs\n// `unassignedPool`, for the identical reason.\n//\n// DECISION: `autoAssign` calls `client.seating.autoAssign(options)`\n// DIRECTLY, bypassing `OfflineEngine.enqueue()` — the same narrow exception\n// `useRooming.autoAssign` documents and for the same two reasons: a\n// `dryRun: true` call writes nothing to enqueue, and even `dryRun: false`'s\n// response (the computed `plan`, `perRule` outcomes with their\n// `no_seat_map` noop branch, the reasoned `unassigned[]`) cannot be\n// recovered from the one value `useOfflineMutation` can hand back\n// (`OutboxOp`), and the calling composite needs that payload synchronously.\n//\n// DECISION: `patchVehicleDays(vehicleRef, days)` — the ONE day-coverage\n// write this hook exposes (`FRD:transport-seating` `D-209`: a whole-array\n// replace, `If-Match` required, never per-day CRUD). The catalog's own\n// signature takes no `version` parameter, yet every patch on this surface\n// requires one (`PatchSeatingVehicleOptions.version`'s own doc comment: \"a\n// missing `If-Match` and a stale one both answer `409 CONFLICT_VERSION`\").\n// Squaring the two: this hook already holds the live `vehicles` cache\n// `patchVehicleDays` is called against, so it resolves the vehicle's\n// current `version` from that same cache internally rather than asking the\n// caller to thread a value the hook can read itself — the literal\n// two-argument shape the spec names stays honoured, and the `If-Match`\n// contract is still met by construction, not skipped.\n\nimport type {\n AssignSeatingOptions,\n AutoAssignSeatingOptions,\n CreateSeatingVehicleOptions,\n DeleteSeatingVehicleOptions,\n LinkSeatingManagerOptions,\n OutboxOp,\n PatchSeatingVehicleOptions,\n SeatingOccupant,\n SeatingResource,\n SeatingVehicleDeltaRow,\n UnlinkSeatingManagerOptions,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\nexport type { SeatingOccupant, SeatingVehicleDeltaRow };\n\n/** What `autoAssign` hands back — the plan, every rule's outcome, the\n * reasoned leftovers and the deltas. A composite renders it directly, so the\n * type is exported rather than inlined. */\nexport type SeatingAutoAssignResult = Awaited<ReturnType<SeatingResource['autoAssign']>>;\n\ntype AssignInput = Omit<AssignSeatingOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype AutoAssignInput = Omit<AutoAssignSeatingOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype CreateVehicleInput = Omit<\n CreateSeatingVehicleOptions,\n 'tripRef' | 'idempotencyKey' | 'signal'\n>;\ntype PatchVehicleInput = Omit<PatchSeatingVehicleOptions, 'tripRef' | 'signal'>;\ntype RemoveVehicleInput = Omit<DeleteSeatingVehicleOptions, 'tripRef' | 'signal'>;\ntype LinkManagerInput = Omit<LinkSeatingManagerOptions, 'tripRef' | 'idempotencyKey' | 'signal'>;\ntype UnlinkManagerInput = Omit<UnlinkSeatingManagerOptions, 'tripRef' | 'signal'>;\n\n/**\n * The unassigned-traveller roster — `SeatingBoardResponse.unassignedPool[]`\n * (`kaafil-js/openapi/openapi.json`, verified). See this file's header for\n * why it is its own live-fetch state rather than folded into `vehicles`.\n */\nexport interface SeatingUnassignedPool {\n readonly travellers: readonly SeatingOccupant[];\n /** `true` once at least one `client.seating.read()` call has settled\n * (success or failure). */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw — rendered differently from\n * `travellers: [], loaded: true`; those are never the same state. */\n readonly lastFetchFailed: boolean;\n /** The server time (`meta.serverTime`) of the last successful fetch. */\n readonly fetchedAt: string | undefined;\n /** Re-runs the live read. `assign` already calls this on its own\n * success; a composite calls it again after any other action that can\n * move someone in or out of the pool (e.g. a vehicle delete releasing\n * its occupants). */\n readonly refresh: () => Promise<void>;\n}\n\nexport interface SeatingReady {\n readonly vehicles: readonly SeatingVehicleDeltaRow[];\n readonly syncedAt: string | undefined;\n readonly unassignedPool: SeatingUnassignedPool;\n /** Re-reads the desk lane after a write. A NO-OP on a field device, where\n * the outbox drain emits `snapshot.updated` and the cache-first read\n * re-renders itself — a composite need not know which lane it is on. */\n readonly refreshLive: () => Promise<void>;\n // `OutboxOp | null` on all seven writes: each carries a desk `direct`\n // lane, and `null` is what it resolves to there — committed, with no\n // outbox row to hand back. Like `useRooming` and unlike `usePickups`,\n // there is no member here that lacks a direct lane, because every\n // `transport-seating` route takes the admin triple.\n readonly assign: (input: AssignInput) => Promise<OutboxOp | null>;\n readonly autoAssign: (input: AutoAssignInput) => ReturnType<SeatingResource['autoAssign']>;\n readonly createVehicle: (input: CreateVehicleInput) => Promise<OutboxOp | null>;\n readonly patchVehicle: (input: PatchVehicleInput) => Promise<OutboxOp | null>;\n readonly removeVehicle: (input: RemoveVehicleInput) => Promise<OutboxOp | null>;\n /** The one day-coverage write this hook exposes — a whole-array replace,\n * never a per-day CRUD method. See this file's header `DECISION` for why\n * this takes no `version` parameter. */\n readonly patchVehicleDays: (\n vehicleRef: string,\n days: readonly number[],\n ) => Promise<OutboxOp | null>;\n readonly linkManager: (input: LinkManagerInput) => Promise<OutboxOp | null>;\n readonly unlinkManager: (input: UnlinkManagerInput) => Promise<OutboxOp | null>;\n}\n\nconst useSeatingInternal = createDomainHook<SeatingReady>('transport-seating', (tripRef) => {\n const client = useKaafilClient();\n // CACHE-FIRST WITH A LIVE FALLBACK. A field device reads its own snapshot\n // exactly as before; a DESK console mounts no `OfflineShell` and has no\n // snapshot at all, so without this the board would render \"no vehicles\"\n // for a trip that has a full fleet. `useSnapshotList`'s own header carries\n // the argument, including why the `live` callback must never reach a\n // dependency array.\n const {\n rows: vehicles,\n syncedAt,\n refreshLive,\n } = useSnapshotList<SeatingVehicleDeltaRow>(tripRef, 'seating', {\n live: async (liveClient, ref) => {\n // The board read carries the vehicles whole, so the desk needs no\n // second call for them — and it is the same endpoint the unassigned\n // pool already uses.\n const response = await liveClient.seating.read({ tripRef: ref });\n return { rows: response.vehicles, syncedAt: response.meta.serverTime };\n },\n });\n\n const assignMutation = useOfflineMutation<AssignInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/seating/assign`,\n operationId: 'assignSeating' as never,\n body: input,\n // `SeatingAssignDto.vehicles` is \"every vehicle touched by this\n // write, whole — a client rebases without a follow-up read\" (the\n // engine DTO's own words) — up to two, on a displacement. `arrayKey`\n // is this hook's one multi-row rebase (`OutboxEntityRef.arrayKey`),\n // the reason the vehicle grid now repaints the instant an assign\n // lands rather than waiting for the next full pull.\n entity: { listName: 'seating', arrayKey: 'vehicles' },\n }),\n // The desk lane. Every `transport-seating` write takes the admin triple,\n // so unlike `usePickups` there is no member here that deliberately\n // lacks one.\n direct: (liveClient, input) => liveClient.seating.assign({ tripRef, ...input }),\n });\n\n // The unassigned pool's own live-fetch state — see `SeatingUnassignedPool`'s\n // doc comment for why this is a `client.seating.read()` call and never a\n // snapshot subscription.\n const [poolTravellers, setPoolTravellers] = useState<readonly SeatingOccupant[]>([]);\n const [poolLoaded, setPoolLoaded] = useState(false);\n const [poolFetchFailed, setPoolFetchFailed] = useState(false);\n const [poolFetchedAt, setPoolFetchedAt] = useState<string | undefined>(undefined);\n\n const refreshUnassignedPool = useCallback(async (): Promise<void> => {\n try {\n const response = await client.seating.read({ tripRef });\n setPoolTravellers(response.unassignedPool);\n setPoolLoaded(true);\n setPoolFetchFailed(false);\n setPoolFetchedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated empty roster — `loaded` stays\n // whatever it already was.\n setPoolFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshUnassignedPool();\n }, [refreshUnassignedPool]);\n\n // The pool is a PLAIN READ, so nothing re-runs it when queued seating\n // writes finally reach the server — the vehicle rows re-sync on their own\n // `snapshot.updated` while the pool keeps listing travellers who have since\n // been seated. Out of signal that gap is arbitrarily long and the screen\n // contradicts itself. One re-read per drain, for as long as this hook is\n // mounted — same shape and reason as `useItinerary`'s `refreshAfterDrain`.\n const engine = useContext(OfflineEngineContext);\n useEffect(() => {\n if (engine === null) {\n return;\n }\n const unsubscribe = engine.events.on('sync.drained', () => {\n void refreshUnassignedPool();\n });\n return unsubscribe;\n }, [engine, refreshUnassignedPool]);\n\n const assignMutate = assignMutation.mutate;\n const assign = useCallback(\n async (input: AssignInput): Promise<OutboxOp | null> => {\n const op = await assignMutate(input);\n // An assign/move/swap/unassign changes who is unassigned — re-request\n // the live pool rather than leaving it stale.\n void refreshUnassignedPool();\n return op;\n },\n [assignMutate, refreshUnassignedPool],\n );\n\n const createVehicleMutation = useOfflineMutation<CreateVehicleInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/seating/vehicles`,\n operationId: 'createSeatingVehicle' as never,\n body: input,\n }),\n direct: (liveClient, input) => liveClient.seating.vehicles.create({ tripRef, ...input }),\n });\n\n const patchVehicleMutation = useOfflineMutation<PatchVehicleInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { vehicleId, version, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}`,\n operationId: 'patchSeatingVehicle' as never,\n body,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.seating.vehicles.patch({ tripRef, ...input }),\n });\n\n const removeVehicleMutation = useOfflineMutation<RemoveVehicleInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { vehicleId, version } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}`,\n operationId: 'deleteSeatingVehicle' as never,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) => liveClient.seating.vehicles.remove({ tripRef, ...input }),\n });\n\n const removeVehicleMutate = removeVehicleMutation.mutate;\n const removeVehicle = useCallback(\n async (input: RemoveVehicleInput): Promise<OutboxOp | null> => {\n const op = await removeVehicleMutate(input);\n // A vehicle delete releases every occupant it carried back to the\n // pool — re-request the live pool the same as `assign` does.\n void refreshUnassignedPool();\n return op;\n },\n [removeVehicleMutate, refreshUnassignedPool],\n );\n\n const patchVehicleMutate = patchVehicleMutation.mutate;\n const patchVehicleDays = useCallback(\n async (vehicleRef: string, days: readonly number[]): Promise<OutboxOp | null> => {\n const current = vehicles.find(\n (row): row is Extract<SeatingVehicleDeltaRow, { id: string; version: number }> =>\n row.id === vehicleRef && !('_tombstone' in row),\n );\n if (current === undefined) {\n throw new Error(\n `patchVehicleDays: vehicle \"${vehicleRef}\" is not in the current seating cache — read the board before patching its day coverage.`,\n );\n }\n return patchVehicleMutate({\n vehicleId: vehicleRef,\n version: current.version,\n days: [...days],\n });\n },\n [patchVehicleMutate, vehicles],\n );\n\n const linkManagerMutation = useOfflineMutation<LinkManagerInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { vehicleId, ...body } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}/manager`,\n operationId: 'linkSeatingManager' as never,\n body,\n });\n },\n direct: (liveClient, input) => liveClient.seating.vehicles.manager.link({ tripRef, ...input }),\n });\n\n const unlinkManagerMutation = useOfflineMutation<UnlinkManagerInput>({\n tripRef,\n enqueue: (engine, input) => {\n const { vehicleId, version } = input;\n return engine.enqueue({\n tripRef,\n method: SyncOpMethod.Delete,\n path: `/api/v1/trips/${tripRef}/seating/vehicles/${vehicleId}/manager`,\n operationId: 'unlinkSeatingManager' as never,\n ifMatch: version,\n });\n },\n direct: (liveClient, input) =>\n liveClient.seating.vehicles.manager.unlink({ tripRef, ...input }),\n });\n\n // MEMOISED, not inline. `createDomainHook`'s `build()` re-runs on every\n // render, so an arrow written straight into the returned object is a NEW\n // function each time — and a composite that puts one in a `useEffect`\n // dependency array gets an effect that re-fires every render, sets state,\n // and re-renders. That froze a browser tab once\n // (`usePickups.spec.tsx` carries the incident and the invariant).\n const autoAssign = useCallback(\n (input: AutoAssignInput) => client.seating.autoAssign({ tripRef, ...input }),\n [client, tripRef],\n );\n\n return {\n vehicles,\n syncedAt,\n refreshLive,\n unassignedPool: {\n travellers: poolTravellers,\n loaded: poolLoaded,\n lastFetchFailed: poolFetchFailed,\n fetchedAt: poolFetchedAt,\n refresh: refreshUnassignedPool,\n },\n assign,\n autoAssign,\n createVehicle: createVehicleMutation.mutate,\n patchVehicle: patchVehicleMutation.mutate,\n removeVehicle,\n patchVehicleDays,\n linkManager: linkManagerMutation.mutate,\n unlinkManager: unlinkManagerMutation.mutate,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'transport-seating'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useSeating(tripRef: string): DomainHookResult<SeatingReady> {\n return useSeatingInternal(tripRef);\n}\n","'use client';\n\n// Manager-facing traveller profile — `travellers.getDetail`/`travellers.addNote`\n// (`kaafil-js/src/resources/travellers.ts`, added this session). No spec row\n// exists yet for this hook (the profile composite is net-new this session),\n// so its shape is derived structurally off the SDK's own resource types\n// rather than restated by hand — mirrors `useJourney.ts`'s exact pattern for\n// the read half (a single explicit-`tripRef`/`travellerRef`-scoped live GET,\n// not a cache-first list — `getDetail` carries no delta/`since` contract).\n//\n// NO CAPABILITY GATE — a traveller profile is roster data, not a\n// plan-gated module feature; every domain-specific field it surfaces\n// (room/seat/balance) is itself already gated server-side by ITS OWN\n// module (balance is `null` when the agency's plan lacks `collections` —\n// `TravellerDetailResponse.balance`'s own doc). Gating this hook a second\n// time client-side would just re-hide what the server already decided.\n//\n// WRITE. `addNote` enqueues via `useOfflineMutation`, the same \"manager\n// writes never call the SDK directly\" shape every other write in this\n// package's hook layer uses (`useParties.ts`'s `add`/`patch`/`remove` is the\n// closest precedent — a plain `POST`, idempotency-key-guarded, no\n// `If-Match` since `AddTravellerNoteRequest` carries no version to send).\n// Re-runs the read on success, same \"the write already re-requests its own\n// read\" contract `useParties.ts`/`useRooming.ts` document.\n\nimport type { OutboxOp, TravellersResource } from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineEvent } from './useOfflineEvent';\nimport { useOfflineMutation } from './useOfflineMutation';\n\nexport type TravellerProfileRead = Awaited<ReturnType<TravellersResource['getDetail']>>;\n\nexport interface AddTravellerNoteInput {\n readonly body: string;\n}\n\nexport interface TravellerProfileResult {\n readonly read: TravellerProfileRead | undefined;\n readonly readFailed: boolean;\n readonly refresh: () => Promise<void>;\n readonly addNote: (input: AddTravellerNoteInput) => Promise<OutboxOp>;\n}\n\nexport function useTravellerProfile(tripRef: string, travellerRef: string): TravellerProfileResult {\n const client = useKaafilClient();\n const [read, setRead] = useState<TravellerProfileRead | undefined>(undefined);\n const [readFailed, setReadFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.travellers.getDetail({ tripRef, travellerRef });\n setRead(response);\n setReadFailed(false);\n } catch {\n setReadFailed(true);\n }\n }, [client, tripRef, travellerRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n // `mutate()` (both here and `useCollections().record()`) resolves once the\n // write is durably ENQUEUED, not once synced — the actual HTTP call fires\n // later via the drainer's fire-and-forget `kick()` (`08-core-hooks.md\n // §2.5`'s own header comment). A `refresh()` called immediately after a\n // write resolves can race ahead of that write's own request and read\n // stale `balance`/`notes`. Subscribing to `sync.drained` — the same fix\n // `useConflicts.ts`/`useBlobStatus.ts` already use — re-reads once the\n // write has actually landed, regardless of which composite triggered it\n // (a payment via `useCollections`, a note via `addNote` below, or any\n // other write against this same `tripRef`).\n useOfflineEvent('sync.drained', refresh);\n\n const noteMutation = useOfflineMutation<AddTravellerNoteInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${tripRef}/travellers/${travellerRef}/notes`,\n operationId: 'addTravellerNote' as never,\n body: input,\n }),\n });\n\n const noteMutate = noteMutation.mutate;\n const addNote = useCallback(\n async (input: AddTravellerNoteInput): Promise<OutboxOp> => {\n const op = await noteMutate(input);\n void refresh();\n return op;\n },\n [noteMutate, refresh],\n );\n\n return { read, readFailed, refresh, addNote };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useVendors(tripRef, agencyRef)`.\n// Primary SDK surface (verified, `kaafil-js/src/resources/vendors.ts`):\n// `vendors.list` (trip-scoped, `listTripVendors`), `vendors.upsert`/`.remove`\n// (agency-scoped, GAP-005's CRUD half). PERSONALIZED mode-dark.\n//\n// Two explicit parameters is why this file does not go through\n// `createDomainHook()` (`../internal/createDomainHook.ts`'s `build` takes\n// exactly one `tripRef`) — it calls the same shared\n// `useCapabilityRows(tripRef)` the factory itself uses, directly, so the\n// gate is still the one shared implementation even though the wrapping\n// shape differs.\n//\n// `agencyRef` IS ACCEPTED BUT UNUSED (verified): `KaafilClient.vendors`\n// (`client-entry.ts`'s `boundVendors`) already auto-binds `agencyRef` from\n// the open session onto `upsert`/`remove` — the same \"wrapper supplies the\n// bound ref, delegates to the real resource method\" precedent every other\n// agency-scoped resource on the client uses (`boundJourney.triggers`,\n// `boundForms`, …). `list` is trip-scoped and never touches `agencyRef` at\n// all. The parameter stays on this hook's own signature only because\n// `08-core-hooks.md §3`'s table names it — passing a second, redundant ref\n// through call sites would be a worse API than a documented no-op.\n//\n// NOT A SNAPSHOT-LIST READ: `SYNC_PULL_SECTIONS`\n// (`kaafil-js/src/offline/pull.ts`, verified) does not include `'vendors'`.\n// `list` is therefore a live, explicitly-refreshed read — the same shape\n// `useTreks.ts`'s `board` documents for its own uncached read — never\n// claimed as offline-cached.\n//\n// STRUCTURAL ABSENCE (load-bearing, verified): this hook has NO `rate`\n// method. `GAP-005`'s rating half remains Open — no such endpoint exists —\n// and adding one here would misrepresent the API. Do not add it.\n//\n// WRITES. `upsert`/`remove` are agency-scoped CRM-directory writes, not\n// trip writes — the same posture `useJourney.ts`'s `triggers.patch` takes\n// (a live, direct SDK call, never routed through `OfflineEngine.enqueue()`,\n// since there is no `tripRef` for an outbox op to key on and no offline\n// guarantee this family's own spec asks for). Neither call is reachable\n// from a `manager` session in practice (`vendors.ts`'s own header: \"NEVER\n// `managerAuth`\") — `UnsatisfiableSchemeError` surfaces from\n// `CredentialResolver` itself if one is attempted; this hook does not\n// re-check persona before calling through.\n\nimport type {\n CreateVendorOptions,\n DeleteVendorOptions,\n UpsertVendorOptions,\n VendorsResource,\n} from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { classifyError, type ErrorClassification } from '../errors/classify';\nimport {\n darkReasonFor,\n deriveCapabilityTriple,\n UNKNOWN_CAPABILITY_TRIPLE,\n} from '../internal/deriveCapabilityTriple';\nimport { useCapabilityRows } from '../internal/useCapabilityRows';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\n\n/** One row of `vendors.list()`'s array — `VendorSummaryResponse`\n * (`kaafil-js/src/generated/schema.d.ts`, verified): `id`/`name`/`category`/\n * `phone`/`city`. `phone`/`city` are nullable — absent until the CRM feeds\n * one. Still no `status`, no `expenseTotalMinor` on the wire — a consumer\n * that needs either is reading a field this response does not send.\n * `KaafilResponse<readonly VendorSummaryResponse[]>` is `T & { meta }`\n * (`kaafil-js/src/types/meta.ts`'s own intersection, verified) — the\n * response IS the array, `meta` attached, never a nested `.data` field. */\nexport type TripVendorRow = Awaited<ReturnType<VendorsResource['list']>>[number];\n\nexport type UpsertVendorInput = Omit<\n UpsertVendorOptions,\n 'agencyRef' | 'idempotencyKey' | 'signal'\n>;\nexport type RemoveVendorInput = Omit<\n DeleteVendorOptions,\n 'agencyRef' | 'idempotencyKey' | 'signal'\n>;\n/** `create` takes neither an external id nor a `sourceUpdatedAt` — the\n * server mints the first and stamps the second. See `VendorsReady.create`. */\nexport type CreateVendorInput = Omit<\n CreateVendorOptions,\n 'agencyRef' | 'idempotencyKey' | 'signal'\n>;\n\nexport interface VendorsReady {\n readonly vendors: readonly TripVendorRow[];\n /** `true` once at least one `client.vendors.list()` call has settled\n * (success or failure) — same `loaded` contract `TrekBoardState`/\n * `RoomingUnassignedPool` document. */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw — distinct from an honest\n * empty directory (`loaded: true`, `vendors: []`). */\n readonly lastFetchFailed: boolean;\n /** The server time (`meta.serverTime`) of the last successful fetch. */\n readonly syncedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n /**\n * Agency-scoped create for a vendor the AGENCY authored, not one a CRM\n * pushed (`POST /agencies/:ref/vendors`).\n *\n * Takes NO external id and NO `sourceUpdatedAt`: `Vendor.externalId` is\n * `NOT NULL`, so before this route existed the only create path was\n * `upsert`, which is addressed by the caller's own CRM id — something an\n * operator adding a supplier by hand does not have and must not be asked\n * to invent. The server mints it (prefixed `kf-`) and stamps the write\n * with its own clock.\n */\n readonly create: (input: CreateVendorInput) => ReturnType<VendorsResource['create']>;\n /** Agency-scoped CRM upsert — see this file's header. Doubles as the EDIT\n * of an existing vendor: `sourceUpdatedAt` is optional on the wire now, and\n * omitting it has the server stamp the edit rather than letting it lose an\n * LWW comparison against the very row the operator is looking at. */\n readonly upsert: (input: UpsertVendorInput) => ReturnType<VendorsResource['upsert']>;\n /** Agency-scoped CRM soft-delete — see this file's header. */\n readonly remove: (input: RemoveVendorInput) => ReturnType<VendorsResource['remove']>;\n // NO `rate` — structurally absent, see this file's header.\n}\n\nexport function useVendors(tripRef: string, agencyRef: string): DomainHookResult<VendorsReady> {\n void agencyRef;\n const client = useKaafilClient();\n const { rows, loaded: capabilitiesLoaded } = useCapabilityRows(tripRef);\n\n const [vendors, setVendors] = useState<readonly TripVendorRow[]>([]);\n const [listLoaded, setListLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n const [syncedAt, setSyncedAt] = useState<string | undefined>(undefined);\n const [firstLoadError, setFirstLoadError] = useState<ErrorClassification | undefined>(undefined);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.vendors.list({ tripRef });\n setVendors(response);\n setListLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n setFirstLoadError(undefined);\n } catch (error) {\n // Honest failure, not a fabricated list — `listLoaded` stays whatever\n // it already was; only `lastFetchFailed` flips. Same reasoning as\n // `useTreks.ts`'s `refreshBoard`. The classified error is only ever\n // surfaced through `status: 'error'` below, for the very first load\n // — a later `refresh()` failure on an already-loaded list instead\n // stays `'ready'` with `lastFetchFailed: true`, matching\n // `useParties.ts`'s identical \"loaded once, stay usable\" contract.\n setLastFetchFailed(true);\n setFirstLoadError((previous) => previous ?? classifyError(error));\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const create = useCallback((input: CreateVendorInput) => client.vendors.create(input), [client]);\n const upsert = useCallback((input: UpsertVendorInput) => client.vendors.upsert(input), [client]);\n const remove = useCallback((input: RemoveVendorInput) => client.vendors.remove(input), [client]);\n\n if (!capabilitiesLoaded) {\n return { status: 'loading' };\n }\n const row = rows.find((candidate) => candidate.capability === 'vendors');\n const triple = row === undefined ? UNKNOWN_CAPABILITY_TRIPLE : deriveCapabilityTriple(row);\n if (triple.status !== 'lit') {\n const reason = darkReasonFor(triple);\n return { status: 'dark', reason: reason as NonNullable<typeof reason> };\n }\n\n if (!listLoaded && lastFetchFailed) {\n // `firstLoadError` is always set in the same `catch` that flips\n // `lastFetchFailed` (above) — this fallback only exists so the\n // compiler sees a total `ErrorClassification`, never because the two\n // can actually diverge at runtime.\n return {\n status: 'error',\n error: firstLoadError ?? {\n path: 'surface-to-user',\n code: undefined,\n status: undefined,\n unsatisfiableScheme: false,\n cause: undefined,\n },\n };\n }\n\n return {\n status: 'ready',\n vendors,\n loaded: listLoaded,\n lastFetchFailed,\n syncedAt,\n refresh,\n create,\n upsert,\n remove,\n };\n}\n"]}
|