200 lines
8.6 KiB
Markdown
200 lines
8.6 KiB
Markdown
# 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<LibraryItem>` ⚠️ **Domain Data**
|
|
- `favorites: NormalizedState<LibraryItem>` ⚠️ **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<string, ChatMessage[]>` ⚠️ **Domain Data**
|
|
- `typingUsers: Record<string, string[]>` ✅ 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)
|
|
- Actions: `addItem`, `removeItem`, `updateQuantity`, `clearCart`, `getTotal`, `getItemCount`
|
|
- **Category**: ✅ **UI State** (appropriate for Zustand - client-side cart)
|
|
- **Migration Priority**: Low (cart is client-side state before checkout)
|
|
- **Analysis**:
|
|
- Cart items are temporary client-side state before checkout
|
|
- Not domain data - cart is created client-side, not fetched from server
|
|
- Persisted to localStorage for user convenience
|
|
- No server synchronization needed until checkout
|
|
- ✅ **Correctly categorized as UI state**
|
|
|
|
### 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<void> | 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<string, ChatMessage[]>` ⚠️ **Domain Data**
|
|
- `currentConversationId: string | null` ✅ UI State
|
|
- `typingUsers: Record<string, string[]>` ✅ 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
|