649 lines
55 KiB
Markdown
649 lines
55 KiB
Markdown
|
|
# 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
|
|||
|
|
|
|||
|
|
Classement pour la suite (post-v1.0.7-rc1 → v1.0.7 final → v1.0.8).
|
|||
|
|
|
|||
|
|
| # | Priorité | Impact | Effort | Rationale |
|
|||
|
|
| --- | -------------------------------------------------------------------------------- | :----: | :-----: | -------------------------------------------------------------------------- |
|
|||
|
|
| 1 | **Supprimer `api` 99 MB + binaires Go trackés racine + `uploads/*.mp3`** | 🔴 CRIT | XS (1h) | Repo .git 2.3 GB. `git rm --cached` + BFG `--strip-blobs-bigger-than 10M`. |
|
|||
|
|
| 2 | **Rotate TLS certs + supprimer `.pem` trackés + .env committed** | 🔴 CRIT | S (4h) | Prod-grade security hygiene. BFG + rotate + K8s Secrets. |
|
|||
|
|
| 3 | **Transactions marketplace/subscription** | 🔴 CRIT | M (3j) | `core/marketplace/service.go:1050+` sans tx → data corruption possible. |
|
|||
|
|
| 4 | **Context propagation : 31× `context.Background()` dans handlers** | 🔴 | S (1j) | Défait timeout middleware. Grep + sed fix. |
|
|||
|
|
| 5 | **Ajouter CSP + X-Frame-Options headers** | 🔴 | S (1j) | OWASP A05. Middleware `SecurityHeaders` à enrichir. |
|
|||
|
|
| 6 | **Pin MinIO `:latest` → tag daté** | 🔴 | XS (10min) | Supply-chain. 4 occurrences dans compose files. |
|
|||
|
|
| 7 | **Nettoyer `.playwright-mcp/*.yml` + 48 PNG racine + `CLAUDE_CONTEXT.txt` + dead reports apps/web/** | 🟡 | S (2h) | Propreté. `rm -r` + update `.gitignore`. |
|
|||
|
|
| 8 | **Terminer OpenAPI typegen** (frontend services + backend swaggo) | 🟡 | L (5j) | Memory entry, drift risk. `api.ts` 6550 LOC déjà là. |
|
|||
|
|
| 9 | **Supprimer 19 workflows `.disabled` (1676 LOC mort) OU réactiver utiles (SAST, DAST, openapi-lint)** | 🟡 | S (4h) | Noise .github/. Archive or reactivate sélectivement. |
|
|||
|
|
| 10 | **Consolider `RespondWithAppError` dupliqué** | 🟡 | S (1j) | `response/response.go:101` + `handlers/error_response.go:12`. |
|
|||
|
|
| 11 | **Wirer `UserRateLimiter` configuré mais non appelé** | 🟡 | S (1j) | Rate limit par user manquant dans la chaîne. |
|
|||
|
|
| 12 | **Supprimer `internal/repository/` (in-mem mock orphelin)** | 🟡 | XS | Dead code. |
|
|||
|
|
| 13 | **Remove/archive `proto/chat/chat.proto` + `veza-common/src/chat.rs`** | 🟡 | XS | Orphelins depuis suppression chat Rust (Feb 2026). |
|
|||
|
|
| 14 | **Ajouter E2E Playwright en CI** | 🟡 | M (3j) | Playwright existe, SKIPPED_TESTS.md documenté, mais pas trigger CI. |
|
|||
|
|
| 15 | **`docs/ENV_VARIABLES.md` — créer si manque, sync avec code** | 🟠 | S (1j) | 99 env vars dans code vs 190 lignes template → drift. |
|
|||
|
|
|
|||
|
|
### 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"
|
|||
|
|
|
|||
|
|
1. **Cleanup repo** (#1, #2, #7, #9 ci-dessus) — 1 jour brutal avant tag v1.0.7 final.
|
|||
|
|
2. **Transactions manquantes** (#3) — 3 jours, critique monétaire.
|
|||
|
|
3. **Context propagation** (#4) — 1 jour, simple grep+sed.
|
|||
|
|
4. **Security headers** (#5) — 1 jour.
|
|||
|
|
5. **OpenAPI typegen** (#8) — 1 semaine, mais une seule fois.
|
|||
|
|
|
|||
|
|
### 9.3 Chemin critique vers v1.0.7 final stable
|
|||
|
|
|
|||
|
|
**~5 jours d'ingénieur, sans feature** :
|
|||
|
|
|
|||
|
|
| Jour | Tâches |
|
|||
|
|
| :--: | ---------------------------------------------------------------------------------------------- |
|
|||
|
|
| J1 | Items #1, #2, #6, #7 — cleanup brutal + rotation secrets. BFG sur .git. Retag. |
|
|||
|
|
| J2 | Item #4 (context) + #10 (dedupe AppError) + #12 (repository) + #13 (proto chat). |
|
|||
|
|
| J3-4 | Item #3 — transactions marketplace/subscription + tests. |
|
|||
|
|
| J5 | Item #5 (CSP/XFO) + #11 (rate limiter) + #15 (.env doc) + tag `v1.0.7`. |
|
|||
|
|
|
|||
|
|
Ensuite v1.0.8 : OpenAPI typegen (#8), E2E CI (#14), item G subscription `pending_payment` (parké dans v107-plan).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 10. Verdict final
|
|||
|
|
|
|||
|
|
**Veza v1.0.7-rc1 : application solide, dépôt sale.**
|
|||
|
|
|
|||
|
|
- **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).
|
|||
|
|
- **Code infra** : 3 variants Dockerfile (dev/prod), K8s avec disaster recovery, 5 workflows CI actifs, 6 compose env, HAProxy blue-green.
|
|||
|
|
- **Hygiène repo** : 2.3 GB `.git`, 99 MB binaire racine, 48 PNG racine, 36 YML debris, 44 audio trackés, 19 workflows morts, CLAUDE_CONTEXT 977 KB, TLS certs committés, `.env` committed. **Les items "hygiène" de l'audit v1 (14 avril) n'ont pas été traités** — l'équipe a fait le bon choix de prioriser la correction produit (v1.0.5 → v1.0.7-rc1), mais ces items doivent maintenant descendre sur la stack.
|
|||
|
|
|
|||
|
|
**En une phrase** : **le code est prêt pour v1.0.7 final, le dépôt n'est pas prêt pour la v1.0.7 final**. 1 jour de cleanup brutal résout 80% du problème.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Annexe — diff v1 ↔ v2
|
|||
|
|
|
|||
|
|
| Thème | v1 (2026-04-14) | v2 (2026-04-20) |
|
|||
|
|
| -------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------- |
|
|||
|
|
| HEAD | `45662aad1` (v1.0.0-mvp-24-g45662aad1) | `89a52944e` (v1.0.7-rc1) |
|
|||
|
|
| 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é** |
|
|||
|
|
| Hygiène binaires tracked | 3 binaires | 1 reste (`api` 99 MB racine) |
|
|||
|
|
| Hygiène `uploads/*.mp3` 44 fichiers | Présent | **Non traité** |
|
|||
|
|
| Hygiène 54 PNG racine | Présent | 48 restent |
|
|||
|
|
| 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 |
|
|||
|
|
| Workflows CI | `.github/workflows/*` non consolidé | Consolidé (`ci.yml`) + **19 disabled qui traînent** |
|
|||
|
|
| `docs/audit-2026-04/` | Absent | **Nouveau** — axis-1-correctness + v107-plan |
|
|||
|
|
|
|||
|
|
**Score global** : v1 disait "Moyen-Haute dette". v2 : **Basse dette code / Haute dette hygiène**. L'équilibre a basculé sur l'hygiène repo.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*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.*
|