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:
parent
ec0598d122
commit
6671bac347
10 changed files with 891 additions and 324 deletions
|
|
@ -6,6 +6,34 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/).
|
|||
|
||||
---
|
||||
|
||||
## [Unreleased] — 2026-04-26 — Sprint 5a — Backend billing cleanup
|
||||
|
||||
### Added
|
||||
|
||||
- `supabase/migrations/007_sprint_5a_stripe_webhook_events.sql` — table `stripe_webhook_events(id TEXT PRIMARY KEY, processed_at TIMESTAMPTZ NOT NULL DEFAULT NOW())` + index sur `processed_at`. Idempotente (`CREATE TABLE IF NOT EXISTS`).
|
||||
- `src/lib/stripeWebhookEvents.ts` — helpers `isEventProcessed` / `markEventProcessed` (insert idempotent, conflit unique `23505` avalé silencieusement).
|
||||
- `src/lib/__tests__/stripeWebhookEvents.test.ts` — 8 tests (lecture, écriture, edge cases vide/erreur DB).
|
||||
- `src/lib/__tests__/createBillingPortalSession.test.ts` — 4 tests (succès, customerId vide, returnUrl vide, URL Stripe vide).
|
||||
- `POST /stripe/customer-portal` — endpoint authentifié qui crée une Stripe Billing Portal Session (gestion abonnement self-service) et redirige l'utilisateur. 400 `NO_ACTIVE_SUBSCRIPTION` si pas de `stripe_customer_id` ; return_url = `${APP_URL}/dashboard`.
|
||||
|
||||
### Changed
|
||||
|
||||
- `POST /stripe/webhook` — déduplication explicite des events Stripe (TD-13 résolu) : check `isEventProcessed(event.id)` avant traitement → early return `200 { received: true, replayed: true }` ; `markEventProcessed` après succès uniquement (pas si exception, pour permettre rejeu Stripe).
|
||||
- `src/lib/stripe.ts` — nouvelle fonction `createBillingPortalSession({ customerId, returnUrl })` (mirror de `createCheckoutSession`).
|
||||
- `src/routes/__tests__/stripe.test.ts` — 5 nouveaux tests (2 idempotency webhook + 3 customer-portal route).
|
||||
- `docs/ARCHITECTURE-backend.md` — §3 commentaire `plans.ts` corrigé (`POST /plans/upgrade-prorata` au lieu de `POST /plans/upgrade` qui n'existait pas) ; §6 retrait de la ligne dupliquée `POST /plans/upgrade` (la création d'abonnement passe par `POST /stripe/checkout`) ; §6 ajout `POST /stripe/customer-portal`.
|
||||
|
||||
### Resolved
|
||||
|
||||
- **TD-13 🔴 → Résolu** : Webhook Stripe idempotent (table `stripe_webhook_events` + helpers + wiring route + 10 tests).
|
||||
|
||||
### Notes
|
||||
|
||||
- Tests : 261 → 278 verts (+17).
|
||||
- Aucun changement frontend dans ce sprint — Sprint 5b (frontend billing) à venir.
|
||||
|
||||
---
|
||||
|
||||
## [Unreleased] — 2026-04-26 — Sprint 4.8 — Phonologie EO
|
||||
|
||||
### Added
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue