14 KiB
TECH_DEBT.md — Expria Frontend
Document de référence — Version 1.2 Ce document recense les décisions techniques prises par pragmatisme qui devront être revisitées, les stubs temporaires, et les fonctionnalités reportées. À mettre à jour après chaque session de développement.
Format : chaque entrée a un identifiant (FTD-XX pour Frontend Tech Debt, différent des
TD-XXbackend), une priorité, un statut. Priorités : 🔴 Critique (bloque la production) / 🟡 Important / 🟢 Mineur
Politique de gestion de la dette
Pour éviter que ce document devienne un cimetière de dette ignorée (le piège classique documenté dans ONBOARDING.md) :
- Maximum 15 FTD actives simultanément. Au-delà, priorisation obligatoire avant d'en ajouter une nouvelle.
- Chaque release production doit résoudre au moins 1 FTD de priorité ≥ 🟡.
- Toute FTD 🔴 doit être résolue dans la session suivante ou bloquer la release.
- Revue trimestrielle du document (Hermann + futur dev).
- Chaque FTD doit avoir une estimation de session (1h, 1 jour, 3 jours) pour permettre la priorisation.
1. Dettes héritées de l'audit backend (2026-04-17)
FTD-01 — Inconsistance des codes de validation côté backend
Priorité : 🟡 Important Statut : Ouvert — dépend du backend Estimation de session : 2h (backend uniquement) Description : Le backend utilise deux codes d'erreur pour la même classe (corps de requête invalide) :
VALIDATION_ERRORdansroutes/simulations.tsetroutes/corrections.tsINVALID_BODYdansroutes/plans.tsetroutes/stripe.ts
Le frontend gère les deux de la même manière (voir ARCHITECTURE.md §5), mais c'est une odeur de code qui devrait être unifiée.
Action côté frontend : aucune — on gère les deux codes.
Action côté backend : unifier sous VALIDATION_ERROR (plus explicite), session dédiée à ouvrir via TD-15 dans expria-backend/docs/TECH_DEBT.md.
Condition de résolution : après résolution de TD-15 backend, simplifier le switch dans les handlers frontend pour ne traiter que VALIDATION_ERROR.
FTD-02 — Header X-API-Version envoyé mais non vérifié
Priorité : 🟡 Important
Statut : Ouvert
Estimation de session : 1h (backend) + 30min (frontend)
Description : Le frontend envoie le header X-API-Version: 1.0 sur toutes les requêtes API (cf. ARCHITECTURE.md §5). Le backend ne le vérifie pas actuellement — donc en pratique, aucune incompatibilité de version ne sera détectée automatiquement.
Impact : si le backend évolue de façon breaking (ex : format de réponse de /plans/status modifié), le frontend peut recevoir un payload incompatible sans message d'erreur clair. Symptôme : bugs silencieux en production après un déploiement backend.
À faire :
- Backend : ajouter un middleware qui lit
X-API-Version, le log, et retourneHTTP 426 Upgrade Requiredavec codeAPI_VERSION_MISMATCHsi breaking change - Frontend : gérer
API_VERSION_MISMATCHdansapi-client.ts→ afficher un message "Une nouvelle version est disponible, veuillez rafraîchir la page"
Condition de résolution : avant l'arrivée d'un dev externe (qui pourrait modifier le backend sans coordination).
FTD-03 — Quirk status dans le body des erreurs de simulations/corrections
Priorité : 🟢 Mineur
Statut : Ouvert — dépend du backend
Estimation de session : 1h (backend uniquement)
Description : Les routes POST /simulations et POST /corrections/ee,eo renvoient un champ status dans le body JSON d'erreur, qui duplique le code HTTP :
{ "error": true, "code": "QUOTA_REACHED", "message": "...", "status": 403 }
Vient du pattern c.json(result, result.status) où result contient déjà status. C'est ignorable côté frontend (on ne lit pas ce champ), mais c'est du bruit.
À faire côté backend : nettoyer les objets d'erreur retournés par simulationController et correctionController pour ne pas contenir de champ status. Tracé dans TD-16 à créer dans expria-backend/docs/TECH_DEBT.md.
Condition de résolution : session de nettoyage backend, non urgente.
2. Dettes frontend propres
FTD-04 — Documents miroir sans automatisation de synchronisation
Priorité : 🟢 Mineur
Statut : Ouvert — accepté par design (voir ADR 004)
Estimation de session : 1 jour (mise en place monorepo)
Description : Les documents PLANS_TARIFAIRES.md, PARCOURS_UTILISATEURS.md, et le fichier de code src/entities/user/access.ts existent à l'identique dans les deux dépôts (frontend et backend). La synchronisation est manuelle — si un changement est fait dans un dépôt sans être répercuté dans l'autre, divergence silencieuse.
Mitigation actuelle :
- Règle G de
DEVELOPMENT_PRINCIPLES.md(modifications simultanées dans le même commit logique) - Commentaire
// SOURCE OF TRUTH:en tête deaccess.ts - Tests de parité dans
src/entities/user/__tests__/access.test.ts(calqués sur les tests backend)
À faire si la dette devient trop coûteuse :
- Migrer vers un monorepo pnpm workspaces avec package partagé
@expria/types-and-access - OU ajouter un script CI qui vérifie que le hash SHA-256 de
access.tsmatche entre les deux dépôts
Condition de résolution : après 3+ mois de production stable, ou si une divergence silencieuse cause un bug.
FTD-05 — Ancien scaffold frontend possiblement caduc
Priorité : 🟡 Important
Statut : Ouvert — diagnostic en cours (session Claude Code)
Estimation de session : variable selon diagnostic
Description : Un scaffold frontend a été créé au démarrage du projet (fin mars 2026 ou début avril 2026), avant que les décisions architecturales récentes (entities/features/shared, auth-client/api-client découplés, pas de Zustand, etc.) ne soient prises. Le contenu actuel de D:\expria-frontend\ peut donc contenir des fichiers qui ne matchent plus l'architecture cible.
À faire : session Claude Code (première session frontend de la V2) qui fait un état des lieux complet et propose une stratégie (clean slate / refactor progressif / adaptation en place). Cf. prompt de session dans l'historique de conversation Claude AI du 2026-04-17.
Condition de résolution : fin du Sprint 0 (scaffold conforme à ARCHITECTURE.md).
FTD-10 — Semgrep non intégré en CI
Priorité : 🟢 Mineur
Statut : Reporté — après MVP
Estimation de session : 2h
Description : ARCHITECTURE.md §CI mentionne semgrep scan (via plugin) dans le workflow CI cible. L'étape 10 du Sprint 0 n'a intégré que lint, format:check, typecheck, test, npm audit --audit-level=high — Semgrep a été volontairement différé pour respecter la règle de scope (max 2-3 fichiers par étape).
Impact actuel : npm audit couvre les vulnérabilités des dépendances npm, mais aucune analyse statique de sécurité (SAST) n'est faite sur le code custom du projet. Des patterns dangereux (eval, innerHTML sans DOMPurify, secrets en dur, etc.) passeraient inaperçus en CI.
À faire :
- Ajouter un step Semgrep au workflow
.github/workflows/ci.yml - Utiliser les rulesets
auto+r2c-security-audit+r2c-ci - Configurer la sortie pour bloquer sur sévérité ERROR uniquement
- Documenter dans SEC-08 de
SECURITY.md
Condition de résolution : avant l'arrivée d'un dev externe (même raisonnement que FTD-02).
FTD-11 — @theme Tailwind 4 non défini
Priorité : 🟢 Mineur
Statut : Ouvert — à faire dans session design system
Estimation de session : 1 jour (palette + typo + itérations design)
Description : src/index.css a été nettoyé à l'étape 11 du Sprint 0 et réduit à la seule ligne @import 'tailwindcss';. L'ADR 006 (§Configuration Tailwind 4) décrit le bloc @theme { ... } comme le mécanisme officiel de configuration Tailwind 4 (CSS-first) :
@theme {
--color-primary: #1B4FD8;
--font-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
La palette brand Expria et la typographie ne sont pas encore décidées, donc @theme est volontairement absent pour ne pas poser de valeurs placeholder qu'il faudrait repasser plus tard.
Impact actuel : les composants utilisent les couleurs Tailwind par défaut (bg-slate-*, text-gray-*). Visuellement cohérent mais pas brand.
À faire au Sprint 1 (design system) :
- Définir la palette brand Expria (primary, secondary, neutrals, danger, success)
- Choisir + installer la typo (Plus Jakarta Sans ou autre) via
<link>dansindex.htmlou@importdansindex.css - Ajouter le bloc
@themedanssrc/index.css - Mettre à jour ADR 006 avec les valeurs retenues
Condition de résolution : Sprint 1 — session dédiée au design system.
3. Fonctionnalités reportées
FTD-06 — AudioWorklet au lieu de ScriptProcessorNode (T2 Live)
Priorité : 🟢 Mineur
Statut : Reporté à après le lancement MVP
Estimation de session : 1 jour
Description : Hérité du backend (TD-09). Côté frontend, le traitement audio pour la T2 Live (capture PCM 16kHz) devra probablement utiliser AudioWorklet au lieu de ScriptProcessorNode qui est déprécié.
Impact actuel : fonctionne avec warnings dans la console. Peut poser problème sur certains navigateurs futurs.
À faire : session dédiée après le lancement MVP, pour migrer le pipeline audio vers AudioWorklet.
Condition de résolution : après 30 jours de production stable.
FTD-07 — Sentry non intégré
Priorité : 🟡 Important Statut : Planifié — après MVP Estimation de session : 3h Description : Le monitoring frontend (erreurs JS, performances, sessions) n'est pas encore en place. Sans Sentry (ou équivalent), les bugs en production ne remontent pas — on les découvre uniquement si un utilisateur prend la peine de les signaler.
À faire :
- Créer un compte Sentry (tier gratuit suffit pour démarrer)
- Ajouter
@sentry/reactau projet - Intégrer dans
src/app/providers.tsx - Ajouter
VITE_SENTRY_DSNdans les variables d'environnement - Configurer le filtrage des données sensibles (JWT, emails)
- Mettre à jour SEC-11 dans
SECURITY.md
Condition de résolution : avant la première vague d'utilisateurs post-MVP (30 jours après lancement).
FTD-08 — Tests E2E non implémentés
Priorité : 🟢 Mineur
Statut : Reporté — accepté par design
Estimation de session : 2 jours (Playwright setup)
Description : Actuellement, les tests de bout en bout sont manuels (via GOLDEN_DATASET.md). Une automatisation avec Playwright permettrait de détecter les régressions UI sans effort humain.
À faire : session Playwright setup après MVP, pour automatiser au minimum les 10 scénarios du Groupe Z (smoke test).
Condition de résolution : quand la maintenance manuelle du Golden Dataset devient trop chronophage.
4. Tests à renforcer
FTD-09 — Tests de la state machine T2 Live non implémentés
Priorité : 🟡 Important
Statut : Planifié — à créer au Sprint 2.5
Estimation de session : 3h
Description : La state machine T2 Live (src/features/t2-live/state/t2-machine.ts) n'existe pas encore. Quand elle sera créée, elle devra être testée de manière exhaustive (6+ tests couvrant les transitions d'états et les cas d'erreur).
À faire au Sprint 2.5 (spike T2 Live) :
- Créer
t2-machine.test.tsavec tests des transitions : idle → connecting, connecting → listening, listening ↔ speaking, * → error, * → ended - Tests des messages d'erreur (close code 4001, 4003, autre)
Condition de résolution : fin Sprint 2.5.
FTD-12 — Tests automatisés manquants pour api-client.ts
Priorité : 🟡 Important
Statut : Ouvert — à faire avant intégration des features critiques
Estimation de session : 3h
Description : Le wrapper apiFetch dans src/shared/lib/api-client.ts (créé à l'étape 7b du Sprint 0) contient une logique critique non couverte par des tests automatisés : timeout via AbortSignal.timeout, retry avec backoff exponentiel, stratégie d'idempotence (retry GET/HEAD/PUT/DELETE uniquement), parsing des erreurs backend (ApiError) vs frontend (ClientError), construction des headers (Authorization, X-API-Version, Content-Type).
Impact actuel : toute régression sur ce fichier (oubli d'un header, mauvais parsing d'une erreur, boucle de retry infinie sur un edge case) passera inaperçue jusqu'aux tests manuels ou à un bug en production.
À faire :
- Créer
src/shared/lib/__tests__/api-client.test.ts - Mocker globalement
fetchviavi.fn() - Couvrir :
- Succès 2xx → retourne le payload parsé
- Erreur 4xx
ApiErrorbien parsée → throw conforme - Erreur 4xx body non-JSON → fallback
INTERNAL_ERROR - Erreur 5xx avec retry → max 2 retries puis throw
- Timeout →
ClientErrorcodeTIMEOUT - Erreur réseau (fetch reject) →
ClientErrorcodeNETWORK_ERROR+ retry - Parsing succès JSON invalide →
ClientErrorcodePARSE_ERROR - Retry désactivé sur POST/PATCH par défaut (non-idempotent)
- Bearer omis sur
/health - Bearer injecté avec token valide depuis
auth-client
- Objectif : ≥ 10 tests, couverture complète des branches
Condition de résolution : avant l'intégration des hooks TanStack Query sur des features critiques (dashboard, simulations, auth).
5. Historique des résolutions
| ID | Description | Résolu le | Comment |
|---|---|---|---|
| FTD-13 | Incompatibilité Vitest 3 / Vite 8 (conflit de types Plugin<any> entre le Vite 8 top-level avec Rolldown et le Vite 7 pinné de Vitest 3.2.4 ; npm run build cassé) |
2026-04-17 | Résolu par upgrade Vitest 3.2.4 → 4.1.4 (et @vitest/coverage-v8 idem) à l'étape 12-bis du Sprint 0. Vitest 4.x supporte nativement Vite 8 Rolldown. Correctif complémentaire : script typecheck passé de tsc --noEmit -p tsconfig.app.json à tsc -b --noEmit pour couvrir aussi tsconfig.node.json (d'où vite.config.ts) et éviter qu'un bug similaire échappe à la CI. |
6. Historique de ce document
| Version | Date | Changements |
|---|---|---|
| 1.0 | 2026-04-17 | Création initiale avec 9 FTD identifiées depuis l'audit backend et les décisions d'architecture |
| 1.1 | 2026-04-17 | Ajout FTD-10 (Semgrep CI), FTD-11 (@theme Tailwind 4), FTD-12 (tests api-client) suite à l'étape 11 du Sprint 0 |
| 1.2 | 2026-04-17 | Ajout FTD-13 résolu (incompatibilité Vitest 3 / Vite 8) suite à l'étape 12-bis du Sprint 0 |