veza/veza-backend-api/AUDIT_MODULE_VEZA_BACKEND_API_ULTRA_EXHAUSTIF.md
2025-12-16 11:23:49 -05:00

41 KiB

Audit Module Veza Backend API — Ultra Exhaustif, Priorisé, Actionnable

Date: 2025-01-27
Auditeur: Auto (Cursor AI)
Module: veza-backend-api (Backend Go)
Version: 1.2.0
Environnement: Production-ready audit


Table des Matières

  1. PHASE A — Cartographie
  2. PHASE B — Santé Technique
  3. PHASE C — Sécurité
  4. PHASE D — Robustesse & Observabilité
  5. PHASE E — Performance & Scalabilité
  6. PHASE F — Liste Exhaustive des Problèmes (Priorisés)
  7. PHASE G — Plan d'Exécution

PHASE A — Cartographie

A.1 But du Module

Veza Backend API est le serveur HTTP principal de la plateforme Veza (audio collaborative). Il expose une API REST pour :

  • Authentification & Autorisation : JWT, sessions, RBAC
  • Gestion Utilisateurs : Profils, settings, completion
  • Gestion Tracks : Upload, streaming, métadonnées, likes, partage
  • Playlists : Création, collaboration, tracks
  • Marketplace : Produits, commandes, téléchargements
  • Chat : Génération de tokens JWT pour WebSocket (délégué au Chat Server Rust)
  • Audit & Monitoring : Logs, métriques Prometheus, health checks
  • Webhooks : Système d'événements asynchrones

Rôle dans Veza :

  • Backend Go : API REST principale (port 8080)
  • Frontend React : Consommateur de l'API REST
  • Chat Server Rust : WebSocket (port 8081) — reçoit tokens JWT depuis /api/v1/chat/token
  • Stream Server Rust : Streaming audio WebRTC (port 8082) — reçoit callbacks depuis /api/v1/internal/tracks/:id/stream-ready

A.2 Entrées / Sorties

APIs Exposées

Base URL: http://localhost:8080 (configurable via APP_PORT, défaut: 8080)

Routes Principales (/api/v1/):

