veza/veza-docs/ORIGIN/ORIGIN_ERROR_PREVENTION_GUIDE.md
okinrev b7955a680c P0: stabilisation backend/chat/stream + nouvelle base migrations v1
Backend Go:
- Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN.
- Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError).
- Sécurisation de config.go, CORS, statuts de santé et monitoring.
- Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles).
- Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés.
- Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*.

Chat server (Rust):
- Refonte du pipeline JWT + sécurité, audit et rate limiting avancé.
- Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing).
- Nettoyage des panics, gestion d’erreurs robuste, logs structurés.
- Migrations chat alignées sur le schéma UUID et nouvelles features.

Stream server (Rust):
- Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core.
- Transactions P0 pour les jobs et segments, garanties d’atomicité.
- Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION).

Documentation & audits:
- TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services.
- Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3).
- Scripts de reset et de cleanup pour la lab DB et la V1.

Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
2025-12-06 11:14:38 +01:00

743 lines
18 KiB
Markdown

# 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."**