veza/docs/PLAN_V0_602_IMPLEMENTATION.md
senke 83ed4f315b
Some checks failed
Backend API CI / test-unit (push) Failing after 0s
Backend API CI / test-integration (push) Failing after 0s
Frontend CI / test (push) Failing after 0s
Storybook Audit / Build & audit Storybook (push) Failing after 0s
chore(release): v0.602 — Payout, Dette Technique & Tests E2E
- Stripe Connect: onboarding, balance, SellerDashboardView
- Interceptors: auth.ts, error.ts extracted, facade
- Grafana: dashboards enriched (p50, top endpoints, 4xx, WS, commerce)
- E2E commerce: product->order->review->invoice
- SMOKE_TEST_V0602, RETROSPECTIVE_V0602, PAYOUT_MANUAL
- Archive V0_602 scope, V0_603 placeholder, SCOPE_CONTROL v0.603
- Fix sanitizer regex (Go no backreferences)
- Marketplace test schema: product_licenses, product_images, orders, licenses
2026-02-23 22:32:01 +01:00

349 lines
12 KiB
Markdown

# 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](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
```mermaid
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
```bash
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`
```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`
```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.ts` `getSellerBalance()`, `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.md` `docs/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 |