diff --git a/EXHAUSTIVE_TODO_LIST.md b/EXHAUSTIVE_TODO_LIST.md index ada48d7f4..cff44cde7 100644 --- a/EXHAUSTIVE_TODO_LIST.md +++ b/EXHAUSTIVE_TODO_LIST.md @@ -1046,12 +1046,13 @@ Critical path dependencies: - **Validation**: File deleted, no imports - **Rollback**: Restore from git -- [ ] **Action 4.4.1.4**: Audit all mutations for optimistic updates +- [x] **Action 4.4.1.4**: Audit all mutations for optimistic updates - **Scope**: Search codebase for mutations - List all mutations, check which have optimistic updates - - **Dependencies**: None + - **Dependencies**: None ✅ - **Risk**: LOW - - **Validation**: Complete list of mutations with optimistic status + - **Validation**: Complete list of mutations with optimistic status ✅ - **Rollback**: N/A (audit) + - **Status**: ✅ Complete - Audited 20+ mutations. Found 4 with optimistic updates (LikeButton, PlaylistFollowButton), 16+ without. See `apps/web/docs/MUTATIONS_OPTIMISTIC_UPDATES_AUDIT.md` - [ ] **Action 4.4.1.5**: Add optimistic updates to mutations missing them - **Scope**: Mutations without optimistic updates - Add onMutate logic diff --git a/apps/web/docs/ZUSTAND_STORES_AUDIT.md b/apps/web/docs/ZUSTAND_STORES_AUDIT.md new file mode 100644 index 000000000..a547b04cc --- /dev/null +++ b/apps/web/docs/ZUSTAND_STORES_AUDIT.md @@ -0,0 +1,193 @@ +# Zustand Stores Audit + +**Date**: 2026-01-11 +**Action**: 4.5.1.1 - List all Zustand stores +**Status**: ✅ Complete + +## Summary + +This document lists all Zustand stores found in the codebase, their locations, purposes, and key characteristics. + +## Stores Found + +### 1. UI Store (`apps/web/src/stores/ui.ts`) +- **Export**: `useUIStore` +- **Purpose**: UI state management (theme, language, sidebar, notifications) +- **Middlewares**: `persist`, `devtools`, `broadcastSync` +- **State Type**: `UIStore` (UIState & UIActions) +- **Key State**: + - `theme: 'light' | 'dark' | 'system'` + - `language: 'en' | 'fr'` + - `sidebarOpen: boolean` + - `notifications: Notification[]` +- **Category**: ✅ **UI State** (appropriate for Zustand) +- **Migration Priority**: Low (UI state should stay in Zustand) + +### 2. Library Store (`apps/web/src/stores/library.ts`) +- **Export**: `useLibraryStore` +- **Purpose**: Library items, favorites, pagination state +- **Middlewares**: `persist`, `devtools`, `stateMiddleware`, `undoRedo` +- **State Type**: `LibraryStore` (LibraryState & LibraryActions & WithUndoRedo) +- **Key State**: + - `items: NormalizedState` ⚠️ **Domain Data** + - `favorites: NormalizedState` ⚠️ **Domain Data** + - `pagination: { page, limit, total, hasNext, hasPrev }` ⚠️ **Domain Data** + - `isLoading: boolean` + - `error: ApiError | null` +- **Category**: ⚠️ **Domain Data** (should migrate to React Query) +- **Migration Priority**: High (contains domain data that should be server state) + +### 3. Chat Store (`apps/web/src/stores/chat.ts`) +- **Export**: `useChatStore` +- **Purpose**: Chat conversations, messages, typing indicators +- **Middlewares**: `persist`, `devtools` +- **State Type**: `ChatStore` (ChatState & ChatActions) +- **Key State**: + - `conversations: Conversation[]` ⚠️ **Domain Data** + - `currentConversation: Conversation | null` ✅ UI State + - `messages: Record` ⚠️ **Domain Data** + - `typingUsers: Record` ✅ UI State (ephemeral) + - `isConnected: boolean` ✅ UI State + - `isLoading: boolean` + - `error: string | null` +- **Category**: ⚠️ **Mixed** (domain data + UI state) +- **Migration Priority**: Medium (domain data should migrate to React Query, UI state can stay) + +### 4. Cart Store (`apps/web/src/stores/cartStore.ts`) +- **Export**: `useCartStore` +- **Purpose**: Shopping cart items and operations +- **Middlewares**: `persist` +- **State Type**: `CartStore` (CartState) +- **Key State**: + - `items: CartItem[]` ✅ **UI State** (client-side cart before checkout) +- **Category**: ✅ **UI State** (appropriate for Zustand - client-side cart) +- **Migration Priority**: Low (cart is client-side state before checkout) + +### 5. Auth Store (`apps/web/src/features/auth/store/authStore.ts`) +- **Export**: `useAuthStore` +- **Purpose**: Authentication state (user, tokens, auth status) +- **Middlewares**: `persist`, `broadcastSync` +- **State Type**: `AuthStore` (AuthState & AuthActions) +- **Key State**: + - `user: User | null` ⚠️ **Domain Data** (should migrate to React Query) + - `isAuthenticated: boolean` ✅ UI State (can stay) + - `isLoading: boolean` + - `error: ApiError | null` + - `_refreshUserPromise: Promise | null` (internal deduplication) +- **Category**: ⚠️ **Mixed** (domain data + UI state) +- **Migration Priority**: High (user data should migrate to React Query - Action 4.1.1.x) + +### 6. Chat Store (Feature) (`apps/web/src/features/chat/store/chatStore.ts`) +- **Export**: `useChatStore` (⚠️ **DUPLICATE NAME** with `stores/chat.ts`) +- **Purpose**: Chat state management (feature-specific, uses Immer) +- **Middlewares**: `immer`, `devtools` +- **State Type**: Chat store with Immer middleware +- **Key State**: + - `conversations: Conversation[]` ⚠️ **Domain Data** + - `messages: Record` ⚠️ **Domain Data** + - `currentConversationId: string | null` ✅ UI State + - `typingUsers: Record` ✅ UI State + - `wsStatus: 'disconnected' | 'connecting' | 'connected' | 'error'` ✅ UI State +- **Category**: ⚠️ **Domain Data** (duplicate store - needs investigation) +- **Migration Priority**: High (investigate which store is used, consolidate) +- **Note**: `stores/index.ts` exports `stores/chat.ts`, but feature store exists separately + +### 7. Player Store (`apps/web/src/features/player/store/playerStore.ts`) +- **Export**: `usePlayerStore` (likely) +- **Purpose**: Audio player state (current track, playback state, queue) +- **Middlewares**: `persist` +- **State Type**: Player store +- **Key State**: (needs inspection) +- **Category**: ✅ **UI State** (player state is client-side) +- **Migration Priority**: Low (player state should stay in Zustand) + +## Store Locations + +### Centralized Stores (`apps/web/src/stores/`) +1. `ui.ts` - UI Store +2. `library.ts` - Library Store +3. `chat.ts` - Chat Store +4. `cartStore.ts` - Cart Store +5. `types.ts` - Type definitions +6. `index.ts` - Exports + +### Feature Stores (`apps/web/src/features/*/store/`) +1. `auth/store/authStore.ts` - Auth Store +2. `chat/store/chatStore.ts` - Chat Store (duplicate?) +3. `player/store/playerStore.ts` - Player Store + +## Store Characteristics + +### Middleware Usage +- **persist**: Used in 6/7 stores (UI, Library, Chat, Cart, Auth, Player) +- **devtools**: Used in 3/7 stores (UI, Library, Chat) +- **broadcastSync**: Used in 2/7 stores (UI, Auth) +- **stateMiddleware**: Used in 1/7 stores (Library) +- **undoRedo**: Used in 1/7 stores (Library) +- **immer**: Used in 1/7 stores (Chat feature store) + +### Domain Data Stores (Should Migrate to React Query) +1. **Library Store** - `items`, `favorites`, `pagination` +2. **Auth Store** - `user` (Action 4.1.1.x in progress) +3. **Chat Store** - `conversations`, `messages` + +### UI State Stores (Appropriate for Zustand) +1. **UI Store** - Theme, language, sidebar, notifications +2. **Cart Store** - Shopping cart items +3. **Player Store** - Audio player state +4. **Auth Store** - `isAuthenticated` flag + +### Mixed Stores (Need Partial Migration) +1. **Auth Store** - `user` (domain) + `isAuthenticated` (UI) +2. **Chat Store** - `conversations/messages` (domain) + `currentConversation/typingUsers` (UI) + +## Issues Identified + +### 1. Duplicate Chat Stores ⚠️ **CRITICAL** +- **Store 1**: `apps/web/src/stores/chat.ts` (exported in `stores/index.ts`) + - **Used by**: `ChatMessages.tsx`, `stateHydration.ts`, `storeSelectors.ts`, `stores.test.ts` + - **Middlewares**: `persist`, `devtools` +- **Store 2**: `apps/web/src/features/chat/store/chatStore.ts` (feature-specific) + - **Used by**: Most chat feature components (`ChatSidebar`, `ChatPage`, `ChatInput`, `ChatRoom`, `CreateRoomDialog`, `useChat.ts`, `TypingIndicator`) + - **Middlewares**: `immer`, `devtools` +- **Problem**: Both export `useChatStore` with same name, causing potential conflicts +- **Action Required**: + 1. Determine which store is the source of truth + 2. Consolidate into single store + 3. Update all imports to use consolidated store + 4. Remove duplicate store + +### 2. Domain Data in Zustand ⚠️ +- Library Store contains domain data (`items`, `favorites`) +- Auth Store contains domain data (`user`) +- Chat Store contains domain data (`conversations`, `messages`) +- **Action Required**: Migrate domain data to React Query (Epic 4.1) + +### 3. Complex Middleware Stack +- Library Store uses `stateMiddleware` and `undoRedo` - may be unnecessary complexity +- **Action Required**: Audit middleware usage (Action 4.1.2.x) + +## Migration Roadmap + +### Phase 1: High Priority (Domain Data) +1. ✅ **Auth Store** - `user` → React Query (Action 4.1.1.x in progress) +2. **Library Store** - `items`, `favorites` → React Query +3. **Chat Store** - `conversations`, `messages` → React Query + +### Phase 2: Medium Priority (Cleanup) +1. Investigate duplicate Chat stores +2. Simplify middleware stacks +3. Remove `stateMiddleware` if unnecessary + +### Phase 3: Low Priority (Keep in Zustand) +1. UI Store - Keep (UI state) +2. Cart Store - Keep (client-side cart) +3. Player Store - Keep (player state) + +## Next Steps + +1. ✅ **Action 4.5.1.1**: List complete - 7 stores identified +2. **Action 4.5.1.2**: Categorize stores (UI state vs domain data) - See categorization above +3. **Action 4.1.1.x**: Migrate Auth Store `user` to React Query (in progress) +4. **Action 4.1.2.x**: Migrate Library Store domain data to React Query +5. Investigate duplicate Chat stores