# 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)
