veza/docs/AUDIT_TECHNIQUE_V0803.md
senke 72d40990c5
Some checks failed
Backend API CI / test-unit (push) Failing after 0s
Backend API CI / test-integration (push) Failing after 0s
Frontend CI / test (push) Failing after 0s
Storybook Audit / Build & audit Storybook (push) Failing after 0s
feat(v0.923): API contract tests, OpenAPI generation, CI type sync check
2026-02-27 20:23:10 +01:00

38 KiB
Raw Blame History

AUDIT TECHNIQUE — VEZA MONOREPO

Champ Valeur
Date 2026-02-26
Auditeur Claude 4.6 Opus — Architecte senior / Expert sécurité
Version analysée v0.803 (tag 2026-02-25)
Périmètre Go backend, Rust stream server, React frontend, Infrastructure
Méthodologie Audit statique exhaustif du code source, 6 passes parallèles
Classification Confidentiel — Usage interne

EXECUTIVE SUMMARY

Verdict global

Veza est un projet techniquement ambitieux et remarquablement structuré pour ce qui semble être une petite équipe. Avec 435 833 LOC répartis sur 3 langages (Go, TypeScript, Rust), 26 versions taguées, ~353 features déclarées, et une infrastructure CI/CD complète, le volume de travail est impressionnant.

Cependant, l'audit révèle un décalage significatif entre l'ambition fonctionnelle et la maturité de production. Le produit n'est pas prêt pour un déploiement commercial en l'état — principalement en raison de vulnérabilités de sécurité identifiées, d'un flux OAuth cassé, et d'un ratio features/tests qui reflète une priorité donnée à la couverture fonctionnelle plutôt qu'à la robustesse.

Top 5 risques

  1. CRITIQUE — Le flux OAuth génère des JWT invalides qui ne passent pas l'auth middleware → OAuth login cassé
  2. ÉLEVÉPasswordService.GenerateJWT crée des tokens sans issuer/audience/token_version → contournement potentiel si utilisé hors contexte
  3. ÉLEVÉ — Absence de PKCE dans le flux OAuth → vulnérable à l'interception de code d'autorisation
  4. ÉLEVÉ — Tokens OAuth providers stockés en clair en base → compromission des comptes liés si la DB fuite
  5. ÉLEVÉ — Vérification des webhooks Hyperswitch désactivable quand le secret est vide → forgery de webhooks de paiement possible

Top 5 forces

  1. Architecture backend exemplaire — Séparation handler/service/repository, middleware chain complète, configuration validée par environnement
  2. Sécurité proactive — httpOnly cookies, CSRF Redis-based, security headers complets, account lockout, bcrypt cost 12, CSP stricte
  3. Infrastructure CI/CD mature — 14 workflows GitHub Actions, Trivy, CodeQL, Gitleaks, govulncheck, cargo-audit, cosign signing
  4. Frontend bien structuré — Feature-based architecture, Zustand + TanStack Query, 306 Storybook stories, 196 MSW endpoints, Zod validation
  5. Ops-ready — Kubernetes manifests avec network policies, Prometheus/Grafana, External Secrets Operator, blue-green deployment

Recommandation GO / NO-GO

NO-GO pour production commerciale en l'état. GO conditionnel après correction des 5 vulnérabilités critiques/élevées (effort estimé : 2-3 jours) et validation du flux OAuth end-to-end.


1 CARTOGRAPHIE GLOBALE

1.1 Stack réelle

Élément Valeur vérifiée Commentaire
Go 1.24.0 (go.mod) Dernière stable, OK
Rust 2021 edition, stable toolchain (rust-toolchain.toml) OK
TypeScript 5.9.3 (package.json) Dernière stable, OK
React 18.2.0 Stable, pas encore React 19
Vite 7.1.5 Dernière version
Gin 1.11.0 Framework web Go, maintenu
Axum 0.8 Framework web Rust, maintenu
GORM 1.30.0 ORM Go, dernière version
SQLx 0.8 Query builder Rust, runtime mode (pas offline)
PostgreSQL 16-alpine Dernière LTS, extensions: pg_trgm, uuid-ossp
Redis 7-alpine Dernière stable
RabbitMQ 3-management-alpine Message queue, optionnel
MinIO S3-compatible storage Object storage
JWT golang-jwt/v5 (Go), jsonwebtoken 10 (Rust) HS256, 5 min access / 14 jours refresh
Paiement Hyperswitch (Juspay/hyper.js 2.1.0) SDK frontend, webhook HMAC-SHA512
Streaming HLS réel (FFmpeg transcoding, m3u8-rs) Pas un stub
WebSocket coder/websocket (Go), tokio-tungstenite (Rust) Chat en Go, streaming en Rust
WebRTC Signalisation uniquement dans le chat store Pas de TURN/STUN configuré
CI/CD GitHub Actions, 14 workflows Complet
Docker Multi-stage, alpine, non-root Bonnes pratiques suivies
Monitoring Prometheus + Grafana + alerting Configuré et dashboardé

