veza/docs/archive/v0-history/PLAN_V0_601_IMPLEMENTATION.md
senke 0e7097ed1b chore(cleanup): J1 — purge 220MB debris, archive session docs (complete)
First-attempt commit 3a5c6e184 only captured the .gitignore change; the
pre-commit hook silently dropped the 343 staged moves/deletes during
lint-staged's "no matching task" path. This commit re-applies the intended
J1 content on top of bec75f143 (which was pushed in parallel).

Uses --no-verify because:
- J1 only touches .md/.json/.log/.png/binaries — zero code that would
  benefit from lint-staged, typecheck, or vitest
- The hook demonstrated it corrupts pure-rename commits in this repo
- Explicitly authorized by user for this one commit

Changes (343 total: 169 deletions + 174 renames):

Binaries purged (~167 MB):
- veza-backend-api/{server,modern-server,encrypt_oauth_tokens,seed,seed-v2}

Generated reports purged:
- 9 apps/web/lint_report*.json (~32 MB)
- 8 apps/web/tsc_*.{log,txt} + ts_*.log (TS error snapshots)
- 3 apps/web/storybook_*.json (1375+ stored errors)
- apps/web/{build_errors*,build_output,final_errors}.txt
- 70 veza-backend-api/coverage*.out + coverage_groups/ (~4 MB)
- 3 veza-backend-api/internal/handlers/*.bak

Root cleanup:
- 54 audit-*.png (visual regression baselines, ~11 MB)
- 9 stale MVP-era scripts (Jan 27, hardcoded v0.101):
  start_{iteration,mvp,recovery}.sh,
  test_{mvp_endpoints,protected_endpoints,user_journey}.sh,
  validate_v0101.sh, verify_logs_setup.sh, gen_hash.py

Session docs archived (not deleted — preserved under docs/archive/):
- 78 apps/web/*.md     → docs/archive/frontend-sessions-2026/
- 43 veza-backend-api/*.md → docs/archive/backend-sessions-2026/
- 53 docs/{RETROSPECTIVE_V,SMOKE_TEST_V,PLAN_V0_,V0_*_RELEASE_SCOPE,
          AUDIT_,PLAN_ACTION_AUDIT,REMEDIATION_PROGRESS}*.md
                        → docs/archive/v0-history/

README.md and CONTRIBUTING.md preserved in apps/web/ and veza-backend-api/.

Note: The .gitignore rules preventing recurrence were already pushed in
3a5c6e184 and remain in place — this commit does not modify .gitignore.

Refs: AUDIT_REPORT.md §11
2026-04-14 17:12:03 +02:00

12 KiB

Plan d'implémentation v0.601 — Production Readiness & Commerce

Date : 2026-02-22 Base : v0.503 taguée Durée estimée : 6 sprints (~30 jours ouvrés) Référence : V0_601_RELEASE_SCOPE.md


Vue d'ensemble

Sprint 1 (j1-5)   → INF1 : Infrastructure Production (blue-green, Grafana, health)
Sprint 2 (j6-10)  → COM1 : Commerce (reviews, factures, remboursements, Hyperswitch prod)
Sprint 3 (j11-15) → AUTH1 : OAuth Discord & Spotify
Sprint 4 (j16-22) → CLN1 : Dette technique (découpage handler, interceptors, migrations)
Sprint 5 (j23-27) → QA1 : Tests E2E, smoke test, documentation
Sprint 6 (j28-30) → QA2 : Rétrospective, tag v0.601

Diagramme d'architecture cible

flowchart TD
    subgraph LB["Load Balancer"]
        HAProxy["HAProxy Blue-Green"]
    end

    subgraph Blue["Blue Stack"]
        API1["veza-backend-api"]
        Stream1["veza-stream-server"]
    end

    subgraph Green["Green Stack"]
        API2["veza-backend-api"]
        Stream2["veza-stream-server"]
    end

    subgraph Monitor["Monitoring"]
        Prometheus["Prometheus"]
        Grafana["Grafana Dashboards"]
        Alertmanager["Alertmanager"]
    end

    subgraph Commerce["Commerce"]
        Reviews["Reviews API"]
        Invoice["Invoice PDF"]
        Refund["Refund API"]
    end

    HAProxy --> Blue
    HAProxy --> Green
    API1 --> Prometheus
    API2 --> Prometheus
    Prometheus --> Grafana
    Prometheus --> Alertmanager
    API1 --> Reviews
    API1 --> Invoice
    API1 --> Refund

Sprint 1 — Infrastructure Production (jours 1-5)

Objectif : Blue-green deployment, dashboards Grafana, health check enrichi, graceful shutdown.

Tâche INF1-01 : Blue-green deployment

Fichiers :

  • config/haproxy/haproxy.cfg — ajouter backends blue/green, health checks
  • config/caddy/Caddyfile.staging — alternative si Caddy utilisé
  • docker-compose.prod.yml — deux stacks (blue, green)
  • scripts/deploy-blue-green.sh — script bascule manuelle

Exemple HAProxy :

backend api_blue
    balance roundrobin
    option httpchk GET /api/v1/health
    http-check expect status 200
    server api1 api-blue:8080 check

backend api_green
    balance roundrobin
    option httpchk GET /api/v1/health
    http-check expect status 200
    server api1 api-green:8080 check

Tâche INF1-02 : Dashboards Grafana

Fichiers :

  • config/grafana/dashboards/api-overview.json — latence, erreurs, throughput
  • config/grafana/dashboards/chat-overview.json — connexions WS, messages/s
  • config/grafana/dashboards/commerce-overview.json — orders, checkout, refunds

Validation : Dashboards chargent les métriques Prometheus existantes.

Tâche INF1-03 : Alertmanager

Fichier : config/alertmanager/alertmanager.yml

route:
  receiver: 'slack-default'
  group_by: ['alertname']
receivers:
  - name: 'slack-default'
    slack_configs:
      - api_url: '${SLACK_WEBHOOK_URL}'
        channel: '#alerts'

Tâche INF1-04 : Graceful shutdown

Fichier : veza-backend-api/cmd/api/main.go

srv := &http.Server{Addr: ":" + port, Handler: router}
go func() {
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatal(err)
    }
}()

quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
    log.Fatal("Server forced to shutdown:", err)
}

Fichier : veza-stream-server/src/main.rs — gérer SIGTERM, drain connexions.

Tâche INF1-05 : Health check enrichi

Fichier : veza-backend-api/internal/handlers/health.go

type HealthResponse struct {
    Status   string            `json:"status"` // "ok" | "degraded"
    DB       string            `json:"db"`
    Redis    string            `json:"redis"`
    RabbitMQ string            `json:"rabbitmq,omitempty"`
    Checks   map[string]string `json:"checks"`
}

Validation Sprint 1 :

cd veza-backend-api && go build ./...
curl -s http://localhost:8080/api/v1/health | jq

Commit Sprint 1 : feat(infra): blue-green deployment, Grafana dashboards, enriched health check, graceful shutdown


Sprint 2 — Commerce Finalisation (jours 6-10)

Objectif : Reviews produits, factures PDF, remboursements, Hyperswitch production.

Tâche COM1-01 : Reviews produits

Migration : veza-backend-api/migrations/114_product_reviews.sql

CREATE TABLE IF NOT EXISTS product_reviews (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    product_id UUID NOT NULL REFERENCES products(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    rating INT NOT NULL CHECK (rating >= 1 AND rating <= 5),
    comment TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(product_id, user_id)
);

CREATE INDEX idx_product_reviews_product ON product_reviews(product_id);

Fichiers :

  • internal/models/product_review.go — modèle GORM
  • internal/repositories/product_review_repository.go — CRUD
  • internal/handlers/marketplace_handler.go — POST/GET reviews, GET moyenne
  • Frontend : ProductDetail — affichage reviews, formulaire

Tâche COM1-02 : Factures PDF

Fichier : veza-backend-api/internal/services/invoice_service.go

  • Lib : github.com/jung-kurt/gofpdf ou github.com/signintech/gopdf
  • Template : numéro facture, date, items, total, TVA
  • GET /api/v1/orders/:id/invoice — génère et retourne PDF

Frontend : bouton « Télécharger facture » dans OrdersView.

Tâche COM1-03 : Remboursements

Fichiers :

  • internal/models/order.go — champ refund_status
  • internal/handlers/marketplace_handler.goPOST /orders/:id/refund
  • internal/services/hyperswitch_service.go — appel Hyperswitch refund API
  • Webhook : traiter refund.succeeded, mettre à jour order, révoquer licence

Tâche COM1-04 : Hyperswitch production

Fichier : veza-backend-api/internal/config/config.go

HyperswitchLiveMode bool   // HYPERSWITCH_LIVE_MODE
HyperswitchSecret   string // Webhook secret pour validation

Tâche COM1-05 : MSW + Stories

Fichiers :

  • apps/web/src/mocks/handlers.ts — handlers reviews, invoice, refund
  • apps/web/src/features/ — stories ProductReviews, InvoiceDownload, RefundButton

Validation Sprint 2 :

cd veza-backend-api && go test ./internal/... -v -count=1 -run Commerce
cd apps/web && npm run build

Commit Sprint 2 : feat(commerce): product reviews, PDF invoices, refunds, Hyperswitch production mode


Sprint 3 — OAuth Discord & Spotify (jours 11-15)

Objectif : Implémenter les providers OAuth manquants.

Tâche AUTH1-01 : OAuth Discord

Fichier : veza-backend-api/internal/services/oauth_service.go

  • Config : DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_REDIRECT_URI
  • Scopes : identify, email
  • Callback : GET /auth/discord/callback
  • Mapping : discord_id → user, création si nouveau

Tâche AUTH1-02 : OAuth Spotify

Fichier : veza-backend-api/internal/services/oauth_service.go

  • Config : SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, SPOTIFY_REDIRECT_URI
  • Scopes : user-read-email
  • Callback : GET /auth/spotify/callback

Tâche AUTH1-03 : Tests OAuth

Fichiers : internal/services/oauth_discord_test.go, oauth_spotify_test.go

Tâche AUTH1-04 : FEATURE_STATUS

Fichier : docs/FEATURE_STATUS.md — OAuth Discord/Spotify → opérationnel

Validation Sprint 3 :

cd veza-backend-api && go test ./internal/services/... -v -run OAuth

Commit Sprint 3 : feat(auth): OAuth Discord and Spotify providers


Sprint 4 — Dette Technique (jours 16-22)

Objectif : Découper handler.go, interceptors.ts, consolidation migrations.

Tâche CLN1-01 : Découper handler.go (track)

Fichier actuel : veza-backend-api/internal/core/track/handler.go (~1463 LOC)

Découpage :

  • track_crud_handler.go — ListTracks, GetTrack, UpdateTrack, DeleteTrack, BatchDelete, BatchUpdate
  • track_social_handler.go — LikeTrack, UnlikeTrack, GetTrackLikes, GetUserLikedTracks, CreateShare, GetSharedTrack, RevokeShare
  • track_search_handler.go — SearchTracks, GetRecommendations, GetSuggestedTags
  • track_analytics_handler.go — GetTrackStats, GetTrackHistory, RecordPlay
  • handler.go — facade, getUserID, respondWithError, délégation

Objectif : handler.go < 500 LOC.

Tâche CLN1-02 : Découper interceptors.ts

Fichier actuel : apps/web/src/services/api/interceptors.ts (~1207 LOC)

Découpage :

  • interceptors/auth.ts — auth interceptor, token refresh
  • interceptors/error.ts — error handling, retry
  • interceptors/logging.ts — request/response logging
  • interceptors/index.ts — re-export, composition

Objectif : chaque fichier < 400 LOC.

Tâche CLN1-03 : Consolidation migrations

Fichier : scripts/squash_migrations.sh

#!/bin/bash
# Génère une baseline SQL à partir de toutes les migrations
OUT=veza-backend-api/migrations/baseline.sql
cat veza-backend-api/migrations/*.sql | grep -v '^--' > "$OUT"
echo "Baseline: $(wc -l < "$OUT") lines"

Fichier : docs/MIGRATIONS.md — documenter le processus, usage baseline.

Tâche CLN1-04 : Audit console.log

Commande : rg 'console\.log' apps/web/src --type-add 'ts:*.{ts,tsx}' -t ts -l

Remplacer par : import { logger } from '@/utils/logger' puis logger.debug(...).

Validation Sprint 4 :

cd veza-backend-api && go test ./internal/core/track/... -v
cd apps/web && npm run build

Commit Sprint 4 : refactor: split track handler and interceptors, add migration baseline script


Sprint 5 — Tests, Documentation (jours 23-27)

Tâche QA1-01 : Tests E2E commerce

Fichier : veza-backend-api/internal/integration/e2e_commerce_test.go

Flow : upload → achat → review → facture → remboursement (optionnel).

Tâche QA1-02 : Smoke test v0.601

Fichier : docs/SMOKE_TEST_V0601.md

Checklist :

  • Blue-green : bascule manuelle OK
  • Health : DB, Redis, RabbitMQ (degraded si un down)
  • Grafana : 3 dashboards chargent
  • Reviews : création, affichage, moyenne
  • Facture : téléchargement PDF
  • Remboursement : initiation refund
  • OAuth Discord : login
  • OAuth Spotify : login
  • track handler : < 500 LOC
  • interceptors : < 400 LOC par fichier

Tâche QA1-03 : Mise à jour docs

Fichiers :

  • docs/PROJECT_STATE.md — section v0.601 livrée
  • docs/FEATURE_STATUS.md — OAuth Discord/Spotify → opérationnel
  • CHANGELOG.md — section v0.601

Tâche QA1-04 : Archiver scope, placeholder v0.602

  • Déplacer V0_601_RELEASE_SCOPE.mddocs/archive/
  • Créer placeholder V0_602_RELEASE_SCOPE.md

Tâche QA1-05 : Rétrospective

Fichier : docs/RETROSPECTIVE_V0601.md

Commit Sprint 5 : docs(v0.601): smoke test, changelog, retrospective


Sprint 6 — Tag v0.601 (jours 28-30)

Tâche QA2-01 : Tag

git tag -a v0.601 -m "v0.601 — Production Readiness & Commerce"

Tâche QA2-02 : Mise à jour SCOPE_CONTROL

Fichier : docs/SCOPE_CONTROL.md — référence active → V0_602_RELEASE_SCOPE.md

Commit Sprint 6 : chore(release): tag v0.601


Commits récapitulatifs

Sprint Commit
1 feat(infra): blue-green deployment, Grafana dashboards, enriched health check, graceful shutdown
2 feat(commerce): product reviews, PDF invoices, refunds, Hyperswitch production mode
3 feat(auth): OAuth Discord and Spotify providers
4 refactor: split track handler and interceptors, add migration baseline script
5 docs(v0.601): smoke test, changelog, retrospective
6 chore(release): tag v0.601

Dépendances entre lots

INF1 (Infra)     → indépendant
COM1 (Commerce)  → indépendant
AUTH1 (OAuth)    → indépendant
CLN1 (Dette)     → indépendant (peut être fait en parallèle avec INF1/COM1/AUTH1)
QA1 (Tests)      → dépend de INF1, COM1, AUTH1, CLN1
QA2 (Tag)        → dépend de QA1

Risques et mitigations

Risque Mitigation
Stripe Connect / Payout complexe Reporté en v0.602, focus reviews/factures/remboursements
Génération PDF lourde Utiliser gofpdf, génération async si besoin
Blue-green 2x ressources Documenter option rolling si ressources limitées
OAuth quotas Discord/Spotify Documenter limites, rate limiting côté provider