veza/docs/REMEDIATION_PROGRESS.md
senke ae586f6134 Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy
Bloc A - Code mort:
- Suppression Studio (components, views, features)
- Suppression gamification + services mock (projectService, storageService, gamificationService)
- Mise à jour Sidebar, Navbar, locales

Bloc B - Frontend:
- Suppression modal.tsx deprecated, Modal.stories (doublon Dialog)
- Feature flags: PLAYLIST_SEARCH, PLAYLIST_RECOMMENDATIONS, ROLE_MANAGEMENT = true
- Suppression 19 tests orphelins, retrait exclusions vitest.config

Bloc C - Backend:
- Extraction routes_auth.go depuis router.go

Bloc D - Rust:
- Suppression security_legacy.rs (code mort, patterns déjà dans security/)
2026-02-14 17:23:32 +01:00

124 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Progression de la remédiation — Stabilisation frontend
**Référence** : [Plan de remédiation](.cursor/plans/frontend_stabilization_remediation_b9e1b51d.plan.md)
**Dernière mise à jour** : 14 février 2026 (Phases 46 complétées, vulnérabilités npm Phase 1, rate limiting A04)
---
## Vulnérabilités npm (A06 — Phase 1) ✅
Référence : [AUDIT_TECHNIQUE_INTEGRAL_2026_02.md](../AUDIT_TECHNIQUE_INTEGRAL_2026_02.md) section A06.
### Correctifs appliqués
- **npm audit fix** : brace-expansion, diff, undici corrigés automatiquement.
- **React Router XSS (GHSA-2w69-qvjg-hvjx)** : `react-router-dom` mis à jour vers ^6.30.3 (@remix-run/router 1.23.2).
- **Axios DoS (GHSA-43fc-jf86-j433)** : override `axios >= 1.13.5` dans `package.json` racine.
- **class-variance-authority** : réintégré (dépendance manquante pour button/card).
- **CI** : `npm audit --audit-level=high` exécuté depuis la racine du monorepo.
### Vulnérabilités restantes (devDependencies uniquement)
25 vulnérabilités dans @lhci/cli, newman, pa11y-ci (cookie, jose, lodash, node-forge, qs, semver, tar-fs, tmp, ws). **Risque accepté** : ces packages ne sont pas inclus dans le build de production. Correction via `npm audit fix --force` entraînerait des breaking changes (downgrade @lhci/cli, newman, pa11y-ci).
---
## Rate limiting (A04) ✅
Référence : [AUDIT_TECHNIQUE_INTEGRAL_2026_02.md](../AUDIT_TECHNIQUE_INTEGRAL_2026_02.md) — Points de rupture (ligne 170), A04 (ligne 232).
### Correctifs appliqués
- **Rate limiting toujours actif** : suppression de la condition `Env != EnvDevelopment` pour le rate limit global et register.
- **Limites assouplies en dev** : `getDefaultRateLimitLimit(env)` — 1000 req/min en dev/test, 200 en staging/prod.
- **Register assoupli en dev** : `getDefaultRegisterAttempts(env)` — 20 inscriptions/heure en dev/test, 3 en staging/prod.
- **Documentation** : README mis à jour avec tableau des limites par environnement.
---
## Phase 1 — Backend solide ✅
### 1.1 Sécurité backend ✅
- **.gitignore** : Renforcement des patterns pour `.env`, `.env.*`, `**/.env`, `**/.env.local`, `veza-*/.env`, `apps/web/.env.local` (ne jamais committer de secrets).
- **Chat server** : Dans `veza-chat-server/src/jwt_manager.rs`, `validate_access_token` vérifie désormais en base que lutilisateur existe (si `db_pool` disponible) ; pas de fallback « user » si absent en DB — connexion refusée.
- **Backend Go** : Le handler de refresh token vérifie déjà lexistence de lutilisateur en DB (voir `internal/core/auth/service.go` RefreshToken).
- **Pagination** : Contrôle strict `page >= 1` et `1 <= limit <= 100` avec retour **400** et message clair dans :
- `internal/handlers/playlist_handler.go` (GetPlaylists),
- `internal/handlers/profile_handler.go` (ListUsers),
- `internal/core/track/handler.go` (ListTracks).
### 1.2 API et contrats ✅
- **Healthcheck** : Les Dockerfiles (Dockerfile, Dockerfile.production) utilisent déjà `http://localhost:8080/api/v1/health`.
- **go-clamd** : Documenté dans `veza-backend-api/docs/CLAMAV_SETUP.md` (limitation : lib abandonnée ; désactivation via `ENABLE_CLAMAV=false` = pas de scan).
- **Search** : Contrat documenté dans `veza-backend-api/docs/API_DOCUMENTATION.md` — recherche par ressource (`/api/v1/tracks/search`, `/api/v1/playlists/search`, `/api/v1/users/search`) ; pas dendpoint unifié `GET /api/v1/search`.
- **Endpoints marketplace / social** : Routes existantes (wishlist, panier, groups) ; pas de 501 ajouté.
### 1.3 Services Rust ✅
- **Redis** : Versions alignées (redis 0.32) dans `veza-chat-server` et `veza-stream-server` (Cargo.toml).
### 1.4 Infra et CD ✅
- **Docker-compose** : Mots de passe en dur remplacés par variables denvironnement (`POSTGRES_PASSWORD`, `RABBITMQ_DEFAULT_PASS`, etc.) avec valeurs par défaut pour le dev dans `docker-compose.yml`.
- **CD** : Commentaire ajouté dans `.github/workflows/cd.yml` : pour pousser vers un registry, configurer les secrets `DOCKER_REGISTRY`, `DOCKER_REGISTRY_USERNAME`, `DOCKER_REGISTRY_PASSWORD`.
---
## Phase 2 — Frontend : bugs et comportements critiques
### 2.1 Auth et 2FA ✅
- **2FA login** : Implémenté. Backend : `POST /api/v1/auth/login/2fa` (body : `email`, `password`, `code`, `remember_me`) ; frontend : `completeLogin2FA()` dans `apps/web/src/services/api/auth.ts`, action `complete2FALogin` dans le store, flux dans LoginPage (affichage TwoFactorVerify quand `requires_2fa`, puis appel API et redirection).
- **Typage auth** : Traité dans `apps/web/src/services/api/auth.ts` (réponse typée `LoginResponse`/`RegisterResponse`, options logout typées, `isAxiosError` pour les erreurs).
- **Redirect si déjà authentifié** : LoginPage / RegisterPage utilisent `authStore` / `useUser` ; à vérifier en conditions réelles (pas de boucle login → redirect).
### 2.2 Memory leaks et logs ✅
- **setTimeout** : ChatInput, SocialViewFeedItem, PostCard ont déjà un cleanup (clearTimeout dans le return du `useEffect`).
- **console.log** : GlobalSearchBar utilise `logger.debug` ; pas de suppression massive demandée pour linstant.
### 2.3 Accessibilité ✅
- **ChatInput** : Le champ principal a déjà `aria-label="Type a message"`.
- **Sidebar (layout)** : `components/layout/Sidebar.tsx` utilise déjà `FocusTrap` quand la sidebar est ouverte en mobile (`sidebarOpen && isMobile`).
---
## Phase 3 — Tests (en cours)
- **Vitest** : Suite complète **0 échec** (265 fichiers passés, 4 skippés ; 3230 tests passés, 87 skippés). Corrections appliquées :
- **SettingsPage.test.tsx** : Load error → assertion sur `getByRole('alert')` + contenu flexible ; save error → reset de `settingsSchema.safeParse` dans `beforeEach` (évite que le test « validation errors » laisse `safeParse` en échec pour le test suivant) ; userEvent pour le clic Save.
- **RegisterPage.test.tsx** : Terms → assertion sur « handleRegister non appelé » + optionnel message terms ; username « déjà pris » → `getAllByText` (plusieurs nœuds affichent le message) ; vérification notice → `findByText` + `act` autour du mock + rerender ; email dans la notice → texte partiel + `test@example.com` (texte split dans le DOM).
- **ForgotPasswordForm.test.tsx** : « should disable form while loading » → attente après `waitFor` pour que la promesse mock se résolve avant teardown (évite « state update after unmount »).
- **usePlaybackRealtime.test.ts** : 8 tests réactivés dans un second `describe` avec vrais timers (WebSocket lifecycle) ; plus de skip.
- **Tests par groupes (machines limitées)** : Vitest configuré pour limiter RAM/CPU (`pool: 'threads'`, `maxThreads: 2`, `fileParallelism: false`). Scripts npm ajoutés pour exécuter les tests par groupe : `test:auth`, `test:tracks`, `test:playlists`, `test:player`, `test:streaming`, `test:settings-profile-chat`, `test:components-ui`, `test:components-other`, `test:services`, `test:hooks`, `test:misc`. Commande `test:groups` lance tous les groupes séquentiellement. Ordre recommandé pour le diagnostic : petits groupes d'abord (settings-profile-chat, streaming, hooks, misc) puis les plus gros.
- **Providers / mocks** : Wrappers dans `src/test/` ; MSW dans `src/mocks/`. À aligner sur les contrats API si besoin.
- **Storybook** : `npm run test:storybook` (script `scripts/audit-storybook.js`) nécessite Storybook servi sur **port 6007** ; lancer `npm run build-storybook` puis servir le dossier `storybook-static` sur 6007, puis `npm run test:storybook`.
- **E2E** : Playwright (`npm run test:e2e`). Parcours critiques et fichiers listés dans `apps/web/e2e/README.md` (auth, smoke, playlists, search, profile, upload). Test search : `e2e/tests/search.spec.ts` (navigation `/search`, saisie requête, résultats ou état vide). Test 2FA : dans `auth.spec.ts` (skippé sauf si `E2E_2FA_CODE` et compte 2FA configurés).
## Phase 4 — Dette structurante ✅
- **Loading** : Composants centralisés en place — `LoadingState`, `LoadingSpinner`, `Skeleton`, `ButtonLoading` ; guide `apps/web/src/docs/LOADING_STATES_PATTERN.md` mis à jour avec section **LoadingState** et recommandation (full-page/block → LoadingState, list/card → Skeleton).
- **Modal → Dialog** : `Modal` déprécié (S1.4) ; `Dialog` sappuie dessus. Feature modals récents utilisent déjà `Dialog`. Préférer `Dialog` pour tout nouveau code.
- **Track type** : Commentaire ajouté dans `apps/web/src/features/tracks/types.ts` — source of truth pour Track = `features/player/types` ; champs upload/backend = `features/tracks/types/track.ts`.
- **Interceptors** : Documenté en en-tête dans `interceptors.ts` ; pas de découpage supplémentaire pour linstant.
## Phase 5 — Features fantômes et cohérence ✅
- **Coming Soon** : Routes documentées dans `apps/web/docs/FEATURE_STATUS.md``/gear`, `/live`, `/education`, `/queue`, `/developer` (placeholder `ComingSoon` dans `routeConfig.tsx`).
- **Feature flags** : Référence dans `FEATURE_STATUS.md` vers `src/config/features.ts` et `VITE_FEATURE_*` ; liste des flags (TWO_FACTOR_AUTH, PLAYLIST_*, HLS_STREAMING, ROLE_MANAGEMENT, NOTIFICATIONS).
- **Marketplace / groups / search** : Mention dans `FEATURE_STATUS.md` (routes marketplace, search par ressource, groups dans Social).
- **Typo** : `useLibraryManager.ts` — message « coming soon available » corrigé en « coming soon — available in the next release ».
## Phase 6 — Maturité ✅
- **TypeScript** : `npx tsc --noEmit` exécuté — 0 erreur.
- **Docs** : `FEATURE_STATUS.md` créé (Coming Soon + feature flags + marketplace/search) ; `LOADING_STATES_PATTERN.md` enrichi ; `REMEDIATION_PROGRESS.md` à jour.
- **UX** : Checklist finale rappelée ci-dessous (skip link, aria-label, focus trap, pas de console.log en prod).
---
## Checklist de validation finale (rappel)
- `npx vitest run` : 0 échec (ou < 5 % skippés avec ticket). Sur machine limitée en RAM/CPU : utiliser `npm run test:groups` ou les scripts par groupe (`test:auth`, `test:tracks`, etc.) pour éviter la saturation des ressources.
- `npm run build` : succès sans warning bloquant.
- `npx tsc --noEmit` : 0 erreur.
- `npm run test:storybook` : 0 erreur. **Procédure de validation Storybook sur 6007** :
1. `cd apps/web && npm run build-storybook`
2. Démarrer le serveur sur le port **6007** : `node scripts/serve-storybook-static.cjs` (ou `npx serve storybook-static -l 6007`) et le laisser tourner
3. Dans un autre terminal : `npm run test:storybook` (le script [scripts/audit-storybook.js](apps/web/scripts/audit-storybook.js) cible `http://localhost:6007` et ne démarre pas le serveur). Option : `npm run test:storybook:playwright` démarre automatiquement le serveur via [playwright.config.storybook.ts](apps/web/playwright.config.storybook.ts).
- Aucun `console.log` / debug en prod.
- Skip link + aria-label ChatInput + focus trap Sidebar en place.
- 2FA login : backend à compléter puis frontend à brancher.