Files
flyer-crawler.projectium.com/docs/adr/0005-frontend-state-management-and-server-cache-strategy.md
Torben Sorensen 2913c7aa09
Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 1m1s
tanstack
2026-01-10 03:20:40 -08:00

13 KiB

ADR-005: Frontend State Management and Server Cache Strategy

Date: 2025-12-12 Implementation Date: 2026-01-08

Status: Accepted and Fully Implemented (Phases 1-8 complete, 100% coverage)

Context

The frontend currently uses React's built-in hooks (useState, useEffect, useContext) for state management, as seen in useAuth.tsx. While effective for simple cases, this manual approach becomes complex and error-prone when fetching, caching, and synchronizing data with the server. It often leads to custom logic for loading states, errors, re-fetching, and optimistic updates.

Decision

We will adopt a dedicated library for managing server state, such as TanStack Query (formerly React Query) or SWR, for all server-side data fetching on the client. This will abstract away the complexities of caching, background re-validation, and request deduplication.

Consequences

Positive: Leads to a more performant, predictable, and simpler frontend codebase. Standardizes how the client-side communicates with the server and handles loading/error states. Improves user experience through intelligent caching. Negative: Introduces a new frontend dependency. Requires a learning curve for developers unfamiliar with the library. Requires refactoring of existing data-fetching logic.

Implementation Status

Phase 1: Infrastructure & Core Queries ( Complete - 2026-01-08)

Files Created:

Files Modified:

Benefits Achieved:

  • Removed ~150 lines of custom state management code
  • Automatic caching of server data
  • Background refetching for stale data
  • React Query Devtools available in development
  • Automatic data invalidation on user logout
  • Better error handling and loading states

Phase 2: Remaining Queries ( Complete - 2026-01-08)

Files Created:

Files Modified:

Benefits Achieved:

  • Removed additional ~50 lines of custom state management code
  • Per-flyer item caching (items cached separately for each flyer)
  • Longer cache times for infrequently changing data (master items)
  • Automatic query disabling when dependencies are not met

Phase 3: Mutations ( Complete - 2026-01-08)

Files Created:

Benefits Achieved:

  • Standardized mutation pattern across all data modifications
  • Automatic cache invalidation after successful mutations
  • Built-in success/error notifications
  • Consistent error handling
  • Full TypeScript type safety
  • Comprehensive documentation with usage examples

See: plans/adr-0005-phase-3-summary.md for detailed documentation

Phase 4: Hook Refactoring ( Complete)

Goal: Refactor user-facing hooks to use TanStack Query mutation hooks.

Files Modified:

Benefits Achieved:

  • Both hooks now use TanStack Query mutations
  • Automatic cache invalidation after mutations
  • Consistent error handling via mutation hooks
  • Clean context interface (read-only server state)
  • Backward compatible API for hook consumers

Phase 5: Admin Features ( Complete)

Goal: Create query hooks for admin features.

Files Created:

Components Migrated:

Benefits Achieved:

  • Automatic caching of admin data
  • Parallel fetching (CorrectionsPage fetches 3 queries simultaneously)
  • Consistent stale times (30s to 2 min based on data volatility)
  • Shared cache across components (useMasterItemsQuery reused)

Phase 6: Analytics Features ( Complete - 2026-01-10)

Goal: Migrate analytics and deals features.

Files Created:

Files Modified:

Benefits Achieved:

  • Removed useApi dependency from analytics features
  • Automatic caching of deal data (2-5 minute stale times)
  • Consistent error handling via TanStack Query
  • Batch fetching for flyer items (single query for multiple flyers)

Phase 7: Cleanup ( Complete - 2026-01-10)

Goal: Remove legacy hooks once migration is complete.

Files Created:

Files Modified:

Files Removed:

  • src/hooks/useApi.ts - Legacy hook removed
  • src/hooks/useApi.test.ts - Test file removed
  • src/hooks/useApiOnMount.ts - Legacy hook removed
  • src/hooks/useApiOnMount.test.ts - Test file removed

Benefits Achieved:

  • Removed all legacy useApi and useApiOnMount hooks
  • Complete TanStack Query coverage for all data fetching
  • Consistent error handling across the entire application
  • Unified caching strategy for all server state

Phase 8: Additional Component Migration ( Complete - 2026-01-10)

Goal: Migrate remaining components with manual data fetching to TanStack Query.

Files Created:

Files Modified:

Benefits Achieved:

  • Parallel fetching for profile + achievements data
  • Public leaderboard cached with 2-minute stale time
  • Price history cached with 10-minute stale time (data changes infrequently)
  • Backward-compatible setProfile function via queryClient.setQueryData
  • Stable query keys with sorted IDs for price history

Migration Status

Current Coverage: 100% complete

Category Total Migrated Status
Query Hooks (User) 7 7 100%
Query Hooks (Admin) 4 4 100%
Query Hooks (Analytics) 3 3 100%
Query Hooks (Phase 8) 3 3 100%
Mutation Hooks 8 8 100%
User Hooks 2 2 100%
Analytics Features 2 2 100%
Component Migration (Phase 8) 3 3 100%
Legacy Hook Cleanup 4 4 100%

Completed:

  • Core query hooks (flyers, flyerItems, masterItems, watchedItems, shoppingLists)
  • Admin query hooks (activityLog, applicationStats, suggestedCorrections, categories)
  • Analytics query hooks (bestSalePrices, flyerItemsForFlyers, flyerItemCount)
  • Auth/Profile query hooks (authProfile, userAddress)
  • Phase 8 query hooks (userProfileData, leaderboard, priceHistory)
  • All mutation hooks (watched items, shopping lists, geocode)
  • Provider refactoring (AppProviders, FlyersProvider, MasterItemsProvider, UserDataProvider, AuthProvider)
  • User hooks refactoring (useWatchedItems, useShoppingLists, useProfileAddress, useUserProfileData)
  • Admin component migration (ActivityLog, AdminStatsPage, CorrectionsPage)
  • Analytics features (MyDealsPage, useActiveDeals)
  • Component migration (Leaderboard, PriceHistoryChart)
  • Legacy hooks removed (useApi, useApiOnMount)

See plans/adr-0005-master-migration-status.md for complete tracking of all components.

Implementation Guide

See plans/adr-0005-implementation-plan.md for detailed implementation steps.