Skip to content

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) in domains/shared/pages/users/queries/useUsersListQuery.ts
    • useUserDetailQuery(userId) in domains/shared/pages/users/queries/useUserDetailQuery.ts
  • Mutations:
    • useCreateUserMutation
    • useUpdateUserPermissionsMutation
    • useSuspendUserMutation
    • useActivateUserMutation
    • useResetVerificationMutation
  • Invalidation contract:
    • list-changing actions invalidate queryKeys.users.lists()
    • detail-changing actions invalidate queryKeys.users.detail(userId) and only related lists

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