# ORIGIN_ERROR_PREVENTION_GUIDE.md

## 📋 RÉSUMÉ EXÉCUTIF

Ce document définit le **système complet de prévention d'erreurs** pour le projet Veza. Il s'intègre parfaitement à la méthodologie ORIGIN_ existante et doit être appliqué **AVANT** de commencer toute nouvelle tâche d'implémentation. Ce guide garantit qu'aucune erreur récurrente ne sera introduite dans le codebase.

**Dernière mise à jour** : 2025-11-09  
**Statut** : ✅ Document de référence officiel  
**Version** : 1.0.0

---

## 🎯 OBJECTIFS

### Objectif Principal
Établir un système de prévention d'erreurs qui garantit qu'aucune erreur récurrente ne sera introduite dans les futures implémentations.

### Objectifs Secondaires
- Réduire le temps de correction d'erreurs (< 5% du temps de développement)
- Maintenir la qualité du code (0 erreurs P0/P1)
- Faciliter l'onboarding (checklists claires)
- Standardiser les patterns de code (templates validés)

---

## 🔒 RÈGLES IMMUABLES

1. **Pre-Flight Check OBLIGATOIRE** avant toute nouvelle tâche
2. **Templates OBLIGATOIRES** pour créer de nouveaux fichiers
3. **Quality Gates BLOQUANTS** en CI/CD
4. **Aucune exception** sans approbation Lead Engineer
5. **Documentation OBLIGATOIRE** de tout nouveau pattern d'erreur

---

## 📖 TABLE DES MATIÈRES

