# Rapport d'État des Lieux du Frontend — Gap Analysis **Date** : 2025-01-27 **Version Backend** : 1.2.0 (selon `FRONTEND_INTEGRATION.md`) **Objectif** : Identifier les écarts entre le Frontend actuel et les exigences du Backend --- ## 1. État des Lieux ### Stack Technique **Framework & Build** : - ✅ **Vite 7.1.5** (build tool moderne) - ✅ **React 18.2.0** (framework UI) - ✅ **TypeScript 5.3.3** (type safety) - ✅ **Tailwind CSS 4.0.0** (styling) **State Management** : - ✅ **Zustand 4.5.0** (state management léger) - ✅ **React Query (TanStack Query) 5.17.0** (server state) **HTTP Client** : - ✅ **Axios 1.6.7** (client HTTP) - ⚠️ **Problème** : Deux instances Axios différentes (voir section 2.1) **Validation & Forms** : - ✅ **Zod 3.25.76** (schema validation) - ✅ **React Hook Form 7.49.3** (form management) **Routing** : - ✅ **React Router DOM 6.22.0** (routing) **Testing** : - ✅ **Vitest 3.2.4** (unit tests) - ✅ **Playwright 1.41.2** (e2e tests) - ✅ **MSW 2.11.2** (API mocking) **Architecture** : - ✅ **Feature-based structure** (`src/features/`) - ✅ **Path aliases configurés** (`@/`, `@components/`, `@features/`, etc.) - ✅ **TypeScript strict mode** activé ### Score de Maturité : **75%** **Points Positifs** : - ✅ Stack moderne et bien configurée - ✅ Structure de dossiers scalable (feature-based) - ✅ Outillage complet (ESLint, Prettier, TypeScript strict) - ✅ Tests configurés (unit + e2e) - ✅ PWA support (service worker, manifest) **Points d'Amélioration** : - ⚠️ Duplication de code (clients API, stores auth) - ⚠️ Incohérences dans les types TypeScript - ⚠️ Variables d'environnement non alignées avec la doc - ⚠️ Format de réponse API non standardisé --- ## 2. Analyse de la "Plomberie" (Core Layer) ### 🔴 **Client API** : **CRITIQUE — Incohérences Majeures** #### Problème 1 : Deux Clients API Différents **Client 1** : `src/lib/apiClient.ts` ```typescript baseURL: '/api/v1' // URL relative ``` - ❌ Utilise une URL relative (ne fonctionne pas avec `VITE_API_URL`) - ❌ Intercepteur de refresh token basique - ⚠️ Utilisé par `src/features/auth/store/authStore.ts` **Client 2** : `src/services/api/client.ts` ```typescript baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api/v1' ``` - ✅ Utilise une variable d'environnement - ✅ Intercepteur de refresh token avec queue - ✅ Utilisé par `src/services/api/auth.ts` **Impact** : Code dupliqué, maintenance difficile, comportements différents. #### Problème 2 : Variables d'Environnement Incohérentes **Documentation Backend** (`FRONTEND_INTEGRATION.md`) : ```bash VITE_API_URL=http://localhost:8080/api/v1 VITE_WS_URL=ws://localhost:8081/ws VITE_STREAM_URL=ws://localhost:8082/stream ``` **Code Frontend** (`src/config/env.ts`) : ```typescript VITE_API_BASE_URL // ❌ Devrait être VITE_API_URL VITE_WS_BASE_URL // ❌ Devrait être VITE_WS_URL VITE_STREAM_URL // ✅ Correct ``` **Impact** : Les développeurs doivent utiliser des noms de variables différents de la doc, confusion. #### Problème 3 : Format de Réponse API Non Standardisé **Backend retourne** (selon `FRONTEND_INTEGRATION.md`) : ```json { "success": true, "data": { ... }, "error": null } ``` **Code Frontend** : - `src/services/api.ts` (ligne 173) : Parse `response.data.data` ✅ - `src/services/api/auth.ts` (ligne 60) : Parse `response.data` directement ❌ - `src/services/api/client.ts` : Ne parse pas le wrapper ❌ **Impact** : Erreurs silencieuses, données non parsées correctement. --- ### 🔴 **Auth Management** : **CRITIQUE — Duplication** #### Problème : Deux Stores d'Authentification **Store 1** : `src/stores/auth.ts` - Utilise `apiService` (ancien service) - Gère `user`, `isAuthenticated`, `isLoading`, `error` - Utilise `tokenManager` pour les tokens **Store 2** : `src/features/auth/store/authStore.ts` - Utilise `apiClient` (nouveau client) - Gère `user`, `accessToken`, `refreshToken`, `isAuthenticated` - Stocke directement dans Zustand persist **Impact** : Confusion sur quel store utiliser, état d'auth désynchronisé. #### Problème : Format de Réponse Login Incohérent **Backend retourne** (selon doc) : ```json { "success": true, "data": { "access_token": "...", "refresh_token": "...", "expires_in": 3600, "token_type": "Bearer", "user": { ... } } } ``` **Code Frontend** : - `src/services/api.ts` (ligne 173) : Attend `{ user, token }` dans `data` ❌ - `src/services/api/auth.ts` (ligne 122) : Attend `{ user, token }` directement ❌ **Impact** : Login ne fonctionne pas correctement. --- ### 🟠 **Types TypeScript** : **ATTENTION — Incohérences** #### Problème 1 : Type `User.id` Incohérent **Backend** : UUID (string) selon `FRONTEND_INTEGRATION.md` **Frontend** : - `src/types/index.ts` : `id: string` ✅ - `src/types/api.ts` : `id: string` ✅ - `src/features/auth/types/index.ts` : `id: number` ❌ - `src/services/api/auth.ts` : `id: number` ❌ **Impact** : Erreurs de type, conversion nécessaire. #### Problème 2 : Interface `ApiError` Incomplète **Backend retourne** (selon doc) : ```typescript { code: number, // 1000, 2000, etc. message: string, details?: Array<{ field: string; message: string }>, request_id?: string, timestamp: string, context?: Record } ``` **Frontend** : - `src/types/api.ts` : `code: string` ❌ (devrait être `number`) - `src/types/index.ts` : `code?: string` ❌ (devrait être `number`) - Manque `request_id`, `timestamp`, `context` ❌ **Impact** : Erreurs API mal parsées, perte d'information. #### Problème 3 : Interface `ApiResponse` Incomplète **Backend retourne** : ```typescript { success: boolean, data: T | null, error?: ApiError, message?: string } ``` **Frontend** (`src/types/api.ts`) : ```typescript { data: T, // ❌ Devrait être T | null message?: string, success: boolean // ❌ Manque error?: ApiError } ``` **Impact** : Types incorrects, pas de type safety pour les erreurs. --- ### 🟡 **Gestion des Erreurs** : **ATTENTION — Non Standardisée** #### Problème : Parsing d'Erreurs Incohérent **Backend retourne** (selon doc) : ```json { "success": false, "data": null, "error": { "code": 2000, "message": "Validation failed", "details": [...] } } ``` **Code Frontend** : - `src/services/api.ts` : Parse `error.response.data` directement ❌ - `src/services/api/auth.ts` : Parse `error.response.data?.error` ou `message` ❌ - `src/features/auth/services/authService.ts` : Parse `error.response.data?.error` ❌ **Impact** : Messages d'erreur incorrects, détails de validation perdus. --- ## 3. Plan d'Action Immédiat (Roadmap) ### Priorité 1 : Standardiser le Client API (2-3h) #### Tâche 1.1 : Unifier les Variables d'Environnement **Fichier** : `src/config/env.ts` **Action** : 1. Renommer `VITE_API_BASE_URL` → `VITE_API_URL` 2. Renommer `VITE_WS_BASE_URL` → `VITE_WS_URL` 3. Mettre à jour tous les imports/utilisations **Validation** : `npm run typecheck` passe, tests passent. --- #### Tâche 1.2 : Créer un Client API Unique et Standardisé **Fichier** : `src/services/api/client.ts` (refactoriser) **Action** : 1. Supprimer `src/lib/apiClient.ts` (ancien client) 2. Refactoriser `src/services/api/client.ts` pour : - Utiliser `env.API_URL` (après Tâche 1.1) - Parser automatiquement le format `{ success, data, error }` - Gérer les erreurs selon le format backend - Intercepteur de refresh token (déjà présent ✅) **Code cible** : ```typescript // Intercepteur de réponse pour parser le format backend apiClient.interceptors.response.use( (response) => { // Backend retourne { success: true, data: {...} } if (response.data.success === true) { return { ...response, data: response.data.data }; } // Si success === false, l'erreur sera gérée par le catch return response; }, async (error) => { // Parser l'erreur backend { success: false, error: {...} } if (error.response?.data?.success === false) { const apiError = error.response.data.error; // Transformer en ApiError standardisé throw new APIError(apiError); } // ... reste du code refresh token } ); ``` **Validation** : Tests unitaires pour le parsing, tests d'intégration avec mock backend. --- #### Tâche 1.3 : Créer les Types TypeScript Alignés avec le Backend **Fichier** : `src/types/api.ts` (refactoriser) **Action** : 1. Corriger `ApiError` : ```typescript export interface ApiError { code: number; // Pas string ! message: string; details?: Array<{ field: string; message: string }>; request_id?: string; timestamp: string; context?: Record; } ``` 2. Corriger `ApiResponse` : ```typescript export interface ApiResponse { success: boolean; data: T | null; error?: ApiError; message?: string; } ``` 3. Corriger `User.id` partout : `string` (UUID) **Validation** : `npm run typecheck` passe, tous les usages mis à jour. --- ### Priorité 2 : Standardiser l'Authentification (2h) #### Tâche 2.1 : Unifier les Stores d'Auth **Fichier** : `src/stores/auth.ts` (garder celui-ci, supprimer l'autre) **Action** : 1. Supprimer `src/features/auth/store/authStore.ts` 2. Mettre à jour `src/stores/auth.ts` pour utiliser `apiClient` (nouveau client unifié) 3. Adapter le format de réponse login selon la doc backend : ```typescript // Backend retourne { success: true, data: { access_token, refresh_token, user } } const response = await apiClient.post('/auth/login', credentials); // apiClient.parse() retourne déjà data (grâce à l'intercepteur) const { access_token, refresh_token, expires_in, user } = response.data; ``` **Validation** : Tests d'authentification passent, redirection login/logout fonctionne. --- #### Tâche 2.2 : Adapter les Services Auth au Format Backend **Fichier** : `src/services/api/auth.ts` **Action** : 1. Mettre à jour `login()` pour parser `{ success: true, data: { access_token, refresh_token, user } }` 2. Mettre à jour `register()` de la même manière 3. Mettre à jour `getCurrentUser()` pour parser `{ success: true, data: { ...user } }` **Validation** : Tests d'intégration auth passent. --- ### Priorité 3 : Créer un Helper de Gestion d'Erreurs (1h) #### Tâche 3.1 : Créer `src/utils/apiErrorHandler.ts` **Action** : 1. Créer une fonction `parseApiError(error: AxiosError): ApiError` 2. Créer une fonction `formatErrorMessage(error: ApiError): string` 3. Créer une fonction `getValidationErrors(error: ApiError): Record` **Code cible** : ```typescript export function parseApiError(error: AxiosError): ApiError { if (error.response?.data?.success === false) { return error.response.data.error; } // Fallback pour erreurs réseau, etc. return { code: error.response?.status || 0, message: error.message || 'An unexpected error occurred', timestamp: new Date().toISOString(), }; } ``` **Validation** : Tests unitaires pour chaque cas d'erreur. --- ### Priorité 4 : Mettre à Jour les Types Partout (1-2h) #### Tâche 4.1 : Audit et Correction des Types **Action** : 1. Chercher tous les usages de `User.id` et s'assurer que c'est `string` 2. Chercher tous les usages de `ApiError` et s'assurer que `code` est `number` 3. Mettre à jour les schémas Zod si nécessaire **Validation** : `npm run typecheck` passe sans erreurs. --- ## 4. Checklist de Validation Finale Avant de commencer l'intégration des fonctionnalités, vérifier : - [ ] **Client API unique** : Un seul `apiClient` utilisé partout - [ ] **Variables d'env** : `VITE_API_URL`, `VITE_WS_URL` (pas `_BASE_URL`) - [ ] **Format de réponse** : Toutes les réponses parsent `{ success, data, error }` - [ ] **Types TypeScript** : `ApiError.code` est `number`, `User.id` est `string` - [ ] **Store auth unique** : Un seul store d'authentification - [ ] **Gestion d'erreurs** : Toutes les erreurs utilisent `parseApiError()` - [ ] **Tests** : Tous les tests passent (`npm test`) - [ ] **Typecheck** : Aucune erreur TypeScript (`npm run typecheck`) --- ## 5. Estimation Totale **Temps estimé** : **6-8 heures** de travail pour aligner le Frontend sur le Backend. **Ordre d'exécution recommandé** : 1. Tâches 1.1 + 1.3 (Types + Env) : **2h** 2. Tâche 1.2 (Client API) : **2-3h** 3. Tâches 2.1 + 2.2 (Auth) : **2h** 4. Tâche 3.1 (Error Handler) : **1h** 5. Tâche 4.1 (Audit Types) : **1h** --- ## 6. Notes Importantes ### ⚠️ Breaking Changes Attendus - Les variables d'environnement changent (`VITE_API_BASE_URL` → `VITE_API_URL`) - Le format de réponse API change (wrapper `{ success, data }`) - Les types `ApiError.code` changent (`string` → `number`) **Action** : Mettre à jour tous les fichiers qui utilisent ces APIs. ### ✅ Points Positifs à Préserver - La structure feature-based est excellente - Les intercepteurs de refresh token sont bien implémentés - Les tests sont configurés et fonctionnels - Le code est globalement bien organisé --- **Prochaine Étape** : Exécuter les tâches dans l'ordre de priorité, puis valider avec des tests d'intégration contre le Backend réel.