Files
flyer-crawler.projectium.com/plans/adr-0005-master-migration-status.md
Torben Sorensen 46c1e56b14
Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 46s
progress enforcing adr-0005
2026-01-08 21:40:20 -08:00

11 KiB

ADR-0005 Master Migration Status

Last Updated: 2026-01-08

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 5 queries + 7 mutations 12/12 0 100%
Admin Features 3 queries 0/3 3 0%
Analytics Features 2 queries 0/2 2 0%
Legacy Hooks 3 hooks 0/3 3 0%
TOTAL 20 items 12/20 8 🟡 60%

COMPLETED: User-Facing Features (Phase 1-3)

Query Hooks (5)

Hook File Query Key Status Phase
useFlyersQuery src/hooks/queries/useFlyersQuery.ts ['flyers', { limit, offset }] Done 1
useFlyerItemsQuery src/hooks/queries/useFlyerItemsQuery.ts ['flyer-items', flyerId] Done 2
useMasterItemsQuery src/hooks/queries/useMasterItemsQuery.ts ['master-items'] Done 2
useWatchedItemsQuery src/hooks/queries/useWatchedItemsQuery.ts ['watched-items'] Done 1
useShoppingListsQuery src/hooks/queries/useShoppingListsQuery.ts ['shopping-lists'] Done 1

Mutation Hooks (7)

Hook File Invalidates Status Phase
useAddWatchedItemMutation src/hooks/mutations/useAddWatchedItemMutation.ts ['watched-items'] Done 3
useRemoveWatchedItemMutation src/hooks/mutations/useRemoveWatchedItemMutation.ts ['watched-items'] Done 3
useCreateShoppingListMutation src/hooks/mutations/useCreateShoppingListMutation.ts ['shopping-lists'] Done 3
useDeleteShoppingListMutation src/hooks/mutations/useDeleteShoppingListMutation.ts ['shopping-lists'] Done 3
useAddShoppingListItemMutation src/hooks/mutations/useAddShoppingListItemMutation.ts ['shopping-lists'] Done 3
useUpdateShoppingListItemMutation src/hooks/mutations/useUpdateShoppingListItemMutation.ts ['shopping-lists'] Done 3
useRemoveShoppingListItemMutation src/hooks/mutations/useRemoveShoppingListItemMutation.ts ['shopping-lists'] Done 3

Providers Migrated (4)

Provider Uses Status
AppProviders.tsx QueryClientProvider wrapper Done
FlyersProvider.tsx useFlyersQuery Done
MasterItemsProvider.tsx useMasterItemsQuery Done
UserDataProvider.tsx useWatchedItemsQuery + useShoppingListsQuery Done

NOT MIGRATED: Admin & Analytics Features

High Priority - Admin Features

Feature Component/Hook Current Pattern API Calls Priority
Activity Log ActivityLog.tsx useState + useEffect fetchActivityLog(20, 0) 🔴 HIGH
Admin Stats AdminStatsPage.tsx useState + useEffect getApplicationStats() 🔴 HIGH
Corrections CorrectionsPage.tsx useState + useEffect + Promise.all getSuggestedCorrections(), fetchMasterItems(), fetchCategories() 🔴 HIGH

Issues:

  • Manual state management with useState/useEffect
  • No caching - data refetches on every mount
  • No automatic refetching or background updates
  • Manual loading/error state handling
  • Duplicate API calls (CorrectionsPage fetches master items separately)

Recommended Query Hooks to Create:

// src/hooks/queries/useActivityLogQuery.ts
queryKey: ['activity-log', { limit, offset }]
staleTime: 30 seconds (frequently updated)

// src/hooks/queries/useApplicationStatsQuery.ts
queryKey: ['application-stats']
staleTime: 2 minutes (changes moderately)

// src/hooks/queries/useSuggestedCorrectionsQuery.ts
queryKey: ['suggested-corrections']
staleTime: 1 minute

// src/hooks/queries/useCategoriesQuery.ts
queryKey: ['categories']
staleTime: 10 minutes (rarely changes)

Medium Priority - Analytics Features

Feature Component/Hook Current Pattern API Calls Priority
My Deals MyDealsPage.tsx useState + useEffect fetchBestSalePrices() 🟡 MEDIUM
Active Deals useActiveDeals.tsx useApi hook countFlyerItemsForFlyers(), fetchFlyerItemsForFlyers() 🟡 MEDIUM

Issues:

  • useActiveDeals uses old useApi hook pattern
  • MyDealsPage has manual state management
  • No caching for best sale prices
  • No relationship to watched-items cache (could be optimized)

Recommended Query Hooks to Create:

// src/hooks/queries/useBestSalePricesQuery.ts
queryKey: ['best-sale-prices', watchedItemIds]
staleTime: 2 minutes
// Should invalidate when flyers or flyer-items update

// Refactor useActiveDeals to use TanStack Query
// Could share cache with flyer-items query

Low Priority - Voice Lab

Feature Component Current Pattern Priority
Voice Lab 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

⚠️ LEGACY HOOKS STILL IN USE

Hooks to Deprecate/Remove

Hook File Used By Status
useApi src/hooks/useApi.ts useActiveDeals, useWatchedItems, useShoppingLists ⚠️ Active
useApiOnMount src/hooks/useApiOnMount.ts None (deprecated) ⚠️ Remove
useInfiniteQuery src/hooks/useInfiniteQuery.ts None (deprecated) ⚠️ Remove

Plan:

  • Phase 4: Refactor useWatchedItems/useShoppingLists to use TanStack Query mutations
  • Phase 5: Refactor useActiveDeals to use TanStack Query
  • Phase 6: Remove useApi, useApiOnMount, custom useInfiniteQuery

📊 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 (Planned)

  • Refactor useWatchedItems to use mutation hooks
  • Refactor useShoppingLists to use mutation hooks
  • Remove deprecated setters from context

Phase 5: Admin Features (Not Started)

  • Create useActivityLogQuery
  • Create useApplicationStatsQuery
  • Create useSuggestedCorrectionsQuery
  • Create useCategoriesQuery
  • Migrate ActivityLog.tsx
  • Migrate AdminStatsPage.tsx
  • Migrate CorrectionsPage.tsx

Phase 6: Analytics Features (Not Started)

  • Create useBestSalePricesQuery
  • Migrate MyDealsPage.tsx
  • Refactor useActiveDeals to use TanStack Query

Phase 7: Cleanup (Not Started)

  • Remove useApi hook
  • Remove useApiOnMount hook
  • Remove custom useInfiniteQuery hook
  • Remove all stub implementations
  • Update all tests

Option A: Complete User Features First (Phase 4)

Focus on finishing the user-facing feature migration by refactoring the remaining custom hooks. This provides a complete, polished user experience.

Pros:

  • Completes the user-facing story
  • Simplifies codebase for user features
  • Sets pattern for admin features

Cons:

  • Admin features still use old patterns

Option B: Migrate Admin Features (Phase 5)

Create query hooks for admin features to improve admin user experience and establish complete ADR-0005 coverage.

Pros:

  • Faster admin pages with caching
  • Consistent patterns across entire app
  • Better for admin users

Cons:

  • User-facing hooks still partially old pattern

Option C: Parallel Migration (Phase 4 + 5)

Work on both user hook refactoring and admin feature migration simultaneously.

Pros:

  • Fastest path to complete migration
  • Comprehensive coverage quickly

Cons:

  • Larger scope, more testing needed

📝 NOTES

Query Key Organization

Currently using literal strings for query keys. Consider creating a centralized query keys file:

// 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

📚 DOCUMENTATION