veza/docs/archive/v0-history/PLAN_V0_602_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.602 — Payout, Dette Technique & Tests E2E

Date : 2026-02-22 Base : v0.601 taguée Durée estimée : 5 sprints (~25 jours ouvrés) Référence : V0_602_RELEASE_SCOPE.md


Vue d'ensemble

Sprint 1 (j1-5)   → CLN2 : Split interceptors (auth, error)
Sprint 2 (j6-12)  → P3 : Payout vendeurs (Stripe Connect)
Sprint 3 (j13-17) → INF2 : Dashboards Grafana métriques réelles
Sprint 4 (j18-22) → QA2 : Tests E2E commerce, smoke test
Sprint 5 (j23-25) → Docs, rétrospective, tag v0.602

Diagramme d'architecture cible

flowchart TD
    subgraph Seller["Seller Flow"]
        Onboard["Stripe Connect Onboard"]
        Balance["GET /sell/balance"]
        Transfer["Transfer after sale"]
    end

    subgraph Interceptors["API Interceptors"]
        Auth["auth.ts - token refresh"]
        Error["error.ts - error handling"]
        Request["request.ts"]
        Response["response.ts"]
    end

    subgraph Monitor["Monitoring"]
        Grafana["Grafana - métriques réelles"]
    end

    Seller --> Onboard
    Onboard --> Balance
    Balance --> Transfer
    Auth --> Error

Sprint 1 — Split interceptors (jours 1-5)

Objectif : Extraire auth.ts et error.ts, réduire interceptors.ts à une facade.

Tâche CLN2-01 : Extraire auth interceptor

Fichier nouveau : apps/web/src/services/api/interceptors/auth.ts

  • Déplacer : isRefreshing, refreshAttempts, MAX_REFRESH_ATTEMPTS, failedQueue, processQueue
  • Logique token refresh : détection 401, appel refreshToken, mise en queue des requêtes en attente
  • Exporter : createAuthRequestInterceptor, createAuthResponseInterceptor (ou équivalent)

Fichier : apps/web/src/services/api/interceptors.ts

  • Importer depuis auth.ts, supprimer le code déplacé

Commit : refactor(api): extract auth interceptor to interceptors/auth.ts

Tâche CLN2-02 : Extraire error interceptor

Fichier nouveau : apps/web/src/services/api/interceptors/error.ts

  • Déplacer : gestion AxiosError, parseApiError, getErrorCategory, formatUserFriendlyError
  • Logique retry : isRetryableError, getRetryDelay, networkFailureTracker
  • Toast, offline queue, rate limit store
  • Exporter : createErrorResponseHandler(apiClient)

Fichier : apps/web/src/services/api/interceptors.ts

  • Importer depuis error.ts, supprimer le code déplacé

Commit : refactor(api): extract error interceptor to interceptors/error.ts

Tâche CLN2-03 : Réduire interceptors.ts à facade

Fichier : apps/web/src/services/api/interceptors.ts

  • Garder uniquement : imports des 5 modules (utils, request, response, auth, error)
  • Composition : apiClient.interceptors.request.use(...), apiClient.interceptors.response.use(...)
  • Objectif : < 80 LOC

Fichier : apps/web/src/services/api/interceptors/index.ts (créer si absent)

  • Re-exporter les modules pour usage externe

Commit : refactor(api): reduce interceptors.ts to facade, add interceptors/index.ts

Tâche CLN2-04 : Validation

cd apps/web && npm run build
cd apps/web && npm test -- --run
rg '\.ts$' apps/web/src/services/api/interceptors/ -l | xargs wc -l
  • Chaque fichier interceptors < 400 LOC
  • Aucune régression

Commit : test(api): validate interceptors split, all tests pass


Sprint 2 — Payout vendeurs (jours 6-12)

Objectif : Stripe Connect onboarding, balance, transfert après vente.

Tâche P3-01 : Config Stripe Connect

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

StripeConnectClientID     string // STRIPE_CONNECT_CLIENT_ID
StripeConnectSecret       string // STRIPE_CONNECT_SECRET
StripeConnectWebhookSecret string // STRIPE_CONNECT_WEBHOOK_SECRET

Fichier : .env.example — documenter les variables

Commit : feat(seller): add Stripe Connect config