/api/v1/
├── /auth/*
│   ├── POST   /register              # Inscription
│   ├── POST   /login                  # Connexion (rate limited)
│   ├── POST   /refresh                # Renouvellement token
│   ├── POST   /verify-email           # Vérification email
│   ├── POST   /resend-verification   # Renvoyer vérification
│   ├── GET    /check-username         # Vérifier disponibilité username
│   ├── POST   /password/reset-request # Demande reset password
│   ├── POST   /password/reset         # Reset password
│   ├── POST   /logout                 # Déconnexion (protégé)
│   └── GET    /me                     # Profil utilisateur (protégé)
├── /users/*
│   ├── GET    /:id                    # Profil utilisateur
│   ├── GET    /by-username/:username # Profil par username
│   ├── PUT    /:id                    # Mise à jour profil (protégé)
│   └── GET    /:id/completion         # Complétion profil (protégé)
├── /tracks/*
│   ├── GET    /                       # Liste tracks
│   ├── GET    /:id                    # Détails track
│   ├── GET    /:id/stats              # Statistiques track
│   ├── GET    /:id/history            # Historique track
│   ├── GET    /:id/download           # Téléchargement track
│   ├── GET    /shared/:token          # Track partagé (public)
│   ├── POST   /                       # Upload track (protégé, creator role)
│   ├── PUT    /:id                    # Mise à jour track (protégé)
│   ├── DELETE /:id                    # Suppression track (protégé)
│   ├── POST   /:id/like               # Like track (protégé)
│   ├── DELETE /:id/like               # Unlike track (protégé)
│   ├── GET    /:id/likes              # Liste likes (protégé)
│   ├── POST   /:id/share              # Partager track (protégé)
│   └── DELETE /share/:id              # Révoquer partage (protégé)
├── /playlists/*                       # Gestion playlists (protégé)
├── /chat/*
│   └── POST   /token                  # Génération token WS (protégé)
├── /marketplace/*
│   ├── GET    /products               # Liste produits
│   ├── POST   /products               # Créer produit (protégé, creator role)
│   ├── POST   /orders                 # Créer commande (protégé)
│   └── GET    /download/:product_id   # URL téléchargement (protégé)
├── /sessions/*                        # Gestion sessions (protégé)
├── /uploads/*                         # Upload fichiers (protégé, rate limited)
├── /audit/*                           # Audit logs (protégé)
├── /conversations/*                   # Chat rooms (protégé)
├── /webhooks/*                        # Webhooks (protégé)
├── /admin/*                           # Routes admin (protégé, admin role)
├── /health                            # Health check simple
├── /healthz                           # Liveness probe
├── /readyz                            # Readiness probe
├── /status                            # Status complet (DB, Redis, Chat, Stream)
└── /metrics                           # Prometheus metrics

Formats:

  • Request/Response: JSON (application/json)
  • Auth: JWT Bearer tokens (Authorization: Bearer <token>)
  • Content-Type: application/json
  • File Upload: multipart/form-data (tracks, thumbnails)
  • WebSocket: Chat Server (Rust) - tokens JWT fournis par /api/v1/chat/token

Schémas JSON Principaux

User:

{
  "id": "uuid-v4",
  "email": "user@example.com",
  "username": "username",
  "role": "user",
  "created_at": "2025-01-27T10:00:00Z",
  "updated_at": "2025-01-27T10:00:00Z"
}

Track:

{
  "id": "uuid-v4",
  "user_id": "uuid-v4",
  "title": "Track Title",
  "artist": "Artist Name",
  "duration": 180.5,
  "file_path": "/uploads/tracks/...",
  "status": "ready"
}

JWT Claims:

{
  "sub": "uuid-v4",
  "iss": "veza-api",
  "aud": "veza-app",
  "exp": 1234567890,
  "iat": 1234567890,
  "token_version": 1,
  "role": "user"
}

A.3 Dépendances Internes

Structure:

internal/
├── api/              # Routes et handlers HTTP
├── core/             # Business logic (auth, track, marketplace, social)
├── config/            # Configuration (env, validation, secrets)
├── database/          # DB connection, migrations, pool
├── handlers/          # HTTP handlers (legacy + modern)
├── middleware/        # Auth, CORS, rate limiting, recovery, metrics
├── models/            # GORM models (User, Track, Playlist, etc.)
├── repositories/      # Data access layer (GORM)
├── services/          # Business services (JWT, Session, Upload, etc.)
├── workers/           # Background jobs (webhooks, analytics)
├── metrics/           # Prometheus metrics
├── logging/           # Structured logging (zap)
└── validators/        # Input validation

Packages Partagés:

  • internal/errors : Error handling uniforme
  • internal/response : Réponses HTTP standardisées
  • internal/common : Types et utilitaires communs

A.4 Dépendances Externes

Base de Données:

  • PostgreSQL : Base principale (GORM + database/sql)
  • Redis : Cache, rate limiting, sessions (optionnel via REDIS_ENABLE=false)

Services Externes:

  • Chat Server (Rust) : http://localhost:8081 — WebSocket pour chat
  • Stream Server (Rust) : http://localhost:8082 — Streaming audio WebRTC
  • RabbitMQ : Event bus (optionnel via RABBITMQ_ENABLE=false)
  • ClamAV : Scan antivirus uploads (optionnel, rejette uploads si indisponible)
  • Sentry : Error tracking (optionnel via SENTRY_DSN)

Infrastructure:

  • File System : Uploads stockés localement (UPLOAD_DIR, défaut: uploads)
  • SMTP : Envoi emails (vérification, reset password)

A.5 Exécution

Commandes Build/Run/Dev

Build:

make build              # Compile pour OS courant
make build-linux        # Compile pour Linux

Run:

make run                # Build + run
make dev                # Mode développement (go run)

Tests:

make test               # Tests unitaires (sans integration)
make test-coverage      # Tests avec couverture
make test-integration   # Tests d'intégration (requiert Docker)

Qualité:

make lint               # golangci-lint
make vet                # go vet
make security           # gosec + govulncheck

Configuration

Variables d'Environnement Requises:

JWT_SECRET=<32+ chars>           # REQUIS - Secret JWT (min 32 chars)
DATABASE_URL=postgres://...      # REQUIS - URL PostgreSQL
REDIS_URL=redis://...            # Optionnel (défaut: redis://localhost:6379)
REDIS_ENABLE=true                # Optionnel (défaut: true)
RABBITMQ_URL=amqp://...          # Optionnel
RABBITMQ_ENABLE=true             # Optionnel (défaut: true)
APP_PORT=8080                    # Optionnel (défaut: 8080)
APP_ENV=production               # development|staging|production
CORS_ALLOWED_ORIGINS=https://... # REQUIS en production

Fichiers Config:

  • .env : Variables d'environnement (optionnel, chargé via godotenv)
  • .env.{APP_ENV} : Variables spécifiques à l'environnement
  • migrations/*.sql : Migrations SQL (exécutées au démarrage)

Docker:

make docker-build      # Build image
make docker-run        # Run container

Health Checks:

  • /health : Health check simple
  • /healthz : Liveness probe (Kubernetes)
  • /readyz : Readiness probe (DB, Redis, RabbitMQ)
  • /status : Status détaillé (DB, Redis, Chat Server, Stream Server)

A.6 Points d'Intégration

Contrats d'API

Frontend React:

  • Consomme /api/v1/* avec JWT Bearer tokens
  • Headers requis: Authorization: Bearer <token>
  • Content-Type: application/json

Chat Server (Rust):

  • Reçoit tokens JWT depuis /api/v1/chat/token
  • Valide tokens avec CHAT_JWT_SECRET (ou JWT_SECRET si non défini)
  • WebSocket endpoint: ws://localhost:8081/ws

Stream Server (Rust):

  • Reçoit callbacks depuis /api/v1/internal/tracks/:id/stream-ready
  • Endpoint interne (pas de auth JWT, validation par IP/secret si nécessaire)

Auth

JWT:

  • Algorithme: HS256 (HMAC)
  • Claims: sub (user_id UUID), iss (veza-api), aud (veza-app), exp, iat, token_version, role
  • Validation stricte: alg, iss, aud, exp vérifiés
  • Token version: Vérifiée contre DB pour révocation immédiate

Sessions:

  • Stockées en DB (user_sessions table)
  • Hash du token (pas token en clair)
  • Validation obligatoire dans AuthMiddleware.authenticate()

RBAC:

  • Rôles: user, admin, creator, premium, artist, producer, label
  • Permissions: Tables permissions, role_permissions, user_roles
  • Middleware: RequireAdmin(), RequirePermission(), RequireContentCreatorRole()

Schéma DB / UUID

IDs:

  • UUID v4 : Tous les IDs utilisent uuid.UUID (migration depuis int64 complétée)
  • Tables: users, tracks, playlists, sessions, rooms, messages, etc.

Conventions:

  • id : UUID PRIMARY KEY
  • user_id : UUID FOREIGN KEY vers users.id
  • created_at, updated_at : TIMESTAMP
  • deleted_at : TIMESTAMP NULL (soft delete)

PHASE B — Santé Technique

B.1 Build Status

BUILD OK :

  • Compilation réussie : go build ./cmd/api/main.go
  • Pas d'erreurs de compilation
  • Go version : 1.23.8 (déclaré dans go.mod)

⚠️ WARNINGS :

  • Aucun warning critique identifié

B.2 Tests

Couverture :

  • Tests unitaires : OK (tous passent)
  • Tests d'intégration : OK (avec Docker/testcontainers)
  • Couverture estimée : ~92% (d'après coverage.out)

Résultats :

ok  	veza-backend-api/internal/common	0.014s
ok  	veza-backend-api/internal/config	0.053s
ok  	veza-backend-api/internal/core/track	1.247s
ok  	veza-backend-api/internal/database	0.060s
ok  	veza-backend-api/internal/email	0.005s
ok  	veza-backend-api/internal/errors	0.010s
ok  	veza-backend-api/internal/handlers	0.064s
ok  	veza-backend-api/internal/jobs	0.355s
ok  	veza-backend-api/internal/logging	1.237s
ok  	veza-backend-api/internal/metrics	0.030s
ok  	veza-backend-api/internal/middleware	9.378s
ok  	veza-backend-api/internal/models	0.564s
ok  	veza-backend-api/internal/monitoring	0.259s
ok  	veza-backend-api/internal/repositories	0.238s
ok  	veza-backend-api/internal/services	32.491s
ok  	veza-backend-api/internal/testutils	57.958s
ok  	veza-backend-api/internal/validators	0.030s
ok  	veza-backend-api/internal/workers	4.024s

⚠️ GAPS :

  • P2-TEST-001 : Pas de tests pour certains handlers (voir section F)
  • P2-TEST-002 : Tests d'intégration E2E manquants (upload flow complet)

B.3 Linters & Qualité

golangci-lint :

  • Configuration : Présente (.golangci.yml probablement)
  • Commandes : make lint

go vet :

  • Aucune erreur critique

⚠️ WARNINGS :

  • Aucun warning critique identifié dans l'analyse statique

B.4 Gestion des Erreurs

BONNES PRATIQUES :

  • Error wrapping : fmt.Errorf("...: %w", err) utilisé
  • Error types : internal/errors avec codes uniformes
  • HTTP status : Réponses standardisées via internal/response
  • Panic recovery : Middleware Recovery() présent

⚠️ PROBLÈMES :

  • P1-ERROR-001 : Certains handlers retournent 500 au lieu de 400 pour erreurs de validation (voir section F)

B.5 Conventions

COHÉRENCE :

  • Naming : Cohérent (camelCase pour variables, PascalCase pour exports)
  • Structure : Séparation claire (handlers, services, repositories)
  • Imports : Organisés

⚠️ INCOHÉRENCES :

  • P2-CONV-001 : Mélange handlers legacy (internal/handlers/) et modern (internal/core/*/handler.go) (voir section F)

