mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
Refonte Structure
This commit is contained in:
116
knowledge/backend/risques/stripe.md
Normal file
116
knowledge/backend/risques/stripe.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Backend — Risques & vigilance : Stripe
|
||||
|
||||
> Extrait de la base de connaissance Lead_tech. Voir `knowledge/backend/risques/README.md` pour l'index complet.
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-stripe-current-period-end"></a>
|
||||
## Stripe (v17+) : confusion `billing_cycle_anchor` vs `current_period_end`
|
||||
|
||||
### Risques
|
||||
|
||||
- Stocker une date de fin de période incorrecte en DB (bug silencieux)
|
||||
- État d'abonnement incohérent (UI, relances, accès premium)
|
||||
|
||||
### Symptômes
|
||||
|
||||
- `currentPeriodEnd` correspond à une date "bizarre" (souvent proche de la création), ou à un jour du mois
|
||||
- Des accès premium expirent trop tôt / trop tard
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Ne jamais interpréter `billing_cycle_anchor` comme une date de fin de période
|
||||
- Utiliser `subscription.current_period_end` (timestamp) pour la fin de période courante
|
||||
- Ajouter un test sur un événement webhook/Subscription qui vérifie la date persistée
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-stripe-list-has-more"></a>
|
||||
## Stripe `list()` sans gestion de `has_more`
|
||||
|
||||
### Risques
|
||||
|
||||
- Pagination tronquée silencieusement
|
||||
- Réconciliation incomplète d'abonnements, achats ou moyens de paiement
|
||||
- Décisions métier prises sur un jeu de données partiel
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Comportement correct sur petits comptes mais faux sur comptes plus chargés
|
||||
- Premiers éléments traités, les suivants ignorés
|
||||
- Absence de boucle de pagination ou d'auto-pagination
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Traiter explicitement `has_more`
|
||||
- Utiliser l'auto-pagination Stripe si adaptée
|
||||
- Tester au moins un cas avec plusieurs pages de résultats
|
||||
- Contexte technique : Stripe API — 10-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-trial-payant-concurrence"></a>
|
||||
## Concurrence entre activation locale et webhook sur transition trial → payant
|
||||
|
||||
### Risques
|
||||
|
||||
- Double création ou double attachement d'une ressource unique
|
||||
- Conflit `P2002`
|
||||
- État local différent de l'état Stripe pendant la transition
|
||||
|
||||
### Symptômes
|
||||
|
||||
- La transition fonctionne parfois, puis échoue aléatoirement
|
||||
- Un webhook Stripe et une action applicative écrivent la même mutation métier
|
||||
- Erreurs d'unicité lors de l'activation payante
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Définir une seule source autorisée pour chaque transition d'état
|
||||
- Rendre les écritures idempotentes
|
||||
- Sérialiser ou réconcilier explicitement les transitions pilotées à la fois par action utilisateur et webhook
|
||||
- Contexte technique : Stripe / Prisma / trial subscription — 10-03-2026
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-non-idempotence"></a>
|
||||
## Non-idempotence sur opérations sensibles
|
||||
|
||||
### Risques
|
||||
|
||||
- Doubles paiements / doubles créations
|
||||
- Webhooks rejoués qui cassent l'état
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Doublons de lignes en DB
|
||||
- Actions exécutées 2 fois après timeout/retry
|
||||
- Incidents difficiles à reproduire
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Idempotency key sur endpoints critiques
|
||||
- Protection anti-doublon côté DB (contraintes uniques)
|
||||
- Comportement défini en cas de retry
|
||||
|
||||
---
|
||||
|
||||
<a id="risque-webhook-200-processing"></a>
|
||||
## Webhooks entrants — répondre 200 pendant `processing` (event perdu)
|
||||
|
||||
### Risques
|
||||
|
||||
- Le provider (Stripe, etc.) arrête ses retries après un 2xx, même si le premier worker a échoué
|
||||
- Event non appliqué mais marqué "traité" → état incohérent silencieux
|
||||
|
||||
### Symptômes
|
||||
|
||||
- Webhook reçu, 200 retourné, mais l'état en base n'est pas mis à jour
|
||||
- Aucun retry du provider → impossible à détecter sans monitoring actif
|
||||
|
||||
### Bonnes pratiques / mitigations
|
||||
|
||||
- Lock DB (`WebhookEvent`) avec machine d'état : `pending` → `processing` → `processed` / `failed`
|
||||
- Si `processing` détecté (concurrent) : attendre brièvement la transition `processed`, sinon répondre **non-2xx** (force retry provider)
|
||||
- Ne jamais passer à `processed` sans preuve d'un traitement effectif
|
||||
- Contexte technique : Stripe / NestJS — 09-03-2026
|
||||
Reference in New Issue
Block a user