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.).
18 KiB
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
- Pre-Flight Check OBLIGATOIRE avant toute nouvelle tâche
- Templates OBLIGATOIRES pour créer de nouveaux fichiers
- Quality Gates BLOQUANTS en CI/CD
- Aucune exception sans approbation Lead Engineer
- Documentation OBLIGATOIRE de tout nouveau pattern d'erreur
📖 TABLE DES MATIÈRES
- Pre-Flight Checklists
- Implementation Patterns
- Validation Gates
- Templates de Code
- Workflow Intégré
- 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.
# 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éé
# 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.mdPAT-002 - Décider une stratégie cohérente avant de modifier un modèle
- Consulter
- Vérifier que tous les packages importés existent
go build ./... # Doit réussir sans erreur - Tests unitaires du composant parent passent
go test ./internal/services/... -v go vetne produit aucun warninggo vet ./...golangci-lintne produit aucune erreurgolangci-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
stringet*stringpour champs optionnels
Patterns sûrs :
- ✅ Interfaces dans
internal/types/ouinternal/interfaces/ - ✅ Services dépendent uniquement d'interfaces
- ✅ Handlers dépendent uniquement d'interfaces
- ✅ Types cohérents (toujours
stringOU toujours*string)
1.3 Checklist Frontend React/TypeScript
Avant de créer/modifier du code TypeScript/React :
- Vérifier que
tsconfig.jsonest correctcd apps/web npx tsc --noEmit --strict - Linter ne produit aucune erreur sur fichiers modifiés
npm run lint - Tests existants passent avant modification
npm test -- --run - Types TypeScript sont stricts (pas de
any)- Vérifier avec
tsc --noEmit --strict - Utiliser
unknownsi le type est vraiment inconnu
- Vérifier avec
- JSX syntax validée (Prettier)
npm run format - Pas de
console.logen production- Utiliser un logger configuré
- ESLint devrait bloquer automatiquement
Patterns à éviter :
- ❌ Regex non terminées dans les tests
- ❌ Tags JSX non fermés
- ❌ Types
anyexplicites - ❌ Variables non utilisées
- ❌
console.logen 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 checkpassecd veza-chat-server # ou veza-stream-server cargo checkcargo clippyne produit aucun warningcargo clippy -- -D warnings- SQLx queries validées avec schema
cargo sqlx prepare --check - Tests unitaires passent
cargo test
Patterns à éviter :
- ❌
unwrap()en production (utiliser?ou gestion d'erreur) - ❌ Types
i32pour IDs (utiliserUuid) - ❌ Queries SQL non validées
Patterns sûrs :
- ✅ Gestion d'erreur avec
Result<T, E> - ✅ Types
Uuidpour 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 :
// ✅ 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é :
// 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 :
// ✅ 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 :
// ✅ 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 :
// ✅ 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 :
// ✅ 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 :
// ✅ 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 :
-
Architecture Validation
- Vérification des import cycles (Go)
- Vérification de la structure des packages
-
Type Safety
- TypeScript strict mode
- Go type checking
-
Test Coverage
- Coverage ≥ 80% pour nouveau code
- Tous les tests passent
-
Linter
- Zero linter errors
- Zero linter warnings (ou < 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 :
- Consulter la liste des templates disponibles dans
/dev-environment/templates/ - Copier le template approprié
- Remplacer les placeholders (
{{PLACEHOLDER}}) - Adapter selon les besoins spécifiques
Exemple :
# 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 interfacebackend-handler.template.go- Handler HTTPbackend-repository.template.go- Repository pattern
Frontend React/TypeScript :
frontend-component.template.tsx- Composant Reactfrontend-hook.template.ts- Custom hookfrontend-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
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 :
- Identifier nouveau pattern d'erreur
- Documenter dans
ORIGIN_ERROR_PATTERNS.md - Mettre à jour ce guide si nécessaire
- 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."