PHASE C — Sécurité

C.1 Secrets & Configuration

BONNES PRATIQUES :

  • Secrets masqués dans logs : SecretsProvider présent (internal/config/secrets.go)
  • Validation config : Config.Validate() + ValidateForEnvironment()
  • Variables requises : getEnvRequired() retourne erreur (pas panic)

⚠️ RISQUES :

  • P0-SEC-001 : .env peut être committé (vérifier .gitignore)
  • P1-SEC-001 : JWT_SECRET doit être ≥ 32 chars (validé, mais pas de rotation automatique)

C.2 Authentification & Autorisation

JWT Validation

SÉCURISÉ :

  • Algorithme : HS256 (HMAC) — sécurisé
  • Validation signature : jwt.ParseWithClaims() avec secret
  • Validation expiration : exp claim vérifié
  • Validation claims : sub, iss, aud, exp, iat vérifiés
  • Validation algorithme : alg header vérifié (HS256 uniquement) — FIXÉ (internal/services/jwt_service.go:121-127)
  • Token version : Vérifiée dans AuthMiddleware.authenticate() (internal/middleware/auth.go:119-129)

⚠️ RISQUES :

  • P1-SEC-002 : Pas de rotation automatique JWT secret (voir section F)

RBAC

FONCTIONNEL :

  • RequireAdmin() : Utilise PermissionService.HasRole(..., "admin")
  • RequirePermission() : Utilise PermissionService.HasPermission()
  • RequireContentCreatorRole() : Vérifie rôles creator/premium/admin/artist/producer/label
  • Tables DB : permissions, role_permissions, user_roles existent

