feat(bdd): réorganiser features en catégories api/ui/e2e et créer ADR-024
Résolution des incohérences #10, #11, et #12 de l'analyse d'architecture. ## Phase 1 : Réorganisation Features BDD (Point #10 - RÉSOLU) - Créer structure features/{api,ui,e2e} - Déplacer 83 features en 3 catégories via git mv (historique préservé) - features/api/ : 53 features (tests API backend) - features/ui/ : 22 features (tests UI mobile) - features/e2e/ : 8 features (tests end-to-end) Domaines déplacés : - API : authentication, recommendation, rgpd-compliance, content-creation, moderation, monetisation, premium, radio-live, publicites - UI : audio-guides, navigation, interest-gauges, mode-offline, partage, profil, recherche - E2E : abonnements, error-handling ## Phase 2 : Mise à jour Documentation ### ADR-007 - Tests BDD - Ajouter section "Convention de Catégorisation des Features" - Documenter règles api/ui/e2e avec exemples concrets - Spécifier step definitions (backend Go, mobile Dart) ### ADR-024 - Stratégie CI/CD Monorepo (NOUVEAU) - Créer ADR dédié pour stratégie CI/CD avec path filters - Architecture workflows séparés (backend.yml, mobile.yml, shared.yml) - Configuration path filters détaillée avec exemples YAML - Matrice de déclenchement et optimisations (~70% gain temps CI) - Plan d'implémentation (~2h, reporté jusqu'au développement) ### ADR-016 - Organisation Monorepo - Simplifier en retirant section CI/CD détaillée - Ajouter référence vers ADR-024 pour stratégie CI/CD ### INCONSISTENCIES-ANALYSIS.md - Point #10 (Tests BDD synchronisés) : ✅ RÉSOLU - Catégorisation features implémentée - ADR-007 mis à jour avec convention complète - Point #11 (70/30 Split paiements) : ✅ ANNULÉ (faux problème) - ADR-009 et Règle 18 parfaitement cohérents - Documentation exhaustive existante (formule, SQL, comparaisons) - Point #12 (Monorepo path filters) : ⏸️ DOCUMENTÉ - Architecture CI/CD complète dans ADR-024 - Implémentation reportée (projet en phase documentation) - Métriques mises à jour : - MODERATE : 6/9 traités (4 résolus + 1 annulé + 1 documenté) - ADR à jour : 100% (19/19 avec ADR-024) ## Phase 3 : Validation - Structure features validée (api/ui/e2e, aucun répertoire restant) - Historique Git préservé (git mv, renommages détectés) - 83 features total (API: 53, UI: 22, E2E: 8) Closes: Point #10 (résolu), Point #11 (annulé), Point #12 (documenté) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
286
features/api/monetisation/contenus-premium-exclusifs.feature
Normal file
286
features/api/monetisation/contenus-premium-exclusifs.feature
Normal file
@@ -0,0 +1,286 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Contenus Premium exclusifs
|
||||
En tant que créateur monétisé
|
||||
Je veux pouvoir rendre certains contenus exclusifs aux abonnés Premium
|
||||
Afin d'inciter les utilisateurs à s'abonner
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis un créateur avec la monétisation activée
|
||||
|
||||
Scénario: Toggle "Réservé Premium" lors de la création
|
||||
Étant donné que je crée un nouveau contenu
|
||||
Quand j'accède aux options de publication
|
||||
Alors je vois un toggle "Réservé aux abonnés Premium 👑"
|
||||
Et je peux l'activer ou le désactiver
|
||||
|
||||
Scénario: Contenu marqué Premium lors de la création
|
||||
Étant donné que je crée un nouveau contenu
|
||||
Quand j'active le toggle "Réservé Premium"
|
||||
Et que je publie le contenu
|
||||
Alors le champ `is_premium` en base est mis à `true`
|
||||
Et le contenu est visible uniquement pour les utilisateurs Premium
|
||||
|
||||
Scénario: Contenu gratuit par défaut
|
||||
Étant donné que je crée un nouveau contenu
|
||||
Quand je ne touche pas au toggle "Réservé Premium"
|
||||
Et que je publie le contenu
|
||||
Alors le champ `is_premium` en base est mis à `false` (défaut)
|
||||
Et le contenu est accessible à tous les utilisateurs
|
||||
|
||||
Scénario: Modification d'un contenu existant en Premium
|
||||
Étant donné que j'ai publié un contenu gratuit il y a 2 jours
|
||||
Quand je modifie le contenu et active le toggle "Réservé Premium"
|
||||
Et que j'enregistre les modifications
|
||||
Alors le contenu devient immédiatement Premium
|
||||
Et les utilisateurs gratuits ne peuvent plus y accéder
|
||||
|
||||
Scénario: Passage d'un contenu Premium en gratuit
|
||||
Étant donné que j'ai publié un contenu Premium il y a 1 mois
|
||||
Quand je modifie le contenu et désactive le toggle "Réservé Premium"
|
||||
Et que j'enregistre les modifications
|
||||
Alors le contenu devient immédiatement gratuit
|
||||
Et tous les utilisateurs peuvent maintenant y accéder
|
||||
|
||||
Scénario: Aucune limite sur pourcentage de contenus Premium
|
||||
Étant donné que je publie 10 nouveaux contenus
|
||||
Quand je décide de rendre les 10 contenus Premium (100%)
|
||||
Alors le système accepte sans limitation
|
||||
Et je peux avoir 100% de mon catalogue en Premium
|
||||
|
||||
Scénario: Stratégie freemium - Mix gratuit/premium
|
||||
Étant donné que je publie 10 nouveaux contenus
|
||||
Quand je décide de rendre 5 contenus Premium et 5 gratuits (50/50)
|
||||
Alors le système accepte cette stratégie
|
||||
Et je peux tester différents mix pour optimiser mes revenus
|
||||
|
||||
Scénario: Stratégie tout gratuit possible
|
||||
Étant donné que je suis monétisé via publicités
|
||||
Quand je décide de ne mettre aucun contenu en Premium (0%)
|
||||
Alors le système accepte cette stratégie
|
||||
Et je génère des revenus uniquement via les publicités
|
||||
|
||||
Scénario: Badge 👑 visible sur l'interface utilisateur
|
||||
Étant donné qu'un utilisateur consulte ma liste de contenus
|
||||
Quand il voit un contenu Premium
|
||||
Alors un badge 👑 "Premium" est affiché
|
||||
Et le contenu est clairement identifiable comme réservé
|
||||
|
||||
Scénario: Utilisateur gratuit voit les contenus Premium dans la liste
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Quand je consulte les contenus d'un créateur
|
||||
Alors je vois aussi les contenus Premium dans la liste
|
||||
Et ils sont affichés avec un badge 👑
|
||||
Mais je ne peux pas les lire
|
||||
|
||||
Scénario: Tentative de lecture Premium par utilisateur gratuit - Overlay bloquant
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Quand je clique sur un contenu Premium pour le lire
|
||||
Alors un overlay bloquant apparaît
|
||||
Et je vois le message:
|
||||
"""
|
||||
👑 Ce contenu est réservé aux abonnés Premium
|
||||
|
||||
Passez Premium pour 4.99€/mois et accédez à tous les contenus exclusifs !
|
||||
"""
|
||||
Et un bouton "Passer Premium" est affiché
|
||||
|
||||
Scénario: CTA "Passer Premium" redirige vers abonnement
|
||||
Étant donné que je vois l'overlay de contenu Premium bloqué
|
||||
Quand je clique sur "Passer Premium"
|
||||
Alors je suis redirigé vers la page d'abonnement Premium
|
||||
Et je peux m'abonner pour 4.99€/mois
|
||||
|
||||
Scénario: Utilisateur Premium peut lire tous les contenus Premium
|
||||
Étant donné que je suis un utilisateur Premium actif
|
||||
Quand je clique sur un contenu Premium
|
||||
Alors le contenu se lance immédiatement
|
||||
Et je n'ai aucun overlay bloquant
|
||||
Et je peux profiter pleinement du contenu exclusif
|
||||
|
||||
Scénario: Contenus Premium inclus dans les recommandations
|
||||
Étant donné que l'algorithme génère ma file de 5 contenus
|
||||
Quand je suis un utilisateur gratuit
|
||||
Alors les contenus Premium peuvent apparaître dans les recommandations
|
||||
Et cela me fait découvrir qu'il existe du contenu exclusif
|
||||
|
||||
Scénario: Contenu Premium skippé automatiquement pour utilisateur gratuit
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Et qu'un contenu Premium apparaît dans ma file de recommandation
|
||||
Quand j'écoute le contenu précédent jusqu'à la fin
|
||||
Alors le contenu Premium est automatiquement skippé
|
||||
Et le contenu suivant (gratuit) est lancé
|
||||
Et le slot Premium ne compte pas dans ma file de 5 contenus
|
||||
|
||||
Scénario: Contenu Premium diffusé normalement pour utilisateur Premium
|
||||
Étant donné que je suis un utilisateur Premium
|
||||
Et qu'un contenu Premium apparaît dans ma file de recommandation
|
||||
Quand j'écoute le contenu précédent jusqu'à la fin
|
||||
Alors le contenu Premium est lancé normalement
|
||||
Et je profite du contenu exclusif sans interruption
|
||||
|
||||
Scénario: Champ `is_premium` boolean en base PostgreSQL
|
||||
Étant donné qu'un contenu est créé
|
||||
Quand il est stocké en base de données
|
||||
Alors la table `contents` contient un champ `is_premium BOOLEAN DEFAULT FALSE`
|
||||
Et ce champ est indexé pour requêtes rapides
|
||||
|
||||
Scénario: Index PostgreSQL sur `is_premium`
|
||||
Étant donné que l'algorithme doit filtrer les contenus selon le statut Premium
|
||||
Quand une requête SQL est exécutée:
|
||||
```sql
|
||||
SELECT * FROM contents
|
||||
WHERE creator_id = :creator_id
|
||||
AND (is_premium = FALSE OR :user_is_premium = TRUE)
|
||||
ORDER BY created_at DESC;
|
||||
```
|
||||
Alors l'index sur `is_premium` accélère la requête
|
||||
Et le temps de réponse reste <20ms
|
||||
|
||||
Scénario: Cache Redis pour statut Premium
|
||||
Étant donné qu'un contenu Premium est consulté fréquemment
|
||||
Quand l'API vérifie le statut Premium
|
||||
Alors la valeur est récupérée depuis Redis:
|
||||
```
|
||||
content:[content_id]:premium = true
|
||||
```
|
||||
Et le cache a un TTL de 1 heure
|
||||
Et cela évite des requêtes SQL inutiles
|
||||
|
||||
Scénario: Invalidation cache lors de modification statut Premium
|
||||
Étant donné qu'un contenu est passé de gratuit à Premium
|
||||
Quand le créateur enregistre la modification
|
||||
Alors le cache Redis `content:[id]:premium` est invalidé immédiatement
|
||||
Et la nouvelle valeur est mise à jour
|
||||
Et les utilisateurs voient le changement en temps réel
|
||||
|
||||
Scénario: Justification liberté créateur - Stratégie personnalisée
|
||||
Étant donné que chaque créateur a une audience différente
|
||||
Quand un créateur décide de sa stratégie Premium
|
||||
Alors il peut tester différentes approches:
|
||||
| stratégie | % Premium | objectif |
|
||||
| Tout gratuit | 0% | Maximiser audience + revenus pub |
|
||||
| Mix 50/50 | 50% | Équilibrer audience et exclusivité |
|
||||
| Premium majoritaire | 80% | Cibler abonnés fidèles |
|
||||
| 100% Premium | 100% | Contenu ultra-exclusif |
|
||||
|
||||
Scénario: Justification incitation Premium - Argument fort pour s'abonner
|
||||
Étant donné qu'un utilisateur gratuit voit beaucoup de contenus Premium
|
||||
Quand il consulte les profils de ses créateurs préférés
|
||||
Alors il voit que 60% de leur contenu est réservé Premium
|
||||
Et cela l'incite à s'abonner pour 4.99€/mois
|
||||
Et RoadWave augmente son taux de conversion vers Premium
|
||||
|
||||
Scénario: Justification équité - Petit créateur peut tout mettre en Premium
|
||||
Étant donné que je suis un petit créateur avec 600 abonnés
|
||||
Et que 50 sont abonnés Premium
|
||||
Quand je mets 100% de mon contenu en Premium
|
||||
Alors je génère des revenus uniquement via mes 50 abonnés Premium
|
||||
Et cela me permet de vivre de mon contenu malgré une petite audience
|
||||
|
||||
Scénario: Justification équité - Gros créateur peut tout offrir gratuitement
|
||||
Étant donné que je suis un gros créateur avec 50 000 abonnés
|
||||
Et que je génère déjà beaucoup de revenus publicitaires
|
||||
Quand je laisse 100% de mon contenu gratuit
|
||||
Alors je maximise mon audience et mes revenus pub
|
||||
Et je n'ai pas besoin de mettre du contenu en Premium
|
||||
|
||||
Scénario: Statistiques créateur - Ratio Premium/Gratuit
|
||||
Étant donné que j'accède à mon tableau de bord créateur
|
||||
Quand je consulte mes statistiques de contenus
|
||||
Alors je vois:
|
||||
| métrique | valeur |
|
||||
| Contenus totaux | 47 |
|
||||
| Contenus gratuits | 32 (68%) |
|
||||
| Contenus Premium | 15 (32%) |
|
||||
| Écoutes Premium ce mois | 12,345 |
|
||||
| Écoutes gratuites ce mois | 28,901 |
|
||||
|
||||
Scénario: Statistiques créateur - Revenus par type
|
||||
Étant donné que j'ai des contenus gratuits et Premium
|
||||
Quand je consulte mes revenus détaillés
|
||||
Alors je vois:
|
||||
| source | montant |
|
||||
| Revenus pub (gratuit) | 86.70€ |
|
||||
| Revenus Premium (exclusifs) | 34.20€ |
|
||||
| Revenus Premium (tout contenu)| 78.90€ |
|
||||
Et je peux comparer l'efficacité de chaque stratégie
|
||||
|
||||
Scénario: Notification créateur - Contenu Premium très écouté
|
||||
Étant donné que j'ai publié un contenu Premium il y a 3 jours
|
||||
Et qu'il a généré 5 000 écoutes Premium (très élevé)
|
||||
Quand le système détecte cette performance
|
||||
Alors je reçois une notification:
|
||||
"""
|
||||
🔥 Votre contenu Premium "[Titre]" cartonne !
|
||||
5 000 écoutes en 3 jours. Continuez à créer du contenu exclusif de qualité !
|
||||
"""
|
||||
|
||||
Scénario: A/B test utilisateur - Impact badge Premium sur conversion
|
||||
Étant donné que RoadWave veut optimiser le taux de conversion Premium
|
||||
Quand un A/B test est lancé
|
||||
Alors groupe A voit le badge 👑 "Premium"
|
||||
Et groupe B voit le badge 💎 "Exclusif"
|
||||
Et les taux de clic et conversion sont mesurés
|
||||
Et le badge le plus performant est déployé définitivement
|
||||
|
||||
Scénario: Analytics plateforme - Adoption fonctionnalité Premium
|
||||
Étant donné que RoadWave suit l'adoption de la fonctionnalité
|
||||
Quand un admin consulte les métriques
|
||||
Alors il voit:
|
||||
| métrique | valeur |
|
||||
| Créateurs utilisant Premium | 847 (68%) |
|
||||
| % moyen contenus Premium | 23% |
|
||||
| Taux conversion vers Premium (users) | 8.5% |
|
||||
| Revenus Premium/mois | 47,890€ |
|
||||
|
||||
Scénario: Impact sur churn - Contenus Premium réduisent le churn Premium
|
||||
Étant donné qu'un utilisateur Premium envisage de résilier
|
||||
Mais qu'il a accès à 150 contenus Premium de ses créateurs préférés
|
||||
Quand il voit la valeur exclusive qu'il perdrait
|
||||
Alors il est moins susceptible de résilier (churn réduit de ~30%)
|
||||
Et les contenus Premium augmentent la rétention
|
||||
|
||||
Scénario: Transparence - Créateur voit combien de contenus Premium il a
|
||||
Étant donné que j'accède à mon profil créateur
|
||||
Quand je consulte mes contenus
|
||||
Alors je peux filtrer par statut:
|
||||
| filtre | résultats |
|
||||
| Tous | 47 |
|
||||
| Gratuits | 32 |
|
||||
| Premium 👑 | 15 |
|
||||
Et je peux facilement gérer mon catalogue
|
||||
|
||||
Scénario: Export liste contenus avec statut Premium (RGPD)
|
||||
Étant donné que je demande l'export de mes données
|
||||
Quand l'export est généré
|
||||
Alors la liste de mes contenus inclut le statut Premium:
|
||||
```json
|
||||
{
|
||||
"contents": [
|
||||
{
|
||||
"title": "Mon épisode exclusif",
|
||||
"is_premium": true,
|
||||
"published_at": "2025-06-15T10:30:00Z"
|
||||
},
|
||||
{
|
||||
"title": "Mon épisode gratuit",
|
||||
"is_premium": false,
|
||||
"published_at": "2025-06-14T08:15:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Scénario: Suppression compte créateur et contenus Premium
|
||||
Étant donné que je supprime définitivement mon compte créateur
|
||||
Quand la suppression est confirmée
|
||||
Alors tous mes contenus (gratuits et Premium) sont supprimés
|
||||
Et les utilisateurs Premium ne peuvent plus y accéder
|
||||
Et les fichiers audio sont supprimés du CDN sous 7 jours
|
||||
|
||||
Scénario: Performance avec 1 million de contenus Premium
|
||||
Étant donné que RoadWave a 1 million de contenus dont 300 000 Premium
|
||||
Quand l'algorithme génère une recommandation
|
||||
Alors la requête SQL filtre efficacement avec l'index `is_premium`
|
||||
Et le temps de réponse reste <50ms
|
||||
Et la scalabilité est garantie
|
||||
Reference in New Issue
Block a user