I'll conduct this audit systematically by exploring the entire frontend codebase. Let me start by gathering information across multiple dimensions in parallel. [4 tools called] Now let me dig deeper into specific critical areas I need to validate. [1 tool called] Let me now gather a few more specific data points needed for the final audit. [6 tools called] Good - no cross-feature imports. Let me check a few more things. [5 tools called] Now I have all the data I need for a comprehensive audit. Let me compile the final report. --- # AUDIT TECHNIQUE INTÉGRAL — FRONTEND & DESIGN SYSTEM **Projet :** Veza — Plateforme Audio Collaborative **Date :** 13 février 2026 **Auditeur :** Architecte frontend indépendant **Branche :** `main` **Dernière mise à jour du document :** 13 février 2026 --- ## 1. EXECUTIVE SUMMARY Ce frontend est **techniquement ambitieux et structurellement solide**, mais souffre d'un **décalage significatif entre l'ampleur du code produit et la maturité réelle du produit**. L'architecture est bien pensée (feature-based, lazy loading, stores Zustand, React Query, i18n), le design system SUMI v2.0 est remarquablement complet dans sa couche tokens/CSS, et la couverture de tests (~287 fichiers) et stories (~323 fichiers) est substantielle. **Cependant :** au moins 5 routes majeures pointent vers des placeholders "Coming Soon" (Gear, Live, Education, Queue, Developer), 3 feature flags restent désactivées par défaut (PLAYLIST_RECOMMENDATIONS, HLS_STREAMING, ROLE_MANAGEMENT) ; NOTIFICATIONS et PLAYLIST_SHARE sont à true, le code contient des `any` dans des services critiques (auth), des `setTimeout` sans cleanup, et la base de code frôle le **surdimensionnement** pour un produit en phase MVP. Le risque principal n'est pas la qualité du code mais la **dispersion** : trop de surface frontale pour un backend partiellement implémenté. Un investisseur verrait un produit impressionnant en démo superficielle, mais fragile dès qu'on sort du chemin heureux. **Verdict : Refactoring ciblé, pas de réécriture.** Score global : **6.8/10**. --- ## 2. CARTOGRAPHIE FRONTEND ### Stack & Tooling | Composant | Technologie | Version | |-----------|-------------|---------| | Framework | React | ^18.2.0 | | Language | TypeScript | ^5.3.3 | | Build tool | Vite | ^7.1.5 | | State management | Zustand + Immer | ^4.5.0 / ^10.0.3 | | Routing | React Router DOM | ^6.22.0 | | Data fetching | TanStack React Query + Axios | ^5.17.0 / ^1.13.5 | | CSS | Tailwind CSS v4 (CSS-first) | ^4.0.0 | | Forms | React Hook Form + Zod | ^7.49.3 / ^3.25.76 | | i18n | i18next + react-i18next | ^25.5.2 / ^15.7.3 | | Animation | Framer Motion | ^12.29.2 | | Icons | Lucide React | ^0.321.0 | | Monitoring | Sentry | ^10.32.1 | | Linting | ESLint 9 (flat config) | ^9.0.0 | | Formatting | Prettier | ^3.2.5 | | Testing | Vitest + Testing Library + Playwright | ^3.2.4 / ^14.2.1 / ^1.58.2 | | Storybook | Storybook | ^8.6.15 | | Mocking | MSW | ^2.11.2 | ### Organisation du code ``` src/ ├── app/ # Root component ├── components/ # Composants partagés (~248 UI + ~545 feature-specific) │ ├── ui/ # Primitives design system (248 fichiers) │ ├── layout/ # Header, Sidebar, DashboardLayout │ ├── admin/ # Admin components │ ├── auth/ # Auth components │ ├── settings/ # Settings (57 fichiers) │ ├── social/ # Social features │ ├── studio/ # Studio/editing (76 fichiers) │ └── views/ # View components (211 fichiers) ├── config/ # Feature flags, env, constants ├── context/ # AudioContext, AuthContext ├── features/ # Feature modules (878 fichiers) │ ├── tracks/ # 189 fichiers — plus gros module │ ├── playlists/ # 148 fichiers │ ├── player/ # 77 fichiers │ ├── chat/ # 56 fichiers │ ├── auth/ # Complet │ ├── search/ # 23 fichiers │ └── ... (14 autres features) ├── hooks/ # 41 custom hooks ├── services/ # 28 fichiers API/domain services ├── stores/ # 11 Zustand stores ├── types/ # 144 fichiers de types ├── locales/ # en.json, fr.json (~528 lignes chaque) ├── mocks/ # MSW handlers (1717 lignes) └── utils/ # 50+ utilitaires ``` **Mise à jour 13/02/2026 :** `mocks/handlers.ts` ~1606 lignes ; `services/api/interceptors.ts` ~1203 lignes. **Convention de nommage :** PascalCase pour composants, camelCase pour hooks/utils/services. Cohérent. **Découpage :** Hybride feature-based + type-based. Le dossier `components/` contient à la fois des UI primitives (`ui/`) et des composants feature-specific (`admin/`, `social/`, `studio/`, `views/`) qui devraient logiquement vivre dans `features/`. Cette duplication structurelle crée une ambiguité : un développeur cherchant les composants social ne sait pas s'il doit regarder `components/social/` ou `features/social/`. **Co-location :** Partielle. Les features co-localisent composants + hooks + services + types. Mais les tests sont co-localisés avec les composants (bon), tandis que les stories sont parfois dans le même dossier, parfois dans `stories/` (incohérent). **Barrel exports :** Présents dans les modules UI (`LazyComponent.ts`, `lazyExports.ts`). Pas de barrel systématique par feature. ### Dépendances — Analyse critique **Redondances identifiées :** - `Spinner.tsx` + `LoadingSpinner.tsx` + `LoadingState.tsx` : trois composants de loading différents - `Modal.tsx` (marqué deprecated) + `Dialog.tsx` : coexistence avec note de migration inachevée - `components/feedback/Alert.tsx` potentiellement dupliqué avec `components/ui/alert.tsx` **Dépendances lourdes :** - `swagger-ui-react` + `swagger-ui-dist` (^5.31.0) : en **devDependencies** (corrigé). - `framer-motion` (^12.29.2) : justifié pour les animations, mais certaines animations CSS pures suffiraient - `emoji-picker-react` (^4.16.1) : lazy-loaded (correct) **Dépendances en production qui devraient être en dev :** - `rollup-plugin-visualizer` (^6.0.5) : dans `dependencies` au lieu de `devDependencies` **Tree-shaking :** Lucide React est correctement importé par icône individuelle. TanStack et date-fns sont tree-shakeable. Le chunk splitting manuel dans `vite.config.ts` est fonctionnel mais basique (tout `node_modules` non catégorisé va dans un seul chunk `vendor`). --- ## 3. INVENTAIRE DESIGN SYSTEM ### Maturité : **Niveau 3.5 / 4** Le design system SUMI v2.0 ("L'encre et la lumière") est **remarquablement complet en tokens** mais **incomplètement consommé** par les composants. ### Tokens & Variables **Forces :** | Catégorie | État | Détail | |-----------|------|--------| | Couleurs | Sémantique | `--sumi-bg-void` à `--sumi-bg-wash`, accents (vermillion, sage, gold), états sémantiques (success, warning, error, info) | | Typographie | Complet | 4 familles (Inter, Space Grotesk, JetBrains Mono, Noto Serif JP), échelle `xs` à `4xl`, weights, tracking, leading | | Espacement | Complet | Échelle `0.5` (2px) à `20` (80px) sur base 4px | | Radius | Complet | `xs` (2px) à `full` (9999px) | | Shadows | Complet | `xs` à `2xl` + glow effects | | Motion | Complet | Durées (75ms à 500ms), easings (6 courbes), transitions prédéfinies | | Z-index | Complet | Échelle `base` (0) à `max` (999) | | Layout | Complet | Max-widths, sidebar, header, player dimensions | | Dark/Light | Fonctionnel | Dark par défaut, light mode avec overrides complets | | Glass effects | Défini | `--sumi-glass-bg`, `--sumi-glass-border`, `--sumi-glass-blur` | **Localisation :** Tous les tokens vivent dans `src/index.css` via `@theme inline` de Tailwind v4. C'est un fichier unique, bien organisé par sections. Les tokens sont mappés vers les utilities Tailwind correctement. **Faiblesses :** - Les tokens sont définis dans CSS mais certains composants utilisent des valeurs Tailwind directes (`rounded-xl`) au lieu de `rounded-[var(--sumi-radius-xl)]` — incohérence entre ce qui est déclaré et ce qui est consommé. - ~100+ valeurs arbitraires Tailwind trouvées dans le code source (bien que beaucoup soient dans les stories ou des cas justifiés comme les SVG). ### Composants UI — Inventaire classé **Composants solides (reusables, testés, accessibles) :** | Composant | Imports | Tests | A11y | Notes | |-----------|---------|-------|------|-------| | Button | ~150+ | button.test.tsx | Focus ring, ARIA | 8 variants, 4 sizes, loading state | | Card | ~150+ | card.test.tsx | Standard | 9 variants, 4 paddings, spotlight effect | | Input | ~70+ | input.test.tsx | aria-invalid, describedby | Icon, label, error props | | Skeleton | ~100+ | skeleton.test.tsx | aria-hidden | 3 variants | | Checkbox | ~15+ | checkbox.test.tsx | useId, aria-label | Proper labeling | | Switch | Low | switch.test.tsx | role="switch", aria-checked | Complete | | RadioGroup | Low | radio-group.test.tsx | Arrow key nav, tabIndex | Full keyboard support | | Slider | Low | slider.test.tsx | aria-valuenow/min/max | Complete ARIA | | Badge | ~20+ | badge.test.tsx | Standard | Multiple variants, pulse | | Alert | ~10+ | alert.test.tsx | role="alert" | 6 variants, dismissible | | Progress | ~5+ | progress.test.tsx | role="progressbar", ARIA | Gaming variant | | Dialog | ~30+ | dialog.test.tsx | role="dialog", aria-modal | Focus trap | | Tabs | ~10+ | tabs.test.tsx | Tab pattern | Sub-components | | Table | None found | table.test.tsx | aria-label, sortable | Complete sub-components | | Avatar | ~15+ | avatar.test.tsx | Standard | 7 sizes, 6 status | | Tooltip | Low | tooltip.test.tsx | Standard | Multiple positions | | FocusTrap | Internal | focus-trap.test.tsx | Tab trapping, Escape | Used by Dialog/Modal | | Select | ~20+ | select.test.tsx | aria-label | Searchable, multi | | ScrollArea | Low | scroll-area.test.tsx | Standard | Custom scrollbar | **Composants fragiles (fonctionnels mais problématiques) :** | Composant | Problème | Impact | |-----------|----------|--------| | ErrorDisplay | Testé (`ErrorDisplay.test.tsx`) | — | | LoadingState | Testé (`LoadingState.test.tsx`) | — | | Accordion | Testé (`Accordion.test.tsx`) | — | | Collapsible | Testé (`collapsible.test.tsx`) | — | | FAB | Testé (`FAB.test.tsx`) | — | | FloatingInput | Testé (`floating-input.test.tsx`), utilise `oklch()` hardcodé | Hors design system (mineur) | | TrackCard | Utilise `(track as any).like_count` (l.43) | Contournement TypeScript | | Modal | **Marqué deprecated** mais encore 6+ imports | Migration inachevée | **Composants morts ou en doublon :** | Composant | Statut | |-----------|--------| | `Spinner.tsx` + `LoadingSpinner.tsx` + `LoadingState.tsx` | 3 implémentations du même concept | | `Modal.tsx` (deprecated) | Coexiste avec `Dialog.tsx` — 6 fichiers l'importent encore | | `components/feedback/Alert.tsx` | Potentiel doublon de `components/ui/alert.tsx` | | `ComingSoon.tsx` | Testé (`ComingSoon.test.tsx`) | | `AnimatedNumber.tsx` | Testé (`AnimatedNumber.test.tsx`) | ### Cohérence visuelle **`!important` :** 4 occurrences dans `index.css`, toutes justifiées (réduction de mouvement `prefers-reduced-motion` et animation d'entrée player). Aucun `!important` abusif. **Styles inline contredisant le système :** Non identifiés (les composants utilisent `cn()` de `clsx`/`tailwind-merge` systématiquement). **Espacements :** Cohérents — la majorité utilise l'échelle Tailwind native (`gap-2`, `p-4`, `space-y-1`). Les valeurs arbitraires sont concentrées dans les stories et les cas justifiés (SVG charts). **Typographie :** L'échelle est définie mais les classes utilitaires SUMI (`sumi-h1`, `sumi-body`, etc.) coexistent avec les classes Tailwind standard (`text-xs`, `font-medium`). Double système typographique non unifié. --- ## 4. DIAGNOSTIC FONCTIONNEL — CE QUE LE FRONTEND PERMET RÉELLEMENT ### Pages/Views fonctionnelles | Route | Composant | État | |-------|-----------|------| | `/login` | LoginPage | Fonctionnel (MSW) | | `/register` | RegisterPage | Fonctionnel (MSW) | | `/forgot-password` | ForgotPasswordPage | Fonctionnel (MSW) | | `/verify-email` | VerifyEmailPage | Fonctionnel (MSW) | | `/reset-password` | ResetPasswordPage | Fonctionnel (MSW) | | `/dashboard` | DashboardPage | Fonctionnel (MSW, données statiques) | | `/library` | LibraryPage | Fonctionnel (MSW) | | `/tracks/:id` | TrackDetailPage | Fonctionnel (MSW) | | `/playlists/*` | PlaylistRoutes | Fonctionnel (MSW, collaboration) | | `/chat` | ChatPage | Fonctionnel (MSW) | | `/search` | SearchPage | Fonctionnel (MSW) | | `/settings` | SettingsPage | Fonctionnel (MSW) | | `/settings/sessions` | SessionsPage | Fonctionnel (MSW) | | `/profile` | UserProfilePage | Fonctionnel (MSW) | | `/u/:username` | UserProfilePage (public) | Fonctionnel | | `/social` | SocialView | Fonctionnel (MSW) | | `/notifications` | NotificationsPage | Fonctionnel (MSW) | | `/marketplace` | MarketplaceHome | Fonctionnel (MSW) | | `/design-system` | DesignSystemDemo | Fonctionnel (statique) | ### Pages partiellement implémentées | Route | État | Détail | |-------|------|--------| | `/analytics` | MSW-only | Backend `NOT IMPLEMENTED` (config/features.ts) | | `/webhooks` | MSW-only | Backend MSW-only | | `/admin` | MSW-only | Backend partiellement implémenté | | `/admin/roles` | MSW-only, flag `ROLE_MANAGEMENT: false` | Backend `NOT IMPLEMENTED` | | `/sell` | MSW-only | Commerce backend non confirmé | | `/wishlist` | MSW-only | Commerce backend non confirmé | | `/purchases` | MSW-only | Commerce backend non confirmé | ### Pages mortes (Coming Soon) | Route | Statut | |-------|--------| | `/gear` | ComingSoon placeholder | | `/live` | ComingSoon placeholder | | `/education` | ComingSoon placeholder | | `/queue` | ComingSoon placeholder | | `/developer` | ComingSoon placeholder | ### Feature flags désactivés par défaut | Flag | Default | Raison documentée | |------|---------|-------------------| | `PLAYLIST_SEARCH` | `false` | Backend pas implémenté | | `PLAYLIST_SHARE` | `true` | Backend implémenté | | `PLAYLIST_RECOMMENDATIONS` | `false` | Backend pas implémenté | | `HLS_STREAMING` | `false` | Backend `NOT IMPLEMENTED` | | `ROLE_MANAGEMENT` | `false` | Backend `NOT IMPLEMENTED` | | `NOTIFICATIONS` | `true` | Backend implémenté | ### Parcours utilisateur complets 1. **Inscription → Vérification email → Connexion → Dashboard** : complet 2. **Connexion → Bibliothèque → Upload track → Détail track** : complet (MSW) 3. **Connexion → Recherche → Résultats → Lecture** : complet (MSW) 4. **Connexion → Playlists → Création → Ajout de tracks → Collaboration** : complet (MSW) 5. **Connexion → Chat → Conversations → Envoi messages** : complet (MSW) 6. **Connexion → Settings → Profil / Sécurité / Sessions** : complet (MSW) 7. **Connexion → Social → Feed → Posts** : complet (MSW) ### Parcours cassés 1. **Connexion → Gear** : se termine sur ComingSoon 2. **Connexion → Live** : se termine sur ComingSoon 3. **Connexion → Education** : se termine sur ComingSoon — pourtant 76 fichiers de composants studio existent dans `components/studio/` 4. **Connexion → Marketplace → Achat** : le flow checkout n'est pas confirmé côté backend 5. **2FA Login Verification** : TODO critique dans `TwoFactorVerify.tsx:47` — le service appelé est celui du setup, pas celui de la vérification login ### Incohérences produit/code - **76 fichiers studio** existent dans `components/studio/` mais aucune route `/studio` n'est définie - **Education** a un service (`educationService.ts`), des handlers MSW complets (courses, enrollments), des composants (`components/education/`) mais est gated derrière ComingSoon - **Gamification** (achievements, leaderboard, XP) a des handlers MSW mais aucune route ni composant visible - **Inventory/Gear** a des composants (`features/inventory/`, `components/inventory/`) et des handlers MSW mais est gated derrière ComingSoon --- ## 5. AUDIT ACCESSIBILITÉ (WCAG 2.1 AA) ### Perception | Critère | Verdict | Détail | |---------|---------|--------| | Contrastes | Correct | Les tokens SUMI définissent des couleurs avec bon contraste dark/light | | Alt text images | Correct | TrackCard utilise `alt={Cover de ${track.title}}`, Avatar a fallback | | Contenu sans couleur | Non vérifié | Badges utilisent couleurs + texte (OK) | | Mode réduit | Correct | `prefers-reduced-motion` respecté dans index.css (l.869-873) | ### Opérabilité | Critère | Verdict | Sévérité | |---------|---------|----------| | Navigation clavier | Bonne | RadioGroup, Dropdown, Dialog ont keyboard nav | | Focus visible | Bon | `focus-visible:ring-2` systématique | | Skip link | **Présent** | Lien dans App.tsx (href="#main-content", sr-only focus:not-sr-only) | | Focus trap modals | Présent | FocusTrap component utilisé | | Focus trap sidebar mobile | **Absent** | **Majeure** — sidebar mobile n'a pas de focus trap | ### Compréhension | Critère | Verdict | Sévérité | |---------|---------|----------| | Labels formulaires | Partiel | Input/Textarea ont labels, ChatInput n'a pas d'aria-label | **Majeure** | | Messages erreur | Partiel | Input a `aria-describedby`, ChatInput non | | Langue HTML | Non vérifié | Dépend de index.html | | Instructions | Correct | HelpText component existe | ### Robustesse | Critère | Verdict | Détail | |---------|---------|--------| | HTML sémantique | Bon | `
`, `