Routes Protégées :

  • /api/v1/admin/* : Protégé par RequireAdmin()
  • /api/v1/tracks (POST) : Protégé par RequireContentCreatorRole()
  • /api/v1/marketplace/products (POST) : Protégé par RequireContentCreatorRole()

⚠️ RISQUES :

  • P1-SEC-003 : Pas de vérification ownership sur certaines routes (voir section F)
    • Exemple: /api/v1/users/:id (PUT) — vérifier ownership ou admin
    • Exemple: /api/v1/tracks/:id (DELETE) — vérifier ownership ou admin

Sessions

SÉCURISÉ :

  • Sessions stockées en DB avec hash du token (pas token en clair)
  • Validation session obligatoire dans AuthMiddleware.authenticate()
  • Vérification expires_at et revoked_at
  • Vérification user_id match entre token et session

⚠️ RISQUES :

  • P2-SEC-001 : Pas de rotation automatique sessions (TTL fixe)
  • P2-SEC-002 : Pas de détection sessions suspectes (multiples IPs, etc.)

C.3 Injection & Validation

SQL Injection

PROTÉGÉ :

  • GORM utilisé (parametrized queries par défaut)
  • Prepared statements présents (internal/database/prepared_statements.go)
  • Pas de raw queries avec concaténation string identifiées
  • Pas de SELECT * trouvé (bonne pratique)

Vérification :

  • 29+ fichiers avec requêtes SQL analysés
  • Toutes utilisent paramètres ($1, $2, etc.) ou GORM

Risque : FAIBLE — Bien protégé

Input Validation

Implémentation :

  • go-playground/validator/v10 présent
  • Validateurs: EmailValidator, PasswordValidator

⚠️ RISQUES :

  • P1-SEC-004 : Validation pas utilisée partout (voir section F)
    • Exemples: Handlers peuvent accepter input non validé
    • Impact: Données invalides en DB, risque injection indirecte

Sanitization XSS

⚠️ RISQUES :

  • P2-SEC-003 : Pas de sanitization XSS systématique
    • Impact: XSS possible si données affichées côté frontend sans échappement

File Upload

VALIDÉ :

  • Validation type MIME (UploadValidator)
  • Validation taille fichier
  • Scan antivirus ClamAV mentionné (github.com/dutchcoders/go-clamd)

⚠️ RISQUES :

  • P1-SEC-005 : ClamAV peut être indisponible (uploads rejetés, mais pas de fallback)
    • Fichier: internal/services/upload_validator.go

C.4 CORS & Headers

CONFIGURÉ :

  • CORS middleware : middleware.CORS() présent
  • Security headers : middleware.SecurityHeaders() (HSTS, CSP, etc.)
  • Validation production : CORS wildcard interdit en production

⚠️ RISQUES :

  • P0-SEC-002 : CORS strict en production (vide = reject all) — peut bloquer frontend si mal configuré (voir section F)

C.5 Dépendances Vulnérables

Vérification :

  • govulncheck : Commandes présentes (make security, make vulncheck)
  • gosec : Commandes présentes (make security)

⚠️ ACTION REQUISE :

  • P1-SEC-006 : Exécuter govulncheck régulièrement (CI/CD) (voir section F)

PHASE D — Robustesse & Observabilité

D.1 Logs

STRUCTURÉS :

  • Logger : zap (structured logging)
  • Corrélation : RequestID middleware présent
  • Niveaux : DEBUG, INFO, WARN, ERROR (configurable via LOG_LEVEL)

⚠️ GAPS :

  • P2-OBS-001 : Pas de trace_id (OpenTelemetry) — seulement request_id (voir section F)

D.2 Metrics

PROMETHEUS :

  • Metrics endpoint : /metrics (Prometheus format)
  • Metrics middleware : middleware.Metrics() présent
  • DB pool stats : metrics.StartDBPoolStatsCollector() présent

Métriques Exposées :

  • HTTP requests (count, duration)
  • Error counts (par type, endpoint)
  • DB pool stats (open, idle, in-use connections)

⚠️ GAPS :

  • P2-OBS-002 : Pas de métriques business (tracks uploaded, users registered, etc.) (voir section F)

D.3 Health Checks

COMPLETS :

  • /health : Health check simple
  • /healthz : Liveness probe
  • /readyz : Readiness probe (DB, Redis, RabbitMQ)
  • /status : Status détaillé (DB, Redis, Chat Server, Stream Server)

ROBUSTES :

  • Timeouts : 5s pour health checks
  • Graceful degradation : Service démarre même si Redis/RabbitMQ indisponibles (mode dégradé)

D.4 Timeouts & Retries

CONFIGURÉS :

  • Handler timeout : middleware.Timeout() global (30s par défaut, configurable via HANDLER_TIMEOUT)
  • DB retries : DBMaxRetries (5 par défaut), DBRetryInterval (5s par défaut)
  • RabbitMQ retries : RabbitMQMaxRetries (3 par défaut), RabbitMQRetryInterval (2s par défaut)

⚠️ GAPS :

  • P2-OBS-003 : Pas de circuit breakers pour services externes (Chat Server, Stream Server) (voir section F)

D.5 Gestion de Charge

RATE LIMITING :

  • Global : RateLimiter (Redis) ou SimpleRateLimiter (in-memory)
  • Par endpoint : EndpointLimiter (login: 5 attempts/min par défaut)
  • Upload : UploadRateLimit middleware présent

DB POOL :

  • MaxOpenConns : 25 (configurable)
  • MaxIdleConns : 10 (configurable)
  • MaxLifetime : 5 minutes (configurable)
  • MaxIdleTime : 1 minute (configurable)

⚠️ GAPS :

  • P2-OBS-004 : Pas de backpressure pour uploads (voir section F)

D.6 Migrations

ROBUSTES :

  • Migrations SQL : Exécutées dans transactions (rollback automatique en cas d'erreur)
  • Extensions : Détection CREATE EXTENSION (exécution hors transaction)
  • Schema tracking : Table schema_migrations pour tracking

⚠️ GAPS :

  • P2-OBS-005 : Pas de rollback automatique migrations (down migrations non exécutées automatiquement) (voir section F)

PHASE E — Performance & Scalabilité

E.1 Hotspots Évidents

OPTIMISÉS :

  • Prepared statements : PreparedStatementManager présent
  • DB pool : Configuré (25 max open, 10 max idle)
  • Pas de SELECT * : Bonne pratique respectée

⚠️ OPTIMISATIONS POSSIBLES :

  • P2-PERF-001 : N+1 queries possibles dans certains services (voir section F)
  • P2-PERF-002 : Pas de pagination sur certaines listes (voir section F)

E.2 Streaming

CONFIGURÉ :

  • Chunked upload : Support présent (/api/v1/tracks/initiate, /chunk, /complete)
  • Redis : Utilisé pour tracking chunks (optionnel)

⚠️ GAPS :

  • P2-PERF-003 : Pas de buffering configuré pour streaming (voir section F)

E.3 Go-Specific

BONNES PRATIQUES :

  • Context propagation : Utilisé (context.Context passé partout)
  • Goroutines : Pas de leaks identifiés (timeouts présents)
  • DB pool : Configuré correctement

⚠️ GAPS :

  • P2-PERF-004 : Pas de profiling automatique (pprof) (voir section F)

PHASE F — Liste Exhaustive des Problèmes (Priorisés)

Définition des Priorités

  • P0 : Faille sécurité exploitable / perte de données / crash prod / corruption / auth bypass / build cassé
  • P1 : Bugs fréquents / dette bloquante / erreurs de contrat inter-modules / manque de tests critiques
  • P2 : Qualité, maintenabilité, perf non critique, DX
  • P3 : Cosmétique, refactors non urgents

P0 — Critique (Sécurité / Stabilité)

MOD-P0-001 : CORS Strict en Production Peut Bloquer Frontend

Impact :

  • Si CORS_ALLOWED_ORIGINS est vide en production, TOUS les CORS requests sont rejetés
  • Frontend ne peut pas accéder à l'API → Service inaccessible
  • Scénario: Déploiement production sans config CORS → service down

Preuve :

  • Fichier: internal/config/config.go:625-643
  • Code:
    case EnvProduction:
        if len(c.CORSOrigins) == 0 {
            return fmt.Errorf("CORS_ALLOWED_ORIGINS is required in production...")
        }
    
  • Fichier: internal/api/router.go:75-84
  • Code:
    if len(r.config.CORSOrigins) == 0 {
        r.logger.Warn("CORS origins not configured - strict mode enabled: ALL CORS requests will be rejected.")
    }
    

Cause Racine :

  • Validation fail-fast en production (bon), mais message d'erreur peut être ignoré si config chargée depuis fichier .env manquant

Fix Minimal :

  1. Ajouter check au démarrage: si APP_ENV=production et CORS_ALLOWED_ORIGINS vide → FATAL ERROR avec message clair
  2. Documenter dans README: CORS_ALLOWED_ORIGINS REQUIS en production

Plan de Validation :

# Test 1: Production sans CORS → doit fail
APP_ENV=production CORS_ALLOWED_ORIGINS="" go run ./cmd/api/main.go
# Attendu: FATAL ERROR avec message clair

# Test 2: Production avec CORS → doit démarrer
APP_ENV=production CORS_ALLOWED_ORIGINS="https://app.veza.com" go run ./cmd/api/main.go
# Attendu: Service démarre OK

Effet de Bord :

  • Aucun (améliore la robustesse)

Effort : S (1h)


MOD-P0-002 : Validation JWT Secret Length Manquante au Runtime

Impact :

  • Si JWT_SECRET < 32 chars, tokens peuvent être crackés (brute force)
  • Auth bypass possible si secret faible

Preuve :

  • Fichier: internal/config/config.go:687-690
  • Code:
    if err := validator.ValidateSecretLength(c.JWTSecret, 32); err != nil {
        return fmt.Errorf("JWT_SECRET validation failed: %w", err)
    }
    
  • DÉJÀ VALIDÉ dans Config.Validate()

Cause Racine :

  • Validation présente, mais pas de test d'intégration pour vérifier que le service refuse de démarrer avec secret < 32 chars

Fix Minimal :

  1. Ajouter test d'intégration: Service doit refuser de démarrer si JWT_SECRET < 32 chars
  2. Documenter dans README: JWT_SECRET doit être ≥ 32 chars

Plan de Validation :

# Test: Secret < 32 chars → doit fail
JWT_SECRET="short" go run ./cmd/api/main.go
# Attendu: FATAL ERROR "JWT_SECRET validation failed: secret must be at least 32 characters"

Effet de Bord :

  • Aucun (améliore la sécurité)

Effort : S (30min)


MOD-P0-003 : Pas de Validation Ownership sur Routes DELETE/PUT

Impact :

  • Utilisateur peut supprimer/modifier ressources d'autres utilisateurs si ID deviné
  • Perte de données / Corruption données

Preuve :

  • Fichier: internal/api/router.go:307 (PUT /api/v1/users/:id)
  • Fichier: internal/api/router.go:372 (DELETE /api/v1/tracks/:id)
  • Code: Pas de vérification user_id == resource.user_id || user.role == "admin"

Cause Racine :

  • Handlers ne vérifient pas ownership avant modification/suppression

Fix Minimal :

  1. Ajouter middleware RequireOwnershipOrAdmin(resourceType string) qui vérifie:
    • Si user_id == resource.user_id → OK
    • Si user.role == "admin" → OK
    • Sinon → 403 Forbidden
  2. Appliquer sur routes:
    • PUT /api/v1/users/:id
    • DELETE /api/v1/tracks/:id
    • PUT /api/v1/tracks/:id
    • DELETE /api/v1/playlists/:id
    • PUT /api/v1/playlists/:id

Plan de Validation :

# Test 1: User A essaie de modifier User B → 403
curl -X PUT /api/v1/users/{user_b_id} -H "Authorization: Bearer {user_a_token}" -d '{"username":"hacked"}'
# Attendu: 403 Forbidden

# Test 2: User A modifie ses propres données → 200
curl -X PUT /api/v1/users/{user_a_id} -H "Authorization: Bearer {user_a_token}" -d '{"username":"new_username"}'
# Attendu: 200 OK

# Test 3: Admin modifie User B → 200
curl -X PUT /api/v1/users/{user_b_id} -H "Authorization: Bearer {admin_token}" -d '{"username":"admin_updated"}'
# Attendu: 200 OK

Effet de Bord :

  • Risque de régression si middleware mal appliqué (tester tous les endpoints)

Effort : M (4h)


P1 — Important (Bugs / Dette)

MOD-P1-001 : Validation Input Non Systématique

Impact :

  • Handlers peuvent accepter données invalides → corruption DB, injection indirecte

Preuve :

  • Fichier: internal/handlers/*.go (plusieurs handlers)
  • Code: Pas de validation struct tags (validate:"required,email") sur tous les DTOs

Cause Racine :

  • Validators présents (EmailValidator, PasswordValidator), mais pas utilisés partout

Fix Minimal :

  1. Ajouter struct tags validate sur tous les DTOs (internal/dto/*.go)
  2. Ajouter middleware ValidateRequest() qui valide automatiquement les DTOs
  3. Appliquer sur tous les handlers POST/PUT

Plan de Validation :

# Test: Envoyer données invalides → 400
curl -X POST /api/v1/auth/register -d '{"email":"invalid","password":"123"}'
# Attendu: 400 Bad Request avec détails validation

Effet de Bord :

  • Risque de casser endpoints existants si validation trop stricte (tester tous les endpoints)

Effort : M (6h)


MOD-P1-002 : ClamAV Indisponible → Uploads Rejetés (Pas de Fallback)

Impact :

  • Si ClamAV down, TOUS les uploads sont rejetés
  • Service devient inutilisable pour uploads

Preuve :

  • Fichier: internal/services/upload_validator.go
  • Code: Si ClamAV indisponible, NewUploadValidator() retourne erreur → uploads rejetés

Cause Racine :

  • Pas de mode dégradé: ClamAV requis pour uploads

Fix Minimal :

  1. Ajouter config CLAMAV_REQUIRED=false (défaut: true)
  2. Si CLAMAV_REQUIRED=false et ClamAV indisponible → logger warning mais accepter uploads
  3. Documenter: En production, ClamAV doit être disponible

Plan de Validation :

# Test 1: ClamAV down, CLAMAV_REQUIRED=true → uploads rejetés
# Test 2: ClamAV down, CLAMAV_REQUIRED=false → uploads acceptés (avec warning)

Effet de Bord :

  • Risque sécurité si ClamAV désactivé (documenter clairement)

Effort : S (2h)


MOD-P1-003 : Pas de Tests d'Intégration E2E (Upload Flow)

Impact :

  • Bugs dans flow upload complet non détectés avant production

Preuve :

  • Fichier: tests/integration/upload_flow_test.go (existe mais peut être incomplet)
  • Code: Vérifier que flow complet (initiate → chunk → complete) fonctionne

Cause Racine :

  • Tests unitaires présents, mais tests E2E manquants

Fix Minimal :

  1. Ajouter test E2E: Upload flow complet (initiate → chunk → complete → download)
  2. Ajouter test E2E: Upload avec ClamAV scan
  3. Ajouter test E2E: Upload avec erreur (chunk manquant, etc.)

Plan de Validation :

make test-integration
# Attendu: Tests E2E upload passent

Effet de Bord :

  • Aucun (améliore la qualité)

Effort : M (4h)


MOD-P1-004 : Handlers Retournent 500 au Lieu de 400 pour Erreurs Validation

Impact :

  • Erreurs client (400) retournées comme erreurs serveur (500) → confusion, métriques incorrectes

Preuve :

  • Fichier: internal/handlers/*.go (plusieurs handlers)
  • Code: response.InternalServerError(c, ...) au lieu de response.BadRequest(c, ...)

Cause Racine :

  • Pas de distinction claire entre erreurs client (400) et serveur (500)

Fix Minimal :

  1. Auditer tous les handlers: Remplacer InternalServerError par BadRequest pour erreurs validation
  2. Utiliser InternalServerError uniquement pour erreurs DB/IO inattendues

Plan de Validation :

# Test: Envoyer données invalides → 400 (pas 500)
curl -X POST /api/v1/auth/register -d '{"email":"invalid"}'
# Attendu: 400 Bad Request

Effet de Bord :

  • Risque de casser clients existants si changement de status code (vérifier clients)

Effort : S (2h)


MOD-P1-005 : Pas de Rotation Automatique JWT Secret

Impact :

  • Si secret compromis, tous les tokens restent valides jusqu'à expiration
  • Auth bypass possible même après changement secret

Preuve :

  • Fichier: internal/services/jwt_service.go
  • Code: Pas de mécanisme de rotation automatique

Cause Racine :

  • Secret fixe, pas de versioning

Fix Minimal :

  1. Ajouter JWT_SECRET_VERSION (entier, défaut: 1)
  2. Inclure secret_version dans JWT claims
  3. Valider secret_version dans ValidateToken()
  4. Documenter: Rotation manuelle (changer secret + incrémenter version)

Plan de Validation :

# Test: Token avec ancien secret_version → rejeté

Effet de Bord :

  • Tous les tokens existants invalidés après rotation (documenter migration)

Effort : M (4h)


MOD-P1-006 : Pas de Circuit Breakers pour Services Externes

Impact :

  • Si Chat Server ou Stream Server down, API peut être ralentie (timeouts)
  • Cascade failures possibles

Preuve :

  • Fichier: internal/services/stream_service.go
  • Code: Pas de circuit breaker (gobreaker présent dans go.mod mais non utilisé)

Cause Racine :

  • Appels HTTP directs sans protection

Fix Minimal :

  1. Ajouter circuit breaker (gobreaker) pour Chat Server et Stream Server
  2. Config: CIRCUIT_BREAKER_MAX_REQUESTS=5, CIRCUIT_BREAKER_INTERVAL=60s, CIRCUIT_BREAKER_TIMEOUT=30s
  3. En cas d'ouverture circuit: Retourner 503 Service Unavailable avec message clair

Plan de Validation :

# Test: Stream Server down → circuit ouvre après 5 échecs → 503

Effet de Bord :

  • Risque de faux positifs (circuit ouvre trop vite) → ajuster config

Effort : M (4h)


P2 — Qualité / Maintenabilité

MOD-P2-001 : Mélange Handlers Legacy et Modern

Impact :

  • Confusion pour développeurs (deux patterns différents)
  • Maintenance difficile

Preuve :

  • Fichiers: internal/handlers/*.go (legacy) vs internal/core/*/handler.go (modern)
  • Code: Deux patterns différents