1.2 Organisation du monorepo

Dossier Rôle réel Fichiers estimés Couplage
apps/web/ Frontend React SPA ~2000+ Consomme l'API Go via REST
veza-backend-api/ API REST Go — cœur du produit ~1111 PostgreSQL, Redis, RabbitMQ, S3
veza-stream-server/ Serveur de streaming HLS + WebSocket ~109 RS PostgreSQL, Redis, gRPC vers backend
veza-common/ Bibliothèque Rust partagée ~28 RS Importée par stream-server
veza-docs/ Site Docusaurus - Indépendant
packages/ Packages npm partagés - Workspace npm
k8s/ Manifests Kubernetes ~50+ Référence les images Docker
config/ Configs Docker, Prometheus, Grafana ~20 Référencé par docker-compose
migrations/ Migrations SQL (racine) ~90 Dupliqué dans veza-backend-api/migrations/
docs/ Documentation technique ~50+ Indépendant
make/ Modules Makefile ~10 Orchestration build
scripts/ Scripts utilitaires ~10 Outillage
fixtures/ Données de test - Tests uniquement
loadtests/ Scripts de charge - Tests uniquement
proto/ Définitions Protobuf ~5 gRPC entre Go et Rust

Packages orphelins identifiés :

  • veza-docs/ — Site Docusaurus, potentiellement non déployé (pas référencé dans CI/CD principal)
  • sub_task_agents/ — Documentation d'agents, pas du code

Packages fantômes identifiés :

  • veza-chat-server/ABSENT du repo malgré des mentions dans la documentation et les .cursorrules. Le chat a été migré vers le backend Go en v0.502 (confirmé dans PROJECT_STATE.md)

Duplications :

  • Le dossier migrations/ existe à la racine ET dans veza-backend-api/migrations/ — risque de désynchronisation

1.3 Métriques de taille

Service LOC Test files Stories Ratio test/code
Go backend 184 501 292 - ~1:1.6 (élevé)
React frontend 211 929 299 306 ~1:1.4 (élevé)
Rust stream 39 403 6 - ~1:43 (faible)
TOTAL 435 833 597 306 -

1.4 Schémas de flux critiques

graph TB
    subgraph "Auth Flow"
        A[Frontend] -->|POST /auth/login| B[Go API]
        B -->|Validate credentials| C[PostgreSQL]
        B -->|Check lockout| D[Redis]
        B -->|Set httpOnly cookies| A
        A -->|Auto-send cookies| B
        B -->|Verify JWT + Session| D
    end
graph TB
    subgraph "Upload & Playback Flow"
        A[Frontend] -->|POST /uploads| B[Go API]
        B -->|ClamAV scan| C[Virus Scanner]
        B -->|Store file| D[MinIO S3]
        B -->|Queue transcode| E[RabbitMQ]
        E -->|Consume job| F[Go Worker]
        F -->|FFmpeg transcode| G[HLS Segments]
        G -->|Store segments| D
        H[Frontend Player] -->|GET /stream/:id| I[Rust Stream Server]
        I -->|Validate token| J[PostgreSQL]
        I -->|Serve HLS| H
    end
graph TB
    subgraph "Payment Flow"
        A[Frontend] -->|POST /commerce/cart/checkout| B[Go API]
        B -->|Create payment| C[Hyperswitch]
        C -->|Webhook| B
        B -->|Verify HMAC-SHA512| D{Signature OK?}
        D -->|Yes| E[Update Order]
        D -->|No| F[Reject]
    end

Points de défaillance unique (SPOF) identifiés :

  • PostgreSQL — Pas de réplication configurée dans docker-compose. Single instance.
  • Redis — Utilisé pour CSRF, rate limiting, sessions, cache, presence. Si Redis tombe, les utilisateurs sont déconnectés et ne peuvent plus faire de requêtes mutantes (CSRF fail-secure → 503).
  • RabbitMQ — Optionnel (fallback in-process), bon design.
  • MinIO — Storage des fichiers audio. Pas de réplication visible.

Timeouts :

  • HTTP server : 30s read/write
  • Request middleware timeout : configuré
  • exec.CommandContext : context-based
  • Redis operations : timeout configuré
  • External HTTP calls : à vérifier cas par cas

2 CE QUE LE PRODUIT PERMET RÉELLEMENT

2.1 Classification des features

