mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 16:19:01 +00:00
docs(adr): record ADR 0001 for query-broadcast-client-experimental
This commit is contained in:
parent
62a51a163c
commit
7de3adc5bb
1 changed files with 73 additions and 0 deletions
73
docs/adr/0001-query-broadcast-client.md
Normal file
73
docs/adr/0001-query-broadcast-client.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# 0001. Cross-tab QueryClient sync via `@tanstack/query-broadcast-client-experimental`
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
The SeaHaven admin SPA is frequently used with multiple browser tabs open
|
||||
against the same work-order board (e.g. a dispatcher triaging the board in one
|
||||
tab while editing a work order in another). Each tab owns its own TanStack
|
||||
Query `QueryClient` cache, so a mutation performed in one tab (status change,
|
||||
dispatch creation, comment, vendor patch, etc.) does not invalidate or update
|
||||
the cache in sibling tabs. Users were seeing stale board/detail data until a
|
||||
manual refresh or the next background refetch.
|
||||
|
||||
We need a way to keep `QueryClient` caches roughly in sync across tabs of the
|
||||
same origin, without introducing a new state-management layer (Redux is
|
||||
disallowed by this repo's conventions) or a server-push mechanism.
|
||||
|
||||
## Decision
|
||||
|
||||
Use TanStack's own experimental broadcast client,
|
||||
[`@tanstack/query-broadcast-client-experimental`](https://tanstack.com/query),
|
||||
wired up in a single dedicated setup module,
|
||||
`src/lib/query/setup-query-broadcast.ts`. The module:
|
||||
|
||||
- Wraps `broadcastQueryClient({ queryClient, broadcastChannel })`, keyed to a
|
||||
single named channel (`seahaven-admin-query`).
|
||||
- No-ops outside the browser (SSR/build) and under Vitest (`import.meta.env.MODE
|
||||
=== "test"`), so it never runs in unit tests or node-based tooling.
|
||||
- Is invoked once from `src/lib/query/query-client.ts` against the app's
|
||||
singleton `QueryClient`, so every tab that loads the SPA subscribes to the
|
||||
same channel automatically — no per-feature wiring required.
|
||||
|
||||
This piggybacks on the query cache we already have (no parallel store), uses
|
||||
the library that owns the `QueryClient` we already depend on, and requires
|
||||
close to zero application code (~20 lines) to adopt.
|
||||
|
||||
### Alternatives considered
|
||||
|
||||
- **Custom `BroadcastChannel` + manual `queryClient.invalidateQueries` calls**
|
||||
— full control over payloads, but requires hand-rolling
|
||||
serialization/versioning of query keys and mutation results, and keeping
|
||||
every future mutation hook wired to broadcast. More code to own and more
|
||||
surface area for subtle cache-desync bugs.
|
||||
- **No cross-tab sync** — simplest option, but leaves the stale-tab UX problem
|
||||
unresolved; users would need to manually refresh or wait for
|
||||
`refetchOnWindowFocus`/`staleTime` to catch up, which is not reliable enough
|
||||
for a live dispatch board.
|
||||
- **Full WebSocket-based real-time sync** — solves both cross-tab and
|
||||
cross-user staleness, but is a materially larger investment (server-side
|
||||
push infra, connection lifecycle, auth over the socket) that is out of scope
|
||||
for the current admin SPA and not justified by the actual problem (same
|
||||
browser, same user, same origin).
|
||||
|
||||
## Consequences
|
||||
|
||||
- **Positive**: sibling tabs reflect mutations (status changes, dispatch
|
||||
actions, comments, patches) without a manual refresh; the integration is
|
||||
isolated to one setup file and does not touch domain/query-key code.
|
||||
- **Risk — package lifecycle**: the dependency is explicitly "experimental" in
|
||||
the TanStack ecosystem; its API may change or be deprecated between minor
|
||||
versions. We pin a specific version in `package.json` and re-evaluate on
|
||||
every TanStack Query upgrade.
|
||||
- **Risk — same-origin only**: `BroadcastChannel` only syncs tabs on the same
|
||||
origin; it does not sync across different users/sessions or devices. This is
|
||||
acceptable for the current requirement (single user, multiple tabs).
|
||||
- **Rollback plan**: remove the `@tanstack/query-broadcast-client-experimental`
|
||||
dependency from `package.json` and delete the call to `setupQueryBroadcast`
|
||||
in `src/lib/query/query-client.ts` (and the `setup-query-broadcast.ts` module
|
||||
itself). No other code depends on it, so rollback is a single, isolated
|
||||
change with no data migration.
|
||||
Loading…
Add table
Reference in a new issue