- Created QueryClient singleton (queryClientSingleton.ts):
- Provides global access to QueryClient for state invalidation
- Set in main.tsx after QueryClient creation
- Updated invalidateQueries() to use QueryClient directly:
- Replaced custom event system with direct QueryClient.invalidateQueries()
- Added query key mapping for all resource types
- Event system kept as fallback if QueryClient not available
- Updated invalidateStore() for Library Store:
- Removed clearItems() call (method doesn't exist, domain data migrated to React Query)
- Library Store now only contains UI state (filters)
- React Query cache invalidation handles refetching
- Query keys mapped:
- tracks: ['tracks'], ['track'], ['library']
- playlists: ['playlists'], ['playlist']
- users: ['users'], ['user'], ['auth'], ['userProfile']
- conversations: ['conversations'], ['conversation'], ['chat'], ['chatConversations']
- roles: ['roles'], ['role']
- library: ['library'], ['tracks'], ['favorites'], ['libraryItems']
- auth: ['auth'], ['user']
- Action 4.6.1.5 complete
- Removed stateMiddleware utility (431 lines):
- Deleted apps/web/src/utils/stateMiddleware.ts
- Deleted apps/web/src/utils/stateMiddleware.test.ts (251 lines)
- Completely unused in production code (only used in test file)
- Previously removed from Library Store in Action 4.1.2.7
- Library Store now only contains UI state (filters), no middleware needed
- Created audit documentation: apps/web/src/docs/STATEMIDDLEWARE_UTILITY_AUDIT.md
- Action 4.6.1.4 complete
- Removed undoRedo utility (8587 bytes):
- Deleted apps/web/src/utils/undoRedo.ts
- Removed WithUndoRedo<T> type from stores/types.ts
- Removed WithUndoRedo export from stores/index.ts
- Completely unused (confirmed in Action 4.6.1.9 audit)
- Removed stateNormalization utility (6321 bytes):
- Deleted apps/web/src/utils/stateNormalization.ts
- Updated stores.test.ts to remove outdated tests:
- Removed createEmptyNormalized import
- Removed outdated Library Store tests (items/favorites)
- Updated Library Store tests to test current structure (filters only)
- Updated Chat Store tests to use feature store
- Updated Auth Store tests (user data migrated to React Query)
- Fixed beforeEach to not call non-existent methods
- Only used in outdated test file (confirmed in Action 4.6.1.11 audit)
- Both utilities made obsolete by React Query migration
- Actions 4.6.1.10 and 4.6.1.12 complete
- Removed duplicate stores/chat.ts (old store)
- Consolidated to features/chat/store/chatStore.ts (active store)
- Updated ChatMessages.tsx to use feature store (currentConversationId + lookup)
- Updated storeSelectors.ts to use feature store and export only existing methods
- Updated stateHydration.ts to skip chat hydration (uses React Query)
- Updated stateInvalidation.ts to not call fetchConversations (React Query handles it)
- Updated stores/index.ts to export feature store
- Updated documentation
- Test files still reference old store (separate update needed)
- Action 4.5.1.5 complete
- Deleted apps/web/src/utils/optimisticStoreUpdates.ts (unused file)
- File was unused - no imports found in codebase
- Mutations already use React Query's onMutate pattern
- No TypeScript errors after deletion
- Actions 4.4.1.2 and 4.4.1.3 complete
- Added optional onStateSync callback to BroadcastSyncOptions
- Callback is called when state is updated locally or synced from another tab
- Callback receives new state and previous state as parameters
- Error handling prevents callback errors from breaking sync
- Stores can opt-in by providing callback that invalidates React Query queries
- No breaking changes - callback is optional
- Action 4.2.1.1 complete
- Added documentation explaining coexistence of Zustand and React Query sync
- Added type guards in broadcastSync.ts to verify message format before processing
- Added type guards in reactQuerySync.ts to verify message format before processing
- Both sync mechanisms use different channel names (no direct conflicts)
- Both sync mechanisms use different message formats (no cross-processing)
- Type guards ensure handlers only process their own message types
- Prevents accidental cross-processing of messages between sync mechanisms
- Both syncs can coexist safely without conflicts
- Action 2.3.1.3 complete
- Created reactQuerySync.ts with setupReactQuerySync() function
- Uses BroadcastChannel API to sync cache updates across browser tabs
- Subscribes to QueryClient mutation cache to broadcast mutation successes
- Subscribes to QueryClient query cache to broadcast query invalidations
- Implements message deduplication using message IDs and processed messages Set
- Implements tab ID tracking to avoid processing messages from same tab
- Handles three message types: query-invalidate, query-set-data, mutation-success
- Includes shouldSync filter function for selective synchronization
- Includes cleanup function to stop synchronization
- Focuses on invalidations and mutations (not every query update) for performance
- Comprehensive error handling and logging
- Action 2.3.1.1 complete - utility ready for integration
- Replace manual ApiError interface with Zod-inferred type from apiSchemas
- Update all imports (15+ files) to use ApiError from @/schemas/apiSchemas
- Remove ApiError interface from types/api.ts
- Update ApiResponse to import ApiError from schemas
- All TypeScript checks pass for ApiError-related code
- Migrated all hooks: useAuth, useChat, useLogin
- Migrated all components: Header, ProfileForm, FollowButton, LikeButton, PlaylistFollowButton, ChatMessage, ChatMessages, CommentThread, CommentSection, PlaylistList, ChatSidebar, SettingsPage, DashboardPage
- Updated storeSelectors.ts useAuthUser() to use React Query
- All production code now uses useUser() hook instead of Zustand store
- Action 4.1.1.3 and 4.1.1.4 complete
- Remove items, favorites, pagination, isLoading, error from LibraryState
- Remove fetchItems, fetchFavorites, uploadFile, toggleFavorite, deleteItem, clearItems, setLoading, setError from LibraryActions
- Remove undoRedo and stateMiddleware wrappers (no domain data to track)
- Update useLibraryActions() to use React Query for all domain data actions
- Store now only contains filters (UI state)
- Update useLibraryItemsNormalized() and useLibraryFavoritesNormalized() to return empty state (deprecated)
- Update useLibraryPagination() to return both camelCase and snake_case for compatibility
Action 4.1.2.4 complete
- Replace useLibraryItems() with React Query hook
- Replace useLibraryFavorites() with React Query hook
- Replace useLibraryPagination() to extract from React Query response
- Replace useLibraryStatus() to use React Query status
- Update useLibraryActions() to use queryClient.refetchQueries()
- Maintain same interface for backward compatibility
- Migrates DashboardPage components automatically
Action 4.1.2.3.3 complete
Frontend fixes:
- Fix 'require is not defined' error in stateHydration.ts
Replace require('react') with ES6 import statement
- Fix DataCloneError in broadcastSync.ts
Serialize state before sending via BroadcastChannel (functions can't be cloned)
Backend fixes:
- Fix Swagger /docs route not found
Redirect /docs to /swagger/index.html for better compatibility
- Created comprehensive unit tests for date utilities
- Created comprehensive unit tests for format utilities
- Created comprehensive unit tests for URL utilities
- Created comprehensive unit tests for logger utility
- Created comprehensive unit tests for errorMessages utility
- Created comprehensive unit tests for sanitize utility
- Created comprehensive unit tests for apiErrorHandler utility
- Created comprehensive unit tests for apiToastHelper utility
- Created comprehensive unit tests for serviceErrorHandler utility
- Created comprehensive unit tests for timeoutHandler utility
All tests pass (163 tests). Covers all utility functions that were missing tests.
Phase: PHASE-5
Priority: P2
Progress: 241/267 (90.26%)
- Created ID normalization utility (idNormalization.ts) with:
* normalizeId: Convert IDs to strings (handles number/string/null)
* normalizeObjectIds: Recursively normalize IDs in objects
* normalizeArrayIds: Normalize IDs in arrays of objects
* Type guards for ID validation
- Updated stores/chat.ts to use normalization instead of manual String() conversions
- Fixed type definitions:
* PlaylistAnalytics: playlistId number -> string
* ImportPlaylistButton: playlistId number -> string
* ExportPlaylistButton: playlistId number -> string
* usePlaylistNotifications: lastNotificationId number -> string
- Removed unnecessary String() conversions in comparisons
- Comprehensive test suite (20 tests, all passing)
- Ensures all IDs are consistently strings (UUIDs) throughout the app
- Created state cleanup system (stateCleanup.ts) with:
* Size limit cleanup: Limit number of items in arrays/normalized state
* Age limit cleanup: Remove items older than specified time
* Custom cleanup: User-defined cleanup functions
* Support for arrays, normalized state, and nested objects
- Added cleanupMiddleware for automatic periodic cleanup
- Added performCleanup function for manual cleanup
- Comprehensive test suite (9 tests, all passing)
- Prevents memory leaks by cleaning unused state data
- Created state versioning system (stateVersioning.ts) with:
* Version management: Wrap/unwrap state with version info
* Migration support: Sequential migrations between versions
* Versioned storage: Adapter for Zustand persist middleware
* Error handling: Fallback to initial state on migration failure
* Automatic migration: Migrate state on load if needed
- Added comprehensive test suite (17 tests, 14 passing)
- Created example integration showing usage with stores
- Supports legacy state (unversioned) and version mismatches
- Created comprehensive state middleware (stateMiddleware.ts) with:
* Logging: State change logging with configurable filters
* Analytics: Event tracking for state changes, actions, errors, performance
* Error handling: Automatic error capture and reporting
* Sanitization: Remove sensitive data from logs
* Performance tracking: Monitor async action durations
- Applied middleware to LibraryStore as example
- Added comprehensive test suite (7 tests, all passing)
- Configurable options for all features
- Global handlers for analytics and errors
- Created state normalization utility (stateNormalization.ts) with functions:
* normalize/denormalize for converting arrays to normalized state
* addToNormalized, updateInNormalized, removeFromNormalized
* Helper functions for working with normalized state
- Applied normalization to LibraryStore (items and favorites)
- Updated storeSelectors to convert normalized state to arrays
- Updated DashboardPage components to use new selectors
- Updated tests to work with normalized state structure
- Improved performance with O(1) lookups instead of O(n) array searches