Skip to content

Add React Query DevTools and structured query-key factory to prevent cache key collisions #38

Description

@prodbycorne

Problem

src/hooks/useSorobanQuery.ts defines query keys as plain string constants (QUERY_KEYS.POOLS, QUERY_KEYS.USER_POSITION). As more queries are added (platform stats, boost config, leaderboard, credits, history) these flat keys will collide — e.g. useUserPosition('pool-a') and useUserPosition('pool-b') both use the key ['userPosition', poolId, publicKey] but if publicKey changes and the old queries are not invalidated correctly, stale data from a previous wallet session can bleed into the new session.

Acceptance Criteria

  • src/lib/queryKeys.ts exports a type-safe query key factory using the pattern from TanStack Query docs:
    export const queryKeys = {
      pools: () => ['pools'] as const,
      userPosition: (poolId: string, publicKey: string) => ['userPosition', poolId, publicKey] as const,
      userCredits: (poolId: string, publicKey: string) => ['userCredits', poolId, publicKey] as const,
      platformStats: () => ['platformStats'] as const,
      boostConfig: (poolId: string) => ['boostConfig', poolId] as const,
      leaderboard: (sortKey: string, page: number) => ['leaderboard', sortKey, page] as const,
    }
  • All useQuery and queryClient.invalidateQueries call sites in useSorobanQuery.ts switch to this factory
  • When publicKey changes in StellarWalletContext, a useEffect calls queryClient.removeQueries({ queryKey: ['userPosition'] }) and queryClient.removeQueries({ queryKey: ['userCredits'] }) so the previous wallet's data is never shown to the next connected wallet
  • ReactQueryDevtools imported from @tanstack/react-query-devtools is rendered inside AppShell.tsx only when process.env.NODE_ENV === 'development' (zero bundle cost in production via next/dynamic with ssr: false)
  • A Vitest test changes publicKey and verifies the user-scoped cache entries are removed

Relevant Files

  • src/lib/queryKeys.ts — create
  • src/hooks/useSorobanQuery.ts — migrate to key factory
  • src/context/StellarWalletContext.tsx — add queryClient.removeQueries on disconnect
  • src/components/AppShell/AppShell.tsx — lazy DevTools

Metadata

Metadata

Labels

Official CampaignCampaign: Official CampaignfarmFarming/staking flow — deposit, lock, unlock, creditshardRequires deep domain knowledge — Soroban, Stellar SDK, or complex stateperformanceRendering performance, caching, or bundle size

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions