# ADR-0005 Master Migration Status **Last Updated**: 2026-01-10 This document tracks the complete migration status of all data fetching patterns in the application to TanStack Query (React Query) as specified in ADR-0005. ## Migration Overview | Category | Total | Migrated | Remaining | % Complete | | ---------------------- | ------------------------ | -------- | --------- | ---------- | | **User Features** | 7 queries + 8 mutations | 15/15 | 0 | ✅ 100% | | **User Hooks** | 3 hooks | 3/3 | 0 | ✅ 100% | | **Admin Features** | 4 queries + 3 components | 7/7 | 0 | ✅ 100% | | **Analytics Features** | 3 queries + 2 components | 5/5 | 0 | ✅ 100% | | **Legacy Hooks** | 4 items | 4/4 | 0 | ✅ 100% | | **Phase 8 Queries** | 3 queries | 3/3 | 0 | ✅ 100% | | **Phase 8 Components** | 3 components | 3/3 | 0 | ✅ 100% | | **TOTAL** | 40 items | 40/40 | 0 | ✅ 100% | --- ## ✅ COMPLETED: User-Facing Features (Phase 1-3) ### Query Hooks (7) | Hook | File | Query Key | Status | Phase | | --------------------- | ------------------------------------------------------------------------------------------- | ------------------------------- | ------- | ----- | | useFlyersQuery | [src/hooks/queries/useFlyersQuery.ts](../src/hooks/queries/useFlyersQuery.ts) | `['flyers', { limit, offset }]` | ✅ Done | 1 | | useFlyerItemsQuery | [src/hooks/queries/useFlyerItemsQuery.ts](../src/hooks/queries/useFlyerItemsQuery.ts) | `['flyer-items', flyerId]` | ✅ Done | 2 | | useMasterItemsQuery | [src/hooks/queries/useMasterItemsQuery.ts](../src/hooks/queries/useMasterItemsQuery.ts) | `['master-items']` | ✅ Done | 2 | | useWatchedItemsQuery | [src/hooks/queries/useWatchedItemsQuery.ts](../src/hooks/queries/useWatchedItemsQuery.ts) | `['watched-items']` | ✅ Done | 1 | | useShoppingListsQuery | [src/hooks/queries/useShoppingListsQuery.ts](../src/hooks/queries/useShoppingListsQuery.ts) | `['shopping-lists']` | ✅ Done | 1 | | useUserAddressQuery | [src/hooks/queries/useUserAddressQuery.ts](../src/hooks/queries/useUserAddressQuery.ts) | `['user-address', addressId]` | ✅ Done | 7 | | useAuthProfileQuery | [src/hooks/queries/useAuthProfileQuery.ts](../src/hooks/queries/useAuthProfileQuery.ts) | `['auth-profile']` | ✅ Done | 7 | ### Mutation Hooks (8) | Hook | File | Invalidates | Status | Phase | | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------- | ------- | ----- | | useAddWatchedItemMutation | [src/hooks/mutations/useAddWatchedItemMutation.ts](../src/hooks/mutations/useAddWatchedItemMutation.ts) | `['watched-items']` | ✅ Done | 3 | | useRemoveWatchedItemMutation | [src/hooks/mutations/useRemoveWatchedItemMutation.ts](../src/hooks/mutations/useRemoveWatchedItemMutation.ts) | `['watched-items']` | ✅ Done | 3 | | useCreateShoppingListMutation | [src/hooks/mutations/useCreateShoppingListMutation.ts](../src/hooks/mutations/useCreateShoppingListMutation.ts) | `['shopping-lists']` | ✅ Done | 3 | | useDeleteShoppingListMutation | [src/hooks/mutations/useDeleteShoppingListMutation.ts](../src/hooks/mutations/useDeleteShoppingListMutation.ts) | `['shopping-lists']` | ✅ Done | 3 | | useAddShoppingListItemMutation | [src/hooks/mutations/useAddShoppingListItemMutation.ts](../src/hooks/mutations/useAddShoppingListItemMutation.ts) | `['shopping-lists']` | ✅ Done | 3 | | useUpdateShoppingListItemMutation | [src/hooks/mutations/useUpdateShoppingListItemMutation.ts](../src/hooks/mutations/useUpdateShoppingListItemMutation.ts) | `['shopping-lists']` | ✅ Done | 3 | | useRemoveShoppingListItemMutation | [src/hooks/mutations/useRemoveShoppingListItemMutation.ts](../src/hooks/mutations/useRemoveShoppingListItemMutation.ts) | `['shopping-lists']` | ✅ Done | 3 | | useGeocodeMutation | [src/hooks/mutations/useGeocodeMutation.ts](../src/hooks/mutations/useGeocodeMutation.ts) | N/A | ✅ Done | 7 | ### Providers Migrated (5) | Provider | Uses | Status | | ------------------------------------------------------------------- | -------------------------------------------- | ------- | | [AppProviders.tsx](../src/providers/AppProviders.tsx) | QueryClientProvider wrapper | ✅ Done | | [FlyersProvider.tsx](../src/providers/FlyersProvider.tsx) | useFlyersQuery | ✅ Done | | [MasterItemsProvider.tsx](../src/providers/MasterItemsProvider.tsx) | useMasterItemsQuery | ✅ Done | | [UserDataProvider.tsx](../src/providers/UserDataProvider.tsx) | useWatchedItemsQuery + useShoppingListsQuery | ✅ Done | | [AuthProvider.tsx](../src/providers/AuthProvider.tsx) | useAuthProfileQuery | ✅ Done | --- ## ✅ COMPLETED: Admin Features (Phase 5) ### Admin Query Hooks (4) | Hook | File | Query Key | Status | Phase | | ---------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------- | ----- | | useActivityLogQuery | [src/hooks/queries/useActivityLogQuery.ts](../src/hooks/queries/useActivityLogQuery.ts) | `['activity-log', { limit, offset }]` | ✅ Done | 5 | | useApplicationStatsQuery | [src/hooks/queries/useApplicationStatsQuery.ts](../src/hooks/queries/useApplicationStatsQuery.ts) | `['application-stats']` | ✅ Done | 5 | | useSuggestedCorrectionsQuery | [src/hooks/queries/useSuggestedCorrectionsQuery.ts](../src/hooks/queries/useSuggestedCorrectionsQuery.ts) | `['suggested-corrections']` | ✅ Done | 5 | | useCategoriesQuery | [src/hooks/queries/useCategoriesQuery.ts](../src/hooks/queries/useCategoriesQuery.ts) | `['categories']` | ✅ Done | 5 | ### Admin Components Migrated (3) | Component | Uses | Status | | ------------------------------------------------------------- | --------------------------------------------------------------------- | ------- | | [ActivityLog.tsx](../src/pages/admin/ActivityLog.tsx) | useActivityLogQuery | ✅ Done | | [AdminStatsPage.tsx](../src/pages/admin/AdminStatsPage.tsx) | useApplicationStatsQuery | ✅ Done | | [CorrectionsPage.tsx](../src/pages/admin/CorrectionsPage.tsx) | useSuggestedCorrectionsQuery, useMasterItemsQuery, useCategoriesQuery | ✅ Done | --- ## ✅ COMPLETED: Analytics Features (Phase 6) ### Analytics Query Hooks (3) | Hook | File | Query Key | Status | Phase | | --------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------- | ------- | ----- | | useBestSalePricesQuery | [src/hooks/queries/useBestSalePricesQuery.ts](../src/hooks/queries/useBestSalePricesQuery.ts) | `['best-sale-prices']` | ✅ Done | 6 | | useFlyerItemsForFlyersQuery | [src/hooks/queries/useFlyerItemsForFlyersQuery.ts](../src/hooks/queries/useFlyerItemsForFlyersQuery.ts) | `['flyer-items-batch', flyerIds]` | ✅ Done | 6 | | useFlyerItemCountQuery | [src/hooks/queries/useFlyerItemCountQuery.ts](../src/hooks/queries/useFlyerItemCountQuery.ts) | `['flyer-item-count', flyerIds]` | ✅ Done | 6 | ### Analytics Components/Hooks Migrated (2) | Component/Hook | Uses | Status | | ----------------------------------------------------- | --------------------------------------------------- | ------- | | [MyDealsPage.tsx](../src/pages/MyDealsPage.tsx) | useBestSalePricesQuery | ✅ Done | | [useActiveDeals.tsx](../src/hooks/useActiveDeals.tsx) | useFlyerItemsForFlyersQuery, useFlyerItemCountQuery | ✅ Done | **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) ### Low Priority - Voice Lab | Feature | Component | Current Pattern | Priority | | ------------- | ------------------------------------------------- | ------------------ | -------- | | **Voice Lab** | [VoiceLabPage.tsx](../src/pages/VoiceLabPage.tsx) | Direct async/await | 🟢 LOW | **Notes:** - Event-driven API calls (not data fetching) - Speech generation and voice sessions - Mutation-like operations, not query-like - Could create mutations but not critical for caching --- ## ✅ COMPLETED: Legacy Hook Cleanup (Phase 7) ### Hooks Removed | Hook | Former File | Replaced By | Status | | ----------------- | ------------------------------ | -------------------- | ---------- | | **useApi** | ~~src/hooks/useApi.ts~~ | TanStack Query hooks | ✅ Removed | | **useApiOnMount** | ~~src/hooks/useApiOnMount.ts~~ | TanStack Query hooks | ✅ Removed | ### Additional Hooks Created (Phase 7) | Hook | File | Purpose | | ------------------- | ----------------------------------------------------------------------------------------- | -------------------------------- | | useUserAddressQuery | [src/hooks/queries/useUserAddressQuery.ts](../src/hooks/queries/useUserAddressQuery.ts) | Fetch user address by ID | | useAuthProfileQuery | [src/hooks/queries/useAuthProfileQuery.ts](../src/hooks/queries/useAuthProfileQuery.ts) | Fetch authenticated user profile | | useGeocodeMutation | [src/hooks/mutations/useGeocodeMutation.ts](../src/hooks/mutations/useGeocodeMutation.ts) | Geocode address strings | ### Files Modified (Phase 7) | File | Change | | --------------------------------------------------------- | ---------------------------------------------------------- | | [useProfileAddress.ts](../src/hooks/useProfileAddress.ts) | Refactored to use useUserAddressQuery + useGeocodeMutation | | [AuthProvider.tsx](../src/providers/AuthProvider.tsx) | Refactored to use useAuthProfileQuery | --- ## 📊 MIGRATION PHASES ### ✅ Phase 1: Core Queries (Complete) - Infrastructure setup (QueryClientProvider) - Flyers, Watched Items, Shopping Lists queries - Providers refactored ### ✅ Phase 2: Additional Queries (Complete) - Master Items query - Flyer Items query - Per-resource caching strategies ### ✅ Phase 3: Mutations (Complete) - All watched items mutations - All shopping list mutations - Automatic cache invalidation ### ✅ Phase 4: Hook Refactoring (Complete) - [x] Refactor useWatchedItems to use mutation hooks - [x] Refactor useShoppingLists to use mutation hooks - [x] Remove deprecated setters from context ### ✅ Phase 5: Admin Features (Complete) - [x] Create useActivityLogQuery - [x] Create useApplicationStatsQuery - [x] Create useSuggestedCorrectionsQuery - [x] Create useCategoriesQuery - [x] Migrate ActivityLog.tsx - [x] Migrate AdminStatsPage.tsx - [x] Migrate CorrectionsPage.tsx ### ✅ Phase 6: Analytics Features (Complete - 2026-01-10) - [x] Create useBestSalePricesQuery - [x] Create useFlyerItemsForFlyersQuery - [x] Create useFlyerItemCountQuery - [x] Migrate MyDealsPage.tsx - [x] Refactor useActiveDeals to use TanStack Query ### ✅ Phase 7: Cleanup (Complete - 2026-01-10) - [x] Create useUserAddressQuery - [x] Create useAuthProfileQuery - [x] Create useGeocodeMutation - [x] Migrate useProfileAddress from useApi to TanStack Query - [x] Migrate AuthProvider from useApi to TanStack Query - [x] Remove useApi hook - [x] Remove useApiOnMount hook ### ✅ Phase 8: Additional Component Migration (Complete - 2026-01-10) - [x] Create useUserProfileDataQuery (combined profile + achievements) - [x] Create useLeaderboardQuery (public leaderboard data) - [x] Create usePriceHistoryQuery (historical price data for watched items) - [x] Refactor useUserProfileData to use TanStack Query - [x] Refactor Leaderboard.tsx to use useLeaderboardQuery - [x] Refactor PriceHistoryChart.tsx to use usePriceHistoryQuery --- ## 🎉 MIGRATION COMPLETE The TanStack Query migration is **100% complete**. All data fetching in the application now uses TanStack Query for: - **Automatic caching** - Server data is cached and shared across components - **Background refetching** - Stale data is automatically refreshed - **Loading/error states** - Consistent handling across the entire application - **Cache invalidation** - Mutations automatically invalidate related queries - **DevTools** - React Query DevTools available in development mode --- ## 📝 NOTES ### Query Key Organization Currently using literal strings for query keys. Consider creating a centralized query keys file: ```typescript // src/config/queryKeys.ts export const queryKeys = { flyers: (limit: number, offset: number) => ['flyers', { limit, offset }] as const, flyerItems: (flyerId: number) => ['flyer-items', flyerId] as const, masterItems: () => ['master-items'] as const, watchedItems: () => ['watched-items'] as const, shoppingLists: () => ['shopping-lists'] as const, // Add admin keys activityLog: (limit: number, offset: number) => ['activity-log', { limit, offset }] as const, applicationStats: () => ['application-stats'] as const, suggestedCorrections: () => ['suggested-corrections'] as const, categories: () => ['categories'] as const, bestSalePrices: (itemIds: number[]) => ['best-sale-prices', itemIds] as const, }; ``` ### Cache Invalidation Strategy Admin features may need different invalidation strategies: - Activity log should refetch after mutations - Stats should refetch after significant operations - Corrections should refetch after approving/rejecting ### Stale Time Recommendations | Data Type | Stale Time | Reasoning | | ----------------- | ---------- | ----------------------------------- | | Master Items | 10 minutes | Rarely changes | | Categories | 10 minutes | Rarely changes | | Flyers | 2 minutes | Moderate changes | | Flyer Items | 5 minutes | Static once created | | User Lists | 1 minute | Frequent changes | | Admin Stats | 2 minutes | Moderate changes | | Activity Log | 30 seconds | Frequently updated | | Corrections | 1 minute | Moderate changes | | Best Prices | 2 minutes | Recalculated periodically | | User Profile Data | 5 minutes | User-specific, changes infrequently | | Leaderboard | 2 minutes | Public data, moderate updates | | Price History | 10 minutes | Historical data, rarely changes | --- ## 📚 DOCUMENTATION - [ADR-0005 Main Document](../docs/adr/0005-frontend-state-management-and-server-cache-strategy.md) - [Phase 1 Implementation Plan](./adr-0005-implementation-plan.md) - [Phase 2 Summary](./adr-0005-phase-2-summary.md) - [Phase 3 Summary](./adr-0005-phase-3-summary.md) - [This Document](./adr-0005-master-migration-status.md)