- Rewrite index.css with complete SUMI token system (dark + light themes) - All --sumi-* variables: backgrounds, surfaces, borders, text, pigments, spacing, radius, shadows, glass, scrollbar, motion, z-index, layout - shadcn/Radix semantic mapping (--background, --foreground, etc.) - Tailwind @theme mapping with new fonts (Inter, Space Grotesk, JetBrains Mono) - SUMI keyframe animations (sumi-fade-in, sumi-slide-up, sumi-scale-in, etc.) - Delete 11 redundant CSS files (design-system.css, design-tokens.css, button.css, card.css, input.css, badge-avatar.css, header.css, fix-input-focus.css, fix-login-form.css, visual-enhancements.css, premium-utilities.css) - Update main.tsx: single CSS import (index.css only) - Update ThemeProvider: data-theme attribute instead of .dark class toggle - Update index.html FOUC script: data-theme attribute Co-authored-by: Cursor <cursoragent@cursor.com>
10 KiB
PHASE 0 — CARTOGRAPHIE FRONTEND
Date d'audit : 12 février 2026 Projet : Veza — Plateforme audio collaborative Scope :
apps/web/src/uniquement
1. Statistiques brutes
| Métrique | Valeur |
|---|---|
Fichiers .tsx |
1 450 |
Fichiers .ts |
620 |
Fichiers .css |
17 |
Fichiers .scss |
0 |
Fichiers .module.css |
0 |
Fichiers .svg |
5 |
| Total fichiers source | ~2 092 |
| Total LOC (ts+tsx+css) | 222 717 |
| Fichiers > 300 lignes | ~50 (dont 7 123 LOC pour types/generated/api.ts) |
| Fichiers > 500 lignes | ~28 |
as any casts |
706 |
@ts-ignore / @ts-expect-error |
8 |
dangerouslySetInnerHTML |
2 occurrences |
eval() / new Function() |
0 |
localStorage / sessionStorage accès |
~20 occurrences |
Inline styles (style={{}}) |
~80 fichiers |
| TODO / FIXME / HACK | ~15 annotations actives |
console.log/debug/info |
~55 occurrences (hors tests) |
2. Stack détectée
| Couche | Technologie | Version |
|---|---|---|
| Framework UI | React | ^18.2.0 |
| Bundler | Vite | ^7.1.5 |
| Langage | TypeScript | ^5.3.3 (strict mode ON, noImplicitAny, noUncheckedIndexedAccess) |
| CSS | Tailwind CSS v4 | ^4.0.0 (CSS-first config via @theme) |
| State management | Zustand | ^4.5.0 |
| Server state | TanStack React Query | ^5.17.0 |
| Routing | React Router DOM | ^6.22.0 |
| Forms | React Hook Form + Zod | ^7.49.3 / ^3.25.76 |
| HTTP client | Axios | ^1.13.5 |
| Animations | Framer Motion | ^12.29.2 |
| Icons | Lucide React | ^0.321.0 |
| i18n | i18next + react-i18next | ^25.5.2 / ^15.7.3 |
| Mocking | MSW | ^2.11.2 |
| Tests | Vitest + Testing Library | ^3.2.4 / ^14.2.1 |
| Storybook | Storybook | ^8.6.15 |
| Linting | ESLint 9 flat config + jsx-a11y | ^9.0.0 / ^6.10.2 |
| Sanitization | DOMPurify | ^3.3.0 |
| Error monitoring | Sentry | ^10.32.1 |
| Drag & Drop | dnd-kit | ^6.3.1 |
| Virtualization | TanStack Virtual | ^3.13.12 |
| Streaming | HLS.js | ^1.6.14 |
3. Dépendances critiques — Observations
| Dépendance | Observation |
|---|---|
@types/dompurify |
Listé en dependencies au lieu de devDependencies — erreur de classification |
rollup-plugin-visualizer |
Listé en dependencies au lieu de devDependencies — inclus inutilement en runtime |
swagger-ui-dist + swagger-ui-react |
En production deps — potentiellement ~2MB de bundle si non tree-shaken / lazy-loaded |
emoji-picker-react |
Dépendance lourde (~200KB) — nécessite lazy loading |
framer-motion |
^12.29.2 — dépendance majeure, impacte le bundle (~30KB min) |
lucide-react |
^0.321.0 — version ancienne (2024), dernière version > 0.450+ |
4. Schéma d'arborescence commenté (2 niveaux)
src/
├── __tests__/ # Tests globaux (accessibility, contrast)
├── app/ # Point d'entrée app (App.tsx probable)
├── components/ # Composants "legacy" / partagés (très large — 40+ sous-dossiers)
│ ├── admin/ # Vue admin
│ ├── analytics/ # Graphiques analytics
│ ├── auth/ # Composants auth
│ ├── base/ # Composants de base
│ ├── charts/ # Charts custom
│ ├── commerce/ # Commerce / e-commerce
│ ├── dashboard/ # Dashboard
│ ├── data/ # Composants data (tables)
│ ├── developer/ # Swagger UI, API keys
│ ├── education/ # Cours, formations
│ ├── feedback/ # Toast, notifications
│ ├── filters/ # Filtres
│ ├── forms/ # Form builder, password strength
│ ├── gamification/ # XP, achievements
│ ├── inventory/ # Gestion d'inventaire
│ ├── keyboard/ # Raccourcis clavier
│ ├── layout/ # DashboardLayout, Sidebar, Header, Navbar
│ ├── library/ # Bibliothèque (playlists)
│ ├── live/ # Streaming live
│ ├── marketplace/ # Place de marché
│ ├── modals/ # Modales partagées
│ ├── monitoring/ # Dashboard monitoring
│ ├── navigation/ # Breadcrumbs
│ ├── notifications/ # Notifications
│ ├── player/ # Audio player (ancien)
│ ├── pwa/ # PWA composants
│ ├── search/ # Barre de recherche globale
│ ├── seller/ # Vue vendeur
│ ├── settings/ # Pages settings (account, security, appearance...)
│ ├── share/ # Share link manager
│ ├── social/ # Feed, groups, connections
│ ├── studio/ # Studio (projets, AI tools, go live)
│ ├── theme/ # ThemeSwitcher
│ ├── ui/ # ⭐ Composants UI primitifs (Button, Modal, Tabs, etc.)
│ ├── upload/ # Upload + metadata
│ └── views/ # Vues décomposées (analytics, cart, chat, discover, etc.)
├── config/ # Feature flags, env config
├── context/ # AuthContext
├── features/ # ⭐ Feature modules (architecture feature-first)
│ ├── admin/ # Admin feature
│ ├── auth/ # Auth feature (pages, components, tests)
│ ├── chat/ # Chat feature
│ ├── dashboard/ # Dashboard feature
│ ├── notifications/ # Notifications feature
│ ├── player/ # Audio player feature (store, hooks, services)
│ ├── playlists/ # Playlists feature (components, hooks, services, tests)
│ ├── profile/ # Profile feature
│ ├── roles/ # Role management feature
│ ├── search/ # Search feature
│ ├── sessions/ # Sessions feature
│ ├── settings/ # Settings feature
│ ├── stream/ # Stream pages
│ ├── streaming/ # Streaming feature (HLS, analytics, bitrate)
│ ├── studio/ # Studio feature
│ ├── tracks/ # Tracks feature (le plus large)
│ ├── upload/ # Upload feature
│ ├── user/ # User profile feature
│ └── webhooks/ # Webhooks feature
├── hooks/ # Hooks partagés (useOnlineStatus, useFormValidation, etc.)
├── lib/ # Utilitaires lib
├── locales/ # Fichiers i18n
├── mocks/ # MSW handlers (1 716 LOC)
├── pages/ # Pages routing (auth, marketplace)
├── providers/ # Providers React
├── router/ # Configuration routing
├── schemas/ # Schemas Zod (validation, API)
├── services/ # Services partagés (API client, websocket, cache, offline queue)
├── stores/ # Zustand stores
├── stories/ # Stories Storybook globales + assets
├── styles/ # 🔴 CSS files séparés (17 fichiers — design-system, tokens, fixes)
├── test/ # Test setup / utilities
├── types/ # Types globaux (generated API types — 7 123 LOC)
└── utils/ # Utilitaires (sanitize, error handler, optimistic updates)
5. Première impression architecturale
L'architecture présente un modèle hybride en transition : un dossier features/ bien structuré coexiste avec un méga-dossier components/ hérité contenant 40+ sous-dossiers qui devraient, pour la plupart, être migrés vers les features correspondantes. Cette dualité crée une ambiguïté sur l'emplacement canonique de chaque composant (ex: components/player/ vs features/player/, components/settings/ vs features/settings/).
La stack technique est moderne et ambitieuse : TypeScript strict, Tailwind v4 CSS-first, Zustand + React Query, Zod validation, MSW mocking, Storybook — c'est un ensemble cohérent et bien choisi pour un SaaS audio. Le design system "KODO" est formalisé via CSS variables avec ~100+ tokens, light/dark mode complet, et des utilitaires custom. L'investissement en outillage (ESLint custom rules pour les tokens, feature flags, Sentry) témoigne d'une volonté de rigueur.
Le volume est considérable pour un pré-MVP : 222K LOC sur 2 092 fichiers, c'est un codebase substantiel. Les 706 as any casts, les ~80 fichiers avec inline styles, et la présence de nombreux TODO indiquent une dette technique significative sous la surface, probablement accumulée lors de phases de développement rapide. Les fichiers de plus de 500 lignes sont concentrés dans les services et tests, pas dans les composants UI — signe que la règle des 300 lignes max est globalement respectée côté UI.
6. Configuration notable
TypeScript
- Strict mode complet activé (
strict: true,noImplicitAny,strictNullChecks,noUncheckedIndexedAccess) - Tests et mocks exclus de la compilation (
excludedans tsconfig) — bon choix - Path aliases configurés (
@/*→./src/*)
Vite
- Build avec manual chunks bien configurés (react, router, tanstack, icons, utils, vendor)
- Source maps cachées en production (
'hidden') - Bundle visualizer en production
- Proxy API configuré pour le dev
Tailwind v4
- Configuration CSS-first via
@theme inlinedansindex.css - Pas de
tailwind.config.tssignificatif (fichier quasi vide, délègue à CSS) - 17 fichiers CSS dans
src/styles/— fragmentation notable
ESLint
- Configuration flat config (ESLint 9)
- Plugin
jsx-a11yactif @typescript-eslint/no-explicit-any: 'off'— ⚠️anyautorisé explicitement- Rules custom pour enforcer les design tokens (pas de Tailwind default colors, pas d'arbitrary values)
- Rule pour forcer
<Button>component au lieu de<button>natif