9.0 KiB
ADR-005: Frontend State Management and Server Cache Strategy
Date: 2025-12-12 Implementation Date: 2026-01-08
Status: Accepted and Implemented (Phases 1-5 complete, user + admin features migrated)
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:
- src/config/queryClient.ts - Global QueryClient configuration
- src/hooks/queries/useFlyersQuery.ts - Flyers data query
- src/hooks/queries/useWatchedItemsQuery.ts - Watched items query
- src/hooks/queries/useShoppingListsQuery.ts - Shopping lists query
Files Modified:
- src/providers/AppProviders.tsx - Added QueryClientProvider wrapper
- src/providers/FlyersProvider.tsx - Refactored to use TanStack Query
- src/providers/UserDataProvider.tsx - Refactored to use TanStack Query
- src/services/apiClient.ts - Added pagination params to fetchFlyers
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:
- src/hooks/queries/useMasterItemsQuery.ts - Master grocery items query
- src/hooks/queries/useFlyerItemsQuery.ts - Flyer items query
Files Modified:
- src/providers/MasterItemsProvider.tsx - Refactored to use TanStack Query
- src/hooks/useFlyerItems.ts - Refactored to use TanStack Query
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:
- src/hooks/mutations/useAddWatchedItemMutation.ts - Add watched item mutation
- src/hooks/mutations/useRemoveWatchedItemMutation.ts - Remove watched item mutation
- src/hooks/mutations/useCreateShoppingListMutation.ts - Create shopping list mutation
- src/hooks/mutations/useDeleteShoppingListMutation.ts - Delete shopping list mutation
- src/hooks/mutations/useAddShoppingListItemMutation.ts - Add shopping list item mutation
- src/hooks/mutations/useUpdateShoppingListItemMutation.ts - Update shopping list item mutation
- src/hooks/mutations/useRemoveShoppingListItemMutation.ts - Remove shopping list item mutation
- src/hooks/mutations/index.ts - Barrel export for all mutation hooks
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 - 2026-01-08)
Files Modified:
- src/hooks/useWatchedItems.tsx - Refactored to use mutation hooks
- src/hooks/useShoppingLists.tsx - Refactored to use mutation hooks
- src/contexts/UserDataContext.ts - Removed deprecated setters
- src/providers/UserDataProvider.tsx - Removed setter stub implementations
Benefits Achieved:
- ✅ Removed 52 lines of code from custom hooks (-17%)
- ✅ Eliminated all
useApidependencies from user-facing hooks - ✅ Removed 150+ lines of manual state management
- ✅ Simplified useShoppingLists by 21% (222 → 176 lines)
- ✅ Maintained backward compatibility for hook consumers
- ✅ Cleaner context interface (read-only server state)
See: plans/adr-0005-phase-4-summary.md for detailed documentation
Phase 5: Admin Features (✅ Complete - 2026-01-08)
Files Created:
- src/hooks/queries/useActivityLogQuery.ts - Activity log query with pagination
- src/hooks/queries/useApplicationStatsQuery.ts - Application statistics query
- src/hooks/queries/useSuggestedCorrectionsQuery.ts - Corrections query
- src/hooks/queries/useCategoriesQuery.ts - Categories query (public endpoint)
Files Modified:
- src/pages/admin/ActivityLog.tsx - Refactored to use TanStack Query
- src/pages/admin/AdminStatsPage.tsx - Refactored to use TanStack Query
- src/pages/admin/CorrectionsPage.tsx - Refactored to use TanStack Query
Benefits Achieved:
- ✅ Removed 121 lines from admin components (-32%)
- ✅ Eliminated manual state management from all admin queries
- ✅ Automatic parallel fetching (CorrectionsPage fetches 3 queries simultaneously)
- ✅ Consistent caching strategy across all admin features
- ✅ Smart refetching with appropriate stale times (30s to 1 hour)
- ✅ Shared cache across components (useMasterItemsQuery reused)
See: plans/adr-0005-phase-5-summary.md for detailed documentation
Phase 6: Cleanup (🔄 In Progress - 2026-01-08)
Completed:
- ✅ Removed custom useInfiniteQuery hook (not used in production)
- ✅ Analyzed remaining useApi/useApiOnMount usage
Remaining:
- ⏳ Migrate auth features (AuthProvider, AuthView, ProfileManager) from useApi to TanStack Query
- ⏳ Migrate useActiveDeals from useApi to TanStack Query
- ⏳ Migrate AdminBrandManager from useApiOnMount to TanStack Query
- ⏳ Consider removal of useApi/useApiOnMount hooks once fully migrated
- ⏳ Update all tests for migrated features
Note: useApi and useApiOnMount are still actively used in 6 production files for authentication, profile management, and some admin features. Full migration of these critical features requires careful planning and is documented as future work.
Migration Status
Current Coverage: 85% complete
- ✅ User Features: 100% - All core user-facing features fully migrated (queries + mutations + hooks)
- ✅ Admin Features: 100% - Activity log, stats, corrections now use TanStack Query
- ⏳ Auth/Profile Features: 0% - Auth provider, profile manager still use useApi
- ⏳ Analytics Features: 0% - Active Deals need migration
- ⏳ Brand Management: 0% - AdminBrandManager still uses 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.