# ORIGIN_ERROR_PATTERNS.md ## 📋 RÉSUMÉ EXÉCUTIF Ce document catalogue **TOUS** les patterns d'erreurs identifiĂ©s dans le projet Veza pendant la Phase 0 (Error Resolution). Chaque pattern inclut la cause racine, la solution standard, et une checklist de prĂ©vention pour Ă©viter sa rĂ©apparition dans les futures implĂ©mentations. **DerniĂšre mise Ă  jour** : 2026-03-04 **Statut** : ✅ Document de rĂ©fĂ©rence officiel **Version** : 2.0.0 --- ## 🔒 RÈGLES IMMUABLES 1. **TOUJOURS consulter ce document** avant de commencer une nouvelle tĂąche 2. **TOUJOURS vĂ©rifier** qu'aucun pattern d'erreur ne sera introduit 3. **TOUJOURS documenter** tout nouveau pattern dĂ©couvert 4. **JAMAIS contourner** une erreur sans la corriger dĂ©finitivement --- ## 📊 STATISTIQUES DES PATTERNS | CatĂ©gorie | Patterns | FrĂ©quence | PrioritĂ© | |-----------|----------|-----------|----------| | **Backend Go** | 10 | Haute | P0-P1 | | **Frontend TypeScript** | 8 | TrĂšs Haute | P0-P2 | | **Tests** | 6 | Haute | P1-P2 | | **Configuration** | 3 | Moyenne | P0-P1 | | **Lint/Format** | 4 | Haute | P2 | **Total** : 31 patterns documentĂ©s --- ## 1. BACKEND GO - PATTERNS D'ERREURS ### PAT-001: Import Cycles (Circular Dependencies) **CatĂ©gorie** : CAT-01 (Compilation) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Haute **DĂ©couvert** : 2025-11-09 #### Description Import cyclique dĂ©tectĂ© entre packages Go, empĂȘchant la compilation. **Pattern typique** : ``` package A imports package B package B imports package C package C imports package A ← CYCLE DÉTECTÉ ``` **Exemple rĂ©el** : ```go // ❌ ERREUR // internal/services/user_service.go package services import "veza-backend-api/internal/handlers" // Import handlers // internal/handlers/user_handlers.go package handlers import "veza-backend-api/internal/services" // Import services → CYCLE! ``` #### Cause Racine - DĂ©pendances circulaires entre couches (handlers → services → handlers) - Types partagĂ©s dĂ©finis dans le mauvais package - Interfaces dĂ©finies dans les packages qui les utilisent #### Solution Standard **Étape 1** : Identifier le cycle ```bash cd veza-backend-api go list -f '{{join .DepsErrors "\n"}}' ./... | grep -i "cycle" ``` **Étape 2** : CrĂ©er package de types partagĂ©s ```go // ✅ SOLUTION - CrĂ©er internal/types/interfaces.go package types // Interfaces dĂ©finies dans package neutre type UserRepository interface { Create(user *User) error FindByID(id uuid.UUID) (*User, error) } type UserService interface { CreateUser(req *CreateUserRequest) (*User, error) } ``` **Étape 3** : Refactorer les packages ```go // ✅ internal/services/user_service.go package services import "veza-backend-api/internal/types" // Import types seulement type UserService struct { repo types.UserRepository // DĂ©pend de l'interface } // ✅ internal/handlers/user_handlers.go package handlers import "veza-backend-api/internal/types" // Import types seulement func CreateUser(c *gin.Context) { service := types.UserService // Utilise l'interface } ``` #### Checklist de PrĂ©vention - [ ] VĂ©rifier qu'aucun import cycle ne sera créé avant d'ajouter un import - [ ] Utiliser `go mod graph` pour visualiser les dĂ©pendances - [ ] DĂ©finir les interfaces dans `internal/types/` ou `internal/interfaces/` - [ ] Services ne doivent JAMAIS importer handlers - [ ] Handlers ne doivent JAMAIS importer services directement - [ ] Utiliser dependency injection via interfaces #### RĂ©fĂ©rences - **Documentation Go** : https://golang.org/ref/spec#Import_declarations - **Best Practices** : Clean Architecture, Dependency Inversion Principle --- ### PAT-002: Type Mismatches (string vs *string) **CatĂ©gorie** : CAT-01 (Compilation) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description IncohĂ©rence entre types `string` et `*string` (nullable) causant des erreurs de compilation. **Exemple rĂ©el** : ```go // ❌ ERREUR - internal/models/responses.go type User struct { FirstName string `json:"first_name"` // string (non-nullable) } func (ur *UserResponse) FromUser(user *User) { if user.FirstName != nil { // ❌ ERREUR: string ne peut pas ĂȘtre nil ur.FirstName = *user.FirstName // ❌ ERREUR: dĂ©rĂ©fĂ©rencement impossible } } ``` #### Cause Racine - Migration partielle de `*string` vers `string` (ou vice versa) - Manque de cohĂ©rence dans la dĂ©finition des modĂšles - Changement de stratĂ©gie nullable/non-nullable non appliquĂ© partout #### Solution Standard **Option A : Utiliser string (non-nullable)** ```go // ✅ SOLUTION A type User struct { FirstName string `json:"first_name,omitempty"` // string, jamais nil } func (ur *UserResponse) FromUser(user *User) { if user.FirstName != "" { // ✅ VĂ©rifier string vide ur.FirstName = user.FirstName // ✅ Pas de dĂ©rĂ©fĂ©rencement } } ``` **Option B : Utiliser *string (nullable)** ```go // ✅ SOLUTION B type User struct { FirstName *string `json:"first_name,omitempty"` // *string, peut ĂȘtre nil } func (ur *UserResponse) FromUser(user *User) { if user.FirstName != nil { // ✅ VĂ©rifier nil ur.FirstName = *user.FirstName // ✅ DĂ©rĂ©fĂ©rencement correct } } ``` **Recommandation** : Utiliser `string` avec valeur vide `""` pour les champs optionnels (plus simple, moins de pointeurs). #### Checklist de PrĂ©vention - [ ] DĂ©cider une stratĂ©gie cohĂ©rente : `string` ou `*string` pour champs optionnels - [ ] Documenter la dĂ©cision dans `ORIGIN_CODE_STANDARDS.md` - [ ] VĂ©rifier la cohĂ©rence des types avant de modifier un modĂšle - [ ] Utiliser `go vet` pour dĂ©tecter les incohĂ©rences - [ ] Tests unitaires pour valider le comportement nullable/non-nullable #### RĂ©fĂ©rences - **Go Best Practices** : https://go.dev/doc/effective_go#pointers_vs_values --- ### PAT-003: Missing Packages (Packages Not in std) **CatĂ©gorie** : CAT-01 (Compilation) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description Import de packages qui n'existent pas ou ne sont pas dans le module. **Exemple rĂ©el** : ```go // ❌ ERREUR import "veza-backend-api/internal/api/search" // Package n'existe pas import "veza-backend-api/internal/mocks" // Package n'existe pas ``` #### Cause Racine - Packages rĂ©fĂ©rencĂ©s mais jamais créés - Imports non nettoyĂ©s aprĂšs refactoring - Packages dĂ©placĂ©s/renommĂ©s sans mise Ă  jour des imports #### Solution Standard **Étape 1** : Identifier les packages manquants ```bash cd veza-backend-api go build ./... 2>&1 | grep "is not in std" ``` **Étape 2** : Pour chaque package manquant, dĂ©cider : - **Option A** : CrĂ©er le package (si nĂ©cessaire pour la tĂąche) - **Option B** : Retirer l'import (si non utilisĂ©) - **Option C** : CrĂ©er un stub minimal (si nĂ©cessaire pour compilation) **Option A - CrĂ©er le package** : ```go // ✅ CrĂ©er internal/api/search/handler.go package search import "github.com/gin-gonic/gin" func SearchHandler(c *gin.Context) { // Stub minimal pour permettre compilation c.JSON(200, gin.H{"message": "Search endpoint - TODO: implement"}) } ``` **Option B - Retirer l'import** : ```go // ✅ Retirer l'import non utilisĂ© // import "veza-backend-api/internal/api/search" ← SUPPRIMÉ ``` #### Checklist de PrĂ©vention - [ ] VĂ©rifier que tous les packages importĂ©s existent avant commit - [ ] Nettoyer les imports non utilisĂ©s avec `goimports -w .` - [ ] CrĂ©er les packages nĂ©cessaires AVANT de les importer - [ ] Utiliser `go mod tidy` pour nettoyer les dĂ©pendances - [ ] VĂ©rifier avec `go build ./...` aprĂšs chaque modification #### RĂ©fĂ©rences - **Go Modules** : https://go.dev/ref/mod --- ### PAT-004: Missing Dependencies (go.mod) **CatĂ©gorie** : CAT-03 (DĂ©pendances) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Basse **DĂ©couvert** : 2025-11-09 #### Description DĂ©pendance Go manquante dans `go.mod`. **Exemple rĂ©el** : ```go // ❌ ERREUR import "github.com/crewjam/saml/samlsp" // Error: no required module provides package github.com/crewjam/saml/samlsp ``` #### Solution Standard ```bash cd veza-backend-api go get github.com/crewjam/saml/samlsp go mod tidy ``` #### Checklist de PrĂ©vention - [ ] VĂ©rifier que toutes les dĂ©pendances sont dans `go.mod` - [ ] Utiliser `go mod tidy` rĂ©guliĂšrement - [ ] Documenter les nouvelles dĂ©pendances dans `ORIGIN_TECHNICAL_STACK.md` --- ### PAT-005: Undefined Types/Variables **CatĂ©gorie** : CAT-01 (Compilation) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Basse **DĂ©couvert** : 2025-11-09 #### Description Utilisation de types ou variables non dĂ©finis. **Exemple rĂ©el** : ```go // ❌ ERREUR // internal/database/chat_repository.go var db *DB // Type DB non dĂ©fini ``` #### Solution Standard - VĂ©rifier que le type existe dans le package ou un package importĂ© - Importer le package contenant le type - CrĂ©er le type si nĂ©cessaire #### Checklist de PrĂ©vention - [ ] VĂ©rifier que tous les types utilisĂ©s sont dĂ©finis - [ ] Utiliser `go vet` pour dĂ©tecter les problĂšmes - [ ] IDE (VS Code/GoLand) devrait signaler les erreurs en temps rĂ©el --- ### PAT-024: JWT Issuer/Audience Mismatch **CatĂ©gorie** : CAT-02 (Configuration) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2026-03-04 (Audit) #### Description Le token JWT est rejetĂ© car l'issuer (`iss`) ou l'audience (`aud`) ne correspond pas Ă  la configuration attendue par le service de validation. Cela provoque des erreurs d'authentification silencieuses ou des 401 intermittents. **Exemple rĂ©el** : ```go // ❌ ERREUR - issuer codĂ© en dur, diffĂ©rent entre services func ValidateToken(tokenString string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { return []byte(os.Getenv("JWT_SECRET")), nil }) // Pas de vĂ©rification de iss/aud → token acceptĂ© mĂȘme si Ă©mis par un autre service } ``` #### Cause Racine - Issuer/audience non validĂ©s lors du parsing JWT - Configuration diffĂ©rente entre le service d'Ă©mission et le service de validation - Variables d'environnement `JWT_ISSUER` et `JWT_AUDIENCE` absentes ou incohĂ©rentes #### Solution Standard ```go // ✅ SOLUTION - Valider issuer et audience explicitement func ValidateToken(tokenString string) (*Claims, error) { expectedIssuer := config.GetJWTIssuer() expectedAudience := config.GetJWTAudience() token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { return []byte(config.GetJWTSecret()), nil }, jwt.WithIssuer(expectedIssuer), jwt.WithAudience(expectedAudience), ) if err != nil { return nil, fmt.Errorf("token validation failed: %w", err) } return token.Claims.(*Claims), nil } ``` #### Checklist de PrĂ©vention - [ ] Valider `iss` et `aud` lors de chaque parsing JWT - [ ] Centraliser la configuration JWT dans un seul package (`internal/auth/config.go`) - [ ] VĂ©rifier la cohĂ©rence des variables `JWT_ISSUER` et `JWT_AUDIENCE` au dĂ©marrage - [ ] Tests unitaires couvrant les cas de mismatch issuer/audience - [ ] Documenter la configuration JWT dans `.env.example` --- ### PAT-025: Context Propagation Manquante **CatĂ©gorie** : CAT-04 (Runtime) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Haute **DĂ©couvert** : 2026-03-04 (Audit) #### Description Utilisation de `context.Background()` ou `context.TODO()` dans les handlers HTTP au lieu de propager le contexte de la requĂȘte (`c.Request.Context()`). Cela empĂȘche la propagation des deadlines, l'annulation des requĂȘtes, et le tracing distribuĂ©. **Exemple rĂ©el** : ```go // ❌ ERREUR - context.Background() utilisĂ© dans un handler func (h *TrackHandler) GetTrack(c *gin.Context) { track, err := h.trackService.GetByID(context.Background(), trackID) // Le context de la requĂȘte HTTP est ignorĂ© } ``` #### Cause Racine - Habitude de passer `context.Background()` par facilitĂ© - Manque de convention de propagation du contexte - Absence de linter rule pour dĂ©tecter ce pattern #### Solution Standard ```go // ✅ SOLUTION - Propager le contexte de la requĂȘte func (h *TrackHandler) GetTrack(c *gin.Context) { ctx := c.Request.Context() track, err := h.trackService.GetByID(ctx, trackID) } ``` #### Checklist de PrĂ©vention - [ ] Toujours utiliser `c.Request.Context()` dans les handlers Gin - [ ] Ajouter une rĂšgle golangci-lint (contextcheck) pour dĂ©tecter `context.Background()` dans les handlers - [ ] Propager le contexte dans toute la chaĂźne service → repository → database - [ ] Code review systĂ©matique sur l'usage du contexte - [ ] Grep rĂ©gulier : `grep -rn "context.Background()" internal/handlers/` --- ### PAT-026: Goroutine Leak Patterns **CatĂ©gorie** : CAT-04 (Runtime) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2026-03-04 (Audit) #### Description Goroutines lancĂ©es sans mĂ©canisme d'arrĂȘt (context, done channel, WaitGroup), provoquant des fuites de goroutines qui consomment de la mĂ©moire et des ressources indĂ©finiment. **Exemple rĂ©el** : ```go // ❌ ERREUR - goroutine sans mĂ©canisme d'arrĂȘt func (s *StreamService) StartProcessing() { go func() { for { s.processQueue() time.Sleep(5 * time.Second) } }() } ``` #### Cause Racine - Goroutines lancĂ©es avec `go func()` sans condition d'arrĂȘt - Absence de `context.Context` pour signaler l'annulation - Pas de `sync.WaitGroup` pour attendre la fin des goroutines au shutdown #### Solution Standard ```go // ✅ SOLUTION - Goroutine avec contexte et WaitGroup func (s *StreamService) StartProcessing(ctx context.Context, wg *sync.WaitGroup) { wg.Add(1) go func() { defer wg.Done() ticker := time.NewTicker(5 * time.Second) defer ticker.Stop() for { select { case <-ctx.Done(): return case <-ticker.C: s.processQueue(ctx) } } }() } ``` #### Checklist de PrĂ©vention - [ ] Toute goroutine doit recevoir un `context.Context` pour l'annulation - [ ] Utiliser `sync.WaitGroup` pour le graceful shutdown - [ ] Utiliser `select` avec `ctx.Done()` dans les boucles - [ ] Monitorer le nombre de goroutines en production (`runtime.NumGoroutine()`) - [ ] Tests avec `goleak` pour dĂ©tecter les fuites de goroutines --- ### PAT-027: Pagination Sans Limite Max **CatĂ©gorie** : CAT-04 (Runtime) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2026-03-04 (Audit) #### Description Les endpoints paginĂ©s acceptent des valeurs `limit` arbitrairement grandes sans borne supĂ©rieure, permettant Ă  un client de demander des millions d'enregistrements en une seule requĂȘte (risque de DoS, OOM). **Exemple rĂ©el** : ```go // ❌ ERREUR - pas de limite max func (h *TrackHandler) ListTracks(c *gin.Context) { limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20")) offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0")) // limit peut valoir 999999999 → charge mĂ©moire excessive tracks, err := h.trackService.List(ctx, limit, offset) } ``` #### Cause Racine - Validation insuffisante des paramĂštres de pagination - Absence de constante `MaxPageSize` partagĂ©e - Confiance implicite dans les paramĂštres du client #### Solution Standard ```go // ✅ SOLUTION - Valider et borner les paramĂštres de pagination const ( DefaultPageSize = 20 MaxPageSize = 100 ) func parsePagination(c *gin.Context) (limit, offset int) { limit, _ = strconv.Atoi(c.DefaultQuery("limit", strconv.Itoa(DefaultPageSize))) offset, _ = strconv.Atoi(c.DefaultQuery("offset", "0")) if limit <= 0 { limit = DefaultPageSize } if limit > MaxPageSize { limit = MaxPageSize } if offset < 0 { offset = 0 } return limit, offset } ``` #### Checklist de PrĂ©vention - [ ] DĂ©finir `MaxPageSize` comme constante partagĂ©e (ex. `internal/api/pagination.go`) - [ ] Valider et borner `limit` dans tous les endpoints paginĂ©s - [ ] Valider que `offset` est ≄ 0 - [ ] Tests unitaires pour les cas limites (limit=0, limit=-1, limit=999999) - [ ] Documenter les limites de pagination dans l'API specification --- ### PAT-028: Error Handling Inconsistant (gin.H vs RespondWithAppError) **CatĂ©gorie** : CAT-04 (Runtime) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Haute **DĂ©couvert** : 2026-03-04 (Audit) #### Description MĂ©lange de deux patterns de rĂ©ponse d'erreur dans les handlers : `gin.H{"error": ...}` (format ad hoc) et `RespondWithAppError()` (format standardisĂ©). Cela crĂ©e des rĂ©ponses d'erreur inconsistantes cĂŽtĂ© client, compliquant le parsing et le traitement des erreurs frontend. **Exemple rĂ©el** : ```go // ❌ ERREUR - MĂ©lange de formats dans le mĂȘme handler func (h *TrackHandler) CreateTrack(c *gin.Context) { if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) // Format ad hoc return } track, err := h.service.Create(ctx, &req) if err != nil { RespondWithAppError(c, err) // Format standardisĂ© return } } ``` #### Cause Racine - Migration partielle vers `RespondWithAppError` - Pas de convention imposĂ©e par linter - Copier-coller de code ancien utilisant `gin.H` #### Solution Standard ```go // ✅ SOLUTION - Utiliser exclusivement RespondWithAppError func (h *TrackHandler) CreateTrack(c *gin.Context) { if err := c.ShouldBindJSON(&req); err != nil { RespondWithAppError(c, apperrors.NewValidationError("invalid request body", err)) return } track, err := h.service.Create(ctx, &req) if err != nil { RespondWithAppError(c, err) return } c.JSON(http.StatusCreated, track) } ``` #### Checklist de PrĂ©vention - [ ] Utiliser exclusivement `RespondWithAppError` pour toutes les rĂ©ponses d'erreur - [ ] Grep rĂ©gulier : `grep -rn 'gin.H{"error"' internal/handlers/` → doit retourner 0 rĂ©sultat - [ ] Envelopper les erreurs de validation dans `apperrors.NewValidationError()` - [ ] Code review systĂ©matique sur le format des rĂ©ponses d'erreur - [ ] Documenter le format standardisĂ© dans `ORIGIN_API_SPECIFICATION.md` --- ## 2. FRONTEND TYPESCRIPT/REACT - PATTERNS D'ERREURS ### PAT-006: Syntax Errors - Unterminated Regex **CatĂ©gorie** : CAT-01 (Compilation) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description Regex non terminĂ©e dans les tests, causant une erreur de syntaxe. **Exemple rĂ©el** : ```typescript // ❌ ERREUR - src/features/auth/hooks/useOAuthCallback.test.ts expect(mockNavigate).toHaveBeenCalledWith('/dashboard/ // ← Guillemet manquant ``` #### Cause Racine - Copier-coller incomplet - Erreur de frappe - Éditeur qui n'a pas signalĂ© l'erreur #### Solution Standard ```typescript // ✅ FIX expect(mockNavigate).toHaveBeenCalledWith('/dashboard'); // Guillemet fermant ajoutĂ© ``` #### Checklist de PrĂ©vention - [ ] Utiliser un linter en temps rĂ©el (ESLint dans VS Code) - [ ] VĂ©rifier la syntaxe avant de sauvegarder - [ ] Utiliser `npm run type-check` avant commit - [ ] Pre-commit hook devrait bloquer les erreurs de syntaxe --- ### PAT-007: Syntax Errors - Unclosed JSX Tags **CatĂ©gorie** : CAT-01 (Compilation) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description Balises JSX non fermĂ©es, causant des erreurs de compilation. **Exemple rĂ©el** : ```typescript // ❌ ERREUR - src/features/playlists/components/PlaylistList.tsx
{playlists.map(p => )} // ← Pas de ni
``` #### Solution Standard ```typescript // ✅ FIX
{playlists.map(p => )} // Self-closing tag
// Tag fermant ajoutĂ© ``` #### Checklist de PrĂ©vention - [ ] Utiliser Prettier pour formater automatiquement - [ ] VĂ©rifier que tous les tags JSX sont fermĂ©s - [ ] Utiliser l'extension React dans VS Code - [ ] `tsc --noEmit` devrait dĂ©tecter ces erreurs --- ### PAT-008: Configuration Errors - vite.config.ts Type Issues **CatĂ©gorie** : CAT-02 (Configuration) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Basse **DĂ©couvert** : 2025-11-09 #### Description IncompatibilitĂ© de types dans la configuration Vite. **Exemple rĂ©el** : ```typescript // ❌ ERREUR - vite.config.ts build: { terserOptions: { compress: { drop_console: true, // Type incompatibilitĂ© } } } ``` #### Solution Standard **Option A - Utiliser esbuild (recommandĂ©)** : ```typescript // ✅ SOLUTION A build: { minify: 'esbuild', // Plus moderne, plus rapide // Pas besoin de terserOptions } ``` **Option B - Corriger terserOptions** : ```typescript // ✅ SOLUTION B build: { minify: 'terser', terserOptions: { compress: { drop_console: process.env.NODE_ENV === 'production', }, } as any, // Type assertion si nĂ©cessaire } ``` #### Checklist de PrĂ©vention - [ ] Utiliser esbuild au lieu de terser (plus moderne) - [ ] VĂ©rifier la compatibilitĂ© des types avec `tsc --noEmit` - [ ] Consulter la documentation Vite pour les types corrects - [ ] Tester le build aprĂšs modification de la config --- ### PAT-009: Type Errors - Missing Type Definitions **CatĂ©gorie** : CAT-01 (Compilation) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Haute **DĂ©couvert** : 2025-11-09 #### Description Types TypeScript manquants ou incorrects. **Exemple rĂ©el** : ```typescript // ❌ ERREUR const user: User = { // Type User non dĂ©fini id: '123', name: 'John' } ``` #### Solution Standard ```typescript // ✅ FIX - DĂ©finir le type interface User { id: string; name: string; } const user: User = { id: '123', name: 'John' } ``` #### Checklist de PrĂ©vention - [ ] Toujours dĂ©finir les types avant utilisation - [ ] Utiliser `strict: true` dans `tsconfig.json` - [ ] Éviter `any` (utiliser `unknown` si nĂ©cessaire) - [ ] VĂ©rifier avec `tsc --noEmit --strict` --- ### PAT-010: Lint Errors - Unused Variables **CatĂ©gorie** : CAT-07 (Lint/Format) **PrioritĂ©** : P2 (Moyenne) **FrĂ©quence** : TrĂšs Haute **DĂ©couvert** : 2025-11-09 #### Description Variables dĂ©clarĂ©es mais jamais utilisĂ©es. **Exemple rĂ©el** : ```typescript // ❌ ERREUR const user = getUser(); // Variable dĂ©clarĂ©e mais non utilisĂ©e console.log('Hello'); ``` #### Solution Standard **Option A - Supprimer la variable** : ```typescript // ✅ SOLUTION A // const user = getUser(); ← SupprimĂ© console.log('Hello'); ``` **Option B - PrĂ©fixer avec underscore** : ```typescript // ✅ SOLUTION B - Si la variable sera utilisĂ©e plus tard const _user = getUser(); // PrĂ©fixe _ indique intentionnellement non utilisĂ© console.log('Hello'); ``` #### Checklist de PrĂ©vention - [ ] Supprimer les variables non utilisĂ©es - [ ] Utiliser `npm run lint -- --fix` pour auto-fix - [ ] Configurer ESLint pour signaler en temps rĂ©el - [ ] Pre-commit hook devrait bloquer les erreurs lint --- ### PAT-011: Lint Errors - Console Statements **CatĂ©gorie** : CAT-07 (Lint/Format) **PrioritĂ©** : P2 (Moyenne) **FrĂ©quence** : Haute **DĂ©couvert** : 2025-11-09 #### Description Utilisation de `console.log` en production (interdit par lint rules). **Exemple rĂ©el** : ```typescript // ❌ ERREUR console.log('Debug info'); // no-console rule ``` #### Solution Standard **Option A - Supprimer en production** : ```typescript // ✅ SOLUTION A if (process.env.NODE_ENV === 'development') { console.log('Debug info'); } ``` **Option B - Utiliser un logger** : ```typescript // ✅ SOLUTION B import { logger } from '@/utils/logger'; logger.debug('Debug info'); // Logger gĂšre l'environnement ``` #### Checklist de PrĂ©vention - [ ] Ne pas utiliser `console.log` en production - [ ] Utiliser un logger configurĂ© - [ ] ESLint devrait bloquer `console.*` en production - [ ] Vite supprime automatiquement les console en build production --- ### PAT-012: Lint Errors - Any Types **CatĂ©gorie** : CAT-07 (Lint/Format) **PrioritĂ©** : P2 (Moyenne) **FrĂ©quence** : Haute **DĂ©couvert** : 2025-11-09 #### Description Utilisation de `any` au lieu de types spĂ©cifiques. **Exemple rĂ©el** : ```typescript // ❌ ERREUR function processData(data: any) { // any interdit return data.value; } ``` #### Solution Standard ```typescript // ✅ FIX - Typer correctement interface Data { value: string; } function processData(data: Data) { return data.value; } // OU utiliser unknown si le type est vraiment inconnu function processData(data: unknown) { if (typeof data === 'object' && data !== null && 'value' in data) { return (data as { value: string }).value; } throw new Error('Invalid data'); } ``` #### Checklist de PrĂ©vention - [ ] Éviter `any` (utiliser `unknown` si nĂ©cessaire) - [ ] Typer toutes les fonctions et variables - [ ] Utiliser `strict: true` dans `tsconfig.json` - [ ] ESLint devrait bloquer `any` explicit --- ### PAT-013: Missing Return Types **CatĂ©gorie** : CAT-07 (Lint/Format) **PrioritĂ©** : P2 (Moyenne) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description Fonctions sans type de retour explicite. **Exemple rĂ©el** : ```typescript // ❌ ERREUR function getUser(id: string) { // Type de retour manquant return { id, name: 'John' }; } ``` #### Solution Standard ```typescript // ✅ FIX interface User { id: string; name: string; } function getUser(id: string): User { // Type de retour explicite return { id, name: 'John' }; } ``` #### Checklist de PrĂ©vention - [ ] Toujours typer le retour des fonctions - [ ] Utiliser `@typescript-eslint/explicit-function-return-type` - [ ] TypeScript peut infĂ©rer, mais explicite est mieux --- ## 3. TESTS - PATTERNS D'ERREURS ### PAT-014: Test Failures - Missing Mocks **CatĂ©gorie** : CAT-05 (Tests) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : TrĂšs Haute **DĂ©couvert** : 2025-11-09 #### Description Tests Ă©chouent car les mocks ne sont pas configurĂ©s. **Exemple rĂ©el** : ```typescript // ❌ ERREUR it('should fetch user', async () => { const user = await userService.getUser('123'); // userService non mockĂ© expect(user).toBeDefined(); }); // Error: Cannot read property 'data' of undefined ``` #### Solution Standard ```typescript // ✅ FIX import { vi } from 'vitest'; vi.mock('@/services/user', () => ({ userService: { getUser: vi.fn().mockResolvedValue({ id: '123', name: 'John' }) } })); it('should fetch user', async () => { const user = await userService.getUser('123'); expect(user).toBeDefined(); }); ``` #### Checklist de PrĂ©vention - [ ] Toujours mocker les dĂ©pendances externes - [ ] Utiliser `vi.mock()` pour les modules - [ ] Configurer les mocks dans `beforeEach` si rĂ©utilisĂ©s - [ ] VĂ©rifier que les mocks correspondent aux vrais services --- ### PAT-015: Test Failures - React act() Warnings **CatĂ©gorie** : CAT-05 (Tests) **PrioritĂ©** : P2 (Moyenne) **FrĂ©quence** : Haute **DĂ©couvert** : 2025-11-09 #### Description Avertissements React `act()` dans les tests. **Exemple rĂ©el** : ```typescript // ❌ WARNING Warning: An update to Component inside a test was not wrapped in act(...). ``` #### Solution Standard ```typescript // ✅ FIX import { act, render, screen } from '@testing-library/react'; it('should update state', async () => { render(); await act(async () => { fireEvent.click(screen.getByRole('button')); await waitFor(() => { expect(screen.getByText('Updated')).toBeInTheDocument(); }); }); }); ``` #### Checklist de PrĂ©vention - [ ] Utiliser `act()` pour les mises Ă  jour d'Ă©tat - [ ] Utiliser `waitFor()` pour les mises Ă  jour asynchrones - [ ] `@testing-library/react` gĂšre `act()` automatiquement dans la plupart des cas - [ ] VĂ©rifier les warnings dans les logs de tests --- ### PAT-016: Test Failures - WebSocket Mocking Issues **CatĂ©gorie** : CAT-05 (Tests) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description ProblĂšmes de mock WebSocket dans les tests. **Exemple rĂ©el** : ```typescript // ❌ ERREUR TypeError: realWebSocket.addEventListener is not a function ``` #### Solution Standard ```typescript // ✅ FIX - Mocker WebSocket globalement global.WebSocket = class MockWebSocket { addEventListener = vi.fn(); removeEventListener = vi.fn(); send = vi.fn(); close = vi.fn(); readyState = WebSocket.OPEN; } as any; ``` #### Checklist de PrĂ©vention - [ ] Mocker WebSocket dans `setupTests.ts` - [ ] Utiliser une bibliothĂšque de mock WebSocket si nĂ©cessaire - [ ] Tester les connexions WebSocket sĂ©parĂ©ment --- ### PAT-017: Test Failures - Outdated Assertions **CatĂ©gorie** : CAT-05 (Tests) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Haute **DĂ©couvert** : 2025-11-09 #### Description Assertions de tests obsolĂštes aprĂšs changement d'API. **Exemple rĂ©el** : ```typescript // ❌ ERREUR - API changĂ©e expect(result).toEqual({ success: true }); // API retourne maintenant: { status: 'success', data: {...} } ``` #### Solution Standard ```typescript // ✅ FIX - Adapter aux nouveaux contracts expect(result).toEqual({ status: 'success', data: expect.objectContaining({ id: expect.any(String), name: expect.any(String), }) }); ``` #### Checklist de PrĂ©vention - [ ] Mettre Ă  jour les tests lors de changement d'API - [ ] Utiliser des matchers flexibles (`expect.objectContaining`) - [ ] Contract testing pour valider les APIs - [ ] Snapshot testing pour dĂ©tecter les changements --- ### PAT-018: Test Failures - Missing Test Data **CatĂ©gorie** : CAT-05 (Tests) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description Tests Ă©chouent car les donnĂ©es de test sont manquantes. #### Solution Standard ```typescript // ✅ FIX - CrĂ©er fixtures // tests/fixtures/users.ts export const testUsers = { normalUser: { id: 'user-123', email: 'user@example.com', name: 'Test User', }, }; // test import { testUsers } from '@/tests/fixtures/users'; it('should work', () => { const user = testUsers.normalUser; // ... }); ``` #### Checklist de PrĂ©vention - [ ] CrĂ©er des fixtures rĂ©utilisables - [ ] Centraliser les donnĂ©es de test - [ ] Utiliser des factories pour gĂ©nĂ©rer des donnĂ©es --- ### PAT-019: Test Coverage Below Threshold **CatĂ©gorie** : CAT-05 (Tests) **PrioritĂ©** : P1 (Haute) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description Couverture de tests en dessous du seuil de 80%. #### Solution Standard - Identifier le code non testĂ© - Écrire des tests pour les branches manquantes - Utiliser `--coverage` pour voir les dĂ©tails #### Checklist de PrĂ©vention - [ ] Maintenir coverage ≄ 80% - [ ] CI/CD devrait bloquer si coverage < 80% - [ ] Écrire les tests en mĂȘme temps que le code (TDD) --- ## 4. CONFIGURATION - PATTERNS D'ERREURS ### PAT-020: Missing Environment Variables **CatĂ©gorie** : CAT-02 (Configuration) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Basse **DĂ©couvert** : 2025-11-09 #### Description Variables d'environnement manquantes. #### Solution Standard - Documenter toutes les variables requises dans `.env.example` - Valider les variables au dĂ©marrage - Utiliser des valeurs par dĂ©faut si appropriĂ© #### Checklist de PrĂ©vention - [ ] Documenter toutes les variables dans `.env.example` - [ ] Valider les variables au dĂ©marrage - [ ] Utiliser `dotenv` pour charger les variables --- ### PAT-021: Docker Configuration Errors **CatĂ©gorie** : CAT-06 (Docker) **PrioritĂ©** : P0 (Critique) **FrĂ©quence** : Basse **DĂ©couvert** : 2025-11-09 #### Description Erreurs de syntaxe YAML dans `docker-compose.yml`. #### Solution Standard - Valider la syntaxe YAML avec `docker-compose config` - VĂ©rifier l'indentation (espaces, pas tabs) - Utiliser un validateur YAML #### Checklist de PrĂ©vention - [ ] Valider `docker-compose.yml` avant commit - [ ] Utiliser 2 espaces pour l'indentation - [ ] VĂ©rifier les guillemets et caractĂšres spĂ©ciaux --- ## 5. LINT/FORMAT - PATTERNS D'ERREURS ### PAT-022: Code Formatting Issues **CatĂ©gorie** : CAT-07 (Lint/Format) **PrioritĂ©** : P2 (Moyenne) **FrĂ©quence** : Haute **DĂ©couvert** : 2025-11-09 #### Description Code non formatĂ© selon les standards. #### Solution Standard ```bash # Auto-fix avec Prettier npm run format # Auto-fix avec ESLint npm run lint -- --fix ``` #### Checklist de PrĂ©vention - [ ] Utiliser Prettier pour formater automatiquement - [ ] Pre-commit hook devrait formater avant commit - [ ] Configurer l'Ă©diteur pour formater Ă  la sauvegarde --- ### PAT-023: Import Order Issues **CatĂ©gorie** : CAT-07 (Lint/Format) **PrioritĂ©** : P2 (Moyenne) **FrĂ©quence** : Moyenne **DĂ©couvert** : 2025-11-09 #### Description Imports non triĂ©s selon les rĂšgles. #### Solution Standard - Utiliser `eslint-plugin-import` avec rĂšgle de tri - Auto-fix avec `npm run lint -- --fix` #### Checklist de PrĂ©vention - [ ] Configurer ESLint pour trier les imports - [ ] Auto-fix devrait corriger automatiquement --- ## 📊 RÉSUMÉ DES CHECKLISTS PAR CATÉGORIE ### Backend Go - [ ] VĂ©rifier import cycles avant d'ajouter un import - [ ] Maintenir cohĂ©rence string vs *string - [ ] VĂ©rifier que tous les packages importĂ©s existent - [ ] Utiliser `go vet` et `golangci-lint` - [ ] Tests unitaires pour chaque fonction - [ ] Valider JWT issuer/audience dans la config et au parsing - [ ] Propager `c.Request.Context()` dans tous les handlers (jamais `context.Background()`) - [ ] Toute goroutine reçoit un `context.Context` et un mĂ©canisme d'arrĂȘt - [ ] Pagination bornĂ©e par `MaxPageSize` sur tous les endpoints - [ ] Utiliser exclusivement `RespondWithAppError` (jamais `gin.H{"error": ...}`) ### Frontend TypeScript/React - [ ] Linter en temps rĂ©el activĂ© - [ ] TypeScript strict mode activĂ© - [ ] Tous les tags JSX fermĂ©s - [ ] Pas de `any` types - [ ] Pas de `console.log` en production - [ ] Prettier configurĂ© ### Tests - [ ] Mocks configurĂ©s pour toutes les dĂ©pendances - [ ] Coverage ≄ 80% - [ ] Tests passent avant commit - [ ] Fixtures rĂ©utilisables ### Configuration - [ ] Variables d'environnement documentĂ©es - [ ] docker-compose.yml validĂ© - [ ] vite.config.ts types corrects --- ## 🔄 MAINTENANCE ### Ajouter un Nouveau Pattern 1. Identifier le pattern rĂ©current 2. Documenter dans ce fichier avec le format standard 3. Mettre Ă  jour les statistiques 4. Ajouter Ă  la checklist de prĂ©vention appropriĂ©e 5. Mettre Ă  jour `ORIGIN_ERROR_PREVENTION_GUIDE.md` ### RĂ©vision - **FrĂ©quence** : Mensuelle - **Responsable** : Lead Engineers - **Processus** : Analyser les nouvelles erreurs, documenter les patterns --- **DerniĂšre mise Ă  jour** : 2026-03-04 **Version** : 2.0.0 **Statut** : ✅ **APPROUVÉ ET VERROUILLÉ**