veza/docs/PLAN_V0_601_IMPLEMENTATION.md
senke cdc4bd82e6 docs(v0.601): scope et plan d'implémentation
- V0_601_RELEASE_SCOPE.md: lots INF1, COM1, AUTH1, CLN1, QA1
- PLAN_V0_601_IMPLEMENTATION.md: 6 sprints, tâches détaillées, commits
- PROJECT_STATE.md: prochaine version v0.601
- FEATURE_STATUS.md: section Prévu en v0.601
- SCOPE_CONTROL.md: référence V0_601_RELEASE_SCOPE
2026-02-23 19:41:19 +01: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