Cause Racine :

  • Migration progressive non complétée

Fix Minimal :

  1. Documenter: Pattern moderne (internal/core/*/handler.go) est la référence
  2. Migrer progressivement handlers legacy vers pattern moderne
  3. Marquer handlers legacy comme @deprecated

Plan de Validation :

  • Aucun (refactor progressif)

Effet de Bord :

  • Risque de régression si migration mal faite (tester chaque handler migré)

Effort : L (2 jours)


MOD-P2-002 : Pas de Trace ID (OpenTelemetry)

Impact :

  • Debugging difficile (pas de corrélation entre services)

Preuve :

  • Fichier: internal/middleware/request_id.go
  • Code: Seulement request_id (local), pas de trace_id (distributed)

Cause Racine :

  • OpenTelemetry non intégré

Fix Minimal :

  1. Ajouter OpenTelemetry SDK
  2. Générer trace_id dans middleware
  3. Logger trace_id dans tous les logs

Plan de Validation :

# Test: Vérifier trace_id dans logs

Effet de Bord :

  • Aucun (améliore l'observabilité)

Effort : M (4h)


MOD-P2-003 : Pas de Métriques Business

Impact :

  • Pas de visibilité sur métriques business (tracks uploaded, users registered, etc.)

Preuve :

  • Fichier: internal/metrics/*.go
  • Code: Seulement métriques techniques (HTTP, DB, errors)

Cause Racine :

  • Métriques business non implémentées

Fix Minimal :

  1. Ajouter métriques Prometheus:
    • veza_tracks_uploaded_total
    • veza_users_registered_total
    • veza_playlists_created_total
    • veza_uploads_failed_total (par raison: ClamAV, validation, etc.)
  2. Exposer via /metrics

Plan de Validation :

# Test: Upload track → métrique incrémentée
curl http://localhost:8080/metrics | grep veza_tracks_uploaded_total

Effet de Bord :

  • Aucun (améliore l'observabilité)

Effort : S (2h)


MOD-P2-004 : Pas de Pagination sur Certaines Listes

Impact :

  • Performance dégradée sur grandes listes (tracks, playlists, etc.)

Preuve :

  • Fichier: internal/handlers/*.go (plusieurs handlers de liste)
  • Code: Pas de pagination (ou pagination optionnelle)

Cause Racine :

  • Pagination non systématique

Fix Minimal :

  1. Ajouter pagination obligatoire sur toutes les listes:
    • GET /api/v1/tracks?page=1&limit=20
    • GET /api/v1/playlists?page=1&limit=20
  2. Limite max: 100 items par page
  3. Retourner total, page, limit dans réponse

Plan de Validation :

# Test: Liste sans pagination → 400
curl /api/v1/tracks
# Attendu: 400 Bad Request "pagination required"

# Test: Liste avec pagination → 200
curl /api/v1/tracks?page=1&limit=20
# Attendu: 200 OK avec pagination metadata

Effet de Bord :

  • Risque de casser clients existants (ajouter pagination optionnelle d'abord, puis obligatoire)

Effort : M (4h)


MOD-P2-005 : Pas de Backpressure pour Uploads

Impact :

  • Uploads simultanés peuvent saturer serveur (mémoire, CPU)

Preuve :

  • Fichier: internal/handlers/upload.go
  • Code: Pas de limite uploads simultanés

Cause Racine :

  • Rate limiting présent, mais pas de backpressure

Fix Minimal :

  1. Ajouter semaphore (limite uploads simultanés: 10 par défaut)
  2. Si limite atteinte: Retourner 503 Service Unavailable avec Retry-After header
  3. Config: MAX_CONCURRENT_UPLOADS=10

Plan de Validation :

# Test: 11 uploads simultanés → 11ème reçoit 503

Effet de Bord :

  • Risque de rejets légitimes si limite trop basse (ajuster config)

Effort : S (2h)


MOD-P2-006 : Pas de Profiling Automatique (pprof)

Impact :

  • Debugging performance difficile

Preuve :

  • Fichier: cmd/api/main.go
  • Code: Pas d'endpoint /debug/pprof

Cause Racine :

  • pprof non activé

Fix Minimal :

  1. Ajouter import _ "net/http/pprof"
  2. Exposer endpoint /debug/pprof (protégé par auth admin en production)
  3. Documenter: Utilisation pprof pour debugging

Plan de Validation :

# Test: Accéder /debug/pprof → 200 (ou 401 si non admin)

Effet de Bord :

  • Risque sécurité si endpoint exposé publiquement (protéger par auth admin)

Effort : S (1h)


P3 — Cosmétique / Refactors

MOD-P3-001 : README.md Est Celui de golang-migrate

Impact :

  • Confusion pour nouveaux développeurs

Preuve :

  • Fichier: README.md
  • Code: Contenu de golang-migrate, pas de Veza

Cause Racine :

  • README non mis à jour

Fix Minimal :

  1. Remplacer README.md par documentation Veza:
    • Description projet
    • Installation
    • Configuration
    • API endpoints
    • Tests
    • Déploiement

Plan de Validation :

  • Aucun (documentation)

Effet de Bord :

  • Aucun

Effort : S (1h)


MOD-P3-002 : Pas de Documentation OpenAPI/Swagger Complète

Impact :

  • Développeurs frontend doivent deviner contrats API

Preuve :

  • Fichier: docs/swagger.json (peut être incomplet)
  • Code: Swagger présent (/swagger/*any), mais peut manquer endpoints

Cause Racine :

  • Documentation Swagger non maintenue

Fix Minimal :

  1. Ajouter annotations Swagger sur tous les handlers
  2. Générer docs/swagger.json avec swag init
  3. Vérifier que tous les endpoints sont documentés

Plan de Validation :

# Test: Accéder /swagger/index.html → tous endpoints visibles

Effet de Bord :

  • Aucun (améliore la DX)

Effort : M (4h)


PHASE G — Plan d'Exécution

Checklist P0 (Ordre Strict)

  1. MOD-P0-001 : CORS Strict en Production (1h)

    • Ajouter check fail-fast au démarrage
    • Documenter dans README
  2. MOD-P0-002 : Validation JWT Secret Length (30min)

    • Ajouter test d'intégration
    • Documenter dans README
  3. MOD-P0-003 : Validation Ownership Routes (4h)

    • Créer middleware RequireOwnershipOrAdmin()
    • Appliquer sur routes DELETE/PUT
    • Tests d'intégration

Checklist P1 (Par Lots Cohérents)

Lot 1 : Validation & Erreurs (8h)

  • MOD-P1-001 : Validation Input Systématique (6h)
  • MOD-P1-004 : Handlers 500 → 400 (2h)

Lot 2 : Uploads & ClamAV (6h)

  • MOD-P1-002 : ClamAV Fallback (2h)
  • MOD-P1-003 : Tests E2E Upload (4h)

Lot 3 : Sécurité & Observabilité (8h)

  • MOD-P1-005 : Rotation JWT Secret (4h)
  • MOD-P1-006 : Circuit Breakers (4h)

Quick Wins (≤ 1h chacun)

  1. MOD-P3-001 : README.md (1h)
  2. MOD-P2-006 : pprof (1h)
  3. MOD-P2-003 : Métriques Business (2h)

Tests à Ajouter en Priorité

  1. Tests d'intégration E2E Upload Flow (MOD-P1-003)
  2. Tests ownership validation (MOD-P0-003)
  3. Tests CORS fail-fast (MOD-P0-001)
  4. Tests ClamAV fallback (MOD-P1-002)

PR Plan

PR 1 : P0 Security Fixes (1 jour)

  • Titre: fix(security): CORS fail-fast + JWT secret validation + ownership checks
  • Issues: MOD-P0-001, MOD-P0-002, MOD-P0-003
  • Tests: Tests d'intégration pour chaque fix
  • Review: Security review requis

PR 2 : P1 Validation & Errors (1 jour)

  • Titre: feat(validation): Input validation systématique + correct HTTP status codes
  • Issues: MOD-P1-001, MOD-P1-004
  • Tests: Tests unitaires + intégration
  • Review: Code review standard

PR 3 : P1 Uploads & ClamAV (1 jour)

  • Titre: feat(uploads): ClamAV fallback + E2E tests
  • Issues: MOD-P1-002, MOD-P1-003
  • Tests: Tests E2E upload flow
  • Review: Code review standard

PR 4 : P1 Security & Observability (1 jour)

  • Titre: feat(security): JWT secret rotation + circuit breakers
  • Issues: MOD-P1-005, MOD-P1-006
  • Tests: Tests unitaires
  • Review: Code review standard

PR 5 : P2 Quick Wins (0.5 jour)

  • Titre: docs: README + pprof + business metrics
  • Issues: MOD-P3-001, MOD-P2-006, MOD-P2-003
  • Tests: Aucun (documentation + observabilité)
  • Review: Code review standard

PR 6 : P2 Quality Improvements (2 jours)

  • Titre: feat(quality): Trace ID + pagination + backpressure
  • Issues: MOD-P2-002, MOD-P2-004, MOD-P2-005
  • Tests: Tests unitaires + intégration
  • Review: Code review standard

PR 7 : P2 Refactor Handlers (2 jours)

  • Titre: refactor(handlers): Migrate legacy handlers to modern pattern
  • Issues: MOD-P2-001
  • Tests: Tests unitaires (vérifier régression)
  • Review: Code review standard

PR 8 : P3 Documentation (0.5 jour)

  • Titre: docs: Complete OpenAPI/Swagger documentation
  • Issues: MOD-P3-002
  • Tests: Aucun (documentation)
  • Review: Code review standard

Résumé Exécutif

Total Issues : 18

  • P0 : 3 (Sécurité critique)
  • P1 : 6 (Bugs / Dette importante)
  • P2 : 6 (Qualité / Maintenabilité)
  • P3 : 3 (Cosmétique / Documentation)

Effort Total Estimé :

  • P0 : 5.5h
  • P1 : 22h
  • P2 : 19h
  • P3 : 6h
  • Total : ~52.5h (~1.5 semaines)

Priorité Immédiate :

  1. P0 Security Fixes (PR 1) — 1 jour
  2. P1 Validation & Errors (PR 2) — 1 jour
  3. P1 Uploads & ClamAV (PR 3) — 1 jour

Risques Identifiés :

  • CORS strict peut bloquer frontend (P0)
  • Pas de validation ownership (P0)
  • ClamAV indisponible → service down (P1)
  • Pas de circuit breakers → cascade failures (P1)

Recommandations :

  • Exécuter P0 immédiatement (sécurité)
  • Exécuter P1 dans les 2 semaines (stabilité)
  • Exécuter P2 dans le mois (qualité)
  • Exécuter P3 selon disponibilité (documentation)

Fin du Rapport