143 lines
6.2 KiB
Markdown
143 lines
6.2 KiB
Markdown
# Story 4.4: Implémenter la gestion des limites de prédictions
|
|
|
|
Status: review
|
|
|
|
## Acceptance Criteria
|
|
|
|
**Given** un utilisateur gratuit consulte une prédiction
|
|
**When** il accède à une prédiction
|
|
**Then** le système vérifie son quota quotidien (1-2 prédictions/jour)
|
|
**And** si le quota n'est pas dépassé, la prédiction est affichée
|
|
**And** le compteur de prédictions consultées est incrémenté
|
|
|
|
**Given** un utilisateur gratuit a atteint sa limite
|
|
**When** il tente de consulter une prédiction supplémentaire
|
|
**Then** un message indique qu'il a atteint sa limite
|
|
**And** une option pour passer à Premium est proposée
|
|
**And** la prédiction n'est pas affichée
|
|
|
|
**Given** un utilisateur premium consulte des prédictions
|
|
**When** il accède à des prédictions
|
|
**Then** aucune limite n'est appliquée
|
|
**And** toutes les prédictions sont accessibles
|
|
|
|
## Tasks / Subtasks
|
|
|
|
- [x] Mettre à jour le schéma utilisateur pour le tracking des limites (AC: #1)
|
|
- [x] Ajouter la colonne `daily_predictions_count` à `users`
|
|
- [x] Ajouter la colonne `last_prediction_date` à `users`
|
|
- [x] Générer et appliquer les migrations
|
|
- [x] Mettre à jour les types TypeScript
|
|
|
|
- [x] Créer le service de vérification des limites (AC: #1)
|
|
- [x] Créer `src/services/limitService.ts`
|
|
- [x] Implémenter `checkFreeUserLimit(userId)`
|
|
- [x] Implémenter `incrementDailyCount(userId)`
|
|
- [x] Implémenter `resetDailyCount()` (cron ou à minuit)
|
|
- [x] Retourner `allowed`, `remaining`, `limit`
|
|
|
|
- [x] Créer le middleware de limitation (AC: #1, #2)
|
|
- [x] Créer `src/middleware/rateLimit.ts`
|
|
- [x] Vérifier le statut premium
|
|
- [x] Vérifier le quota quotidien pour les utilisateurs gratuits
|
|
- [x] Bloquer l'accès si limite atteinte
|
|
- [x] Retourner 429 si limite atteinte
|
|
|
|
- [x] Créer un composant de limite atteinte (AC: #2)
|
|
- [x] Créer `src/components/limits/LimitReached.tsx`
|
|
- [x] Afficher le message: "Limite de prédictions atteinte"
|
|
- [x] Afficher le compteur (ex: "1/2 prédictions utilisées")
|
|
- [x] Ajouter bouton "Passer à Premium"
|
|
- [x] Utiliser shadcn/ui components
|
|
|
|
- [x] Créer le composant de compteur de prédictions (AC: #1)
|
|
- [x] Créer `src/components/limits/PredictionCounter.tsx`
|
|
- [x] Afficher les prédictions restantes
|
|
- [x] Afficher le quota (ex: "1/2")
|
|
- [x] Mettre à jour en temps réel
|
|
- [x] Ne pas afficher pour les utilisateurs premium
|
|
|
|
- [x] Configurer le reset quotidien des limites (AC: #1)
|
|
- [x] Créer un cron job ou endpoint `/api/limits/reset`
|
|
- [x] Réinitialiser `daily_predictions_count` à 0
|
|
- [x] Mettre à jour `last_prediction_date`
|
|
- [x] Logger les resets
|
|
- [x] Tester le reset à minuit
|
|
|
|
- [x] Tester la gestion des limites (AC: #1, #2, #3)
|
|
- [x] Tester avec utilisateur gratuit (1-2 prédictions)
|
|
- [x] Tester quand la limite est atteinte
|
|
- [x] Tester avec utilisateur premium (illimité)
|
|
- [x] Vérifier que le reset quotidien fonctionne
|
|
- [x] Vérifier que le compteur est mis à jour
|
|
|
|
## Dev Notes
|
|
|
|
### Stack Technique
|
|
- **Limites:** 1-2 prédictions/jour (free), illimité (premium)
|
|
- **Cron:** Vercel Cron ou node-cron
|
|
- **State:** Zustand + React Query
|
|
|
|
### File Structure
|
|
```
|
|
src/
|
|
├── services/
|
|
│ └── limitService.ts
|
|
├── middleware/
|
|
│ └── rateLimit.ts
|
|
├── components/
|
|
│ └── limits/
|
|
│ ├── LimitReached.tsx
|
|
│ └── PredictionCounter.tsx
|
|
└── app/
|
|
└── api/
|
|
└── limits/
|
|
└── reset/route.ts
|
|
```
|
|
|
|
### References
|
|
- [Source: _bmad-output/planning-artifacts/epics.md#Story-4.4]
|
|
|
|
## Dev Agent Record
|
|
|
|
### Agent Model Used
|
|
GLM-4.7
|
|
|
|
### Completion Notes List
|
|
- Schéma utilisateur mis à jour avec colonnes daily_predictions_count et last_prediction_date
|
|
- Migration générée (0003_cheerful_true_believers.sql) et appliquée à la base de données
|
|
- Types TypeScript automatiquement mis à jour par Drizzle ORM
|
|
- Service de vérification des limites créé avec checkFreeUserLimit(), incrementDailyCount(), resetDailyCount()
|
|
- Middleware de limitation implémenté avec vérification du statut premium et du quota quotidien
|
|
- Composant LimitReached créé avec design shadcn/ui, affichage du compteur et bouton "Passer à Premium"
|
|
- Composant PredictionCounter créé, affiche les prédictions restantes, ne s'affiche pas pour les utilisateurs premium
|
|
- API endpoint /api/limits/reset créé pour réinitialiser les limites quotidiennes
|
|
- Tests complets: 50 tests passants pour la gestion des limites (schéma, service, middleware, composants, API, intégration)
|
|
|
|
### File List
|
|
- `src/db/schema.ts` - Schéma utilisateur mis à jour avec daily_predictions_count et last_prediction_date
|
|
- `drizzle/migrations/0003_cheerful_true_believers.sql` - Migration générée
|
|
- `src/services/limitService.ts` - Service de vérification des limites
|
|
- `src/middleware/rateLimit.ts` - Middleware de limitation des prédictions
|
|
- `src/components/limits/LimitReached.tsx` - Composant de limite atteinte
|
|
- `src/components/limits/PredictionCounter.tsx` - Composant de compteur de prédictions
|
|
- `src/app/api/limits/reset/route.ts` - API endpoint pour reset quotidien
|
|
- `src/tests/limits-schema.test.ts` - Tests du schéma (8 tests)
|
|
- `src/tests/limit-service-real.test.ts` - Tests du service (8 tests)
|
|
- `src/tests/rate-limit-middleware.test.ts` - Tests du middleware (6 tests)
|
|
- `src/tests/limit-reached.test.tsx` - Tests du composant LimitReached (6 tests)
|
|
- `src/tests/prediction-counter.test.tsx` - Tests du composant PredictionCounter (6 tests)
|
|
- `src/tests/limits-reset-api.test.ts` - Tests de l'API reset (5 tests)
|
|
- `src/tests/limits-integration.test.ts` - Tests d'intégration (11 tests)
|
|
|
|
## Change Log
|
|
- 2026-01-17: Implémentation complète de la gestion des limites de prédictions
|
|
- Ajouté les colonnes daily_predictions_count et last_prediction_date au schéma utilisateur
|
|
- Créé le service limitService.ts avec les fonctions checkFreeUserLimit, incrementDailyCount, resetDailyCount
|
|
- Créé le middleware rateLimit.ts pour vérifier et bloquer les utilisateurs gratuits
|
|
- Créé les composants LimitReached.tsx et PredictionCounter.tsx
|
|
- Créé l'endpoint /api/limits/reset pour le reset quotidien
|
|
- 50 tests d'unité et d'intégration écrits et passants
|
|
- Tous les critères d'acceptation satisfaits
|
|
- Aucune régression détectée
|