Query Cache Migration Plan
Goal
Standardize TanStack Query usage across the app so that:- every query key comes from one shared factory
- every user-scoped query includes
userIdat index[1] - every read uses a
useQueryhook underhooks/queries/ - every write uses a
useMutationhook underhooks/mutations/ - invalidation is intentional, minimal, and type-safe
- cache behavior is documented in
AGENTS.mdand becomes the default pattern for future work
Problem Summary
The current codebase has several related issues:- query keys are scattered as inline arrays across hooks, components, and pages
- many user-specific queries are not user-scoped, which creates cross-user cache leakage risk
queryClient.clear()is being used as a broad safety net inlib/react-query.tsx- writes are implemented inconsistently, with many raw
fetchcalls inside components/pages - invalidation blocks often overlap and refetch the same query multiple times
- there is no single registry for root cache key names, which increases the chance of typos and drift
Target Architecture
1. Uppercase cache key registry
Createlib/cache-keys.ts as the single source of truth for root key names.
This should be an uppercase registry such as CACHE_KEYS, used in an enum-like way. We should keep it as a constant object rather than a TypeScript enum so it stays aligned with the project rule to prefer unions/constants over enums.
Example:
2. Shared query key factory
Createlib/query-keys.ts with:
globalKeysfor non-user datauserKeys(userId)for user-scoped data
userId at index [1].
3. Hook-only data layer
- reads belong in
hooks/queries/ - writes belong in
hooks/mutations/ - pages and components should not call
fetchdirectly for app data
4. Standard mutation policy
Use the same mutation pattern across the repo:setQueryData and setQueriesData to keep mutation behavior consistent and easier to audit.
Workstreams
Phase 0: Foundations
Deliverables:lib/cache-keys.tslib/query-keys.ts- documentation set under
docs/react-query/
- all root key names come from
CACHE_KEYS - new key arrays are composed only in
lib/query-keys.ts
Phase 1: Query hook migration
Scope:- migrate all query hooks to
globalKeysoruserKeys(userId) - remove local key factories such as
createQueryKeys - ensure every user-scoped query includes
userId
- no inline
queryKey: [...]in query hooks - no user-specific query missing
userIdin the key
Phase 2: Mutation and fetch standardization
Scope:- move all raw write-side
fetchcalls intohooks/mutations/ - move all raw read-side
fetchcalls intohooks/queries/ - replace component/page mutation logic with hook usage
- replace
setQueryDataandsetQueriesDatawithinvalidateQueriesin mutation flows
- no page/component should own app-data mutation logic directly
- no mutation should rely on
setQueryDataorsetQueriesData
Phase 3: Invalidation audit and cleanup
Scope:- review every
invalidateQueriesusage file by file - remove overlapping invalidations
- keep
refetchQueriesonly where immediate UX requires it
- each invalidation block is justified by dependent data
- redundant cases like multiple invalidations for the same active query are removed
Phase 4: Query client provider cleanup
Scope:- replace full-cache
queryClient.clear()with targeted removal of user-scoped queries - preserve global cache where appropriate across sign-in/sign-out transitions
- user-scoped cache is removed safely on user switch
- global/public cache is not unnecessarily destroyed
Phase 5: Documentation and guardrails
Scope:- document the rules in
AGENTS.md - add grep-based or lint-style checks where practical
- future query/mutation work follows the documented pattern
- regressions are easier to catch during review
PR Breakdown
Suggested PR order:- Foundation files and docs
- Core query hook migration
- Remaining query hook migration by domain
- Mutation hook migration
- Component/page fetch extraction
- Invalidation audit and cleanup
- Query client provider cleanup
AGENTS.mdupdate and guardrails
Detailed Docs
docs/react-query/01-CACHE-KEY-REGISTRY.mddocs/react-query/02-QUERY-HOOK-MIGRATION.mddocs/react-query/03-MUTATION-STANDARDIZATION.mddocs/react-query/04-INVALIDATION-AUDIT.mddocs/react-query/05-PROVIDER-AND-AGENTS-UPDATE.md
Verification
npm run build- smoke test authenticated flows
- mutation test on accounts/holdings/net-worth paths
- React Query DevTools inspection of key shapes
- multi-user sign-out/sign-in validation
- grep review for inline keys and raw component/page
fetchusage