feat(billing): TD-13 webhook idempotency + Stripe Customer Portal + doc cleanup

- Table stripe_webhook_events + helpers isEventProcessed/markEventProcessed
- POST /stripe/customer-portal (auth + stripe_customer_id check)
- ARCHITECTURE-backend.md: suppression POST /plans/upgrade (duplication doc)
- TD-13 fermé dans TECH_DEBT-backend.md
- Tests: 261 → 278 verts (+17)
This commit is contained in:
Hermann_Kitio 2026-04-26 04:15:46 +03:00
parent ec0598d122
commit 6671bac347
10 changed files with 891 additions and 324 deletions

View file

@ -72,6 +72,7 @@ Tier gratuit, déploiement automatique depuis GitHub.
### Pourquoi Supabase est conservé
Supabase fournit trois services critiques déjà en production :
- Authentification complète (email, OAuth Google/Apple, sessions JWT)
- Base de données PostgreSQL avec Row Level Security
- Stockage de fichiers (enregistrements audio EO)
@ -159,8 +160,8 @@ expria-backend/
│ │ ├── auth.ts # POST /auth/verify-token
│ │ ├── simulations.ts # POST /simulations, GET /simulations/:id
│ │ ├── corrections.ts # POST /corrections/ee, POST /corrections/eo
│ │ ├── plans.ts # GET /plans/status, POST /plans/upgrade
│ │ ├── stripe.ts # POST /stripe/checkout, POST /stripe/webhook
│ │ ├── plans.ts # GET /plans/status, POST /plans/upgrade-prorata
│ │ ├── stripe.ts # POST /stripe/checkout, /stripe/customer-portal, /stripe/webhook
│ │ └── t2live.ts # WebSocket /t2/live (T2 EO proxy Gemini)
│ ├── controllers/ # Logique métier (une par domaine)
│ │ ├── simulationController.ts
@ -292,11 +293,13 @@ USING (auth.uid() = user_id);
## 6. Routes API backend
### Authentification
```
POST /auth/verify-token Vérifie le JWT Supabase, retourne le profil + plan
```
### Simulations
```
POST /simulations Crée une simulation, vérifie les quotas selon le plan
GET /simulations/:id Récupère une simulation par ID
@ -304,25 +307,29 @@ GET /simulations Liste les simulations de l'utilisateur connec
```
### Corrections
```
POST /corrections/ee Soumet une production EE pour correction (DeepSeek)
POST /corrections/eo Soumet une production EO pour correction (Gemini)
```
### Plans
```
GET /plans/status Retourne le plan actuel + permissions de l'utilisateur
POST /plans/upgrade Crée une session Stripe Checkout (nouveau abonnement)
POST /plans/upgrade-prorata Upgrade en cours d'abonnement (prorata Stripe)
POST /plans/upgrade-prorata Upgrade en cours d'abonnement (prorata Stripe — preview du montant)
```
### Stripe
```
POST /stripe/checkout Crée une Checkout Session Stripe
POST /stripe/webhook Reçoit les events Stripe (checkout, invoice, deleted)
POST /stripe/checkout Crée une Checkout Session Stripe (nouveau abonnement)
POST /stripe/customer-portal Crée une Billing Portal Session (gestion abonnement self-service)
POST /stripe/webhook Reçoit les events Stripe (checkout, invoice, deleted) — idempotent (TD-13 résolu Sprint 5a)
```
### T2 EO Live
```
WS /t2/live WebSocket — proxy Gemini Live API (Premium uniquement)
```
@ -388,6 +395,7 @@ WS /t2/live WebSocket — proxy Gemini Live API (Premium
## 8. Variables d'environnement
### Frontend (.env)
```
VITE_API_URL=https://api.expria.app # URL du backend Render
VITE_SUPABASE_URL=https://xxx.supabase.co
@ -395,6 +403,7 @@ VITE_SUPABASE_ANON_KEY=xxx # Clé publique uniquement
```
### Backend (.env)
```
# Supabase
SUPABASE_URL=https://xxx.supabase.co
@ -481,29 +490,35 @@ npx wrangler pages deploy dist --project-name=expria
## 10. Règles de développement
### Règle 1 — Séparation stricte
Le frontend ne contient aucune logique métier.
Il appelle le backend et affiche ce qu'il reçoit.
Toute vérification de plan, de quota, de droit d'accès se fait côté backend.
### Règle 2 — Source de vérité unique des plans
`lib/access.ts` existe dans les deux dépôts (frontend et backend).
Le fichier doit être identique dans les deux.
Toute modification des plans tarifaires met à jour ce fichier en premier,
dans les deux dépôts, avant tout autre changement de code.
### Règle 3 — Jamais plus de 3 fichiers touchés par session Claude
Si une modification nécessite de toucher plus de 3 fichiers,
elle doit être découpée en plusieurs sessions avec validation intermédiaire.
### Règle 4 — Plan avant code
Claude Code ne commence jamais à coder sans avoir d'abord produit
un plan détaillé (fichiers impactés, risques, étapes).
Le plan est validé par Hermann avant l'exécution.
### Règle 5 — Tests manuels après chaque session
Après chaque session Claude Code, rejouer le golden dataset
(voir GOLDEN_DATASET.md) avant de passer à la session suivante.
### Règle 6 — Variables d'environnement
Aucune valeur de variable d'environnement n'est jamais écrite en dur dans le code.
Toujours lire depuis `process.env` (backend) ou `import.meta.env` (frontend).