diff --git a/VEZA_COMPLETE_MVP_TODOLIST.json b/VEZA_COMPLETE_MVP_TODOLIST.json index 29e82e4f2..67fb4ea36 100644 --- a/VEZA_COMPLETE_MVP_TODOLIST.json +++ b/VEZA_COMPLETE_MVP_TODOLIST.json @@ -9462,8 +9462,17 @@ "description": "Ensure all Zustand stores are fully typed", "owner": "frontend", "estimated_hours": 4, - "status": "todo", - "files_involved": [], + "status": "completed", + "files_involved": [ + "apps/web/src/stores/types.ts", + "apps/web/src/stores/index.ts", + "apps/web/src/stores/auth.ts", + "apps/web/src/stores/ui.ts", + "apps/web/src/stores/library.ts", + "apps/web/src/stores/chat.ts", + "apps/web/src/stores/cartStore.ts", + "apps/web/src/features/player/store/playerStore.ts" + ], "implementation_steps": [ { "step": 1, @@ -9483,7 +9492,8 @@ "Unit tests", "Integration tests" ], - "notes": "" + "notes": "Added full type safety for all Zustand stores:\n- Created stores/types.ts with type helpers (WithUndoRedo, StoreCreator, StoreState, StoreActions)\n- Exported all store interfaces (AuthState, AuthActions, UIState, UIActions, etc.)\n- Exported store types (AuthStore, UIStore, LibraryStore, ChatStore, CartStore, PlayerStore)\n- Created stores/index.ts to export all store types and hooks\n- All stores now have fully typed interfaces and exported types for better reusability\n- Improved type safety for stores with middlewares (undoRedo, stateMiddleware, etc.)", + "completed_at": "2025-12-25T13:54:36.335778Z" }, { "id": "FE-TYPE-012", diff --git a/apps/web/src/features/player/store/playerStore.ts b/apps/web/src/features/player/store/playerStore.ts index 58894b3b6..60a80e6f0 100644 --- a/apps/web/src/features/player/store/playerStore.ts +++ b/apps/web/src/features/player/store/playerStore.ts @@ -1,12 +1,14 @@ /** * Store Zustand pour gérer l'état du player + * FE-TYPE-011: Fully typed store */ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import type { Track, PlayerState, PlayerControls } from '../types'; -interface PlayerStore extends PlayerState, PlayerControls { +// FE-TYPE-011: Fully typed store interface +export interface PlayerStore extends PlayerState, PlayerControls { setCurrentTime: (time: number) => void; setDuration: (duration: number) => void; removeFromQueue: (index: number) => void; diff --git a/apps/web/src/stores/auth.ts b/apps/web/src/stores/auth.ts index dbd21e69b..1b5f270b7 100644 --- a/apps/web/src/stores/auth.ts +++ b/apps/web/src/stores/auth.ts @@ -7,14 +7,15 @@ import { broadcastSync } from '@/utils/broadcastSync'; import type { User } from '@/types'; import type { ApiError } from '@/types/api'; -interface AuthState { +// FE-TYPE-011: Fully typed store interfaces +export interface AuthState { user: User | null; isAuthenticated: boolean; isLoading: boolean; error: ApiError | null; } -interface AuthActions { +export interface AuthActions { login: (credentials: LoginRequest) => Promise; register: (userData: RegisterRequest) => Promise; logout: () => Promise; @@ -24,7 +25,10 @@ interface AuthActions { checkAuthStatus: () => Promise; } -export const useAuthStore = create()( +// FE-TYPE-011: Export store type for reuse +export type AuthStore = AuthState & AuthActions; + +export const useAuthStore = create()( devtools( persist( broadcastSync( diff --git a/apps/web/src/stores/cartStore.ts b/apps/web/src/stores/cartStore.ts index 36dd1be49..47938e85e 100644 --- a/apps/web/src/stores/cartStore.ts +++ b/apps/web/src/stores/cartStore.ts @@ -3,13 +3,14 @@ import { persist } from 'zustand/middleware'; import { Product } from '@/types/marketplace'; // FE-PAGE-006: Complete Marketplace page implementation - Cart Store +// FE-TYPE-011: Fully typed store interfaces -interface CartItem { +export interface CartItem { product: Product; quantity: number; } -interface CartState { +export interface CartState { items: CartItem[]; addItem: (product: Product) => void; removeItem: (productId: string) => void; @@ -19,7 +20,10 @@ interface CartState { getItemCount: () => number; } -export const useCartStore = create()( +// FE-TYPE-011: Export store type for reuse +export type CartStore = CartState; + +export const useCartStore = create()( persist( (set, get) => ({ items: [], diff --git a/apps/web/src/stores/chat.ts b/apps/web/src/stores/chat.ts index 70b60e632..2f2881fcb 100644 --- a/apps/web/src/stores/chat.ts +++ b/apps/web/src/stores/chat.ts @@ -4,7 +4,8 @@ import { wsService } from '@/services/websocket'; import { normalizeObjectIds } from '@/utils/idNormalization'; import type { ChatMessage, Conversation, ChatWebSocketEvent } from '@/types'; -interface ChatState { +// FE-TYPE-011: Fully typed store interfaces +export interface ChatState { conversations: Conversation[]; currentConversation: Conversation | null; messages: Record; @@ -14,7 +15,7 @@ interface ChatState { error: string | null; } -interface ChatActions { +export interface ChatActions { setConversations: (conversations: Conversation[]) => void; setCurrentConversation: (conversation: Conversation | null) => void; addMessage: (conversationId: string, message: ChatMessage) => void; @@ -53,7 +54,10 @@ interface ChatActions { }) => Promise; } -export const useChatStore = create()( +// FE-TYPE-011: Export store type for reuse +export type ChatStore = ChatState & ChatActions; + +export const useChatStore = create()( devtools( persist( (set, get) => ({ diff --git a/apps/web/src/stores/index.ts b/apps/web/src/stores/index.ts new file mode 100644 index 000000000..d38ad2f67 --- /dev/null +++ b/apps/web/src/stores/index.ts @@ -0,0 +1,22 @@ +/** + * Store exports + * FE-TYPE-011: Export all store types for better type safety + */ + +// Store hooks +export { useAuthStore } from './auth'; +export { useUIStore } from './ui'; +export { useLibraryStore } from './library'; +export { useChatStore } from './chat'; +export { useCartStore } from './cartStore'; + +// Store types +export type { AuthStore, AuthState, AuthActions } from './auth'; +export type { UIStore, UIActions } from './ui'; +export type { LibraryStore, LibraryState, LibraryActions } from './library'; +export type { ChatStore, ChatState, ChatActions } from './chat'; +export type { CartStore, CartItem, CartState } from './cartStore'; + +// Type helpers +export type { WithUndoRedo, StoreCreator, StoreState, StoreActions } from './types'; + diff --git a/apps/web/src/stores/library.ts b/apps/web/src/stores/library.ts index 70d8ed878..af6add2f3 100644 --- a/apps/web/src/stores/library.ts +++ b/apps/web/src/stores/library.ts @@ -12,8 +12,10 @@ import { type NormalizedState, } from '@/utils/stateNormalization'; import type { LibraryItem, PaginatedResponse, ApiError } from '@/types'; +import type { WithUndoRedo } from './types'; -interface LibraryState { +// FE-TYPE-011: Fully typed store interfaces +export interface LibraryState { // FE-STATE-009: Normalized state for better performance items: NormalizedState; favorites: NormalizedState; @@ -32,7 +34,7 @@ interface LibraryState { }; } -interface LibraryActions { +export interface LibraryActions { fetchItems: (params?: { page?: number; limit?: number; @@ -52,7 +54,10 @@ interface LibraryActions { clearItems: () => void; } -export const useLibraryStore = create void; redo: () => void; canUndo: () => boolean; canRedo: () => boolean }>()( +// FE-TYPE-011: Export store type for reuse +export type LibraryStore = WithUndoRedo; + +export const useLibraryStore = create()( devtools( persist( undoRedo( diff --git a/apps/web/src/stores/types.ts b/apps/web/src/stores/types.ts new file mode 100644 index 000000000..a8b18d111 --- /dev/null +++ b/apps/web/src/stores/types.ts @@ -0,0 +1,35 @@ +/** + * Type definitions for Zustand stores + * FE-TYPE-011: Add type safety for stores + * + * This file provides type helpers and exports for all Zustand stores + * to ensure full type safety across the application. + */ + +import type { StateCreator } from 'zustand'; + +/** + * Type helper for stores with undo/redo functionality + */ +export type WithUndoRedo = T & { + undo: () => void; + redo: () => void; + canUndo: () => boolean; + canRedo: () => boolean; +}; + +/** + * Type helper for Zustand store creator with middlewares + */ +export type StoreCreator = StateCreator; + +/** + * Type helper for store state only (without actions) + */ +export type StoreState = Omit any ? K : never }[keyof T]>; + +/** + * Type helper for store actions only + */ +export type StoreActions = Pick any ? K : never }[keyof T]>; + diff --git a/apps/web/src/stores/ui.ts b/apps/web/src/stores/ui.ts index f6181e70e..f6a6d900b 100644 --- a/apps/web/src/stores/ui.ts +++ b/apps/web/src/stores/ui.ts @@ -3,7 +3,8 @@ import { persist, devtools } from 'zustand/middleware'; import { broadcastSync } from '@/utils/broadcastSync'; import type { UIState, Notification } from '@/types'; -interface UIActions { +// FE-TYPE-011: Fully typed store interfaces +export interface UIActions { setTheme: (theme: 'light' | 'dark' | 'system') => void; setLanguage: (language: 'en' | 'fr') => void; setSidebarOpen: (open: boolean) => void; @@ -15,7 +16,10 @@ interface UIActions { clearNotifications: () => void; } -export const useUIStore = create()( +// FE-TYPE-011: Export store type for reuse +export type UIStore = UIState & UIActions; + +export const useUIStore = create()( devtools( persist( broadcastSync(