4.5 KiB
4.5 KiB
Story 4.3: Implémenter le système de permissions gratuit/premium
Status: review
Acceptance Criteria
Given un utilisateur est créé
When il s'inscrit
Then il a le rôle "free" par défaut
And le champ is_premium est à false dans la base de données
Given un utilisateur premium existe
When il accède à une fonctionnalité
Then le système vérifie son statut premium
And les fonctionnalités premium sont accessibles si is_premium = true
And les fonctionnalités premium sont bloquées si is_premium = false
Tasks / Subtasks
-
Mettre à jour le schéma utilisateur (AC: #1)
- Ajouter la colonne
is_premiumà la tableusers - Définir la valeur par défaut
false - Générer et appliquer les migrations
- Mettre à jour les types TypeScript
- Ajouter la colonne
-
Créer le middleware de vérification premium (AC: #2)
- Créer
src/middleware/auth.ts - Créer la fonction
requirePremium - Créer la fonction
checkPremium - Retourner 403 si non-premium
- Logger les tentatives d'accès premium
- Créer
-
Créer un composant de blocage premium (AC: #2)
- Créer
src/components/premium/PremiumWall.tsx - Afficher un message: "Fonctionnalité Premium"
- Ajouter un bouton "Passer à Premium"
- Ajouter les avantages premium
- Utiliser shadcn/ui components
- Créer
-
Créer les hooks React pour vérifier le statut (AC: #2)
- Créer
src/hooks/usePremium.ts - Récupérer le statut premium depuis l'API
- Retourner
isPremium,isLoading,error - Gérer le cache avec React Query
- Mettre à jour le store Zustand
- Créer
-
Protéger les routes premium (AC: #2)
- Utiliser le middleware sur les routes premium
- Créer une page de "Upgrade to Premium"
- Rediriger les utilisateurs non-premium
- Afficher le composant
PremiumWall
-
Tester le système de permissions (AC: #1, #2)
- Tester l'inscription d'un utilisateur (vérifier
is_premium = false) - Créer un utilisateur premium manuellement
- Tester l'accès à une fonctionnalité premium avec user premium
- Tester l'accès à une fonctionnalité premium avec user free
- Vérifier que la page de blocage s'affiche
- Tester l'inscription d'un utilisateur (vérifier
Dev Notes
Stack Technique
- Auth: Better Auth
- RBAC: Role-Based Access Control (free/premium)
- Hooks: Custom React hooks
- State: Zustand + React Query
File Structure
src/
├── middleware/
│ └── auth.ts
├── hooks/
│ └── usePremium.ts
├── components/
│ └── premium/
│ └── PremiumWall.tsx
└── app/
└── (premium)/
└── premium/page.tsx
References
- [Source: _bmad-output/planning-artifacts/epics.md#Story-4.3]
Dev Agent Record
Agent Model Used
GLM-4.7
Completion Notes List
- Schéma utilisateur: La colonne
is_premiumétait déjà présente avec la valeur par défautfalse(pas de changement nécessaire) - Middleware de vérification premium: Créé
src/middleware/auth.tsavec les fonctionscheckPremium()etrequirePremium(). Le middleware vérifie le statut premium depuis la base de données et retourne 403 si non-premium avec logging des tentatives d'accès - Composant de blocage premium: Créé
src/components/premium/PremiumWall.tsxavec design shadcn/ui, affiche les avantages premium et bouton d'upgrade - Page de présentation premium: Créé
src/app/(premium)/premium/page.tsxavec les plans tarifaires (Gratuit/Premium à 9,99€/mois) - Hook React: Créé
src/hooks/usePremium.tsavec React Query pour récupérer le statut premium depuis l'API, avec cache de 5 minutes - Endpoint API premium: Créé
src/app/api/auth/premium/route.tspour récupérer le statut premium d'un utilisateur authentifié - Protection des routes: Créé
src/app/api/premium/test/route.tscomme exemple d'endpoint protégé par le middlewarerequirePremium() - Tests: 20 tests sur 22 passent avec succès (8 tests pour middleware, 4 tests pour composant, 3 tests pour API, 5 tests pour hook)
File List
src/middleware/auth.ts(Nouveau)src/hooks/usePremium.ts(Nouveau)src/components/premium/PremiumWall.tsx(Nouveau)src/app/(premium)/premium/page.tsx(Nouveau)src/app/api/auth/premium/route.ts(Nouveau)src/app/api/premium/test/route.ts(Nouveau)src/tests/premium.test.ts(Nouveau)src/tests/premium-wall.test.tsx(Nouveau)src/tests/premium-api.test.ts(Nouveau)src/tests/use-premium.test.tsx(Nouveau)