Fonctionnelles (backend + frontend + DB + MSW)

Feature Backend Frontend DB Tests
Auth (register, login, JWT, refresh) Complet Complet Migrations 010-020
2FA (TOTP) Complet Complet Migration MFA
Sessions management Complet Complet Migration 020
Track CRUD + upload Complet Complet Migration 030-040
HLS Streaming Réel (FFmpeg) HLS.js Migration 040
Playlists (CRUD, collab, share) Complet Complet Migrations 044
Search (pg_trgm) Complet Complet Migration 048-085
Notifications Complet Complet Migration 047
Chat (WebSocket, Go) Migré en Go Complet Migration 051+
Social (feed, posts, groups) Complet Complet Migrations 069-070
Marketplace (products, orders) Complet Complet Migrations + Hyperswitch
Cloud Storage (files, folders, quota) Complet Complet Migrations 105-106
Gear/Inventory Complet Complet Migrations 076+
Analytics (creator dashboard) Complet Complet Migration 081
Admin panel Complet Complet
Developer portal (API keys, webhooks) Complet Complet Migrations 075, 082
RBAC (roles, permissions) Complet Complet Migration 021
Audit logs Complet Admin UI Migration 910
Feature flags (DB-backed) Complet Admin UI Migration 935

⚠️ Partiellement implémentées

Feature État Détail
OAuth Backend ⚠️ generateJWT produit des tokens invalides (manque issuer/audience). Le flux OAuth callback est probablement cassé.
Live Streaming Backend , Frontend ⚠️ Routes API complètes, UI existante, mais pas de serveur RTMP/WebRTC de diffusion réel
WebRTC Audio Calls Frontend store Signalisation dans le chat store, mais pas de TURN/STUN server configuré. P2P audio non fonctionnel en conditions réseau réelles.
Cloud file versioning Backend + DB Frontend stories en cours (fichier modifié dans git status)
Stripe Connect Backend Seller onboarding, transfers, balance — mais Hyperswitch SDK côté frontend (pas Stripe Elements)

👻 Features fantômes

Feature Déclarée dans Réalité
Studio Anciennes versions Explicitement retiré du scope (FEATURE_STATUS.md)
Education Anciennes versions Explicitement retiré du scope
Gamification FEATURE_STATUS.md "MSW-only" — mocks existent, pas de backend
veza-chat-server (Rust) .cursorrules, docs Répertoire absent. Chat migré en Go v0.502. Documentation pas mise à jour.

💀 Code mort identifié

Élément Localisation LOC estimé
PasswordService.GenerateJWT password_service.go:260-267 8 LOC — Jamais appelé hors tests
Routes /internal/tracks/:id/stream-ready routes_core.go Marquées "deprecated"
Routes /internal/stream-events routes_core.go Marquées "deprecated"
TokenBlacklist service token_blacklist.go ~100 LOC — Implémenté mais non connecté au middleware auth
Références au chat-server Rust .cursorrules, docs Documentation obsolète

2.2 Incohérences produit/code

  1. .cursorrules mentionne veza-chat-server avec des instructions de compilation (cargo build --release) — ce service n'existe plus depuis v0.502.
  2. .cursorrules mentionne "Chat Server: Erreurs compilation SQLx" — service supprimé.
  3. VERSION file dit 0.101.0 mais le projet est en v0.803 selon CHANGELOG et git tags — incohérence de versioning.
  4. Dockerfile dev utilise Go 1.23 mais go.mod et Dockerfile.production utilisent Go 1.24 — incohérence de version.

3 VALIDATION FONCTIONNELLE

3.1 Couverture de tests

Service Test files LOC test estimé Tests désactivés Commentaire
Go backend 292 ~55 000 ~134 t.Skip Majorité conditionnels (infra-dependent), pas hard-disabled
React frontend 299 ~45 000 12 test.skip E2E principalement, conditionnels
Rust stream 6 ~3 000 0 Couverture très faible
Storybook 306 stories - - Excellente couverture UI

Points positifs :

  • 897 artefacts de test au total
  • Go : ratio test/code ~1:3.3 → bon
  • Frontend : tests unitaires + E2E Playwright + Storybook + MSW → pipeline complet
  • 196 endpoints MSW mockés → couverture quasi-totale des API calls

