veza/docs/ROADMAP_V1.0_LAUNCH.md
senke 5b2f230544
Some checks failed
Veza CI / Rust (Stream Server) (push) Successful in 4m12s
Security Scan / Secret Scanning (gitleaks) (push) Successful in 41s
E2E Playwright / e2e (full) (push) Failing after 14m25s
Veza CI / Backend (Go) (push) Failing after 14m43s
Veza CI / Frontend (Web) (push) Successful in 26m12s
Veza CI / Notify on failure (push) Successful in 4s
docs(roadmap): add v1.0 → v2.0.0-public launch roadmap (6 weeks)
Living operational document tracking the path from v1.0.8 to public
launch as a SoundCloud-alternative. Compresses the original 24-week
plan to 6 weeks by explicit scope-control:

  - §2 Scope contract: IN/OUT/COMPRESSED matrix (what ships, what
    defers post-launch v1.1+, what's MVP-but-shippable)
  - §1 External actions EX-1 to EX-12 (legal, pentest, DMCA agent,
    DNS, TLS, CDN, OAuth secrets, Stripe live, transactional email,
    status page, coturn) with cycle estimates
  - §4 Day-by-day sprint breakdown for 6 weeks (W1 v1.0.9 + Ansible,
    W2 Postgres HA + obs, W3 storage HA + signature features,
    W4 PWA + HLS + faceted search + load test, W5 pentest + game day
    + canary + status page, W6 GO/NO-GO + soft launch + go-live)
  - §6 Risk register (R-1 to R-10) with mitigations
  - §7 Defended scope (refused additions during the 6 weeks)
  - §8 37 absolute Production-Ready criteria

Daily updates expected: tick acceptance criteria as they land, commit
each update with `docs: roadmap launch — <jour X> done`.

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

686 lines
44 KiB
Markdown
Raw Permalink 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.

# ROADMAP — Veza v1.0 Public Launch (4-6 semaines)
> **Cible** : ouverture publique grand-public en 4-6 semaines, positionnée
> comme alternative sérieuse à SoundCloud, sur infra self-hosted Incus
> (R720 + débordement Hetzner si nécessaire).
>
> **Auteur** : architecte principal Veza + Claude Code Opus 4.7
> **Dernière mise à jour** : 2026-04-26
> **État de départ** : v1.0.8 + sprint 1 v1.0.9 partiellement livré
> (Item G subscription en cours, items 1.2/1.3/1.4/1.5/1.6 commit-prêts)
---
## 0. Cadrage honnête
**Compression** : le plan original (`/home/senke/.claude/plans/quelles-sont-les-prochaines-playful-beaver.md`)
visait 24 semaines pour atteindre une vraie maturité opérationnelle. On
compresse 4× ici. Ça implique de **trancher** sur ce qui rentre et ce
qui n'y rentre pas — la liste explicite est en §2. Si tu doutes pendant
les 6 semaines, reviens à §2 : tout ce qui n'y est pas listé comme IN
attend post-launch.
**Réalité** :
- Solo dev, ~50h/semaine, pas de marges pour rattraper du retard
- 30 jours ouvrés disponibles, dont ~20% absorbés par l'imprévu (CI
rouge, dette qui remonte, decisions externes)
- Effort réel = 24 jours productifs sur 30
- Budget temps perdu sur la légal/pentest/ops externes : 0 (ces tâches
doivent tourner en parallèle, JAMAIS sur le critical path code)
**Verdict honnête** :
- 4 semaines = irréaliste sauf à accepter risques élevés (pas de pentest
externe, ToS template non-revu, infra single-instance)
- **6 semaines = atteignable si discipline scope-control + démarrage
immédiat des tâches externes**
- 8 semaines = confortable
Je rédige pour 6 semaines avec marge à droite.
---
## 1. À démarrer AUJOURD'HUI en parallèle (externe au code)
Ces actions ont des cycles longs incompressibles. Elles doivent partir
**maintenant** sinon le lancement glisse de 2-4 semaines.
| # | Action | Cycle | Owner | Statut |
|---|--------|-------|-------|--------|
| EX-1 | Contacter avocat pour ToS / Privacy / DMCA / DSA | 2-4 sem | toi | ⏳ |
| EX-2 | Demander devis pentest externe (ouvert sur surface v1.0.9) | 1 sem devis + 2 sem exec | toi | ⏳ |
| EX-3 | Enregistrer agent DMCA US Copyright Office (~120 USD, 2-3 sem traitement) | 2-3 sem | toi | ⏳ |
| EX-4 | Désigner point de contact DSA (UE) — soit toi soit représentant local | 1 sem | toi | ⏳ |
| EX-5 | DNS production : `veza.fr`, `api.veza.fr`, `cdn.veza.fr`, `turn.veza.fr`, `embed.veza.fr` | 1 j | toi | ⏳ |
| EX-6 | TLS certs (Let's Encrypt) pour tous les sous-domaines | 1 j | toi | ⏳ |
| EX-7 | Compte CDN edge (Cloudflare R2 + Workers ou Bunny.net) | 1 j | toi | ⏳ |
| EX-8 | Rotation OAuth secrets prod (Google, GitHub, Discord, Spotify) | 0.5 j | toi | ⏳ |
| EX-9 | Stripe / Hyperswitch live mode setup + KYC marketplace | 2-3 sem | toi | ⏳ |
| EX-10 | Email transactionnel : domaine custom + SPF/DKIM/DMARC (Mailjet/Postmark/Brevo) | 1 sem | toi | ⏳ |
| EX-11 | Status page (statuspage.io free OU Cachet self-hosted) | 1 j | toi | ⏳ |
| EX-12 | Coturn déploiement Incus (cf. `infra/coturn/README.md`) | 1 j | toi | ⏳ |
**Critical path externe** : EX-1 (légal) et EX-2 (pentest) sont les deux
contraintes majeures. Si tu démarres EX-1 le lundi semaine 1, tu auras
les drafts ToS/Privacy semaine 3 et la version finale signée semaine 5.
EX-2 même calendrier : devis semaine 1, exécution semaines 4-5, rapport
semaine 6. Sans ces deux-là on ne tag pas v2.0.0-public.
---
## 2. Scope contract — ce qui rentre vs sort
### IN (livré avant le tag v2.0.0-public)
**Code applicatif**
- Sprint 1 v1.0.9 (subscription Item G + items 1.2/1.3/1.4/1.5/1.6 + 1.7 flake stab)
- DMCA notice workflow (formulaire + admin queue + take-down handler)
- Embed widget `/embed/track/:id` + oEmbed
- Track sharing tokens privés (parité avec playlist share)
- Service worker offline track cache (Workbox CacheFirst)
- HLS streaming activé par défaut + ABR validé
- Faceted search UI sur `/search` et `/discover`
- Open Graph tags dynamiques sur les pages tracks/playlists
- Status page côté ops + endpoint `/api/v1/status` public
**Infrastructure**
- IaC Ansible playbooks (Postgres, Redis, MinIO, RabbitMQ, coturn, HAProxy, backend-api, stream-server)
- Postgres streaming replica + pg_auto_failover (RTO < 60s)
- pgBackRest WAL archive + restore drill cron hebdo
- PgBouncer transaction-mode pool
- Redis Sentinel 3-node
- MinIO erasure-coded 4-node EC4+2
- HAProxy frontal + 2 backend-api containers actif/actif (sticky WS)
- CDN edge externe (Cloudflare R2 + Workers OU Bunny.net) câblé
- OpenTelemetry collector Tempo (traces visibles)
- Loki HA 3 réplicas + S3 backend (sur ton MinIO)
- SLO burn-rate alerts (remplacement seuils statiques)
- Backup restore drill automatisé hebdo
- Synthetic monitoring (blackbox exporter rejouant les 6 parcours)
- Game day #1 réalisé + runbooks testés
- Canary release script
**Légal**
- Terms of Service (avocat-revu)
- Privacy Policy RGPD + CCPA + DPA template processeurs
- DMCA notice + agent enregistré
- DSA point de contact + transparency report template
- CGV vendeur marketplace
- Mentions légales + politique cookies + bannière consentement
**Sécurité**
- Pentest externe rapport reçu, 0 critique/haut ouvert
- Secrets hors git (Vault sur conteneur Incus OU sops/age versionné)
- Rotation OAuth secrets effectuée
- JWT RS256 prod (déjà en place vérifier rotation key)
**Business**
- Stripe live mode actif + KYC créateurs testé E2E avec vrais fonds
- Hyperswitch live mode actif + flux paiement E2E réel
- Email transactionnel sur domaine custom (SPF/DKIM/DMARC OK)
- 5-10 testeurs beta privée semaines 5-6 avec retours documentés
### OUT (deferred post-launch v1.1+)
- **Native mobile (iOS/Android)** Capacitor wrap après launch (~3 semaines)
- **Audio fingerprinting (Chromaprint)** DMCA workflow MANUEL au launch ; fingerprinting v1.1
- **Public API SDK** (`@veza/sdk-js`, `@veza/sdk-py`) + dev portal v2 v1.1
- **OAuth2 client credentials** + rate limit tiers per-app v1.1
- **Multi-region failover** single region (R720 + Hetzner debordement) au launch
- **Tipping / fan support** décision business post-launch
- **Distribution intégrale DSP** (TuneCore, CD Baby, etc.) v1.1
- **Subscription per-creator (Patreon-style)** v1.1+
- **CarPlay / Android Auto** nécessite app native d'abord
- **Lossless tier FLAC subscriber** codec déjà supporté, exposer post-launch
- **"Fresh from your follows" tab discovery** déferred (chronologique du feed suffit au launch)
- **Editorial collections admin UI** défferred (curation manuelle DB au launch)
- **Faceted search saved searches** UI faceted suffit, "saved" v1.1
### COMPRESSED (livré mais minimum viable, à durcir post-launch)
- **MinIO erasure-coded** : 4 nœuds EC4+2 mais sur la même machine R720 (pas vraiment HA matériel ajoute Hetzner storage post-launch)
- **HAProxy sticky WS** : 2 backend-api sur la même machine R720 (pas N+1 hardware HA)
- **Loki HA** : 3 réplicas en conteneurs Incus mais sur le même hôte (single-host failure mode, accepté pour launch)
- **DMCA workflow** : workflow complet + agent enregistré, MAIS audit fingerprinting reporté take-down purement humain
- **Pentest** : externe mais light scope (auth + paiement + DMCA + uploads), pas full deep dive
- **Game day** : 1 game day cycle complet, pas 3 cycles répétés
---
## 3. Critical path & dépendances
```
EX-1 légal ──────────────────────────────▶ EX week 5 signature ──▶
EX-2 pentest ────────────────────▶ EX week 4 exec ──▶ rapport week 6
EX-9 stripe live ────────▶ KYC ──▶ test E2E vrais fonds week 5
EX-10 email custom ──────▶ DKIM/SPF prop ────▶ délivrabilité week 4
Code:
W1 finir v1.0.9 + IaC ──▶ W2 Postgres HA + obs ──▶ W3 stockage + features ──▶
W4 PWA + search + load test ──▶ W5 game day + canary ──▶ W6 go-live
```
**Top-3 risques de glissement** :
1. **Légal** : si EX-1 traîne, on tag mais on ne lance pas. Démarre lundi.
2. **Pentest findings critiques** : si le pentest revèle un finding HIGH semaine 6, on rétrograde de tag et on patch peut décaler 1-2 semaines. Mitigation : faire un pentest interne semaine 4 (ZAP + nuclei + manual audit) pour pré-filtrer.
3. **Postgres HA failover en game day rouge** : si le failover n'atteint pas RTO < 60s on doit ré-architecturer. Mitigation : tester pg_auto_failover en lab Incus dès semaine 1.
---
## 4. Sprint breakdown — jour par jour
> **Convention** : chaque jour = ~6-8h productives. Acceptance criteria
> mesurables. Si un jour déborde, le suivant glisse — pas de "je
> rattraperai le week-end" autorisé sinon le burn-out garantit le slip
> de 2 semaines fin de roadmap.
### Semaine 1 — Closer v1.0.9 + amorçage IaC
**Objectif** : tag v1.0.9, scaffolding Ansible posé, Postgres HA en lab.
#### Jour 1 — Lundi : Démarrer les externes + commit sprint 1
- **AM** : Envoyer EX-1 (avocat), EX-2 (devis pentest), EX-3 (DMCA agent), EX-9 (Stripe KYC), EX-10 (email transactionnel). Ces 5 emails partent avant midi.
- **PM** : Commit + push les 4 commits préparés (`/tmp/v1.0.9-commit-messages.md`). Vérifier CI Forgejo verte. Si rouge debug avant de continuer.
- **Acceptance** : 5 emails envoyés, 4 commits pushés, CI verte sur main.
- **Files** : `/tmp/v1.0.9-commit-messages.md`
#### Jour 2 — Mardi : Item G subscription Phase 2
- Webhook handler `subscription.payment_succeeded` / `payment_failed` dans `internal/services/hyperswitch/webhook_subscription.go`
- Dispatcher dans `ProcessPaymentWebhook` qui détecte le type subscription et route
- Reuse `webhook_raw_payloads` table (item E v1.0.7) pour persistence
- Tests : webhook arrive row pending_payment active. Webhook payment_failed expired.
- **Acceptance** : 4 tests unitaires verts (success, failed, replay idempotent, unknown event)
- **Files** : `internal/services/hyperswitch/webhook_subscription.go` (nouveau), `internal/services/hyperswitch/webhook_subscription_test.go` (nouveau)
#### Jour 3 — Mercredi : Item G subscription Phase 3 + E2E
- Endpoint recovery `POST /api/v1/subscriptions/complete/:id` qui retourne le `client_secret` Hyperswitch pour reprendre un paiement stalled
- Distribution gate : `distribution.checkEligibility` traite `pending_payment` comme ineligible
- E2E `@critical` `tests/e2e/subscription-pending-payment.spec.ts` : subscribe paid plan distribution submit retourne 403 simuler webhook distribution OK
- Remove `TODO(v1.0.7-item-G)` annotation dans `subscription/service.go`
- **Acceptance** : E2E vert + grep TODO Item G = 0 hit
- **Files** : `internal/handlers/subscription_handler.go`, `internal/api/routes_subscription.go`, `internal/core/distribution/service.go`, `tests/e2e/28-subscription-pending-payment.spec.ts`
#### Jour 4 — Jeudi : Item 1.7 flake stab + tag v1.0.9
- Lire les rapports CI Forgejo des 5 derniers runs E2E sur main
- Identifier flakes : tests qui ont failé puis passé sans changement code
- Stabiliser : remplacer `waitForTimeout` par `waitFor` ciblés, ajouter retry-on-flake helpers, augmenter `expect.timeout` ciblé
- 3 cycles E2E nightly verts consécutifs avant tag
- **Acceptance** : 3 nightly E2E verts, `git tag v1.0.9` poussé
- **Files** : `tests/e2e/*.spec.ts` (stabilisations ciblées), `tests/e2e/playwright.config.ts` (timeout ciblé si nécessaire)
#### Jour 5 — Vendredi : IaC scaffolding Ansible
- Créer `infra/ansible/` avec layout standard : `inventory/`, `group_vars/`, `host_vars/`, `roles/`, `playbooks/`
- Inventaire : 1 host R720 prod + 1 host Hetzner staging + 1 host R720 lab
- Rôle `common` : SSH hardening, fail2ban, unattended-upgrades, monitoring agent
- Rôle `incus_host` : install Incus + configuration networking
- Test : déployer le rôle common sur le host lab
- **Acceptance** : `ansible-playbook -i inventory/lab playbooks/site.yml --check` passe sans erreur
- **Files** : `infra/ansible/inventory/{lab,staging,prod}.yml`, `infra/ansible/playbooks/site.yml`, `infra/ansible/roles/common/tasks/main.yml`, `infra/ansible/roles/incus_host/tasks/main.yml`, `infra/ansible/README.md`
**Verification gate W1** : tag v1.0.9 poussé, Ansible scaffolding fonctionne en lab, externes EX-1 à EX-10 démarrés.
---
### Semaine 2 — Postgres HA + observabilité
**Objectif** : Postgres failover automatique testé, OpenTelemetry collector wired, SLO alerts définies.
#### Jour 6 — Lundi : Postgres HA — pg_auto_failover lab
- Rôle Ansible `postgres_ha` : 2 conteneurs Incus (primary + replica), pg_auto_failover monitor
- Configuration : sync replication, HOT_STANDBY, max_wal_senders, etc.
- Test : kill primary, vérifier failover automatique en < 60s, vérifier replica devient primary
- **Acceptance** : failover test scripté `infra/ansible/tests/test_pg_failover.sh` rouge avant fix, vert après. RTO mesuré < 60s.
- **Files** : `infra/ansible/roles/postgres_ha/{tasks,templates,defaults}/`, `infra/ansible/tests/test_pg_failover.sh`
#### Jour 7 — Mardi : PgBouncer + connection pool
- Rôle Ansible `pgbouncer` : conteneur Incus avec PgBouncer en transaction mode
- Pool size : 50 server connections × 1000 client connections capacity
- Backend-api config : `DATABASE_URL` pointe vers PgBouncer, pas direct Postgres
- Load test : 500 connexions concurrentes simulées via `pgbench`, vérifier pas d'épuisement
- **Acceptance** : pgbench 500 clients × 30s sans erreur de connexion
- **Files** : `infra/ansible/roles/pgbouncer/{tasks,templates}/`, `veza-backend-api/internal/config/config.go` (URL pointe PgBouncer en prod)
#### Jour 8 — Mercredi : pgBackRest + restore drill
- Rôle Ansible `pgbackrest` : install + configuration WAL archive vers MinIO bucket dédié
- Backup full hebdo + différentiels quotidiens + WAL continu
- Script `scripts/dr-drill.sh` : restore le dernier full+WAL dans un conteneur éphémère, lance `cmd/tools/seed --ci` partial check, assertion `SELECT count(*) FROM users > 0`
- Cron hebdo qui execute le script + alerte Prometheus si fail
- **Acceptance** : `bash scripts/dr-drill.sh` passe vert localement
- **Files** : `infra/ansible/roles/pgbackrest/{tasks,templates}/`, `scripts/dr-drill.sh`, `config/prometheus/alert_rules.yml` (ajout `BackupRestoreDrillFailed`)
#### Jour 9 — Jeudi : OpenTelemetry collector + Tempo
- Rôle Ansible `otel_collector` : conteneur OpenTelemetry collector (config receivers + processors + exporters)
- Conteneur Tempo (Grafana stack) pour stocker les traces
- Backend-api : exporter OTLP vers le collector (déjà câblé en émetteur, juste activer le wire)
- Instrumenter 4 hot paths : auth login, track upload (chunked init/chunk/complete), payment webhook, search
- Dashboard Grafana basique avec service map + p99 par endpoint
- **Acceptance** : tracer une requête login voir le span dans Tempo UI
- **Files** : `infra/ansible/roles/otel_collector/`, `config/otel/collector-config.yaml`, `veza-backend-api/internal/tracing/otlp_exporter.go` (nouveau ou extension), `config/grafana/dashboards/service-map.json`
#### Jour 10 — Vendredi : SLO burn-rate alerts + runbooks
- Définir 3 SLO dans `config/prometheus/slo.yml` :
- `SLO_API_AVAILABILITY` : 99.5% sur `/api/v1/health` + endpoints lecture
- `SLO_API_LATENCY` : 99% p95 < 500ms sur endpoints écriture
- `SLO_PAYMENT_SUCCESS` : 99.5% des `/api/v1/orders` POST 201
- Multi-window burn-rate alerts (fast 1h burn 14.4× page, slow 6h burn 6× ticket)
- Annotations `runbook_url` sur chaque alert pointant `docs/runbooks/<alert-name>.md`
- Squelette runbooks pour les 6 alerts les plus probables
- **Acceptance** : `promtool check rules config/prometheus/slo.yml` vert, dashboard Grafana SLO visible avec error budget tracking
- **Files** : `config/prometheus/slo.yml`, `config/alertmanager/routes.yml` (acheminement page vs ticket), `docs/runbooks/{api-availability-slo-burn,payment-success-slo-burn,db-failover,redis-down,disk-full,cert-expiring-soon}.md`
**Verification gate W2** : `pg_auto_failover` test rouge vert, `pgbench` 500 connections OK, traces visibles dans Tempo, SLO burn-rate alerts définies + runbooks indexés.
---
### Semaine 3 — Stockage HA + features signature
**Objectif** : MinIO erasure-coded, CDN edge wired, embed widget + DMCA workflow + track sharing.
#### Jour 11 — Lundi : Redis Sentinel HA + cache metrics
- Rôle Ansible `redis_sentinel` : 3 conteneurs Incus (1 master + 2 replicas + 3 sentinels colocated)
- Backend-api : `RedisClient` switch vers `NewFailoverClient` avec MasterName + SentinelAddrs
- Cache hit rate metrics : ajouter compteurs Prometheus dans rate limiter, chat pubsub, presence
- Test : kill Redis master, vérifier promotion automatique d'un replica en < 30s
- **Acceptance** : failover Redis test rouge vert, dashboard Grafana avec hit rate par service
- **Files** : `infra/ansible/roles/redis_sentinel/`, `veza-backend-api/internal/config/config.go` (Sentinel config), `veza-backend-api/internal/metrics/cache_hit_rate.go` (nouveau)
#### Jour 12 — Mardi : MinIO distribué + migration
- Rôle Ansible `minio_distributed` : 4 conteneurs Incus en pool EC4+2 (résiste perte 2 conteneurs sans data loss)
- Configuration : bucket `veza-prod-tracks`, lifecycle policy (versioning 30j, Glacier après 90j)
- Migration depuis le single-node actuel via `mc mirror veza-current/ veza-distributed/`
- Backend-api : pas de changement code (interface S3 reste identique)
- Smoke test : upload 100MB via `mc cp`, kill 2 nœuds, vérifier read OK, restart nœuds, vérifier rebuild
- **Acceptance** : EC4+2 résiste à 2 nœud kills, dashboard MinIO healthcheck vert
- **Files** : `infra/ansible/roles/minio_distributed/{tasks,templates}/`
#### Jour 13 — Mercredi : CDN edge externe (Cloudflare R2 ou Bunny.net)
- Choisir : Cloudflare R2 (gratuit 10GB, $0.015/GB stockage, $0/GB egress) OU Bunny.net Stream ($0.005/GB egress audio)
- Configurer compte + bucket + cache rules + signed URL
- Câbler `internal/services/cdn_service.go` (déjà existant) pour générer URLs CDN au lieu de MinIO direct
- Trackservice `GetStorageURL` : retourner CDN signed URL pour les routes publiques (stream, download)
- Cache headers backend-api : Cache-Control: public, max-age=86400, immutable pour les segments HLS
- Test : upload track, lire via /tracks/:id/stream assert URL = `cdn.veza.fr/...`
- **Acceptance** : 1 track lue via CDN edge, latence first byte < 200ms depuis 3 PoPs
- **Files** : `veza-backend-api/internal/services/cdn_service.go` (extend), `veza-backend-api/internal/core/track/service.go` (GetStorageURL hook CDN), `infra/ansible/roles/backend_api/templates/.env.j2` (env vars CDN)
#### Jour 14 — Jeudi : DMCA notice handler + workflow
- Migration `987_dmca_notices.sql` : table `dmca_notices` (id, status, claimant_email, claimant_name, claimant_address, work_description, infringing_track_id, sworn_statement_at, status, takedown_at, counter_notice_at, restored_at, audit_log)
- Handler `internal/handlers/dmca_handler.go` :
- `POST /api/v1/dmca/notice` : public, rate-limited (5/IP/h), validate fields, enregistre `pending`
- `GET /api/v1/admin/dmca/notices` : admin-only, queue + pagination
- `POST /api/v1/admin/dmca/notices/:id/takedown` : admin action set `status=takedown`, set `takedown_at=NOW()`, mark track `is_public=false` + `dmca_blocked=true`
- `POST /api/v1/admin/dmca/notices/:id/dismiss` : admin action set `status=rejected`
- Page publique frontend `/legal/dmca` avec formulaire + agent désigné info
- Audit log dans `audit_logs` (existing v0.803 SEC2)
- **Acceptance** : E2E `tests/e2e/29-dmca-notice.spec.ts` vert (notice admin queue takedown track plus accessible)
- **Files** : `veza-backend-api/migrations/987_dmca_notices.sql` + rollback, `veza-backend-api/internal/handlers/dmca_handler.go` (nouveau), `veza-backend-api/internal/api/routes_legal.go` (nouveau), `apps/web/src/features/legal/pages/DmcaNoticePage.tsx` (nouveau), `tests/e2e/29-dmca-notice.spec.ts`
#### Jour 15 — Vendredi : Embed widget + oEmbed + track share tokens
- Route backend `GET /embed/track/:id` : retourne page HTML standalone (pas le SPA, page minimaliste avec player + waveform SVG)
- Route backend `GET /oembed?url=<track_url>&format=json` : réponse oEmbed standard (type=rich, html=`<iframe src="...">`)
- Open Graph tags dynamiques sur `/tracks/:id` (SSR mini ou meta runtime)
- Migration `988_track_share_tokens.sql` : table `track_share_tokens` (id, track_id, token UUID, expires_at NULLABLE, created_by_user_id)
- Handler `POST /api/v1/tracks/:id/share-tokens` (création) + `GET /api/v1/tracks/share/:token` (lecture)
- Test : créer share token → fetch via token → assert track lisible même si is_public=false
- **Acceptance** : embed iframe Twitter card preview OK, oEmbed JSON valide, share token E2E vert
- **Files** : `veza-backend-api/internal/handlers/embed_handler.go` (nouveau), `veza-backend-api/internal/handlers/oembed_handler.go` (nouveau), `veza-backend-api/migrations/988_track_share_tokens.sql` + rollback, `apps/web/embed/track.html` (template standalone), `tests/e2e/30-embed-and-share.spec.ts`
**Verification gate W3** : Redis HA failover OK, MinIO EC4+2 résiste 2 kills, 1 track lue via CDN, DMCA notice E2E vert, embed widget Twitter card preview verte, share token fonctionne.
---
### Semaine 4 — PWA mobile + HLS default + faceted search + load test
**Objectif** : expérience mobile aboutie, HLS ABR par défaut, recherche faceted, capacité validée 1k VU.
#### Jour 16 — Lundi : Service worker offline track cache (Workbox)
- Activer service worker en prod (déjà câblé `pwa.ts:48-56`)
- Workbox stratégies :
- Static assets : `StaleWhileRevalidate`
- HLS segments : `CacheFirst` avec max-age 7j, max 50 entries
- API calls : `NetworkFirst` avec timeout 5s
- Cache offline track : intercepter les fetch `/api/v1/tracks/:id/stream` redirigés vers CDN, cacher les segments HLS du track en cours + les 50 derniers favoris
- Background sync API pour les actions hors-ligne (like, comment) qui rejouent au retour réseau
- Test : devtools network offline mode, jouer un track déjà écouté, doit fonctionner
- **Acceptance** : test manuel offline OK, Lighthouse PWA score ≥ 90
- **Files** : `apps/web/src/sw.ts` (extend Workbox config), `apps/web/src/services/offlineQueue.ts` (extend pour background sync)
#### Jour 17 — Mardi : HLS par défaut + lossless tier preview
- Flip `HLS_STREAMING=true` dans `.env.production`
- Smoke test : upload track, vérifier que le transcode HLS s'execute, vérifier ABR sur le frontend (`useHLSPlayer` hook)
- Pre-listen 30s public sur les produits marketplace : extend `marketplace.go:258-298` pour les tracks publics si créateur opt-in
- FLAC tier preview : ajouter une checkbox "FLAC available" sur la page upload pour les Premium subscribers (visible mais reporté post-launch pour la consommation effective)
- **Acceptance** : nouveau track uploadé sert HLS ABR (3 niveaux 128/256/320), Network panel devtools confirme switch ABR sur réseau dégradé
- **Files** : `infra/ansible/roles/backend_api/templates/.env.j2` (HLS_STREAMING=true), `apps/web/src/features/upload/components/UploadForm.tsx` (FLAC checkbox)
#### Jour 18 — Mercredi : Faceted search UI
- Composant `apps/web/src/features/search/components/FacetSidebar.tsx` : sidebar avec filtres genre / BPM range / musical_key / year / type (track/playlist/user)
- Wire avec orval-generated `useGetSearch` hook : passer `params.type[]`, query params custom pour bpm_min/max
- Backend : étendre `search_handlers.go:Search` pour accepter `bpm_min`, `bpm_max`, `musical_key`, `year_from`, `year_to` (déjà partiellement supportés via SearchService)
- Test : recherche "rock" + filtre BPM 120-130 → résultats restreints
- **Acceptance** : E2E `tests/e2e/31-faceted-search.spec.ts` vert
- **Files** : `apps/web/src/features/search/components/FacetSidebar.tsx` (nouveau), `apps/web/src/features/search/pages/search-page/SearchPage.tsx` (intégration), `veza-backend-api/internal/handlers/search_handlers.go` (extend params), `veza-backend-api/internal/services/search_service.go` (extend filter SQL), `tests/e2e/31-faceted-search.spec.ts`
#### Jour 19 — Jeudi : HAProxy sticky WS + 2 backend-api actif/actif
- Rôle Ansible `haproxy` : conteneur HAProxy avec config `frontend tls / backend api_pool` + sticky cookie sur les routes WS
- Backend-api : déployer 2 conteneurs Incus actif/actif derrière HAProxy. Stateless OK (sessions Redis-backed déjà câblé).
- Health check `/api/v1/health` toutes les 5s, drain 30s avant remove
- Test : kill backend-api 1, vérifier HAProxy bascule, vérifier sessions WS reconnectent au backend-api 2 sans perte de message
- Stream-server : 2 conteneurs avec affinité sticky par `track_id` hash (HLS cache local optimisé)
- **Acceptance** : test scripté `infra/ansible/tests/test_backend_failover.sh` vert
- **Files** : `infra/ansible/roles/haproxy/{tasks,templates}/`, `infra/ansible/roles/backend_api/tasks/main.yml` (multi-instance), `infra/ansible/tests/test_backend_failover.sh`
#### Jour 20 — Vendredi : Load test k6 nightly + capacity validation
- Compléter `scripts/loadtest/k6_load_test.js` avec scénarios mix réalistes :
- 100 VU upload concurrent (10MB tracks)
- 500 VU streaming HLS (segments fetch)
- 1000 VU search + browse mixte
- 50 VU checkout marketplace
- Threshold p95 < 500ms global, error rate < 0.5%
- Workflow CI nightly `.github/workflows/loadtest.yml` qui lance k6 sur staging
- Profiling pprof endpoints lents identifiés
- Capacité validée : 1k users concurrents tenus sur 1 R720 sans saturation
- **Acceptance** : nightly load test passe vert pendant 3 nuits consécutives, dashboard Grafana avec p95/p99 par endpoint
- **Files** : `scripts/loadtest/k6_*.js`, `.github/workflows/loadtest.yml` (nouveau), `docs/PERFORMANCE_BASELINE.md` (update avec chiffres réels)
**Verification gate W4** : Lighthouse PWA 90, HLS ABR par défaut OK, faceted search E2E vert, HAProxy failover OK, k6 nightly 1k VU green 3 nuits.
---
### Semaine 5 — Pentest + game day + canary + status page
**Objectif** : pentest exécuté, game day rejoué et runbooks validés, canary release process automatisé, status page publique.
#### Jour 21 — Lundi : Pré-flight pentest interne (avant le pentest externe)
- Lancer ZAP automated scan sur staging : `docker run -v $(pwd):/zap/wrk owasp/zap2docker-stable zap-baseline.py -t https://staging.veza.fr`
- Lancer nuclei : `nuclei -u https://staging.veza.fr -t cves/ -t vulnerabilities/ -t exposures/`
- Manual audit OWASP Top 10 sur les nouveaux endpoints v1.0.9 :
- `/api/v1/dmca/notice` : XSS via work_description, SSRF via URLs, CSRF
- `/embed/track/:id` : XSS via track metadata
- `/api/v1/config/webrtc` : disclosure (rappel : volontairement public)
- `/api/v1/tracks/share/:token` : enumeration timing
- Fix les findings HIGH internes avant l'externe
- **Acceptance** : 0 finding HIGH dans le rapport ZAP/nuclei, manual audit issues fixées ou justifiées
- **Files** : `docs/SECURITY_PRELAUNCH_AUDIT.md` (nouveau, avec findings + résolutions)
#### Jour 22 — Mardi : Game day #1 — failures simulées
- Scénario A : kill primary Postgres pendant 5min, vérifier failover < 60s + apps reconnectent
- Scénario B : kill HAProxy backend-api 1, vérifier autres backends servent + WS clients reconnect
- Scénario C : kill Redis sentinel master, vérifier promotion replica + chat continue
- Scénario D : saturate disque MinIO 95%, vérifier alertes + degraded write mode
- Scénario E : RabbitMQ down 30min, vérifier event bus log error loud + queue mémoire fallback
- Documenter chaque incident dans `docs/runbooks/game-days/2026-W5-game-day-1.md` : timestamp, action, observation, runbook utilisé, gap découvert
- **Acceptance** : aucun silent fail, aucune 5xx > 30s post-incident, chaque alert Prometheus déclenchée < 1min
- **Files** : `docs/runbooks/game-days/2026-W5-game-day-1.md` (nouveau), `docs/runbooks/<alert-name>.md` (mises à jour selon gaps trouvés)
#### Jour 23 — Mercredi : Canary release process
- Script `scripts/deploy-canary.sh` :
1. Pull nouvelle image backend-api
2. Désactiver backend-api 2 dans HAProxy (drain mode)
3. Déployer nouvelle image sur backend-api 2
4. Health check : `curl https://api.veza.fr/api/v1/health` doit return 200
5. Re-enable backend-api 2 dans HAProxy
6. Monitor pendant 1h : SLI doivent rester verts (p95 < 500ms, err rate < 0.5%)
7. Si SLI vert : repeat sur backend-api 1 (full deploy)
8. Si SLI rouge : rollback automatique (re-déployer ancienne image)
- Pre-deploy hook : check migrations DB sont backward-compatible (nouveau schema doit fonctionner avec ancienne version code)
- Documentation `docs/CANARY_RELEASE.md`
- Test : faire 3 canary deploys sur staging avec rollback simulé
- **Acceptance** : 3 canary deploys réussis (2 normaux + 1 avec rollback simulé volontaire)
- **Files** : `scripts/deploy-canary.sh` (nouveau), `docs/CANARY_RELEASE.md` (nouveau), `Makefile` (target `deploy-canary`)
#### Jour 24 — Jeudi : Status page + synthetic monitoring
- Setup status page : Cachet (self-hosted) sur conteneur Incus OU statuspage.io free tier
- Composants à monitor : API, Stream, Chat, Marketplace, Live, CDN
- Endpoint `GET /api/v1/status` public qui retourne `{status: "operational"|"degraded"|"down", components: {...}}` (utilisé par la status page + supervision)
- Synthetic monitoring : Blackbox exporter Prometheus rejouant 6 parcours toutes les 5min depuis un Incus externe (hors-réseau prod) :
- Register verify login
- Login search "test" play first result
- Login upload tiny audio poll status
- Login browse marketplace add to cart
- WebSocket chat connect + send message
- Live stream metadata fetch
- Alert Prometheus si parcours fail 2 fois consécutives
- **Acceptance** : status page accessible sur `status.veza.fr`, synthetic monitoring vert sur 6 parcours pendant 24h
- **Files** : `infra/ansible/roles/cachet/` (si self-hosted), `veza-backend-api/internal/handlers/status_handler.go` (nouveau), `infra/ansible/roles/blackbox_exporter/`, `config/prometheus/blackbox_targets.yml`
#### Jour 25 — Vendredi : Pentest externe kick-off + buffer
- Briefer le pentester (selon EX-2) : scope auth + paiement + DMCA + uploads + WebRTC + embed widget. Donner accès staging dédié avec données pré-seed.
- Le pentest s'exécute en async semaine 5 et début semaine 6.
- Buffer day pour rattraper les retards des jours 21-24 + tester le canary process une fois encore.
- Si tout est en avance : commencer 2.7 (rate limit tiers per-app) en avance sur la semaine 6.
- **Acceptance** : pentester actif, staging accessible, runbooks à jour
- **Files** : `docs/PENTEST_SCOPE_2026.md` (nouveau, brief technique pour le pentester)
**Verification gate W5** : pentest interne 0 HIGH, game day documenté avec 0 silent fail, 3 canary deploys verts, status page publique, synthetic monitoring vert 24h.
---
### Semaine 6 — GO/NO-GO + go-live
**Objectif** : tout le checklist GO/NO-GO vert, soft launch beta privée, public launch.
#### Jour 26 — Lundi : GO/NO-GO checklist final pass
- Réutiliser et faire passer en vert `docs/GO_NO_GO_CHECKLIST_v1.0.0.md` mais cible **v2.0.0-public** :
- **Sécurité** : pentest 0 critique/haut, JWT RS256 prod ✓, secrets hors git
- **Stabilité** : uptime 99.9% staging 30j (vérifier dashboards), taux 5xx < 0.1%, 0 incident P0 ouvert
- **Performance** : p95 API < 100ms, Lighthouse perf 85, a11y 90, PWA 90
- **Qualité** : coverage 70%, 0 lint, CI verte 2 sem
- **Éthique** : audit anti-dark-pattern (relire `ORIGIN_UI_UX_SYSTEM.md` §13), 0 ML reco, feed chronologique, algo découverte documenté
- **Business** : flow paiement E2E réel testé (jour 27), KYC vendeur testé E2E, support accessible
- Documenter chaque ligne avec preuve (lien dashboard, commit, test passing)
- Lister les RED items avec plan de remédiation jour 27-28
- **Acceptance** : checklist exhaustive, RED items < 3 et tous remédiables d'ici jour 28
- **Files** : `docs/GO_NO_GO_CHECKLIST_v2.0.0_PUBLIC.md` (nouveau, dérivé du v1.0.0)
#### Jour 27 — Mardi : Test E2E paiement réel + remediation RED items
- AM : Stripe live mode + Hyperswitch live actifs (selon EX-9), faire un vrai achat marketplace (5 produit test) avec ta propre carte. Vérifier : webhook reçu, license attribuée, vendeur Connect crédité, payout planifié, refund possible.
- PM : remediation RED items du checklist GO/NO-GO. Si > 5 RED items, escalade : décaler le launch d'1 semaine.
- **Acceptance** : 1 achat E2E réel avec vrais fonds, refund testé, RED items 0
- **Files** : `docs/PAYMENT_E2E_LIVE_REPORT.md` (nouveau, traces de la transaction live)
#### Jour 28 — Mercredi : Game day #2 + canary deploy prod
- Game day #2 : rejouer les 5 scénarios du jour 22 sur prod (avec maintenance window 1h annoncée). Cible : tout vert sans intervention manuelle, runbooks validés.
- Canary deploy prod : déployer la version v2.0.0-rc1 sur le R720 prod via le script du jour 23. Soak test 4h, vérifier SLI verts.
- Annonce interne (Discord/Slack équipe) que prod est sur v2.0.0-rc1.
- **Acceptance** : game day prod vert, canary deploy v2.0.0-rc1 vert, soak 4h vert
- **Files** : `docs/runbooks/game-days/2026-W6-game-day-2.md`, `docs/RELEASE_NOTES_V2.0.0_RC1.md`
#### Jour 29 — Jeudi : Soft launch beta privée
- Inviter 50-100 testeurs (mailing list pré-launch, contacts perso, communautés musicales sélectives)
- Email d'invitation avec lien d'inscription + code beta + form Typeform de feedback
- Monitor en temps réel : status page, Grafana dashboards, Sentry frontend errors, support inbox
- Documenter chaque issue rapportée → triage HIGH/MED/LOW
- HIGH issues fixées le jour même, MED le lendemain, LOW backlog post-launch
- **Acceptance** : 50+ testeurs onboardés, < 3 HIGH issues, monitoring vert
- **Files** : `docs/SOFT_LAUNCH_BETA_2026.md` (rapport feedback consolidé)
#### Jour 30 — Vendredi : Public launch
- AM : final pre-launch checklist :
- Status page tout vert
- Game day #2 runbook signed off
- Pentest report reçu, 0 critique/haut ouvert (ou risques accepted documentés)
- Légal signé : ToS, Privacy, DMCA agent enregistré
- Soft launch beta : 0 HIGH issue ouverte
- PM : `git tag v2.0.0` + push, annonce publique (réseaux sociaux, Hacker News, communautés musicales, Product Hunt prep)
- DNS : couper la maintenance page, ouvrir le trafic public
- War room ouvert (Discord/Slack) pour les 48h post-launch
- **Acceptance** : v2.0.0 tagué, publication publique, monitoring actif 24h
- **Files** : `CHANGELOG.md` (entry v2.0.0), `docs/RELEASE_NOTES_V2.0.0.md`, `docs/POST_LAUNCH_RUNBOOK.md`
**Verification gate W6 = LAUNCH** : tag v2.0.0 poussé, trafic public ouvert, monitoring vert 24h, war room actif.
---
## 5. Post-launch immédiat (D+1 à D+7)
| Jour | Action | Owner |
|------|--------|-------|
| D+1 | War room actif, monitor toutes les 30min, daily standup interne | toi |
| D+2 | Premier patch release v2.0.1 si HIGH issues remontées | toi |
| D+3 | Post-mortem du launch : ce qui a bien marché, ce qui a cassé | toi |
| D+5 | Annonce status : "X users, Y tracks, Z transactions, uptime A%" | toi |
| D+7 | Démarrer v2.1 backlog post-launch (Capacitor mobile, fingerprinting, distribution DSP) | toi |
---
## 6. Risk register
| # | Risque | Proba | Impact | Mitigation | Owner |
|---|--------|-------|--------|------------|-------|
| R-1 | Légal traîne au-delà de semaine 5 | M | HIGH | Démarrer EX-1 jour 1, relancer chaque semaine, ToS template open-source en backup (`commonsclause-style`) | toi |
| R-2 | Pentest finding CRITICAL semaine 6 | M | CRITICAL | Pentest interne semaine 5 jour 21 pour pré-filtrer, budget 3-5j patch reserve semaine 6 | toi |
| R-3 | Postgres failover ne tient pas RTO < 60s | L | HIGH | Tester en lab dès jour 6, fallback : monitor + alert + manual failover documenté (RTO ~5min) | toi |
| R-4 | Item G subscription bug en prod (paiement réel) | L | CRITICAL | E2E `@critical` + manual smoke jour 27 + reconciliation worker (déjà v1.0.7) catch les drifts | toi |
| R-5 | Coturn deploy raté (NAT/UDP forwarding) | M | MED | Tester en sandbox semaine 1-2 (lab Incus), fallback : STUN seul pour launch + advisory UI | toi |
| R-6 | CDN coûts explosent au launch (audio bandwidth) | M | MED | Bunny.net (~5 €/TB) plus prévisible que Cloudflare R2 ($/GB), monitoring bandwidth daily | toi |
| R-7 | Soft launch beta trouve un vrai bug bloquant | H | HIGH | Buffer jour 27 PM + jour 28, max 3 HIGH issues acceptables | toi |
| R-8 | DDoS / abuse au launch | M | MED | Rate limits déjà en place v0.803, Cloudflare proxy en option pour absorption L7 | toi |
| R-9 | Dette technique remonte (CI rouge, flake) | H | LOW | Buffer 20% dans chaque journée, git revert prêt si une feature sabote l'ensemble | toi |
| R-10 | Burnout / décrochage perso | M | CRITICAL | Pas de week-end de "rattrapage", buffer ½ journée par sem, scope-creep refusé | toi |
---
## 7. Defended scope — ce qu'on REFUSE pendant les 6 semaines
Si pendant les 6 semaines tu te poses la question "devrais-je rajouter
X au scope launch", la réponse par défaut est **non, post-launch**.
Liste explicite des refus pré-approuvés :
- **Native mobile (iOS/Android)** REFUS. Capacitor wrap post-launch, ~3 sem.
- **Audio fingerprinting** REFUS. DMCA workflow manuel suffit. Chromaprint v1.1.
- **Public API SDK** REFUS. API key + webhooks v0.803 restent. SDK v1.1.
- **OAuth2 client credentials** REFUS. v1.1.
- **Multi-region failover** REFUS. R720 + Hetzner standby suffit. v1.2.
- **Tipping / fan support** REFUS. Décision business post-launch.
- **Distribution DSP** (TuneCore/CD Baby) REFUS. v1.1.
- **Subscription per-creator** (Patreon-style) REFUS. v1.1+.
- **CarPlay / Android Auto** REFUS. Nécessite app native.
- **Lossless tier FLAC consommation** REFUS UI complète. Codec exposé en upload form, consommation v1.1.
- **"Fresh from your follows" tab** REFUS. Filtre chronologique simple suffit.
- **Editorial collections admin UI** REFUS. Curation manuelle DB suffit.
- **Saved searches** REFUS. Faceted search UI suffit.
- **PWA push notifications custom** REFUS extends. Le push existant v0.302 N1 suffit.
- **Light/dark theme switcher avancé** REFUS. Le `prefers-color-scheme` actuel suffit.
- **Internationalisation full** REFUS extends. FR + EN au launch (déjà v0.12.7).
- **Accessibility AAA** REFUS. AA suffit (déjà v0.12.6).
- **GraphQL API** REFUS jamais (pas dans la stack).
- **Migration vers cloud managed** REFUS. Self-hosted Incus est le choix.
Si quelqu'un te pousse à ajouter du scope, refer ce document.
---
## 8. Definition of "Production Ready" — critères absolus
Au tag v2.0.0 le **8 juin 2026** (jour 30 = vendredi semaine 6), Veza
DOIT remplir tous les critères suivants :
### Sécurité (5 critères)
- [ ] JWT RS256 prod, clés rotées récemment (< 90j)
- [ ] Secrets hors git (Vault ou sops/age)
- [ ] Pentest externe rapport reçu, 0 finding critique/haut ouvert (HAUT moyens acceptés documentés)
- [ ] Rate limits prod actifs (1000/s global, 100/IP/s)
- [ ] HTTPS partout, HSTS preload submitted, certs auto-renouvellement
### Stabilité (5 critères)
- [ ] Postgres HA failover testé (RTO < 60s) sur staging ET prod
- [ ] Redis Sentinel failover testé
- [ ] Backup restore drill cron passe vert depuis 7j consécutifs
- [ ] Game day #1 + #2 documentés, runbooks signés
- [ ] Canary release process testé 3 fois, rollback automatique vérifié
### Performance (4 critères)
- [ ] p95 API < 500ms sur 1k VU mixed load (k6 nightly green)
- [ ] Lighthouse Performance 85, Accessibility 90, PWA 90
- [ ] CDN edge actif, latence first byte < 200ms depuis 3 PoPs
- [ ] HLS ABR fonctionne (3 niveaux 128/256/320)
### Observabilité (5 critères)
- [ ] Grafana dashboards : API overview, Chat, Commerce, Stream, Live, Ledger health
- [ ] OpenTelemetry collector vivant, traces visibles dans Tempo
- [ ] Loki HA 3 réplicas, logs application centralisés
- [ ] SLO burn-rate alerts définies (3 SLO), runbooks indexés
- [ ] Status page publique sur `status.veza.fr`, synthetic monitoring vert 7j
### Légal (5 critères)
- [ ] Terms of Service publié sur `/legal/terms`, avocat-validé
- [ ] Privacy Policy publié sur `/legal/privacy`, RGPD + CCPA conformes
- [ ] DMCA notice formulaire actif sur `/legal/dmca`, agent enregistré US Copyright Office
- [ ] DSA point de contact UE désigné, transparency report template prêt
- [ ] CGV vendeur marketplace publiées
### Business (4 critères)
- [ ] Stripe Connect live mode actif, KYC créateur testé E2E
- [ ] Hyperswitch live mode actif, paiement E2E vrai fonds testé (5+€)
- [ ] Refund E2E vrai fonds testé
- [ ] Email transactionnel sur domaine custom (SPF/DKIM/DMARC vert)
### Qualité (4 critères)
- [ ] Coverage tests 70% (Go + Rust + TS)
- [ ] 0 lint error (golangci-lint, ESLint, clippy)
- [ ] CI verte sur main depuis 2 semaines consécutives
- [ ] E2E `@critical` vert sur les 5 derniers nightly
### Éthique (5 critères absolus, non-négociables)
- [ ] Aucun code AI/ML recommandation (grep `tensorflow|pytorch|sklearn` = 0 hit)
- [ ] Aucune métrique popularité publique (likes/plays cachés des vues publiques)
- [ ] Feed chronologique (`ORIGIN_REVISION_SUMMARY.md` rule 7)
- [ ] Algorithme découverte documenté + auditable (`docs/DISCOVERY_ALGORITHM.md`)
- [ ] Audit UX anti-dark-pattern signed off
**Total : 37 critères. Si > 3 sont rouges au matin du jour 30, le launch décale d'1 semaine.**
---
## 9. Communication & external comms
### Pré-launch (semaines 1-5)
- Lundi semaine 1 : annonce interne (Discord équipe / proches) "lancement public début juin 2026"
- Semaine 3 : ouvrir un compte X/Mastodon Veza, premiers posts teaser
- Semaine 4 : open la mailing list pré-launch (formulaire `veza.fr`)
- Semaine 5 : envoi soft launch invitations 50-100 testeurs
### Launch jour 30
- Annonce simultanée : Twitter/X, Mastodon, Hacker News (Show HN), Reddit /r/musicians, /r/Wearethemusicmakers, Product Hunt préparé pour J+1
- Email à la mailing list pré-launch
- Communiqué de presse short (3 paragraphes) à musique-tech press (TechCrunch, ResidentAdvisor, Music Ally)
### Post-launch (D+1 à D+30)
- Daily monitoring stats sur le compte X/Mastodon
- Weekly product update blog
- Office hours hebdo Discord (Q&A créateurs)
---
## 10. Annexes — références rapides
- **État de départ** : `docs/PROJECT_STATE.md`, `docs/FEATURE_STATUS.md`, `FUNCTIONAL_AUDIT.md`
- **Audit complet** : `AUDIT_REPORT.md`, `docs/audit-2026-04/`
- **Plan original 24 semaines** : `/home/senke/.claude/plans/quelles-sont-les-prochaines-playful-beaver.md`
- **Sprint 1 v1.0.9 commit messages** : `/tmp/v1.0.9-commit-messages.md`
- **Configurations infra** : `infra/coturn/`, `infra/ansible/` (à créer semaine 1)
- **Runbooks** : `docs/runbooks/` + `k8s/disaster-recovery/runbooks/`
- **Règles immuables** : `CLAUDE.md` §🚫 + `veza-docs/ORIGIN/`
- **GO/NO-GO précédent (v1.0.0-rc1)** : `docs/GO_NO_GO_CHECKLIST_v1.0.0.md`
---
## 11. Cadence quotidienne suggérée
```
08:00-08:30 Café + revue plan (ce doc) + vérif notif Forgejo nightly
08:30-09:00 Revue inbox externe (légal/pentest/ops emails)
09:00-12:30 Bloc focus matin — la tâche du jour (~3.5h)
12:30-13:30 Pause déjeuner OBLIGATOIRE
13:30-17:00 Bloc focus après-midi — finir tâche du jour + tests + commit (~3.5h)
17:00-17:30 Update du checklist + push final + setup demain
17:30 Stop. Pas de "juste un dernier truc".
```
Si une journée glisse de > 4h, **ne pas** rattraper le soir/week-end —
re-prioriser la suite. Le burnout au jour 20 = launch raté.
---
*Document vivant. Mettre à jour le statut des tâches en cochant directement dans ce fichier (`[ ]` → `[x]`). Commit chaque mise à jour avec `docs: roadmap launch — <jour X> done` pour traçabilité.*