Tâche P3-02 : Migration seller_stripe_accounts

Fichier : veza-backend-api/migrations/114_seller_stripe_accounts.sql

CREATE TABLE IF NOT EXISTS seller_stripe_accounts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE UNIQUE,
    stripe_account_id VARCHAR(255) NOT NULL UNIQUE,
    onboarding_completed BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_seller_stripe_accounts_user ON seller_stripe_accounts(user_id);

Commit : feat(seller): add seller_stripe_accounts migration

Tâche P3-03 : POST /sell/connect/onboard

Fichier : veza-backend-api/internal/handlers/sell_handler.go (ou créer)

  • Handler ConnectOnboard : vérifier user vendeur, créer lien Stripe Express, redirect URL
  • Route : POST /api/v1/sell/connect/onboard
  • Callback : GET /api/v1/sell/connect/callback — traiter retour Stripe, sauvegarder account_id

Commit : feat(seller): add Stripe Connect onboarding endpoint

Tâche P3-04 : GET /sell/balance

Fichier : veza-backend-api/internal/services/stripe_connect_service.go (ou sell_service.go)

  • GetSellerBalance(userID) : appeler Stripe API Balance, ou table locale si cache
  • Handler : GET /api/v1/sell/balance — retourne { available, pending }

Commit : feat(seller): add balance endpoint

Tâche P3-05 : Transfert après vente

Fichier : veza-backend-api/internal/services/hyperswitch/ ou stripe_connect_service.go

  • Sur webhook payment.succeeded (ou post-order) : récupérer transfer_data.destination
  • Si vendeur a compte Connect : initier transfer vers son compte
  • Alternative MVP : ne pas implémenter transfert auto, documenter pour v0.603

Commit : feat(seller): add payout transfer on sale (ou feat(seller): document payout transfer for v0.603 si MVP)

Tâche P3-06 : SellerDashboardView — balance, onboarding

Fichier : apps/web/src/features/seller/SellerDashboardView.tsx

  • Carte balance : afficher available, pending (ou message "Configurez les paiements")
  • Bouton « Configurer les paiements » : appelle POST /sell/connect/onboard, redirect Stripe

Fichier : apps/web/src/services/marketplaceService.tsgetSellerBalance(), connectOnboard()

Commit : feat(seller): add balance and onboarding UI to SellerDashboard

Tâche P3-07 : MSW + Stories

Fichier : apps/web/src/mocks/handlers.ts — handlers balance, onboard redirect

Stories : SellerBalanceCard, SellerOnboardingButton

Commit : test(seller): add MSW handlers and stories for payout


Sprint 3 — Dashboards Grafana (jours 13-17)

Objectif : Connecter les dashboards aux métriques Prometheus réelles.

Tâche INF2-04 : Vérifier exposition métriques backend

Fichier : veza-backend-api/internal/middleware/ — prometheus, metrics

  • Vérifier : http_requests_total, http_request_duration_seconds, http_requests_errors
  • Labels : method, path, status
  • Ajouter si manquant

Commit : feat(monitoring): ensure Prometheus metrics exposed for API

Tâche INF2-01 : API dashboard

Fichier : config/grafana/dashboards/api-overview.json

  • Panels : rate(http_requests_total[5m]), histogram_quantile(0.95, http_request_duration_seconds), error rate
  • Top endpoints par volume

Commit : feat(monitoring): connect API dashboard to real Prometheus metrics

Tâche INF2-02 : Chat dashboard

Fichier : config/grafana/dashboards/chat-overview.json

  • Panels : connexions WS actives (si métrique existe), messages/s
  • Vérifier métriques chat dans backend Go

Commit : feat(monitoring): connect Chat dashboard to real metrics

Tâche INF2-03 : Commerce dashboard

Fichier : config/grafana/dashboards/commerce-overview.json

  • Panels : orders créés, checkout success, refunds
  • Métriques à exposer si manquantes : commerce_orders_total, commerce_checkout_success_total

Commit : feat(monitoring): connect Commerce dashboard to real metrics


Sprint 4 — Tests E2E (jours 18-22)

Objectif : E2E commerce, smoke test v0.602.

Tâche QA2-01 : E2E commerce