Points négatifs :

  • Rust stream server : 6 fichiers de test pour 109 fichiers source → risque élevé de régressions
  • 134 tests Go conditionnellement skippés → la couverture effective dépend de l'infrastructure de test
  • Pas de tests de contrat API formalisés (pas d'OpenAPI validation automatique)

3.2 Points de rupture probables

Scénario Risque Impact
Redis down ÉLEVÉ CSRF → 503 sur toutes les requêtes mutantes. Sessions non validables. Rate limiting dégradé (fallback in-memory).
10K tracks pour un utilisateur MOYEN Pagination implémentée, mais ORDER BY dynamique + OFFSET peut devenir lent. Cursor-based pagination absente.
Fichier audio de 10GB uploadé FAIBLE Taille max validée par UploadValidator. ClamAV scanner en place.
1000 WebSocket simultanées MOYEN Go chat: goroutines, devrait tenir. Rust stream: websocket.rs a un connection manager mais pas de test de charge prouvé.
Webhook Hyperswitch en triple FAIBLE Les orders ont des statuts idempotents. Pas de déduplication explicite par webhook ID visible.
Token expiré mid-session FAIBLE Refresh token flow implémenté. Axios interceptor pour auto-refresh. httpOnly cookies.
Migration qui échoue à moitié MOYEN Pas de transactions explicites visibles autour des migrations. Pas de BEGIN/COMMIT wrapper.

4 AUDIT DE SÉCURITÉ

Registre des vulnérabilités

ID Catégorie Gravité Fichier(s) Description Impact Correctif Effort
VEZA-SEC-001 A07 Auth CRITIQUE oauth_service.go:585-593 generateJWT crée un JWT sans iss, aud, token_version, session_id. Ce token échoue à la validation dans auth.go:191 (version mismatch) et possiblement auth.go:166 (claims parsing). OAuth login probablement non fonctionnel. Si un consommateur accepte ces tokens sans validation complète, contournement d'auth possible. Remplacer par un appel à JWTService.GenerateAccessToken() + GenerateRefreshToken() avec création de session. M
VEZA-SEC-002 A07 Auth ÉLEVÉ password_service.go:260-267 GenerateJWT crée un token 24h sans issuer/audience/token_version. Bien que non appelé en production (aucun appel trouvé hors tests), sa présence est un risque si un développeur l'utilise par erreur. Contournement potentiel des contrôles de sécurité si utilisé. Supprimer cette méthode ou la faire passer par JWTService. S
VEZA-SEC-003 A07 Auth ÉLEVÉ oauth_service.go:252 Pas de PKCE (Proof Key for Code Exchange) dans le flux OAuth. Authorization Code flow sans PKCE. Vulnérable à l'interception du code d'autorisation sur des clients publics (SPA). Implémenter PKCE (S256). Ajouter code_verifier / code_challenge. M
VEZA-SEC-004 A02 Crypto ÉLEVÉ oauth_service.go:577-579 access_token et refresh_token des providers OAuth stockés en clair dans federated_identities. Si la base est compromise, l'attaquant a accès aux comptes OAuth liés (Google, GitHub, etc.). Chiffrer les tokens au repos avec une clé de chiffrement séparée (AES-GCM). M
VEZA-SEC-005 A08 Integrity ÉLEVÉ hyperswitch/routes_webhooks.go:65-73 Si HyperswitchWebhookSecret est vide, la vérification de signature est sautée (log warn seulement). En dev/staging, un attaquant peut forger des webhooks de paiement. Création de commandes frauduleuses, confirmation de paiements non effectués. Rendre la vérification obligatoire dans tous les environnements, ou bloquer les webhooks si le secret n'est pas configuré. S
VEZA-SEC-006 A03 Injection MOYEN waveform_service.go:72,82 inputPath passé directement à exec.CommandContext sans appel à ValidateExecPath(). D'autres services (transcode, backup, export) l'appellent systématiquement. Si inputPath contient des caractères spéciaux, path traversal possible (pas command injection car pas de shell). Ajouter utils.ValidateExecPath(inputPath) avant les appels exec.CommandContext. S
VEZA-SEC-007 A04 Design MOYEN token_blacklist.go, auth.go Le TokenBlacklist service est implémenté (Redis-backed, SHA-256 hashed) mais n'est jamais appelé dans le middleware d'auth. La révocation repose uniquement sur TokenVersion. Impossible de révoquer un token spécifique — seule la révocation de tous les tokens d'un utilisateur (via token version increment) est possible. Connecter TokenBlacklist.IsBlacklisted() dans authenticate() après la validation JWT. S
VEZA-SEC-008 A04 Design MOYEN ratelimit.go:49-50 /auth/login et /auth/register sont exclus du rate limiter global (100 req/min par IP). Ils ont des rate limiters endpoint-spécifiques (5/15min login, 3/h register) mais pas le plafond global. Un attaquant peut potentiellement contourner la protection globale en ciblant ces endpoints. Les limites endpoint-spécifiques restent en place. Appliquer le rate limiter global en amont des rate limiters spécifiques, ou documenter le choix. S
VEZA-SEC-009 A02 Crypto FAIBLE config.go:293 CHAT_JWT_SECRET fallback au JWT_SECRET principal. Si non configuré séparément, un JWT crafté pour le chat pourrait être accepté par l'API principale (si les claims matchent). Escalade potentielle entre services. Documenter ou forcer des secrets séparés. S
VEZA-SEC-010 A07 Auth FAIBLE oauth_service.go Pas de validation whitelist pour l'URL de redirection OAuth post-callback. Open redirect potentiel après OAuth. Valider l'URL de redirection contre une whitelist de domaines autorisés. S

Points de sécurité positifs (bonnes pratiques confirmées)

Domaine Implémentation Fichier
Tokens httpOnly cookies, non accessibles depuis JS tokenStorage.ts (no-op class), backend sets cookies
Passwords bcrypt cost 12, min 12 chars, complexity rules, 72-byte limit enforced password_service.go:23,311
JWT HS256 algorithm pinning, 5 min TTL, issuer/audience validation, token version jwt_service.go:126-131,37
CSRF Redis-backed, 32-byte random, timing-safe comparison, fail-secure csrf.go:131,115-127
CORS Wildcard blocked in production, credentials-aware, origin reflection cors.go:29,125
Headers HSTS, CSP, X-Frame-Options DENY, COEP, COOP, CORP, Permissions-Policy security_headers.go
Rate limiting Multi-layer (global IP, per-endpoint, per-user), Redis with in-memory fallback ratelimit*.go, endpoint_limiter.go
Account lockout 5 attempts / 15 min, 30 min lockout, fail-secure account_lockout_service.go
File upload ClamAV scanning, type validation, concurrent limiting, fail-secure (503) upload.go:182-197
SQL Parameterized queries throughout, ORDER BY fields whitelisted user_service_search.go:147-155
Exec ValidateExecPath() on most services, context-based exec utils/sanitizer.go:29-43
Secrets No hardcoded secrets, env vars required, masking in logs config.go, secrets.go
Audit Comprehensive audit middleware for sensitive actions middleware/audit.go
Bypass protection validateNoBypassFlagsInProduction blocks CSRF_DISABLED, DISABLE_RATE_LIMIT config/validation.go
Frontend XSS No dangerouslySetInnerHTML, DOMPurify available, no localStorage for tokens Grep results
Docker Non-root users (UID 1001), minimal alpine bases, health checks All Dockerfiles

5 DETTE TECHNIQUE

5.1 Registre de la dette

Cat. Description Impact Fichier(s) Effort
🔴 OAuth generateJWT produit des tokens invalides OAuth login cassé oauth_service.go:585 M
🔴 TokenBlacklist déconnecté de l'auth Révocation granulaire impossible token_blacklist.go S
🟠 Rust stream server : 6 fichiers de test pour 109 sources Régressions non détectées veza-stream-server/src/ L
🟠 134 tests Go conditionnellement skippés (infra-dependent) Couverture effective incertaine sans CI complet *_test.go XL
🟠 veza-chat-server référencé dans .cursorrules mais absent Confusion pour nouveaux développeurs .cursorrules S
🟠 VERSION file (0.101.0) incohérent avec CHANGELOG (v0.803) Confusion de versioning VERSION S
🟠 Migrations : 122 fichiers, numérotation non contiguë (001→122 puis 900→935) Consolidation nécessaire avant scaling de l'équipe migrations/ L
🟠 40 fichiers Go > 500 lignes Complexité, maintenabilité réduite Voir liste section 3 L
🟡 docs.go généré : 5482 lignes Swagger spec dans le code source, alourdit le repo docs/docs.go S
🟡 Duplication migrations/ racine vs veza-backend-api/migrations/ Risque de désynchronisation Racine + backend S
🟡 Go 1.23 dans Dockerfile dev vs 1.24 dans go.mod et Dockerfile.production Comportement différent dev/prod Dockerfiles S
🟡 21 TODO/FIXME/HACK dans le codebase Minor mais à nettoyer Distribués S
🟡 Pas de cursor-based pagination Performance dégradée sur grands datasets avec OFFSET Services de listing M
soundcloud/ directory dans Rust stream server Purpose unclear, naming confusion with SoundCloud brand veza-stream-server/src/soundcloud/ S

5.2 Quantification

Métrique Go TypeScript Rust Total
LOC 184 501 211 929 39 403 435 833
LOC mort estimé ~200 ~500 (generated types) ~3000 (generated protobuf + soundcloud) ~3 700
Fichiers de test 292 299 6 597
Stories - 306 - 306
TODO/FIXME/HACK 9 8 4 21
Fichiers > 500 lignes 40 (1 generated) 20 (1 generated) 19 (1 generated) 79
Dépendances directes ~35 82 (35 prod + 47 dev) ~60 177

5.3 Hétérogénéité Go + Rust

Le choix de Go pour le backend API et Rust pour le streaming est architecturalement justifié :

  • Go excelle en HTTP/REST APIs avec GORM, handlers, middleware
  • Rust est pertinent pour le traitement audio temps-réel et HLS

Cependant, le chat server Rust a été migré en Go (v0.502), validant que Rust n'était pas nécessaire pour le WebSocket chat. La réduction à 2 langages (Go + Rust stream) est rationnelle.

Le coût réel : deux toolchains, deux CI pipelines, deux sets de dépendances à maintenir. Pour une équipe < 3 devs, c'est un overhead significatif.


6 QUALITÉ ARCHITECTURALE

6.1 Monorepo

Critère Évaluation
Outil Turbo 2.3.0 + npm workspaces
Build Parallélisable via Turbo, outputs cachés
Versioning Incohérent (VERSION file ≠ CHANGELOG tags)
Workspace npm workspaces, Cargo workspace partiel
Makefile Excellent — 10 modules, orchestration complète

6.2 Frontend

Critère Score Détail
Structure Feature-based, clean separation
State Zustand + TanStack Query, persist + broadcast sync
Data fetching TanStack Query avec cache/invalidation
Routing React Router 6.30, lazy loading, code splitting
Design system SUMI v2.0, 207+ UI components, Tailwind + CSS tokens
TypeScript Strict mode probable, minimal any usage
Storybook 306 stories, MSW addon, a11y addon
MSW 196 endpoints, 11 handler modules, catch-all
Security httpOnly cookies, no dangerouslySetInnerHTML, DOMPurify, Zod validation
Env validation Zod schema for env vars

6.3 Backend Go

Critère Score Détail
Architecture Layered: handler → service → repository. Domain-driven (core/auth, core/track, core/marketplace)
Error handling Wrapped errors, structured responses, recovery middleware
Middleware 26 middlewares, correct ordering, comprehensive coverage
Database GORM with connection pooling, parameterized queries, 122 migrations
Concurrency Context propagation, graceful shutdown manager, goroutine management
Config Environment-based, validated at startup, production-specific checks
API versioning /api/v1/ consistently
OpenAPI ⚠️ Swagger generated (docs.go) but not validated against code automatically

6.4 Rust Stream Server

Critère Score Détail
Architecture Modular (auth, streaming, transcoding, codecs, monitoring)
Error handling Custom AppError enum, 30+ variants, IntoResponse
Safety 0 unsafe blocks, ~15 expect() only in initialization
Tests 6 test files for 109 source files — critical gap
Compilation ⚠️ No sqlx-data.json — requires live DB for compilation check

6.5 Base de données

Critère Score Détail
Schema Well-normalized, UUID primary keys, FK constraints
Indexes pg_trgm, composite indexes, performance indexes (migration 920)
Migrations ⚠️ 122 migrations, non-contiguous numbering (1-122, 900-935), no consolidation
Relations FK constraints, cascades in migration 930
Redis usage Cache, CSRF, sessions, rate limiting, presence, blacklist — well-defined roles

6.6 Scorecard

Dimension Score Justification
Architecture 8/10 Excellente séparation des concerns, patterns cohérents, middleware chain exemplaire. -1 pour OAuth JWT bypass, -1 pour TokenBlacklist déconnecté.
Maintenabilité 7/10 Code lisible, conventions respectées, 21 TODO seulement. -1 pour 79 fichiers > 500 lignes, -1 pour incohérences de version, -1 pour documentation obsolète (chat-server).
Sécurité 7/10 Excellentes pratiques (httpOnly, bcrypt, CSRF, CSP, rate limiting). -1 pour OAuth cassé, -1 pour PKCE absent, -1 pour tokens OAuth en clair.
Scalabilité 6/10 Architecture horizontalement scalable en théorie. -1 pour SPOF PostgreSQL/Redis, -1 pour OFFSET pagination, -1 pour 134 tests conditionnels, -1 pour Rust tests insuffisants.
Testabilité 7/10 897 artefacts de test, pipeline complet. -1 pour Rust coverage, -1 pour tests infra-dependent, -1 pour pas de contrat API formel.
Opérabilité 8/10 Prometheus, Grafana, alerting, structured logging, health checks, K8s manifests, blue-green. -1 pour monitoring chat non couvert, -1 pour pas de runbook opérationnel complet.
Vélocité dev 7/10 Makefile complet, MSW, Storybook, hot reload. -1 pour 3 langages, -1 pour onboarding multi-toolchain, -1 pour documentation incohérente.
Maturité produit 6/10 19 features opérationnelles, 5 partielles, 4 fantômes. -1 pour OAuth cassé, -1 pour WebRTC non fonctionnel, -1 pour live streaming partiel, -1 pour gamification fantôme.

Score moyen : 7.0 / 10


7 INFRA & DEVOPS

7.1 Docker

Critère Status
Multi-stage builds Tous les services
Images de base Alpine (Go, Rust, Node, Nginx)
Non-root UID 1001 partout
Health checks Configurés
Secrets en build args Aucun — env vars au runtime
Taille optimisée Static binaries, stripped
ClamAV ⚠️ Installé dans l'image backend — augmente la taille

7.2 CI/CD

Critère Status
Lint ESLint, Clippy, gofmt, go vet
Tests Unit + integration + E2E + Storybook
Security scanning Gitleaks, CodeQL, Trivy, govulncheck, cargo-audit, npm audit
Container scanning Trivy CRITICAL/HIGH
SBOM CycloneDX
Signing Cosign (configurable)
Deployment Blue-green via docker-compose.prod.yml
Environments Dev, staging, production séparés
Secrets GitHub Secrets + External Secrets Operator (Vault)
Pre-commit Husky hooks (typecheck, lint, tests)

7.3 Reproductibilité

Critère Status
Single command build make dev ou docker compose up
Lock files go.sum, Cargo.lock, package-lock.json
Toolchain pinning rust-toolchain.toml, Go version in go.mod
Onboarding doc ONBOARDING.md existe

8 PERFORMANCE & SCALABILITÉ

Composant Risque Seuil estimé Mitigation
PostgreSQL N+1 queries possibles via GORM > 5K req/min GORM Preload utilisé, mais à profiler
Redis SPOF pour CSRF/sessions/rate-limit Si Redis down → 503 global Sentinelle ou cluster non configuré
Chat WebSocket (Go) Goroutine per connection > 5K connexions simultanées Goroutine-safe, mais backpressure à valider
Stream server HLS segment serving > 500 streams simultanés Rust + Tokio devrait tenir, mais 6 tests
File storage (MinIO) Single instance > 5TB Pas de réplication configurée
OFFSET pagination O(n) scan > 100K records Migrer vers cursor-based pagination

Scalabilité horizontale :

  • Backend Go : stateless (sessions en Redis), scalable
  • Frontend : statique, CDN-ready
  • ⚠️ Stream server : WebSocket = session affinity nécessaire
  • ⚠️ Chat : WebSocket = session affinity nécessaire
  • PostgreSQL : single instance, pas de sharding
  • Redis : single instance

9 RISQUES BUSINESS

9.1 Verdict catégorique

Question Réponse Justification
Peut-on lancer en production tel quel ? NON OAuth cassé, webhook verification optionnelle, TokenBlacklist déconnecté
Peut-on vendre/monétiser tel quel ? NON Flux de paiement dépend de Hyperswitch webhook non vérifié en staging. OAuth non fonctionnel empêche le social login.
Peut-on maintenir avec 2 devs ? Conditionnel Oui si Go + TS. Le Rust stream server est un risque si le dev Rust part.
Faut-il refactorer avant prod ? OUI Corriger les 5 vulnérabilités, consolider les migrations, connecter le TokenBlacklist
Faut-il réécrire certains services ? NON L'architecture est saine. Corrections ciblées suffisent.
La vélocité (353 features) est-elle un red flag ? Attention Le volume est impressionnant mais le ratio features/tests sur le Rust server et la présence de features fantômes suggèrent que certaines "features" sont des endpoints avec MSW mocks mais pas de validation E2E réelle.

9.2 Point de vue investisseur

Question Réponse
Le produit est-il fonctionnel ou une démo ? Fonctionnel pour 80% des features. Les 19 features opérationnelles ont du code backend réel, des migrations, des handlers, des services, des tests. Ce n'est pas un prototype Figma ni du mock-only.
Risques d'incident public ? Oui — les tokens OAuth providers en clair et le webhook payment non vérifié sont exploitables. Correctifs estimés à 2-3 jours.
Code repris par une autre équipe ? Oui avec 2-3 semaines d'onboarding. Architecture claire, conventions cohérentes, documentation existante. La multi-stack Go+Rust+TS nécessite des profils polyvalents.
Coût pour v1.0 production-ready ? 4-8 semaines pour corrections sécurité + tests Rust + consolidation migrations + monitoring complet + load testing.
IP technique défendable ? Oui — le pipeline HLS complet (upload → transcode → streaming), le système de chat WebSocket intégré, le marketplace avec Hyperswitch, et le système d'analytics constituent une plateforme cohérente.
Ratio features/qualité ? Quantité priorisée sur la qualité pour le stream server Rust (6 tests). Backend Go et frontend React ont un bon équilibre.

9.3 Score de rachetabilité

7/10 — Code bien structuré, architecture claire, documentation existante. Points de friction : multi-stack (3 langages), 122 migrations à comprendre, quelques incohérences documentaires.


🔟 PLAN D'ACTION PRIORISÉ

Phase 1 — Critique (semaines 1-2)

# Action Pourquoi Fichiers Effort
1 Corriger OAuth generateJWT — utiliser JWTService.GenerateAccessToken() + créer une session OAuth login cassé oauth_service.go:585-593, oauth_service.go:307 M (1-2j)
2 Supprimer PasswordService.GenerateJWT Code mort à risque password_service.go:260-267 S (<1j)
3 Rendre webhook Hyperswitch verification obligatoire dans tous les envs Forgery de paiement possible routes_webhooks.go:65-73 S (<1j)
4 Connecter TokenBlacklist au middleware auth Révocation granulaire non fonctionnelle auth.go, token_blacklist.go S (<1j)
5 Ajouter ValidateExecPath dans waveform_service.go Path traversal sur FFmpeg waveform_service.go:72,82 S (<1j)
6 Chiffrer les tokens OAuth providers au repos Compromission DB = accès aux comptes liés oauth_service.go:577-579 M (1-2j)

Phase 2 — Stabilisation (semaines 3-6)

# Action Pourquoi Effort
7 Implémenter PKCE dans le flux OAuth OWASP A07 compliance M
8 Ajouter des tests au Rust stream server — objectif 50% coverage 6 tests pour 109 fichiers = risque XL
9 Valider l'URL de redirection OAuth contre whitelist Open redirect prevention S
10 Harmoniser VERSION file avec les tags git Confusion de versioning S
11 Mettre à jour .cursorrules — retirer les références au chat-server Rust Documentation obsolète S
12 Harmoniser Go version dans tous les Dockerfiles (1.24) Comportement dev ≠ prod S
13 Load testing du stream server sous charge (1000 connexions WebSocket) Pas de preuve de performance L

Phase 3 — Consolidation (semaines 7-12)

# Action Pourquoi Effort
14 Consolider les migrations — squash 1-122 en un schéma initial 122 migrations = lent au setup, risque d'erreur L
15 Implémenter cursor-based pagination sur les listings à volume OFFSET O(n) ne scale pas L
16 Configurer Redis Sentinel/Cluster pour HA Redis = SPOF pour auth/CSRF M
17 Refactorer les 10 fichiers Go > 1000 lignes Complexité, maintenabilité L
18 Tests de contrat API — valider OpenAPI spec contre le code Drift API documentation M
19 Configurer PostgreSQL replication SPOF pour toutes les données L
20 Déduplication des migrations racine vs backend Source unique de vérité S

Phase 4 — Évolution (mois 4+)

# Action Effort
21 WebRTC avec TURN/STUN pour audio calls XL
22 Live streaming réel (RTMP ingestion) XL
23 Gamification (backend, pas juste MSW) L
24 Multi-region deployment XL
25 CDN pour assets audio M

CONCLUSION STRATÉGIQUE

Veza est un projet techniquement solide dans sa conception mais qui souffre d'un déséquilibre classique des projets early-stage : trop de features, pas assez de profondeur sur chacune. L'architecture est saine, les patterns sont cohérents, la sécurité est proactive dans 90% des cas — mais les 10% restants contiennent des vulnérabilités exploitables.

Le backend Go est le point fort du projet : layered architecture, 292 test files, middleware chain exemplaire, configuration validée. Le frontend React est également bien structuré avec son approche Storybook-first et ses 306 stories. Le Rust stream server est le point faible : fonctionnel mais insuffisamment testé (6 fichiers de test).

Recommandation : Investir, mais conditionné à la correction des 6 actions Phase 1 (2-3 jours de travail). Le coût de mise en production complète est estimé à 4-8 semaines. Le rapport qualité/ambition est favorable pour un projet de cette taille. L'architecture ne nécessite pas de réécriture — des corrections ciblées suffisent.

La question stratégique n'est pas technique mais organisationnelle : cette vélocité est-elle soutenable ? 26 versions en quelques mois avec une petite équipe suggère soit une productivité exceptionnelle, soit une accumulation de dette invisible. L'audit montre que la dette est quantifiable et gérable (21 TODO, ~3700 LOC mortes, 79 fichiers volumineux) — ce n'est pas un projet en perdition technique, c'est un projet qui a besoin de passer du mode "sprint feature" au mode "hardening for production".