1. [Pre-Flight Checklists](#1-pre-flight-checklists)
2. [Implementation Patterns](#2-implementation-patterns)
3. [Validation Gates](#3-validation-gates)
4. [Templates de Code](#4-templates-de-code)
5. [Workflow Intégré](#5-workflow-intégré)
6. [Références](#6-références)

---

## 1. PRE-FLIGHT CHECKLISTS

### 1.1 Checklist Globale (Avant TOUTE Tâche)

**OBLIGATOIRE** : Exécuter cette checklist avant de commencer une nouvelle tâche.

```bash
# Exécuter le script de pre-flight check
./scripts/pre-flight-check.sh
```

**Checklist manuelle** :

- [ ] Aucune erreur P0/P1 existante (vérifier avec `./scripts/discover-errors.sh`)
- [ ] Tests existants passent (`go test ./...` / `npm test`)
- [ ] Linter ne produit aucune erreur (`golangci-lint run` / `npm run lint`)
- [ ] Code est à jour avec `main` (`git pull origin main`)
- [ ] Branche créée pour la tâche (`git checkout -b feature/TXXXX-description`)

---

### 1.2 Checklist Backend Go

**Avant de créer/modifier du code Go** :

- [ ] Vérifier qu'aucun import cycle ne sera créé
  ```bash
  # Visualiser le graphe de dépendances
  cd veza-backend-api
  go mod graph | grep -i "cycle"
  ```
- [ ] Valider la cohérence des types (string vs *string)
  - Consulter `ORIGIN_ERROR_PATTERNS.md` PAT-002
  - Décider une stratégie cohérente avant de modifier un modèle
- [ ] Vérifier que tous les packages importés existent
  ```bash
  go build ./...  # Doit réussir sans erreur
  ```
- [ ] Tests unitaires du composant parent passent
  ```bash
  go test ./internal/services/... -v
  ```
- [ ] `go vet` ne produit aucun warning
  ```bash
  go vet ./...
  ```
- [ ] `golangci-lint` ne produit aucune erreur
  ```bash
  golangci-lint run
  ```

**Patterns à éviter** :
- ❌ Services qui importent handlers
- ❌ Handlers qui importent services directement
- ❌ Types partagés dans les packages qui les utilisent
- ❌ Mélange de `string` et `*string` pour champs optionnels

**Patterns sûrs** :
- ✅ Interfaces dans `internal/types/` ou `internal/interfaces/`
- ✅ Services dépendent uniquement d'interfaces
- ✅ Handlers dépendent uniquement d'interfaces
- ✅ Types cohérents (toujours `string` OU toujours `*string`)

---

### 1.3 Checklist Frontend React/TypeScript

**Avant de créer/modifier du code TypeScript/React** :

- [ ] Vérifier que `tsconfig.json` est correct
  ```bash
  cd apps/web
  npx tsc --noEmit --strict
  ```
- [ ] Linter ne produit aucune erreur sur fichiers modifiés
  ```bash
  npm run lint
  ```
- [ ] Tests existants passent avant modification
  ```bash
  npm test -- --run
  ```
- [ ] Types TypeScript sont stricts (pas de `any`)
  - Vérifier avec `tsc --noEmit --strict`
  - Utiliser `unknown` si le type est vraiment inconnu
- [ ] JSX syntax validée (Prettier)
  ```bash
  npm run format
  ```
- [ ] Pas de `console.log` en production
  - Utiliser un logger configuré
  - ESLint devrait bloquer automatiquement

**Patterns à éviter** :
- ❌ Regex non terminées dans les tests
- ❌ Tags JSX non fermés
- ❌ Types `any` explicites
- ❌ Variables non utilisées
- ❌ `console.log` en production

**Patterns sûrs** :
- ✅ Types explicites pour toutes les fonctions
- ✅ Self-closing tags JSX (`<Component />`)
- ✅ Mocks configurés pour tous les tests
- ✅ Logger au lieu de `console.log`

---

### 1.4 Checklist Services Rust

**Avant de créer/modifier du code Rust** :

- [ ] `cargo check` passe
  ```bash
  cd veza-chat-server  # ou veza-stream-server
  cargo check
  ```
- [ ] `cargo clippy` ne produit aucun warning
  ```bash
  cargo clippy -- -D warnings
  ```
- [ ] SQLx queries validées avec schema
  ```bash
  cargo sqlx prepare --check
  ```
- [ ] Tests unitaires passent
  ```bash
  cargo test
  ```

**Patterns à éviter** :
- ❌ `unwrap()` en production (utiliser `?` ou gestion d'erreur)
- ❌ Types `i32` pour IDs (utiliser `Uuid`)
- ❌ Queries SQL non validées

**Patterns sûrs** :
- ✅ Gestion d'erreur avec `Result<T, E>`
- ✅ Types `Uuid` pour tous les IDs
- ✅ SQLx queries validées avec `sqlx::query!`

---

## 2. IMPLEMENTATION PATTERNS

### 2.1 Backend Service Pattern

**Pattern sûr pour créer un nouveau service** :

```go
// ✅ PATTERN SÛR - Évite import cycles
// internal/services/user_service.go
package services

import (
    "context"
    "veza-backend-api/internal/types"  // Interfaces dans package neutre
    "veza-backend-api/internal/models"
)

// UserService implémente l'interface définie dans types
type UserService struct {
    repo types.UserRepository  // Dépend de l'interface, pas de l'implémentation
    logger types.Logger
}

// NewUserService crée une nouvelle instance
func NewUserService(repo types.UserRepository, logger types.Logger) *UserService {
    return &UserService{
        repo: repo,
        logger: logger,
    }
}

// CreateUser crée un nouvel utilisateur
func (s *UserService) CreateUser(ctx context.Context, req *CreateUserRequest) (*models.User, error) {
    // Validation
    if err := s.validateCreateRequest(req); err != nil {
        return nil, err
    }
    
    // Business logic
    user := &models.User{
        Email:    req.Email,
        Username: req.Username,
    }
    
    // Persistence
    if err := s.repo.Create(ctx, user); err != nil {
        return nil, fmt.Errorf("failed to create user: %w", err)
    }
    
    return user, nil
}

// validateCreateRequest valide la requête
func (s *UserService) validateCreateRequest(req *CreateUserRequest) error {
    if req.Email == "" {
        return types.ErrValidation("email is required")
    }
    // ... autres validations
    return nil
}
```

**Interfaces dans package séparé** :

```go
// internal/types/interfaces.go
package types

import (
    "context"
    "veza-backend-api/internal/models"
)

// UserRepository définit les opérations de persistence
type UserRepository interface {
    Create(ctx context.Context, user *models.User) error
    FindByID(ctx context.Context, id uuid.UUID) (*models.User, error)
    FindByEmail(ctx context.Context, email string) (*models.User, error)
}

// Logger définit les opérations de logging
type Logger interface {
    Info(msg string, fields ...interface{})
    Error(msg string, fields ...interface{})
    Debug(msg string, fields ...interface{})
}
```

---

### 2.2 Backend Handler Pattern

**Pattern sûr pour créer un nouveau handler** :

```go
// ✅ PATTERN SÛR - Évite import cycles
// internal/handlers/user_handlers.go
package handlers

import (
    "net/http"
    "github.com/gin-gonic/gin"
    "veza-backend-api/internal/types"  // Interfaces seulement
    "veza-backend-api/internal/models"
)

// UserHandlers gère les requêtes HTTP pour les utilisateurs
type UserHandlers struct {
    userService types.UserService  // Interface, pas l'implémentation
}

// NewUserHandlers crée une nouvelle instance
func NewUserHandlers(userService types.UserService) *UserHandlers {
    return &UserHandlers{
        userService: userService,
    }
}

// CreateUser gère POST /api/v1/users
func (h *UserHandlers) CreateUser(c *gin.Context) {
    var req CreateUserRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
        return
    }
    
    user, err := h.userService.CreateUser(c.Request.Context(), &req)
    if err != nil {
        handleError(c, err)
        return
    }
    
    c.JSON(http.StatusCreated, user)
}

// handleError gère les erreurs de manière cohérente
func handleError(c *gin.Context, err error) {
    // Logique de gestion d'erreur centralisée
    // ...
}
```

---

### 2.3 Frontend Component Pattern

**Pattern sûr pour créer un nouveau composant React** :

```typescript
// ✅ PATTERN SÛR - Évite import hell
// src/components/user/UserProfile.tsx
import type { User } from '@/types';  // Types séparés
import { useUserStore } from '@/stores/user';  // State management
import { userService } from '@/services/user';  // API calls
import { useUser } from '@/hooks/useUser';  // Custom hook

interface UserProfileProps {
  userId: string;
  className?: string;
}

// Component NE fait PAS de logic business
export const UserProfile: React.FC<UserProfileProps> = ({ 
  userId, 
  className 
}) => {
  // Custom hook gère la logique
  const { data: user, isLoading, error } = useUser(userId);
  
  // États de chargement et d'erreur
  if (isLoading) return <Spinner />;
  if (error) return <ErrorMessage error={error} />;
  if (!user) return <div>User not found</div>;
  
  // Rendu simple
  return (
    <div className={className}>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
};
```

**Custom Hook Pattern** :

```typescript
// ✅ PATTERN SÛR - Logique réutilisable
// src/hooks/useUser.ts
import { useQuery } from '@tanstack/react-query';
import { userService } from '@/services/user';

export function useUser(userId: string) {
  return useQuery({
    queryKey: ['user', userId],
    queryFn: () => userService.getUser(userId),
    enabled: !!userId,
  });
}
```

---

### 2.4 Frontend Service Pattern

**Pattern sûr pour créer un nouveau service API** :

```typescript
// ✅ PATTERN SÛR - Types explicites
// src/services/user.ts
import type { User, CreateUserRequest } from '@/types';
import { apiClient } from './apiClient';

export const userService = {
  async getUser(userId: string): Promise<User> {
    const response = await apiClient.get<User>(`/api/v1/users/${userId}`);
    return response.data;
  },
  
  async createUser(request: CreateUserRequest): Promise<User> {
    const response = await apiClient.post<User>('/api/v1/users', request);
    return response.data;
  },
  
  async updateUser(userId: string, request: Partial<User>): Promise<User> {
    const response = await apiClient.put<User>(`/api/v1/users/${userId}`, request);
    return response.data;
  },
};
```

---

### 2.5 Test Pattern (Frontend)

**Pattern sûr pour écrire des tests** :

```typescript
// ✅ PATTERN SÛR - Mocks configurés
// src/components/user/UserProfile.test.tsx
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import { UserProfile } from './UserProfile';
import { useUser } from '@/hooks/useUser';

// Mock le hook
vi.mock('@/hooks/useUser');

describe('UserProfile', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });
  
  it('should render user profile', () => {
    // Arrange
    const mockUser = {
      id: '123',
      name: 'John Doe',
      email: 'john@example.com',
    };
    
    vi.mocked(useUser).mockReturnValue({
      data: mockUser,
      isLoading: false,
      error: null,
    } as any);
    
    // Act
    render(<UserProfile userId="123" />);
    
    // Assert
    expect(screen.getByText('John Doe')).toBeInTheDocument();
    expect(screen.getByText('john@example.com')).toBeInTheDocument();
  });
  
  it('should show loading state', () => {
    // Arrange
    vi.mocked(useUser).mockReturnValue({
      data: null,
      isLoading: true,
      error: null,
    } as any);
    
    // Act
    render(<UserProfile userId="123" />);
    
    // Assert
    expect(screen.getByRole('status')).toBeInTheDocument();  // Spinner
  });
});
```

---

## 3. VALIDATION GATES

### 3.1 Pre-Commit Gates (Husky)

**Configuration automatique** : Les hooks Husky sont configurés dans `.husky/pre-commit`.

**Gates activés** :
- ✅ Formatage automatique (Prettier, gofmt)
- ✅ Linter (ESLint, golangci-lint)
- ✅ Tests unitaires rapides (`go test -short`, `npm test -- --run`)
- ✅ Type checking (TypeScript)

**Si un gate échoue** :
- ❌ Le commit est bloqué
- ✅ Corriger les erreurs
- ✅ Réessayer le commit

---

### 3.2 Pre-Merge Gates (GitHub Actions)

**Configuration** : `.github/workflows/error-prevention.yml`

**Gates activés** :

1. **Architecture Validation**
   - Vérification des import cycles (Go)
   - Vérification de la structure des packages

2. **Type Safety**
   - TypeScript strict mode
   - Go type checking

3. **Test Coverage**
   - Coverage ≥ 80% pour nouveau code
   - Tous les tests passent

4. **Linter**
   - Zero linter errors
   - Zero linter warnings (ou < 5)

5. **Build**
   - Backend compile sans erreur
   - Frontend build réussit

**Si un gate échoue** :
- ❌ La PR ne peut pas être mergée
- ✅ Corriger les erreurs
- ✅ Push les corrections
- ✅ Les gates se relancent automatiquement

---

### 3.3 Pre-Deployment Gates

**Gates activés** :
- ✅ Tous les tests passent (unit, integration, E2E)
- ✅ Coverage ≥ 80% (global)
- ✅ Performance tests passent
- ✅ Security scan pass
- ✅ Smoke tests passent en staging

---

## 4. TEMPLATES DE CODE

### 4.1 Utilisation des Templates

**Avant de créer un nouveau fichier** :

1. Consulter la liste des templates disponibles dans `/dev-environment/templates/`
2. Copier le template approprié
3. Remplacer les placeholders (`{{PLACEHOLDER}}`)
4. Adapter selon les besoins spécifiques

**Exemple** :
```bash
# Créer un nouveau service Go
cp dev-environment/templates/backend-service.template.go \
   veza-backend-api/internal/services/my_service.go

# Éditer et remplacer les placeholders
# {{SERVICE_NAME}} → MyService
# {{PACKAGE_NAME}} → myservice
```

---

### 4.2 Templates Disponibles

**Backend Go** :
- `backend-service.template.go` - Service avec interface
- `backend-handler.template.go` - Handler HTTP
- `backend-repository.template.go` - Repository pattern

**Frontend React/TypeScript** :
- `frontend-component.template.tsx` - Composant React
- `frontend-hook.template.ts` - Custom hook
- `frontend-service.template.ts` - Service API

**Rust** :
- `rust-service.template.rs` - Service Rust

**Voir** : `/dev-environment/templates/` pour les templates complets.

---

## 5. WORKFLOW INTÉGRÉ

### 5.1 Workflow Complet

```mermaid
graph TD
    A[Nouvelle Tâche TXXXX] --> B[Pre-Flight Check]
    B -->|FAIL| C[Corriger Erreurs Existantes]
    C --> B
    B -->|PASS| D[Choisir Template]
    D --> E[Implémenter avec Pattern Sûr]
    E --> F[Tests Unitaires TDD]
    F --> G{Coverage ≥ 80%?}
    G -->|Non| F
    G -->|Oui| H[Lint Check]
    H --> I{Zero Errors?}
    I -->|Non| E
    I -->|Oui| J[Pre-Commit Hook]
    J --> K{Hook Pass?}
    K -->|Non| E
    K -->|Oui| L[Commit]
    L --> M[Push & Create PR]
    M --> N[CI/CD Gates]
    N --> O{All Gates Pass?}
    O -->|Non| E
    O -->|Oui| P[Code Review]
    P --> Q{Approved?}
    Q -->|Non| E
    Q -->|Oui| R[Merge]
```

---

### 5.2 Checklist par Étape

#### Étape 1: Pre-Flight Check
- [ ] Exécuter `./scripts/pre-flight-check.sh`
- [ ] Vérifier qu'aucune erreur P0/P1 existe
- [ ] Tests existants passent
- [ ] Linter clean

#### Étape 2: Implémentation
- [ ] Utiliser template approprié
- [ ] Suivre pattern sûr (voir section 2)
- [ ] Éviter les anti-patterns (voir `ORIGIN_ERROR_PATTERNS.md`)
- [ ] Tests en TDD (Red-Green-Refactor)

#### Étape 3: Validation Locale
- [ ] Tests unitaires passent
- [ ] Coverage ≥ 80%
- [ ] Linter zero errors
- [ ] Type check passe
- [ ] Build réussit

#### Étape 4: Commit
- [ ] Pre-commit hook passe
- [ ] Message de commit suit format: `TXXXX: type: description`
- [ ] Commit atomique (une fonctionnalité par commit)

#### Étape 5: PR & Review
- [ ] CI/CD gates passent
- [ ] Code review approuvé (2 reviewers)
- [ ] Documentation mise à jour si nécessaire

---

## 6. RÉFÉRENCES

### Documents ORIGIN

- **ORIGIN_ERROR_PATTERNS.md** - Catalogue des patterns d'erreurs
- **ORIGIN_CODE_STANDARDS.md** - Standards de code
- **ORIGIN_MASTER_ARCHITECTURE.md** - Architecture du projet
- **ORIGIN_TESTING_STRATEGY.md** - Stratégie de tests
- **ORIGIN_IMPLEMENTATION_TASKS.md** - Tâches d'implémentation

### Scripts Utilitaires

- `./scripts/pre-flight-check.sh` - Validation pré-tâche
- `./scripts/discover-errors.sh` - Découverte d'erreurs
- `./scripts/generate-error-summary.sh` - Rapport d'erreurs

### Outils

- **Go** : `go vet`, `golangci-lint`, `go test`
- **TypeScript** : `tsc`, `eslint`, `prettier`
- **Rust** : `cargo check`, `cargo clippy`, `cargo test`

---

## ✅ CHECKLIST DE VALIDATION

### Avant de Commencer une Tâche

- [ ] Pre-flight check exécuté et passé
- [ ] Template choisi et copié
- [ ] Pattern sûr identifié
- [ ] Checklist spécifique (Backend/Frontend/Rust) complétée

### Pendant l'Implémentation

- [ ] Pattern sûr suivi
- [ ] Anti-patterns évités
- [ ] Tests écrits en TDD
- [ ] Linter activé en temps réel

### Avant le Commit

- [ ] Tests passent
- [ ] Coverage ≥ 80%
- [ ] Linter zero errors
- [ ] Type check passe
- [ ] Build réussit

### Avant le Merge

- [ ] CI/CD gates passent
- [ ] Code review approuvé
- [ ] Documentation mise à jour

---

## 🔄 MAINTENANCE

### Mise à Jour du Guide

- **Fréquence** : Mensuelle ou après découverte d'un nouveau pattern
- **Responsable** : Lead Engineers
- **Processus** :
  1. Identifier nouveau pattern d'erreur
  2. Documenter dans `ORIGIN_ERROR_PATTERNS.md`
  3. Mettre à jour ce guide si nécessaire
  4. Communiquer à l'équipe

### Amélioration Continue

- Analyser les erreurs qui passent malgré les gates
- Améliorer les templates si nécessaire
- Ajuster les checklists selon les retours

---

**Dernière mise à jour** : 2025-11-09  
**Version** : 1.0.0  
**Statut** : ✅ **APPROUVÉ ET VERROUILLÉ**

**"Prevention is better than cure."**







