Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 46s
277 lines
11 KiB
Markdown
277 lines
11 KiB
Markdown
# 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](../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 |
|
|
|
|
### Mutation Hooks (7)
|
|
|
|
| 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 |
|
|
|
|
### Providers Migrated (4)
|
|
|
|
| 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 |
|
|
|
|
---
|
|
|
|
## ❌ NOT MIGRATED: Admin & Analytics Features
|
|
|
|
### High Priority - Admin Features
|
|
|
|
| Feature | Component/Hook | Current Pattern | API Calls | Priority |
|
|
|---------|----------------|-----------------|-----------|----------|
|
|
| **Activity Log** | [ActivityLog.tsx](../src/components/ActivityLog.tsx) | useState + useEffect | `fetchActivityLog(20, 0)` | 🔴 HIGH |
|
|
| **Admin Stats** | [AdminStatsPage.tsx](../src/pages/AdminStatsPage.tsx) | useState + useEffect | `getApplicationStats()` | 🔴 HIGH |
|
|
| **Corrections** | [CorrectionsPage.tsx](../src/pages/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:**
|
|
```typescript
|
|
// 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](../src/pages/MyDealsPage.tsx) | useState + useEffect | `fetchBestSalePrices()` | 🟡 MEDIUM |
|
|
| **Active Deals** | [useActiveDeals.tsx](../src/hooks/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:**
|
|
```typescript
|
|
// 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](../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
|
|
|
|
---
|
|
|
|
## ⚠️ LEGACY HOOKS STILL IN USE
|
|
|
|
### Hooks to Deprecate/Remove
|
|
|
|
| Hook | File | Used By | Status |
|
|
|------|------|---------|--------|
|
|
| **useApi** | [src/hooks/useApi.ts](../src/hooks/useApi.ts) | useActiveDeals, useWatchedItems, useShoppingLists | ⚠️ Active |
|
|
| **useApiOnMount** | [src/hooks/useApiOnMount.ts](../src/hooks/useApiOnMount.ts) | None (deprecated) | ⚠️ Remove |
|
|
| **useInfiniteQuery** | [src/hooks/useInfiniteQuery.ts](../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
|
|
|
|
---
|
|
|
|
## 🎯 RECOMMENDED NEXT STEPS
|
|
|
|
### 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:
|
|
|
|
```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 |
|
|
|
|
---
|
|
|
|
## 📚 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)
|