Option A : veza-backend-api/internal/integration/e2e_commerce_test.go

  • Flow : créer produit (ou utiliser fixture) → checkout (mock Hyperswitch) → review → invoice download
  • Utiliser testify, appels HTTP réels

Option B : Playwright apps/web/e2e/commerce.spec.ts

  • Flow : login → marketplace → achat (mock) → review → téléchargement facture

Commit : test(commerce): add E2E flow upload-achat-review-facture

Tâche QA2-02 : Smoke test v0.602

Fichier : docs/SMOKE_TEST_V0602.md

Checklist :

  • Payout : onboarding Stripe Connect, balance affichée
  • Interceptors : auth.ts, error.ts extraits, build OK
  • Grafana : 3 dashboards chargent métriques
  • Commerce : achat, review, facture, remboursement
  • OAuth : Discord, Spotify login

Commit : docs: add SMOKE_TEST_V0602.md

Tâche QA2-03 : Mise à jour docs

Fichiers :

  • docs/PROJECT_STATE.md — section v0.602 livrée
  • docs/FEATURE_STATUS.md — P3 Payout → opérationnel
  • CHANGELOG.md — section v0.602

Commit : docs: update PROJECT_STATE, FEATURE_STATUS, CHANGELOG for v0.602


Sprint 5 — Finalisation (jours 23-25)

Objectif : Archiver scope, rétrospective, tag.

Tâche QA2-04 : Archive, placeholder, rétro, tag

  1. Déplacer V0_602_RELEASE_SCOPE.mddocs/archive/
  2. Créer placeholder V0_603_RELEASE_SCOPE.md
  3. Créer docs/RETROSPECTIVE_V0602.md
  4. Mettre à jour docs/SCOPE_CONTROL.md — référence active → V0_603
  5. Tag : git tag -a v0.602 -m "v0.602 — Payout, Dette Technique & Tests E2E"

Commits :

  • chore(release): archive v0.602 scope, create v0.603 placeholder
  • docs: add RETROSPECTIVE_V0602.md
  • chore(release): tag v0.602

Commits récapitulatifs (ordre d'exécution)

# Sprint Commit
1 1 refactor(api): extract auth interceptor to interceptors/auth.ts
2 1 refactor(api): extract error interceptor to interceptors/error.ts
3 1 refactor(api): reduce interceptors.ts to facade, add interceptors/index.ts
4 1 test(api): validate interceptors split, all tests pass
5 2 feat(seller): add Stripe Connect config
6 2 feat(seller): add seller_stripe_accounts migration
7 2 feat(seller): add Stripe Connect onboarding endpoint
8 2 feat(seller): add balance endpoint
9 2 feat(seller): add payout transfer on sale
10 2 feat(seller): add balance and onboarding UI to SellerDashboard
11 2 test(seller): add MSW handlers and stories for payout
12 3 feat(monitoring): ensure Prometheus metrics exposed for API
13 3 feat(monitoring): connect API dashboard to real Prometheus metrics
14 3 feat(monitoring): connect Chat dashboard to real metrics
15 3 feat(monitoring): connect Commerce dashboard to real metrics
16 4 test(commerce): add E2E flow upload-achat-review-facture
17 4 docs: add SMOKE_TEST_V0602.md
18 4 docs: update PROJECT_STATE, FEATURE_STATUS, CHANGELOG for v0.602
19 5 chore(release): archive v0.602 scope, create v0.603 placeholder
20 5 docs: add RETROSPECTIVE_V0602.md
21 5 chore(release): tag v0.602

Dépendances entre lots

CLN2 (Interceptors) → indépendant (peut démarrer immédiatement)
P3 (Payout)         → indépendant
INF2 (Grafana)      → peut nécessiter P3 métriques commerce
QA2 (Tests)         → dépend de CLN2, P3, INF2
Sprint 5            → dépend de QA2

Risques et mitigations

Risque Mitigation
Stripe Connect complexité MVP balance seule, transfert reporté v0.603
Hyperswitch vs Stripe Vérifier doc Hyperswitch Connect ; Stripe si Hyperswitch non supporté
Métriques backend absentes Tâche INF2-04 en premier ; ajouter middleware si besoin
E2E flaky Utiliser mocks Hyperswitch ; éviter dépendances externes