TanStack Query Strategy
Boundary
- Context = app state
- TanStack Query = server state
Where to use Query
- users list/detail
- maintenance list/detail
- analytics datasets
- logs/audit pagination and filters
Key rules
- Use stable query keys from
src/query/keys.ts(domain-first) - Keep hooks domain-local (e.g.
domains/shared/pages/users/queries/*) - Invalidate only affected keys on mutation
- Do not put query cache into context
Query client
Configured in src/lib/query/client.ts and provided via AppContextProvider.
Users pattern (reference implementation)
- Keys:
queryKeys.users.list(params)queryKeys.users.detail(userId)
- Queries:
useUsersListQuery(params)indomains/shared/pages/users/queries/useUsersListQuery.tsuseUserDetailQuery(userId)indomains/shared/pages/users/queries/useUserDetailQuery.ts
- Mutations:
useCreateUserMutationuseUpdateUserPermissionsMutationuseSuspendUserMutationuseActivateUserMutationuseResetVerificationMutation
- Invalidation contract:
- list-changing actions invalidate
queryKeys.users.lists() - detail-changing actions invalidate
queryKeys.users.detail(userId)and only related lists
- list-changing actions invalidate
Extensibility rules for future tech
- Add new server-state tools (streaming, realtime sync, background sync) behind domain hooks, not inside pages.
- Keep transport in service modules (
lib/services/*), keep caching/invalidation in query hooks. - If a new library is introduced, preserve the same boundaries:
- page = UI wiring
- hook = data lifecycle
- service = HTTP transport and typing