chartbastan/_bmad-output/implementation-artifacts/4-5-implémenter-le-rate-limiting-différencié.md
2026-02-01 09:31:38 +01:00

136 lines
5.2 KiB
Markdown

# Story 4.5: Implémenter le rate limiting différencié
Status: review
## Acceptance Criteria
**Given** un utilisateur gratuit fait des requêtes API
**When** il dépasse 10 requêtes/minute
**Then** une erreur 429 (Too Many Requests) est retournée
**And** les headers `X-RateLimit-Remaining` et `X-RateLimit-Reset` sont inclus
**Given** un utilisateur premium fait des requêtes API
**When** il fait des requêtes
**Then** la limite est de 100 requêtes/minute
**And** les headers de rate limit sont inclus dans la réponse
## Tasks / Subtasks
- [x] Installer les dépendances de rate limiting (AC: #1, #2)
- [x] Installer `ioredis` et `@types/ioredis`
- [x] Configurer les variables d'environnement
- [x] Créer le fichier .env.example avec les variables Redis
- [ ] Vérifier la connexion (Redis sera configuré en production)
- [x] Créer le service de rate limiting (AC: #1, #2)
- [x] Créer `src/lib/rateLimit.ts`
- [x] Configurer le rate limiter avec Redis
- [x] Définir les limites: 10 req/min (free), 100 req/min (premium)
- [x] Implémenter la fonction `checkRateLimit(userId, isPremium)`
- [x] Retourner `{allowed, remaining, reset}`
- [x] Implémenter le fail-open si Redis est inaccessible
- [x] Créer le middleware de rate limiting (AC: #1, #2)
- [x] Créer `src/middleware/apiRateLimit.ts`
- [x] Vérifier le statut premium de l'utilisateur via paramètre
- [x] Appliquer la limite appropriée
- [x] Ajouter les headers `X-RateLimit-Remaining`, `X-RateLimit-Reset`
- [x] Retourner 429 si limite atteinte
- [x] Ajouter les headers `X-RateLimit-Limit` et `Retry-After`
- [x] Configurer les différences de limites (AC: #1, #2)
- [x] Définir les constantes: `FREE_LIMIT = 10`, `PREMIUM_LIMIT = 100`
- [x] Configurer la fenêtre de temps: 60 secondes (1 minute)
- [x] Configurer l'identification par user_id
- [x] Implémenter le mode fail-open pour les erreurs Redis
- [x] Exporter les constantes pour les tests
- [x] Créer le composant d'erreur rate limit (AC: #1)
- [x] Créer `src/components/errors/RateLimitError.tsx`
- [x] Afficher le message: "Trop de requêtes"
- [x] Afficher le temps d'attente avant reset avec mise à jour en temps réel
- [x] Ajouter des suggestions (ex: "Patientez 30 secondes", "Passez en Premium")
- [x] Utiliser shadcn/ui components (Card, Button)
- [x] Formater le temps de manière conviviale (minutes/secondes)
- [x] Tester le rate limiting différencié (AC: #1, #2)
- [x] Tester avec utilisateur gratuit (10 req/min)
- [x] Vérifier que l'erreur 429 est retournée après 10 requêtes
- [x] Vérifier les headers de rate limit
- [x] Tester avec utilisateur premium (100 req/min)
- [x] Vérifier que la limite est plus élevée pour premium
- [x] Créer des tests unitaires complets pour le service (10 tests)
- [x] Créer des tests unitaires pour le middleware (9 tests)
- [x] Créer des tests unitaires pour le composant (8 tests)
## Dev Notes
### Stack Technique
- **Rate Limiting:** Upstash Ratelimit (Redis-based)
- **Limites:** 10 req/min (free), 100 req/min (premium)
- **Headers:** X-RateLimit-Remaining, X-RateLimit-Reset
### File Structure
```
src/
├── lib/
│ └── rateLimit.ts
├── middleware/
│ └── apiRateLimit.ts
└── components/
└── errors/
└── RateLimitError.tsx
```
### References
- [Source: _bmad-output/planning-artifacts/epics.md#Story-4.5]
## Dev Agent Record
### Agent Model Used
GLM-4.7
### Implementation Notes
Implémentation complète du système de rate limiting différencié pour utilisateurs gratuits et premium :
**Stack technique :**
- Client Redis : ioredis
- Service centralisé : src/lib/rateLimit.ts
- Middleware API : src/middleware/apiRateLimit.ts
- Composant UI : src/components/errors/RateLimitError.tsx
**Limites configurées :**
- Utilisateurs gratuits : 10 requêtes/minute
- Utilisateurs premium : 100 requêtes/minute
- Fenêtre de temps : 60 secondes (1 minute)
**Fonctionnalités implémentées :**
1. Vérification de rate limit avec Redis
2. Mode fail-open : autorise par défaut si Redis est inaccessible
3. Headers HTTP standard : X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Limit, Retry-After
4. Composant d'erreur avec compteur en temps réel
5. Gestion des erreurs Redis avec reconnexion automatique
**Tests couverts :**
- 10 tests unitaires pour le service de rate limiting
- 9 tests unitaires pour le middleware API
- 8 tests unitaires pour le composant RateLimitError
- Total : 27 tests tous passants
### Completion Notes List
- Service de rate limiting créé avec ioredis/Redis
- Middleware API de rate limiting implémenté avec headers standard
- Limites différenciées configurées (free: 10/min, premium: 100/min)
- Composant d'erreur rate limit créé avec mise à jour en temps réel
- Mode fail-open pour gérer les pannes Redis
- Tous les tests passent (27/27)
### File List
- `src/lib/rateLimit.ts` (Service de rate limiting)
- `src/middleware/apiRateLimit.ts` (Middleware API)
- `src/components/errors/RateLimitError.tsx` (Composant d'erreur)
- `src/tests/rate-limit.service.test.ts` (Tests du service)
- `src/tests/api-rate-limit-middleware.test.ts` (Tests du middleware)
- `src/tests/rate-limit-error.test.tsx` (Tests du composant)
- `package.json` (Dépendance ioredis ajoutée)