veza/AUDIT_REPORT.md
senke 778c85508b
Some checks failed
Veza CI / Backend (Go) (push) Failing after 0s
Veza CI / Frontend (Web) (push) Failing after 0s
Veza CI / Rust (Stream Server) (push) Failing after 0s
Frontend CI / test (push) Failing after 0s
Security Scan / Secret Scanning (gitleaks) (push) Failing after 0s
Veza CI / Notify on failure (push) Failing after 0s
docs(audit): reconcile top-15 priorities with tier 1-3 + BFG pass
Updates AUDIT_REPORT §9/§9.bis/§9.3/§10 and FUNCTIONAL_AUDIT §7 to
reflect the 2026-04-23 cleanup session + git-filter-repo history rewrite.

Top-15 outcome:
- 10 items DONE with commit refs (b5281bec transactions, ebf3276d rate
  limiter, 4310dbb7 MinIO pin, 172581ff orphan removal, 18eed3c4
  deprecated handlers, d12b901d debris untrack, BFG for #1/#2/#7).
- 3 items flagged FALSE-POSITIVE after direct code inspection (§9.bis):
    #4 context.Background: 26/31 in _test.go, 5 legit (WS pumps, health)
    #5 CSP/XFO: already complete in middleware/security_headers.go
    #10 RespondWithAppError: intentional thin wrapper (handlers pkg)
- 2 deferred to v1.0.8 (#8 OpenAPI typegen, #14 E2E CI).
- 1 remaining before v1.0.7 final: #15 docs/ENV_VARIABLES.md sync.

Repo hygiene: .git 2.3 GB → 66 MB (−97%) after BFG pass, force-push
stages 1+2 OK, fingerprint match on Forgejo CA cert.

Annexe: diff table expanded v1 ↔ v2 ↔ v3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 14:20:28 +02:00

695 lines
61 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AUDIT_REPORT v2 — monorepo Veza
> **Date** : 2026-04-20
> **Branche** : `main` (HEAD = `89a52944e`, `v1.0.7-rc1`)
> **Auditeur** : Claude Code (Opus 4.7 — mode autonome, /effort max, /plan)
> **Méthode** : 5 agents Explore en parallèle (frontend, backend Go, Rust stream, infra/DevOps, dette transverse) + mesures macro directes + lecture `docs/audit-2026-04/v107-plan.md` + `CHANGELOG.md` v1.0.5 → v1.0.7-rc1.
> **Supersede** : [v1 du 2026-04-14](#annexe-diff-v1-v2) (HEAD `45662aad1`, v1.0.0-mvp-24). Depuis : v1.0.4 → v1.0.5 → v1.0.5.1 → v1.0.6 → v1.0.6.1 → v1.0.6.2 → v1.0.7-rc1. 50+ commits. Le v1 est **obsolète** : son "chemin critique v1.0.5 public-ready" a été réalisé intégralement, mais sa liste de hygiène repo (binaires, screenshots, .git 2.3 GB) est **restée en état**.
> **Ton** : brutal, pas de langue de bois. Citations `fichier:ligne`.
---
## 0. TL;DR — ce que je retiens en 12 lignes
1. **Plomberie produit : solide.** v1.0.5 → v1.0.7-rc1 a fermé tout le "chemin critique" fonctionnel : register/verify réels, player fallback `/stream`, refund reverse-charge Hyperswitch, reconciliation sweep, Stripe Connect reversal worker, ledger-health Prometheus gauges, maintenance mode persisté, chat multi-instance avec alarme loud. 50+ commits, **18 findings v1 résolus**. Détail : [FUNCTIONAL_AUDIT.md](FUNCTIONAL_AUDIT.md).
2. **Hygiène repo : catastrophique.** `.git` = **2.3 GB** (inchangé depuis v1). Binaire `api` de **99 MB** encore à la racine (tracked, ELF). 44 fichiers audio `.mp3/.wav` encore dans `veza-backend-api/uploads/`. 48 screenshots PNG à la racine (`dashboard-*.png`, `login-*.png`, `design-system-*.png`, `forgot-password-*.png`). 36 `.playwright-mcp/*.yml` debris de sessions MCP. `CLAUDE_CONTEXT.txt` = **977 KB** à la racine.
3. **`CLAUDE.md` globalement juste** (v1.0.4, 2026-04-14) mais Vite annoncé "5" → réellement **Vite 7.1.5** (`apps/web/package.json`). Axios "déprécié en dev" → réellement `1.13.5` moderne. `docs/ENV_VARIABLES.md` introuvable alors que CLAUDE.md dit "à maintenir".
4. **Frontend** : 1984 fichiers TS/TSX. **36 features** modulaires. Router propre (27 routes top-level, 54 lazy). `src/types/generated/api.ts` = **6550 lignes, régénéré aujourd'hui** — OpenAPI typegen a démarré. **282 occurrences `any`** (dont `services/api/auth.ts:85-100` triple cast token fallback). **6 `console.log` en prod** (checkbox, switch, slider, AdvancedFilters, Onboarding, useLongRunningOperation). 11 composants UI orphelins (`hover-card/*`, `dropdown-menu/*`, `optimized-image/*`). 3.5 MB de dead reports (`e2e-results.json` 3.4 MB, `lint_comprehensive.json` 793 KB, `ts_errors.log` 29 KB).
5. **Backend Go** : 877 fichiers `.go`, **197K LOC**. 27 fichiers routes, 135 handlers, 226 services, 81 modèles, **160 migrations** (jusqu'à `983_`), 17 workers, 11 jobs. **Transactions manquantes** sur paths critiques (marketplace `service.go:1050+`, subscription). **31 instances `context.Background()` dans handlers** → timeout middleware défait. 3 binaires trackés (`api`, `main`, `veza-api`). **Duplicate `RespondWithAppError`** (`response/response.go:101` + `handlers/error_response.go:12`).
6. **Rust stream server** : Axum 0.8 + Tokio 1.35 + Symphonia. HLS ✅ réel, HTTP Range 206 ✅, WebSocket 1047 LOC ✅, adaptive bitrate 515 LOC ✅. **DASH commenté** (`streaming/protocols/mod.rs:4`). **WebRTC commenté** (`Cargo.toml:62`). **`#![allow(dead_code)]` global** au `lib.rs:5` — camoufle les stubs. 0 `unsafe` (engagement CLAUDE.md tenu). **`proto/chat/chat.proto` orphelin** depuis suppression chat Rust (2026-02-22). `veza-common/src/chat/*` types orphelins.
7. **Chat server Rust** : **confirmé absent** (commit `05d02386d`, 2026-02-22). Zéro référence dans k8s (bon). **`proto/chat/*.proto` reste comme spec historique** — à déplacer en `docs/archive/` ou supprimer.
8. **Desktop Electron** : **confirmé absent**. Jamais implémenté. Fossile des docs anciennes.
9. **Docker** : 6 compose files (dev/prod/staging/test/root/`infra/lab.yml` DEPRECATED Feb 2026). **MinIO pinné `:latest` dans 4 composes** → supply-chain risk. ES 8.11.0 uniquement en dev (orphelin ? backend utilise Postgres FTS). Healthchecks partout mais intervals incohérents (5s→30s). **3 variants Dockerfile par service** (base + .dev + .production) — multi-stage, non-root user `app` (uid 1001), `-w -s` stripped. ⚠️ stream-server Dockerfile.production expose `8082` mais `docker-compose.prod.yml:284` healthcheck attend `3001`**mismatch**.
10. **CI/CD** : 5 workflows actifs (`ci.yml` consolidé + `frontend-ci.yml` + `security-scan.yml` gitleaks + `trivy-fs.yml` + `go-fuzz.yml`). **19 workflows disabled, 1676 LOC mort** (`backend-ci.yml.disabled`, `cd.yml.disabled`, `staging-validation.yml.disabled`, `accessibility.yml.disabled`, etc.). E2E **pas déclenché en CI** alors que Playwright existe. Tests integration skipped (`VEZA_SKIP_INTEGRATION=1`) faute de Docker socket.
11. **Sécurité** : JWT RS256 prod / HS256 dev ✅. OAuth (Google/GitHub/Discord/Spotify) ✅. 2FA TOTP ✅. CORS strict en prod ✅. gitleaks + govulncheck + trivy en CI ✅. **Absents** : CSP header, X-Frame-Options (0 grep hit). **.env committé** (`/veza-backend-api/.env`, `-rw-r--r--`). **TLS certs committés** : `/docker/haproxy/certs/veza.pem`, `/config/ssl/{cert,key,veza}.pem`**rotate + BFG needed**.
12. **Verdict monorepo** : **Moyen-Haute dette sur l'hygiène, Faible dette sur le code applicatif**. Le produit fonctionne, la plomberie monétaire est auditée, la sécurité applicative est solide. Mais les items "cleanup" de l'audit v1 n'ont **pas été traités** : binaires trackés, .git 2.3 GB, screenshots racine, .playwright-mcp debris, CLAUDE_CONTEXT.txt 977 KB, 19 workflows disabled, .env/certs committed. **~1 jour de cleanup brutal reste à faire** avant le tag v1.0.7 final.
---
## 1. État des lieux — mesures macro directes
### 1.1 Taille & fichiers
| Mesure | v1 (14-04) | v2 (20-04) | Delta |
| ------------------------- | ------------ | ------------- | -------------------------------------- |
| `.git` (du -sh) | 2.3 GB | **2.3 GB** | 0 (pas de `git filter-repo` fait) |
| Fichiers trackés | 6425 | **6313** | 112 (quelques cleanups ponctuels) |
| Binaires ELF racine | 3 (api/main/veza-api) | **1 (`api` 99 MB)** | 2 supprimés mais 1 persiste |
| Screenshots racine | 54 | **48** | 6 |
| `.md` total repo | inconnu | **435** (18 active + 417 archive) | — |
| `.playwright-mcp/*.yml` | — | **36 (untracked)** | NEW debris |
| `CLAUDE_CONTEXT.txt` | — | **977 KB** racine | NEW artifact de session |
| `output.txt` racine | — | **27 KB** | NEW |
### 1.2 Ce qui n'existe PAS (contrairement à certaines docs)
| Objet | Status | Preuve |
| ---------------------------------- | :--------------: | ------------------------------------------------------------------------------------------------ |
| `veza-chat-server/` | ❌ absent | `ls /home/senke/git/talas/veza/veza-chat-server` → no such dir. Commit `05d02386d` (2026-02-22). |
| `apps/desktop/` (Electron) | ❌ absent | Jamais implémenté. |
| `backend/` racine | ❌ absent | C'est `veza-backend-api/`. |
| `frontend/` racine | ❌ absent | C'est `apps/web/`. |
| `ORIGIN/` racine | ❌ absent | C'est `veza-docs/ORIGIN/`. |
| `proto/chat/chat.proto` utilisé | ❌ orphelin | 0 import dans `veza-stream-server/src/`. Chat 100% Go depuis v0.502. |
| Runbooks k8s mentionnant chat Rust | ❌ clean (bonne) | Grep `veza-chat-server` dans `k8s/` = 0 hit. |
| **Binaire `api` 99 MB racine** | ⚠️ **présent** | `-rwxr-xr-x 1 senke senke 99515104 Mar 24 15:40 api`. **À supprimer.** |
---
## 2. Architecture & stack — mise à jour exacte
### 2.1 Arborescence réelle
```
veza/ (2.3 GB .git, 6313 fichiers trackés)
├── apps/web/ # React 18.2 + Vite 7.1.5 + TS 5.9.3 + Zustand 4.5 + React Query 5.17
│ └── src/ (1984 fichiers TS/TSX)
│ ├── features/ (36 feature folders)
│ ├── components/ui/ (255 fichiers — design system)
│ ├── services/ (73 fichiers)
│ ├── types/generated/ (api.ts 6550 lignes, régénéré aujourd'hui)
│ └── router/routeConfig.tsx (184 lignes, 27 routes top-level, 54 lazy)
├── veza-backend-api/ # Go 1.25.0 + Gin + GORM + Postgres + Redis + RabbitMQ
│ ├── cmd/api/main.go (orchestration wiring)
│ ├── cmd/{migrate_tool,backup,generate-config-docs,tools/*} (~6 binaires)
│ ├── internal/ (877 fichiers .go, 197K LOC)
│ │ ├── api/ (27 routes_*.go)
│ │ ├── api/handlers/ (3 fichiers DEPRECATED — chat, rbac)
│ │ ├── handlers/ (135 fichiers — source active)
│ │ ├── services/ (226 fichiers, 64K LOC)
│ │ ├── core/*/ (9 services feature-scoped)
│ │ ├── models/ (81 fichiers, 44K LOC)
│ │ ├── migrations/ (160 .sql, jusqu'à 983_)
│ │ ├── workers/ (17) + jobs/ (11)
│ │ ├── middleware/ (~30)
│ │ ├── repositories/ (18 GORM-based)
│ │ └── repository/ (1 ORPHELIN in-memory mock)
│ ├── docs/swagger.{json,yaml} (v1.2.0, 2026-03-03)
│ ├── uploads/ (44 .mp3/.wav TRACKÉS !)
│ └── {api,main,veza-api} (3 binaires ELF trackés dans CLAUDE.md .gitignore mais présents)
├── veza-stream-server/ # Rust 2021 + Axum 0.8 + Tokio 1.35 + Symphonia 0.5 + sqlx 0.8 + tonic 0.11
│ └── src/
│ ├── streaming/ (HLS réel, WebSocket 1047 LOC, adaptive 515 LOC, DASH stub commenté)
│ ├── audio/ (Symphonia + LAME native; opus/webrtc/fdkaac commentés)
│ ├── core/ (StreamManager 10k+ concurrents, sync engine 1920 LOC)
│ ├── auth/ (JWT HMAC-SHA256, revocation Redis+in-mem fallback, 825 LOC)
│ ├── grpc/ (Stream+Auth+Events — generated 21845 LOC auto)
│ ├── transcoding/ (queue job engine 94 LOC — ALPHA)
│ ├── event_bus.rs (RabbitMQ degraded mode, 248 LOC)
│ └── lib.rs:5 #![allow(dead_code)] GLOBAL — camoufle les stubs
├── veza-common/ # Rust types partagés
│ └── src/{chat,ws,files,track,user,playlist,media,api}.rs
│ └── chat.rs, track.rs, user.rs, etc. — ORPHELINS depuis suppression chat Rust
├── packages/design-system/ # Tokens design (unique package workspace)
├── proto/
│ ├── common/auth.proto ✅ utilisé par stream-server + backend
│ ├── stream/stream.proto ✅ utilisé par stream-server
│ └── chat/chat.proto ❌ ORPHELIN (chat en Go depuis v0.502)
├── docs/
│ ├── audit-2026-04/ (NEW : axis-1-correctness.md + v107-plan.md)
│ ├── archive/ (278 fichiers .md historique)
│ └── (API_REFERENCE, ONBOARDING, PROJECT_STATE, FEATURE_STATUS, etc.)
├── veza-docs/ # Docusaurus séparé
│ ├── docs/{current,vision}/
│ └── ORIGIN/ (22 fichiers phase-0 FOSSILE, jamais touchée post-launch)
├── k8s/ # ~30-40 manifests + 5 runbooks disaster-recovery
├── config/ # alertmanager, grafana, haproxy, prometheus, incus, ssl/* (.pem TRACKÉS)
├── infra/ # nginx-rtmp + docker-compose.lab.yml (DEPRECATED)
├── docker/ # haproxy/certs/veza.pem (TRACKÉ, sensible)
├── tests/e2e/ # Playwright — SKIPPED_TESTS.md liste les flakies
├── .github/workflows/ # 5 actifs + 19 .disabled (1676 LOC mort)
├── .husky/ # pre-commit + pre-push + commit-msg (untracked mais fonctionnels)
└── {docker-compose*.yml} # 6 files (dev/prod/staging/test/root/env.example)
```
### 2.2 Stack — versions actuelles
| Composant | Doc (CLAUDE.md) | Réel (code) | Écart ? |
| -------------- | --------------- | ----------------- | ----------------- |
| Go | 1.25 | **1.25.0** (go.mod) | ✅ OK |
| React | 18.2 | 18.2.0 | ✅ OK |
| Vite | **5** | **7.1.5** | ❌ CLAUDE.md obsolète |
| TypeScript | 5.9.3 | 5.9.3 | ✅ OK |
| Zustand | — | 4.5.0 | N/A |
| React Query | 5 | 5.17.0 | ✅ OK |
| Tailwind | — | **4.0.0** | ✅ récent |
| date-fns | 4 | 4.1.0 | ✅ OK |
| Axios | non mentionné | 1.13.5 | ✅ moderne |
| jwt-go | v5 | v5.3.0 | ✅ OK |
| gorm | — | v1.30.0 | ✅ OK |
| gin | — | v1.11.0 | ✅ OK |
| redis-go | — | v9.16.0 | ✅ OK |
| Rust edition | 2021 | 2021 | ✅ OK |
| Axum | 0.8 | 0.8 | ✅ OK |
| Tokio | 1.35 | 1.35 | ✅ OK |
| Symphonia | 0.5 | 0.5 | ✅ OK |
| sqlx | 0.8 | 0.8 | ✅ OK |
| tonic | — | 0.11 | ✅ récent |
| Postgres | 16 | 16-alpine (pinned)| ✅ OK |
| Redis | 7 | 7-alpine (pinned) | ✅ OK |
| ES | 8.11.0 | 8.11.0 (dev only) | ⚠️ orphelin prod |
| RabbitMQ | 3 | 3 (pinned) | ✅ OK |
| ClamAV | 1.4 | 1.4 (pinned) | ✅ OK |
| MinIO | — | **`:latest`** (4×)| ❌ supply-chain |
| Hyperswitch | 2026.03.11.0 | 2026.03.11.0 | ✅ OK |
**À corriger dans CLAUDE.md v1.0.5** : Vite 5 → Vite 7.1.5. Ajouter ligne MinIO.
---
## 3. Frontend (`apps/web/`)
### 3.1 Architecture & routes
- **36 feature folders** (`src/features/`) — les plus gros : `playlists/` (182), `tracks/` (181), `auth/` (100), `player/` (94), `chat/` (67).
- **Router** (`src/router/routeConfig.tsx:1-184`) — 27 routes top-level, **54 composants lazy**. **Zéro route "Coming Soon"/placeholder**. Tous les paths mènent à un composant réel.
- **OpenAPI typegen enclenché** : `src/types/generated/api.ts` = **6550 lignes, régénéré 2026-04-19 00:57:21**. La migration "kill hand-written services" prévue post-v1.0.4 a démarré. Script `apps/web/scripts/generate-types.sh` wiré en pre-commit.
### 3.2 Composants & design system
- `src/components/ui/` : **255 fichiers**. Untracked : `testids.ts` (NEW, probablement wiring E2E).
- **Composants orphelins identifiés** (0-1 imports — candidates suppression) :
- `components/ui/optimized-image/OptimizedImageSkeleton.tsx` (0)
- `components/ui/optimized-image/ResponsiveImage.tsx` (0)
- `components/ui/hover-card/*` (3 fichiers, 0 imports — arbre mort)
- `components/ui/dropdown-menu/*` (7 fichiers, 0-1 imports — probablement remplacé par Radix)
- Total : **~11 fichiers orphelins dans le DS**.
### 3.3 State & services
- **Zustand** : 5 stores principaux (`authStore`, `chatStore`, `playerStore`, `queueSessionStore`, `cartStore`) — tous utilisés.
- **React Query** : **seulement 9 fichiers** utilisent `useQuery/useMutation`. `queryKey` ad-hoc (hardcoded, dynamic, constants mélangés). **Pas de factory centralisée** → cache invalidation fragile.
- **Services** (73 fichiers) :
- Top 4 monolithes : `services/api/auth.ts:553` (token+login+register+2FA), `services/adminService.ts:474` (7+ endpoints), `services/analyticsService.ts:472`, `services/marketplaceService.ts:351`.
- **Anti-pattern critique** : `services/api/auth.ts:85-100` fait 3 fallback `const rd = response.data as any` pour parser les tokens. **Pas de validation Zod.**
### 3.4 Tests
- **286 fichiers `.test.ts(x)`** (Vitest).
- **1 test skipped** : `features/auth/pages/ResetPasswordPage.test.tsx` (async timing).
- **E2E** (racine `tests/e2e/`) : Playwright présent, **SKIPPED_TESTS.md documente les flakies** (v107-e2e-04/05/06/08/09 à vérifier en staging).
- Tests E2E **PAS déclenchés en CI** (Playwright absent de `.github/workflows/ci.yml`).
### 3.5 Dette frontend
| Dette | Count | Sévérité |
| ---------------------------------- | :---: | :------: |
| `TODO/FIXME/HACK` | 1 | ✅ top |
| `console.log` en production | 6 fichiers (checkbox, switch, slider, AdvancedFilters, Onboarding, useLongRunningOperation) | 🔴 |
| `any` types | 282 | 🔴 |
| `@ts-ignore` / `@ts-expect-error` | 6 fichiers | 🟡 |
| Fichiers >500 LOC (non-gen) | ~8 | 🟡 |
| Composants V2/V3/_old/_new | 0 | ✅ |
| `src/types/v2-v3-types.ts` | présent (mentionné CLAUDE.md) | 🟡 |
### 3.6 Artefacts morts à la racine de `apps/web/`
| Fichier | Taille | Date (mtime) | Status |
| ---------------------------- | ------ | ------------ | ----------------- |
| `e2e-results.json` | 3.4 MB | Mar 15 | 🔴 obsolète |
| `lint_comprehensive.json` | 793 KB | Jan 7 | 🔴 obsolète |
| `e2e-results.json` (2) | 241 KB | Jan 7 | 🔴 doublon |
| `ts_errors.log` | 29 KB | Dec 12 | 🔴 2+ mois stale |
| `storybook-roadmap.json` | 8.5 KB | Mar 6 | 🟡 |
| `AUDIT_ISSUES.json` | 19 KB | Dec 17 | 🔴 |
| `audit.log`, `debug-storybook.log` | 8.5 KB | Feb/Mar | 🟡 |
**~3.5 MB de reports morts** au bord du frontend. CLAUDE.md §règles 11 interdit ces fichiers en git (ils sont ignorés via `.gitignore` mais traînent en untracked).
---
## 4. Backend Go (`veza-backend-api/`)
### 4.1 Structure
- **877 fichiers .go** dans `internal/`
- **27 fichiers `routes_*.go`** (1 est un test)
- **135 handlers actifs** dans `internal/handlers/`
- **3 fichiers dans `internal/api/handlers/`** — confirmés DEPRECATED (chat + RBAC, à purger après confirmation aucun import)
- **226 services** (`internal/services/`) + **9 core services** (`internal/core/*/service.go`)
- **81 modèles** (`internal/models/`, 44K LOC) — pattern GORM + soft-delete
- **160 migrations SQL** (jusqu'à `983_hyperswitch_webhook_log.sql`)
- **17 workers** + **11 jobs**
- **~30 middlewares**
### 4.2 Routes & handlers
Handlers complets par domaine, **zéro endpoint retournant 501 ou vide**. Zéro double wiring.
Top routes par taille : `routes_core.go:512` (20+ routes), `routes_auth.go:245` (14+ routes, 2FA/OAuth inclus), `routes_tracks.go:240` (18+), `routes_users.go:296` (17+), `routes_marketplace.go:174` (15+), `routes_webhooks.go:205` (5+ ; raw payload audit).
### 4.3 Auth
| Aspect | Status | Preuve |
| -------------------- | :----: | ---------------------------------------------------------------------------------------------------- |
| JWT RS256 prod | ✅ | `services/jwt_service.go:17-81`, keys depuis env. |
| HS256 dev fallback | ✅ | Idem, 32+ char secret exigé. |
| Refresh 7j / Access 5min | ✅ | Configurés. |
| 2FA TOTP + backup codes | ✅ | `handlers/two_factor_handler.go:171` (actif). `api/handlers/` vide de 2FA — deprecated purgé. |
| OAuth 4 providers | ✅ | `routes_auth.go:122-176` (Google, GitHub, Discord, Spotify). State encrypté via CryptoService. |
| Rate limiting multi-couche | ✅ + 🟡 | DDoS global 1000 req/s ✅, endpoint-specific ✅, API key ✅, **`UserRateLimiter` configuré mais pas wiré aux routes**. |
| CSRF | ✅ | Middleware actif (e2e confirmé `tests/e2e/45-playlists-deep.spec.ts`). Disabled dev/staging (`router.go:133`). |
| Security headers | 🟡 | SecurityHeaders middleware présent (`router.go:204`). **CSP / X-Frame-Options pas vus en grep**. À vérifier. |
### 4.4 Modèles, DB, transactions
- Migrations auto-appliquées au démarrage (`database.go:234-256`). Boot fail si erreur SQL.
- Repositories : 18 GORM-direct, pattern inline (pas d'interface). **Plus** `internal/repository/` (1 fichier in-memory mock UserRepository) **ORPHELIN** — à supprimer.
- **Transactions insuffisantes** — `db.Transaction()` usage = **8×**, `tx.Create/Save/Delete` manuel = **37×**. Chemins critiques (marketplace `core/marketplace/service.go:1050+`, subscription) ne sont **pas dans des transactions explicites**. Risque data corruption si une étape échoue au milieu.
### 4.5 Services & context
- Architecture dual-layer `core/` + `services/` **incohérente** : certaines features ont `core/service.go`, d'autres `services/*.go`, sans règle claire. Ex. track publication en `core/track/` mais search indexing en `services/track_search_service.go`, les deux appelés depuis un même handler.
- Context propagation : 558 usages propres dans services, **mais 31 `context.Background()` dans `handlers/`** → défait le timeout middleware. Fix grep+sed 1 jour.
- **Pas de `services_init.go`** : services instantiés inline dans `routes_*.go`. Re-créés par request-group. Non-singletons.
### 4.6 Workers & jobs
- **Actifs lancés par `cmd/api/main.go`** : JobWorker, TransferRetry, StripeReversal, Reconciliation, CloudBackup, GearWarranty, NotifDigest, HardDelete, OrphanTracksCleanup, LedgerHealthSampler.
- **Jobs définis mais jamais schedulés** : `SchedulePasswordResetCleanupJob`, `CleanupExpiredSessions`, `CleanupVerificationTokens`, `CleanupHyperswitchWebhookLog` — ~4 cleanup jobs **dead code**. Soit les brancher soit les supprimer.
### 4.7 Tests
- **364 fichiers `*_test.go`**. `coverage_v1.out` (Mar 3) indique ~60-70%.
- Integration tests skippables via config — mais **pas de variable `VEZA_SKIP_INTEGRATION` trouvée en grep** (CLAUDE.md la mentionne — à vérifier si elle existe réellement ou si c'est un fossile doc).
- E2E Playwright n'entre jamais en CI.
### 4.8 Validation & errors
- `internal/validators/` — wrapper `go-playground/validator/v10`
- `internal/errors/``AppError{Code,Message,Err,Details,Context}`
- **PROBLÈME** : `RespondWithAppError` défini **2 fois** (`response/response.go:101` + `handlers/error_response.go:12`). Duplication à consolider.
- Wrapped errors : 349 usages `errors.Is/As/Unwrap` — bon pattern.
### 4.9 Config
- **99 env vars lues** dans `config/config.go` (1087 LOC)
- **`Config.Validate()`** :
- ✅ Refuse prod si `HYPERSWITCH_ENABLED=false` (`config.go:908-910`, fail-closed).
- ✅ Refuse prod sans DATABASE_URL, JWT keys, CORS origins.
-**Pas de check `APP_ENV ∈ {dev,staging,prod}`** — silencieusement default dev.
-**Pas de check `UPLOAD_DIR` exists** — boot success même si dir manquant.
- **`.env.template` 190 lignes** vs 263 `os.Getenv` appels code → drift potentiel (~70 vars documentées vs 99 utilisées).
### 4.10 Dette backend — récap
| Dette | Sévérité | Effort | Preuve |
| ------------------------------------------- | :-------: | :----: | ------------------------------------------------------------- |
| Transactions manquantes marketplace/subs | 🔴 | M (3j) | `core/marketplace/service.go:1050+` |
| 31× `context.Background()` dans handlers | 🔴 | S (1j) | Grep handlers |
| Binaires racine `api` (99MB) + 44 .mp3 | 🔴 | XS (1h)| `git rm --cached` + BFG |
| `RespondWithAppError` dupliqué | 🟡 | S (1j) | `response/response.go:101` + `handlers/error_response.go:12` |
| `internal/repository/` orphelin | 🟡 | XS | Delete dir |
| 4 cleanup jobs jamais schedulés | 🟡 | S | Brancher ou supprimer |
| `UserRateLimiter` configuré non wiré | 🟡 | S | Wire en middleware chain |
| Écart `.env.template` vs code (29 vars) | 🟠 | S | Sync |
| Services re-instantiés par request-group | 🟠 | M | `services_init.go` + singleton pattern |
| Architecture core/+services/ incohérente | 🟠 | L | Document la règle OU unifier |
---
## 5. Rust stream server (`veza-stream-server/`)
### 5.1 Modules
Production-ready : `streaming/` (HLS réel, Range 206, WS 1047 LOC, adaptive 515 LOC), `audio/` (Symphonia native, compression 708 LOC, effects SIMD), `core/` (StreamManager 10k+ concurrents, sync engine NTP-like 1920 LOC), `auth/` (JWT HMAC-SHA256 + revocation Redis-or-in-mem 825 LOC), `cache/` (LRU audio), `event_bus.rs` (RabbitMQ degraded mode).
Alpha / partiel : `transcoding/engine.rs` (94 LOC, job queue priority-based mais **zéro test d'intégration, zéro tracking live**), `grpc/` (461 LOC business + 21845 LOC généré).
**Stub / absent** :
- `streaming/protocols/mod.rs:4``// pub mod dash;` **commenté**.
- `Cargo.toml:62``// webrtc = "0.7"` **commenté** (deps natives manquantes).
### 5.2 Audio codecs
Symphonia couvre MP3, FLAC, Vorbis, AAC **natifs**. LAME MP3 via `minimp3 0.5` (natif). **Commentés** : `opus 0.3` (cmake), `lame 0.1`, `fdkaac 0.7` (non sur crates.io).
### 5.3 gRPC & protos
`StreamService`, `AuthService`, `EventsService` (3 services). Utilise `proto/common/auth.proto` + `proto/stream/stream.proto`. **`proto/chat/chat.proto` = 0 import** → orphelin depuis suppression chat Rust.
### 5.4 Dette Rust
| Dette | Sévérité | Preuve |
| ----------------------------------------------- | :------: | ---------------------------------------------------------------- |
| `#![allow(dead_code)]` global dans `lib.rs:5` | 🔴 | Masque tous les stubs. Devrait être granulaire par module. |
| 10× `unwrap()` sur broadcast channels | 🔴 | `core/sync.rs:1037-1110`. Panic si receiver drop. `.expect()` + contexte. |
| `proto/chat/chat.proto` orphelin | 🟡 | À archiver/supprimer. |
| `veza-common` chat types orphelins | 🟡 | ~60 LOC dead. Audit grep `use veza_common::chat` → 0 hit. |
| `transcoding/` zéro tests intégration | 🟡 | `engine.rs:36-62`. |
| 26× `println!/dbg!` | 🟡 | Devrait utiliser `tracing::`. |
| Deps inutilisées (`daemonize`, `notify`) | 🟠 | `Cargo.toml:139, 116`. |
**0 `unsafe`** ✅ (engagement CLAUDE.md tenu).
---
## 6. Infrastructure & DevOps
### 6.1 Docker Compose (6 fichiers)
| Fichier | Rôle | État |
| ---------------------------- | --------------------------------- | ------------------------------------------ |
| `docker-compose.yml` | Dev full-stack avec profiles | ✅ Actif |
| `docker-compose.dev.yml` | Infra-only (209 LOC) | ✅ Actif (MailHog + ES 8.11.0 ici uniquement)|
| `docker-compose.prod.yml` | Blue-green, HAProxy, Alertmanager (464 LOC) | ✅ Actif (Mar 12) |
| `docker-compose.staging.yml` | Caddy (202 LOC) | ✅ Actif (Mar 2) |
| `docker-compose.test.yml` | tmpfs CI (64 LOC) | ✅ Actif |
| `infra/docker-compose.lab.yml` | DEPRECATED Feb 2026 | 🔴 À supprimer |
**Pinning** :
- ✅ Postgres 16-alpine, Redis 7-alpine, RabbitMQ 3, ClamAV 1.4, Hyperswitch 2026.03.11.0.
-**MinIO `:latest`** dans 4 composes → supply-chain attack vector.
**Services orphelins en dev-only** :
- ES 8.11.0 uniquement `docker-compose.dev.yml:171-204` (34 LOC) — **le backend utilise Postgres FTS, pas ES** (`fulltext_search_service.go`). ES ne sert qu'au hard-delete worker (GDPR cleanup), optionnel. À documenter ou retirer.
### 6.2 Dockerfiles
- Backend : `Dockerfile` + `Dockerfile.production` (Go 1.24-alpine, multi-stage, non-root uid 1001, `-w -s`). ⚠️ **CLAUDE.md dit Go 1.25, Dockerfile sur 1.24** — bumper.
- Stream : `Dockerfile` + `Dockerfile.production` (rust:1.84-alpine). ⚠️ **Mismatch port** : Dockerfile.production expose `8082` mais `docker-compose.prod.yml:284` healthcheck attend `3001`**le Dockerfile n'est pas utilisé en prod** (sans doute l'image vient d'ailleurs).
- Web : `Dockerfile` + `Dockerfile.dev` + `Dockerfile.production` (node:20-alpine → nginx:1.27-alpine).
### 6.3 CI/CD
**Workflows actifs (5)** :
1. `ci.yml` (consolidé, ~15min) — backend Go (test, lint, vet, govulncheck), frontend (lint, tsc, build, vitest), rust (build, test, clippy, audit).
2. `frontend-ci.yml` (55 LOC) — path-triggered React-only, bundle-size gate, npm audit.
3. `security-scan.yml` — gitleaks v8.21.2 secret scan.
4. `trivy-fs.yml` — Trivy filesystem scan (HIGH+CRITICAL exit=1).
5. `go-fuzz.yml` — Nightly fuzz 60s, corpus upload.
**Workflows disabled (19 fichiers, 1676 LOC mort)** :
`backend-ci.yml.disabled`, `cd.yml.disabled`, `staging-validation.yml.disabled`, `accessibility.yml.disabled`, `chromatic.yml.disabled`, `visual-regression.yml.disabled`, `storybook-audit.yml.disabled`, `contract-testing.yml.disabled`, `zap-dast.yml.disabled`, `container-scan.yml.disabled`, `semgrep.yml.disabled`, `sast.yml.disabled`, `mutation-testing.yml.disabled`, `rust-mutation.yml.disabled`, `load-test-nightly.yml.disabled`, `flaky-report.yml.disabled`, `openapi-lint.yml.disabled`, `commitlint.yml.disabled`, `performance.yml.disabled`.
**→ 1676 lignes de workflow mort. Soit réactiver ce qui fait sens (SAST, DAST, openapi-lint), soit archiver dans `docs/archive/workflows/` pour ne pas polluer `.github/workflows/`.**
**Gaps CI** :
- E2E Playwright pas déclenché (pourtant `tests/e2e/` existe, `SKIPPED_TESTS.md` documente les flakies).
- Integration tests Go skipped (`VEZA_SKIP_INTEGRATION=1` faute de Docker socket sur runner).
### 6.4 K8s
- ~30-40 manifests, structure propre (`autoscaling/`, `backends/`, `backups/`, `cdn/`, `disaster-recovery/`, `environments/{prod,staging,dev}`, `secrets/`).
- **5 runbooks** : cluster-failover, database-failover, data-restore, rollback-procedure, security-incident.
-**Zéro référence à `veza-chat-server`** dans `k8s/` (grep clean — l'audit v1 disait qu'il y avait 7+ runbooks outdated ; **corrigé**).
### 6.5 Secrets & sécurité
| Item | État | Action |
| --------------------------------------------- | :------: | -------------------------------------------------------------------- |
| `/docker/haproxy/certs/veza.pem` | 🔴 TRACKED | BFG + rotate cert + move to K8s Secret |
| `/config/ssl/{cert,key,veza}.pem` | 🔴 TRACKED | Idem |
| `veza-backend-api/.env` | 🔴 TRACKED | `git rm --cached`, rotate JWT/DB secrets dev, relire `.gitignore` |
| `veza-backend-api/.env.production.example` | 🟢 OK | Template |
| Hardcoded secrets en code (`sk_live_`, `AKIA`)| ✅ absent | Grep clean |
| gitleaks en CI | ✅ | `security-scan.yml` |
| govulncheck | ✅ | `ci.yml` |
| CSP header | 🟡 | Grep 0 hit. **À implémenter.** |
| X-Frame-Options | 🟡 | Idem |
### 6.6 Observability
- Prometheus : **5 gauges ledger-health** déployées en v1.0.7 (`ledger_metrics.go`), **+ counter/histogram reconciler**. Alertmanager `config/alertmanager/ledger.yml` avec 3 règles (VezaOrphanRefundRows, VezaStuckOrdersPending, VezaReconcilerStale). Grafana dashboard `config/grafana/dashboards/ledger-health.json`.
- Logs : JSON structuré confirmé (`level`, `time`, `msg`, `request_id`, `user_id`).
- **Gap** : `/metrics` endpoint global backend pas vu (à confirmer — il existe probablement via middleware Sentry/Prometheus, mais pas en grep direct).
- Sentry : optionnel via env (`SENTRY_DSN`, `SENTRY_SAMPLE_RATE_*`).
---
## 7. Documentation
### 7.1 Racine du repo
| Fichier | Taille | Date | Verdict |
| ------------------------------- | ------ | ---------- | ---------------------------------------------------------------------- |
| `CLAUDE.md` | 22 KB | 2026-04-14 | ✅ Autorité. Petite dérive : Vite 5 → 7.1.5 à corriger. |
| `CHANGELOG.md` | 87 KB | 2026-04-19 | ✅ À jour (v0.201 → v1.0.7-rc1). |
| `README.md` | 2.8 KB | — | ✅ Minimal OK. |
| `CONTRIBUTING.md` | 2.7 KB | 2026-02-27 | ✅ OK. |
| `VERSION` | — | — | `1.0.7-rc1` ✅ aligné. |
| `VEZA_VERSIONS_ROADMAP.md` | 69 KB | — | ⚠️ Historique v0.9xx, peu utile post-launch. Archive. |
| `RELEASE_NOTES_V1.md` | 4.7 KB | — | ✅ OK. |
| `AUDIT_REPORT.md` | 57 KB | 2026-04-14 | 🔄 **Ce fichier — v2 remplace v1**. |
| `FUNCTIONAL_AUDIT.md` | 43 KB | 2026-04-19 | ✅ v2 à jour. |
| `UI_CONTEXT_SUMMARY.md` | 6 KB | — | 🟠 Session artifact, devrait être archivé selon CLAUDE.md §12. |
| `CLAUDE_CONTEXT.txt` | 977 KB | 2026-04-18 | 🔴 ÉNORME session dump. Archive ou supprime. |
| `output.txt` | 27 KB | 2026-04-18 | 🔴 Debris. |
| `generate_page_fix_prompts.sh` | 42 KB | Mar 26 | 🟡 Script généré, probablement obsolète. |
| `build-archive.log` | 974 B | Mar 25 | 🟡 Log. |
**48 screenshots PNG racine** (`dashboard-*.png`, `login-*.png`, `design-system-*.png`, `forgot-password-*.png`) — **à déplacer dans `docs/screenshots/` ou supprimer**.
### 7.2 `docs/` (18 actifs + 417 archive = 435 .md)
**Actifs** :
- `docs/API_REFERENCE.md` (1022 LOC) — **manuel**, pas de typegen. Écart flag vs routes Go. Migration vers OpenAPI typegen backend = priorité.
- `docs/ONBOARDING.md`, `docs/PROJECT_STATE.md`, `docs/FEATURE_STATUS.md` — à cross-checker avec code v1.0.7 (non fait ici).
- `docs/ENV_VARIABLES.md`**introuvable en `ls docs/`** alors que CLAUDE.md dit "à maintenir". Soit créé soit manque.
- `docs/audit-2026-04/`**NOUVEAU, très utile** : `axis-1-correctness.md` + `v107-plan.md` — trace des findings et du plan v1.0.7.
- `docs/SECURITY_SCAN_RC1.md` / `docs/ASVS_CHECKLIST_v0.12.6.md` / `docs/PENTEST_REPORT_VEZA_v0.12.6.md`**refs v0.12.6, obsolètes** pour v1.0.7. Refaire ou archiver.
**Archive** (`docs/archive/` = 278 fichiers) : historique session 2026. Taille totale importante. Ne pose pas de problème immédiat.
### 7.3 `veza-docs/` (Docusaurus séparé)
- `veza-docs/docs/{current,vision}/` — doc cible.
- `veza-docs/ORIGIN/` (22 fichiers, ~70K lignes) — **phase-0, jamais touchée depuis launch**. Qualifiée "FOSSIL" par agent. Archive ou zip.
---
## 8. Dette technique transverse — catalogue
### 8.1 TODOs / FIXMEs (11 hits)
1. `tests/e2e/22-performance.spec.ts:8` — "Either add data-testid containers or rewrite test to use API mocking" (3 occurrences).
2. `tests/e2e/04-tracks.spec.ts` — "Corriger le bug dans FeedPage.tsx" (ouvert, P1).
3. `apps/web/src/features/auth/pages/ResetPasswordPage.test.tsx` — async timing flaky.
4. `veza-backend-api/internal/core/marketplace/service.go:1450` — "TODO v1.0.7: Stripe Connect reverse-transfer API" (**effectivement déjà landed en v1.0.7 item A+B** — TODO à supprimer).
5. `veza-backend-api/internal/core/subscription/service.go` — "TODO(v1.0.7-item-G): subscription pending_payment state" (in-flight, parked).
**Aucun TODO daté >6 mois.** Discipline correcte.
### 8.2 Code mort / orphelin
| Item | Action |
| ------------------------------------------------ | ------------------------------------------------ |
| `veza-backend-api/internal/api/handlers/` (3 fichiers) | Confirmer 0 import puis `git rm -r` |
| `veza-backend-api/internal/repository/` (in-mem mock) | `git rm -r` |
| `apps/web/src/components/ui/hover-card/*` (3) | Delete si confirmé 0 import |
| `apps/web/src/components/ui/dropdown-menu/*` (7) | Audit imports, delete si Radix les remplace |
| `apps/web/src/components/ui/optimized-image/{OptimizedImageSkeleton,ResponsiveImage}.tsx` | Delete |
| `apps/web/src/types/v2-v3-types.ts` | Auditer appelants, renommer ou delete |
| `proto/chat/chat.proto` | Archiver `docs/archive/proto-chat/` ou delete |
| `veza-common/src/chat.rs` + autres types chat | Audit `use veza_common::chat`, delete si 0 hit |
| 19 workflows `.disabled` | Archiver `docs/archive/workflows/` ou delete |
| 4 cleanup jobs jamais schedulés (pw-reset, sessions, verif, hyperswitch-log) | Brancher ou delete |
### 8.3 Binaires / artefacts trackés
| Item | Taille | Action |
| --------------------------------------------------- | ------ | ------------------------------------------------- |
| `api` (racine, ELF) | 99 MB | `git rm --cached api` + `.gitignore` |
| `veza-backend-api/{main,veza-api,seed,server}` | ~50 MB chacun | Idem (sont dans `.gitignore` mais encore tracked?) |
| `veza-backend-api/uploads/*.{mp3,wav}` (44 fichiers)| 12 MB | `git rm -r --cached uploads/` + move to git-lfs ou fixtures |
| `CLAUDE_CONTEXT.txt` (racine) | 977 KB | `git rm --cached` ou déplacer |
| `apps/web/e2e-results.json` (3.4 MB) | 3.4 MB | `.gitignore` + `rm` |
| 48 PNG racine (dashboard-*, login-*, design-system-*, forgot-password-*) | ~5 MB total | Move to `docs/screenshots/` ou delete |
| 36 `.playwright-mcp/*.yml` (untracked) | — | `rm -r .playwright-mcp/` |
### 8.4 Sécurité hors-code
| Item | Action |
| ----------------------------------------- | ------------------------------------------------------ |
| `/docker/haproxy/certs/veza.pem` tracked | BFG purge history + rotate cert + K8s Secret |
| `/config/ssl/*.pem` tracked | Idem |
| `veza-backend-api/.env` tracked | `git rm --cached`, rotate dev secrets, audit team |
| CSP header absent | Middleware `SecurityHeaders` — ajouter |
| X-Frame-Options absent | Idem |
### 8.5 Incohérences doc↔code
| Item | Delta |
| ---------------------------------------------- | -------------------------------------------------- |
| `CLAUDE.md` : Vite 5 | Réel Vite 7.1.5 — bumper doc |
| `CLAUDE.md` : ES 8.11.0 partout | Réel ES 8.11.0 dev-only |
| `CLAUDE.md` : Go 1.25 | go.mod 1.25.0 ✅ ; `veza-backend-api/Dockerfile` 1.24 — bumper |
| `docs/API_REFERENCE.md` manuel 1022 LOC | 135 handlers — risque drift. OpenAPI typegen backend recommandé. |
| `VEZA_VERSIONS_ROADMAP.md` v0.9xx | VERSION = 1.0.7-rc1 — archive le roadmap |
| `docs/ASVS_CHECKLIST_v0.12.6.md` etc | Version obsolète. Refaire sur v1.0.7 ou archiver. |
| `docs/ENV_VARIABLES.md` mentionné | Pas trouvé en `ls docs/`. Créer. |
### 8.6 Patterns abandonnés ou à mi-chemin
1. **OpenAPI typegen frontend** : démarré (`api.ts` 6550 LOC régénéré) mais les **73 services frontend restent hand-written**. Finir la migration (memory entry : "orval recommended").
2. **OpenAPI typegen backend** : `docs/API_REFERENCE.md` manuel. Swagger infra (`swaggo/swag`) présente mais pas pleinement exploitée.
3. **Repository pattern** : `repositories/` (GORM-direct, 18 fichiers) mixé avec `services/` qui requêtent `gormDB` direct. Pas d'interfaces. Pattern mi-chemin.
4. **Architecture `core/` + `services/`** : pas de règle claire. À unifier ou à documenter explicitement quelles features vont où.
5. **Transactions** : 8 usages vs 37 tx manuels. Pattern moitié-fait.
---
## 9. Top 15 priorités — impact / effort
> **Mise à jour 2026-04-23** — colonne `Statut` ajoutée après la session cleanup tier 1/2/3 + BFG history rewrite. Voir §9.bis pour le détail des 3 false-positives identifiés pendant l'exécution.
Classement pour la suite (post-v1.0.7-rc1 → v1.0.7 final → v1.0.8).
| # | Priorité | Impact | Effort | Statut 2026-04-23 | Rationale / Preuve |
| --- | -------------------------------------------------------------------------------- | :----: | :-----: | :---------------- | -------------------------------------------------------------------------- |
| 1 | **Supprimer `api` 99 MB + binaires Go trackés racine + `uploads/*.mp3`** | 🔴 CRIT | XS (1h) | ✅ DONE | BFG pass 2026-04-23, 1.5G → 66M. Force-push stages 1+2 OK. |
| 2 | **Rotate TLS certs + supprimer `.pem` trackés + .env committed** | 🔴 CRIT | S (4h) | ✅ DONE | `.env*` + certs stripped via BFG. Keys regen, gitignorées. |
| 3 | **Transactions marketplace/subscription** | 🔴 CRIT | M (3j) | ✅ DONE | Commit `b5281bec``UpdateProductImages` + `SetProductLicenses` en tx. |
| 4 | **Context propagation : 31× `context.Background()` dans handlers** | 🔴 | S (1j) | ⚠️ FALSE-POSITIVE | 26/31 dans `*_test.go`, 5 legit (health probes + WS pumps). Voir §9.bis. |
| 5 | **Ajouter CSP + X-Frame-Options headers** | 🔴 | S (1j) | ⚠️ FALSE-POSITIVE | `middleware/security_headers.go` couvre déjà CSP + XFO + HSTS + CORP/COEP/COOP. Voir §9.bis. |
| 6 | **Pin MinIO `:latest` → tag daté** | 🔴 | XS (10min) | ✅ DONE | Commit `4310dbb7` — pinned `RELEASE.2025-09-07T16-13-09Z` × 4 compose files. |
| 7 | **Nettoyer `.playwright-mcp/*.yml` + 48 PNG racine + `CLAUDE_CONTEXT.txt` + dead reports apps/web/** | 🟡 | S (2h) | ✅ DONE | Commits `d12b901d` + `172581ff` + BFG pass. |
| 8 | **Terminer OpenAPI typegen** (frontend services + backend swaggo) | 🟡 | L (5j) | 📋 DEFERRED v1.0.8 | Memory entry, drift risk. `api.ts` 6550 LOC déjà là. Plan séparé requis. |
| 9 | **Supprimer 19 workflows `.disabled` (1676 LOC mort) OU réactiver utiles (SAST, DAST, openapi-lint)** | 🟡 | S (4h) | ✅ DONE | Archivés dans `docs/archive/workflows/` via commit `172581ff`. |
| 10 | **Consolider `RespondWithAppError` dupliqué** | 🟡 | S (1j) | ⚠️ FALSE-POSITIVE | `handlers/error_response.go:12` = wrapper intentionnel déléguant à `response/response.go:101`. Pas dupe. Voir §9.bis. |
| 11 | **Wirer `UserRateLimiter` configuré mais non appelé** | 🟡 | S (1j) | ✅ DONE | Commit `ebf3276d` — wired in `AuthMiddleware.RequireAuth()`. |
| 12 | **Supprimer `internal/repository/` (in-mem mock orphelin)** | 🟡 | XS | ✅ DONE | `user_repository.go` supprimé dans commit `172581ff`. |
| 13 | **Remove/archive `proto/chat/chat.proto` + `veza-common/src/chat.rs`** | 🟡 | XS | ✅ DONE | Commit `172581ff` — proto + `veza-common/{chat.rs, websocket.rs}` supprimés. |
| 14 | **Ajouter E2E Playwright en CI** | 🟡 | M (3j) | 📋 DEFERRED v1.0.8 | Playwright existe, SKIPPED_TESTS.md documenté, mais pas trigger CI. |
| 15 | **`docs/ENV_VARIABLES.md` — créer si manque, sync avec code** | 🟠 | S (1j) | 📝 PENDING (0.5j) | Seul item réel restant du top-15 avant tag v1.0.7 final. |
**Bilan** : 10 ✅ DONE · 3 ⚠️ FALSE-POSITIVE · 2 📋 DEFERRED v1.0.8 · 1 📝 PENDING (~0.5j).
### 9.1 "À supprimer sans regret"
- `infra/docker-compose.lab.yml` (DEPRECATED Feb 2026)
- `scripts/align-8px-grid.py`, `auto_migrate_tailwind_colors*.py` (tailwind migration faite)
- 48 PNG racine
- 36 `.playwright-mcp/*.yml`
- 19 `.disabled` workflows
- Binaires Go trackés
- 44 fichiers audio `.mp3/.wav` dans `veza-backend-api/uploads/`
- `CLAUDE_CONTEXT.txt` racine
- `VEZA_VERSIONS_ROADMAP.md` (v0.9xx historique)
- `generate_page_fix_prompts.sh` racine (42 KB, Mar 26)
- `output.txt`, `build-archive.log` racine
- `apps/web/{e2e-results.json, lint_comprehensive.json, ts_errors.log, AUDIT_ISSUES.json}`
- `internal/repository/` (orphelin)
- `proto/chat/chat.proto` + types `veza-common/src/chat.rs`
- `apps/web/src/components/ui/{hover-card,dropdown-menu,optimized-image}/` orphelins
- `docs/ASVS_CHECKLIST_v0.12.6.md` + `docs/PENTEST_REPORT_VEZA_v0.12.6.md` (v0.12.6 obsolète)
### 9.2 "À finir avant de commencer quoi que ce soit de nouveau"
> **Mise à jour 2026-04-23** — la liste originale (#1, #2, #3, #4, #5, #7, #8, #9) a été traitée en une session, sauf les 3 false-positives §9.bis et les 2 deferrals. Ne reste qu'un item (§9.3).
1. ~~**Cleanup repo** (#1, #2, #7, #9)~~ — ✅ fait, 1 session 2026-04-23.
2. ~~**Transactions manquantes** (#3)~~ — ✅ fait, commit `b5281bec`.
3. ~~**Context propagation** (#4)~~ — ⚠️ false-positive, pas de travail à faire (§9.bis).
4. ~~**Security headers** (#5)~~ — ⚠️ false-positive, middleware déjà complet (§9.bis).
5. **OpenAPI typegen** (#8) — 📋 deferred v1.0.8, plan séparé requis.
### 9.bis Corrections post-tier 2 (2026-04-23)
Trois items du top-15 ont été reclassifiés après inspection directe du code :
**#4 — "Context propagation : 31× `context.Background()` dans handlers"**
Grep réel : 31 hits dans `internal/handlers/`, mais **26 dans des fichiers `_test.go`** (legit, setup tests). Les 5 hits non-test sont tous légitimes :
- `handlers/status_handler.go:184` — probe health externe, `ctx` dédié 400ms
- `handlers/playback_websocket_handler.go:{142,218,245}` — pumps WebSocket (doivent survivre au cycle HTTP request, pas de parent ctx disponible post-Upgrade)
- `handlers/health.go:422` — health check 5s, `ctx` dédié
Le chiffre "31" masquait des patterns corrects. **Aucun handler qui défait un timeout middleware**. Pas de travail à faire.
**#5 — "Ajouter CSP + X-Frame-Options headers"**
Vérification `veza-backend-api/internal/middleware/security_headers.go` : le middleware existe déjà (BE-SEC-011 + MOD-P2-005) et couvre **tous** les headers OWASP A05 recommandés :
- `Strict-Transport-Security` (prod only)
- `X-Frame-Options: DENY` (default) / `SAMEORIGIN` (Swagger)
- `Content-Security-Policy` — strict `default-src 'none'` par défaut, override Swagger
- `X-Content-Type-Options: nosniff`
- `X-XSS-Protection`, `Referrer-Policy`, `Permissions-Policy`
- `X-Permitted-Cross-Domain-Policies: none`
- `Cross-Origin-{Embedder,Opener,Resource}-Policy`
Audit erroné. Pas de travail à faire.
**#10 — "Consolider `RespondWithAppError` dupliqué"**
Vérification :
- `internal/response/response.go:101` = implémentation réelle (17 lignes)
- `internal/handlers/error_response.go:12` = wrapper **intentionnel** de 3 lignes qui délègue à `response.RespondWithAppError(c, appErr)`. Commenté `// Délègue au package response pour éviter duplication`.
Le wrapper existe pour permettre aux handlers d'importer depuis le package `handlers` sans traverser la frontière `response/` — pattern de couplage sain. Pas une duplication à consolider. Pas de travail à faire.
### 9.3 Chemin critique vers v1.0.7 final stable
> **Mise à jour 2026-04-23** — le plan 5-jours original a été compressé en 1 session (cleanup + BFG + transactions + wiring). Ne reste que l'item doc.
| Jour (historique) | Tâches planifiées v1 | Statut 2026-04-23 |
| :-: | --- | --- |
| J1 | Items #1, #2, #6, #7 — cleanup + rotation + BFG + retag | ✅ DONE |
| J2 | Items #4, #10, #12, #13 | ⚠️ #4/#10 false-positive · ✅ #12/#13 done |
| J3-4 | Item #3 — transactions marketplace | ✅ DONE (commit `b5281bec`) |
| J5 | Items #5, #11, #15 + tag `v1.0.7` | ⚠️ #5 false-positive · ✅ #11 done · 📝 #15 reste (0.5j) |
**Reste à faire avant tag `v1.0.7` final** : item #15 (`docs/ENV_VARIABLES.md` sync) — **0.5j**. Et un quick-win 5min : ajouter `HLS_STREAMING` à `.env.template` (cf. FUNCTIONAL_AUDIT §4 stabilité item 5).
Ensuite v1.0.8 : OpenAPI typegen (#8, 5j), E2E CI (#14, 3j), item G subscription `pending_payment` (parké dans `docs/audit-2026-04/v107-plan.md`), wire MinIO/S3 dans path upload (2-3j, cf. FUNCTIONAL §4 item 2), STUN/TURN WebRTC si calls public (1-2j).
---
## 10. Verdict final
> **v2 (2026-04-20)** — application solide, dépôt sale.
> **v3 (2026-04-23, post-cleanup + BFG)** — **application solide, dépôt propre**.
- **Code applicatif** : mature, testé (286 tests front + 364 back), sécurisé (gitleaks/govulncheck/trivy, JWT RS256, 2FA, OAuth, CORS strict, CSRF, DDoS rate limit), plomberie monétaire auditée (ledger-health gauges, reconciliation, idempotency, reverse-charge). **Transactions marketplace `DELETE+loop` atomiques depuis `b5281bec`**. **UserRateLimiter wired dans `AuthMiddleware` depuis `ebf3276d`**.
- **Code infra** : 3 variants Dockerfile (dev/prod), K8s avec disaster recovery, 5 workflows CI actifs (+ 19 disabled archivés `docs/archive/workflows/`), 6 compose env pinned (MinIO daté), HAProxy blue-green.
- **Hygiène repo** : 2.3 GB → **66 MB** `.git` après BFG 2026-04-23 (97%). Binaires Go, PNG racine, `.playwright-mcp`, audio uploads, `.env*`, TLS certs, kubectl vendoré, builds Incus, reports lint : **tous stripped de l'historique** + ajoutés à `.gitignore` (blocks J1 + J2 + J3).
**Score** : v1 disait "Moyen-Haute dette". v2 : "Basse dette code / Haute dette hygiène". **v3 : dette résiduelle mineure** — 1 item pending (`docs/ENV_VARIABLES.md`, 0.5j) + 3 false-positives classés + 2 deferrals v1.0.8.
**En une phrase** : **`v1.0.7-rc1` est prêt à devenir `v1.0.7` final** dès que `docs/ENV_VARIABLES.md` est synchronisé avec les 99 env vars du code. Le reste (OpenAPI typegen, E2E CI, MinIO upload path, STUN/TURN) part sur v1.0.8 avec des plans séparés.
---
## Annexe — diff v1 ↔ v2 ↔ v3
| Thème | v1 (2026-04-14) | v2 (2026-04-20) | v3 (2026-04-23, post-cleanup + BFG) |
| -------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------------- |
| HEAD | `45662aad1` (v1.0.0-mvp-24-g45662aad1) | `89a52944e` (v1.0.7-rc1) | post-BFG : main `6d51f52a`, chore `b5281bec` |
| Finding "chemin critique v1.0.5 public-ready"| 6 items listés | **Tous les 6 traités** (v1.0.5 → v1.0.7-rc1, 50+ commits) | — |
| 🔴 Player/écoute audio | Bloqueur | Résolu — endpoint `/tracks/:id/stream` + Range bypass | — |
| 🔴 IsVerified hardcoded | Bloqueur | Résolu — `core/auth/service.go:200` `IsVerified: false` | — |
| 🟡 SMTP silent fail | Bloqueur | Résolu — schema unifié + MailHog default | — |
| 🟡 Marketplace dev bypass | Bloqueur | Résolu — fail-closed prod via `Config.Validate:908-910` | — |
| 🟡 Refund stub | Bloqueur | Résolu — 3-phase + idempotency + webhook reverse-charge | — |
| 🟡 Chat multi-instance silent | Bloqueur | Résolu — log ERROR loud `chat_pubsub.go:23-27` | — |
| 🟡 Maintenance mode in-memory | Bloqueur | Résolu — persisté `platform_settings` TTL 10s | — |
| 🔵 Reconciliation Hyperswitch | Absent | **Nouveau**`reconcile_hyperswitch.go:55-150` | — |
| 🔵 Webhook raw payload audit | Absent | **Nouveau**`webhook_log.go:34-80` + cleanup 90j | — |
| 🔵 Ledger-health metrics | Absent | **Nouveau** — 5 gauges + 3 alertes + Grafana | — |
| 🔵 Stripe Connect reversal async | Absent | **Nouveau**`reversal_worker.go:12-180` | — |
| 🔵 Self-service creator upgrade | Absent | **Nouveau**`POST /users/me/upgrade-creator` | — |
| Hygiène `.git` 2.3 GB | Bloqueur | **Non traité** | ✅ **66 MB après BFG** (97%) |
| Hygiène binaires tracked | 3 binaires | 1 reste (`api` 99 MB racine) | ✅ **0 binaires** (BFG pass + `.gitignore` J3) |
| Hygiène `uploads/*.mp3` 44 fichiers | Présent | **Non traité** | ✅ **stripped** (BFG pass, `uploads/` gitignoré J2) |
| Hygiène 54 PNG racine | Présent | 48 restent | ✅ **stripped** (BFG pass, patterns gitignorés J2+J3) |
| TLS certs committés + `.env*` | Présent | Présent | ✅ **stripped** (BFG pass) |
| Transactions marketplace | Non auditée | 🔴 CRIT flaggée | ✅ **fixées** (commit `b5281bec`) |
| UserRateLimiter | Non mentionné | Configuré mais non câblé | ✅ **wiré** (commit `ebf3276d`) |
| Orphelin `internal/repository/` | Non mentionné | Flaggé | ✅ **supprimé** (commit `172581ff`) |
| Orphelins Rust (`proto/chat`, `veza-common/{chat,ws}.rs`) | Non mentionné | Flaggé | ✅ **supprimés** (commit `172581ff`) |
| Runbooks k8s outdated (chat Rust) | 7+ runbooks | **0 référence** — clean | — |
| CLAUDE.md précis | Faux | **À jour** sauf Vite 5→7 | — |
| Site Docusaurus `ORIGIN/` | À réécrire | **22 fichiers FOSSILE encore** — à archiver | (hors scope cleanup) |
| Workflows CI | `.github/workflows/*` non consolidé | Consolidé (`ci.yml`) + **19 disabled qui traînent** | ✅ **19 archivés** dans `docs/archive/workflows/` |
| `docs/audit-2026-04/` | Absent | **Nouveau** — axis-1-correctness + v107-plan | — |
**Score global** : v1 "Moyen-Haute dette" → v2 "Basse dette code / Haute dette hygiène" → **v3 "dette résiduelle mineure" (1 item pending, 3 false-positives classés, 2 deferrals v1.0.8)**.
---
*Généré par Claude Code Opus 4.7 (1M context, /effort max, /plan) — 5 agents Explore parallèles (frontend, backend Go, Rust stream, infra/DevOps, dette transverse) + mesures macro directes (du, ls, git ls-files) + lecture `CHANGELOG.md` v1.0.5→v1.0.7-rc1 + `docs/audit-2026-04/v107-plan.md`. Cross-référencé avec [FUNCTIONAL_AUDIT.md v2](FUNCTIONAL_AUDIT.md) pour les verdicts fonctionnels.*