Initial commit
This commit is contained in:
362
features/premium/avantages-premium.feature
Normal file
362
features/premium/avantages-premium.feature
Normal file
@@ -0,0 +1,362 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Avantages Premium
|
||||
En tant qu'abonné Premium
|
||||
Je veux bénéficier d'avantages exclusifs
|
||||
Afin de profiter d'une expérience audio améliorée sans publicité
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis connecté à l'application RoadWave
|
||||
|
||||
# ===== PUBLICITÉS =====
|
||||
|
||||
Scénario: Utilisateur gratuit voit 1 publicité tous les 5 contenus
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Quand j'écoute ma file de contenus
|
||||
Alors je vois une publicité tous les 5 contenus
|
||||
Et la publicité dure 30 secondes en moyenne
|
||||
Et je ne peux pas la skip
|
||||
|
||||
Scénario: Utilisateur Premium ne voit aucune publicité
|
||||
Étant donné que je suis un utilisateur Premium
|
||||
Quand j'écoute mes contenus
|
||||
Alors aucune publicité n'est diffusée
|
||||
Et je passe directement d'un contenu à l'autre
|
||||
Et l'expérience d'écoute est fluide et ininterrompue
|
||||
|
||||
Scénario: Badge "0 publicité" sur page Premium
|
||||
Étant donné que je consulte la page des avantages Premium
|
||||
Quand je lis la liste des avantages
|
||||
Alors je vois en premier:
|
||||
"""
|
||||
🚫 0 publicité
|
||||
Profitez d'une écoute sans interruption
|
||||
"""
|
||||
Et c'est l'argument principal mis en avant
|
||||
|
||||
# ===== CONTENUS EXCLUSIFS =====
|
||||
|
||||
Scénario: Utilisateur gratuit voit contenus Premium bloqués
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Quand je consulte les contenus d'un créateur
|
||||
Alors je vois les contenus marqués Premium avec badge 👑
|
||||
Mais je ne peux pas les lire (overlay bloquant)
|
||||
|
||||
Scénario: Utilisateur Premium accède à tous les contenus exclusifs
|
||||
Étant donné que je suis un utilisateur Premium
|
||||
Quand je consulte les contenus d'un créateur
|
||||
Alors tous les contenus Premium sont accessibles
|
||||
Et je peux les lire sans restriction
|
||||
Et j'ai accès à 100% du catalogue (gratuit + Premium)
|
||||
|
||||
Scénario: Nombre de contenus Premium disponibles
|
||||
Étant donné que je suis Premium
|
||||
Quand je consulte les statistiques
|
||||
Alors je vois combien de contenus Premium sont disponibles sur la plateforme
|
||||
Et par exemple: "8,547 contenus Premium exclusifs disponibles"
|
||||
Et cela justifie la valeur de l'abonnement
|
||||
|
||||
# ===== QUALITÉ AUDIO =====
|
||||
|
||||
Scénario: Utilisateur gratuit écoute en 48 kbps Opus
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Quand je lance un contenu
|
||||
Alors l'audio est streamé en 48 kbps Opus
|
||||
Et cela consomme environ 20 MB/heure
|
||||
Et la qualité est très correcte pour de la voix
|
||||
|
||||
Scénario: Utilisateur Premium écoute en 64 kbps Opus
|
||||
Étant donné que je suis un utilisateur Premium
|
||||
Quand je lance un contenu
|
||||
Alors l'audio est streamé en 64 kbps Opus
|
||||
Et cela consomme environ 30 MB/heure
|
||||
Et la qualité est excellente (détails audio supérieurs)
|
||||
|
||||
Scénario: Comparaison qualité 48 kbps vs 64 kbps
|
||||
Étant donné que je consulte la page Premium
|
||||
Quand je lis la section qualité audio
|
||||
Alors je vois l'explication:
|
||||
"""
|
||||
📻 Qualité audio supérieure
|
||||
|
||||
Gratuit: 48 kbps Opus (~20 MB/h)
|
||||
Premium: 64 kbps Opus (~30 MB/h)
|
||||
|
||||
Profitez d'une qualité audio exceptionnelle avec plus de détails
|
||||
et une meilleure restitution des voix et ambiances.
|
||||
"""
|
||||
|
||||
Scénario: Justification 48 kbps suffisant pour gratuit
|
||||
Étant donné que le contenu RoadWave est principalement de la voix
|
||||
Quand la qualité est fixée à 48 kbps pour gratuit
|
||||
Alors c'est largement suffisant pour comprendre clairement
|
||||
Et équivalent à la qualité radio FM
|
||||
Et les utilisateurs gratuits ne sont pas frustrés
|
||||
|
||||
Scénario: Justification 64 kbps avantage tangible Premium
|
||||
Étant donné que les audiophiles et créateurs audio sont exigeants
|
||||
Quand la qualité Premium est à 64 kbps
|
||||
Alors la différence est perceptible à l'oreille
|
||||
Et les ambiances, musiques de fond, nuances de voix sont mieux rendues
|
||||
Et cela justifie l'abonnement Premium
|
||||
|
||||
Scénario: Switch automatique qualité selon abonnement
|
||||
Étant donné que je suis gratuit et j'écoute en 48 kbps
|
||||
Quand je souscris à Premium
|
||||
Alors dès le contenu suivant, je passe automatiquement en 64 kbps
|
||||
Et je peux entendre la différence de qualité immédiatement
|
||||
|
||||
Scénario: Consommation data Premium vs Gratuit
|
||||
Étant donné que je roule 1 heure par jour
|
||||
Quand je calcule la consommation mensuelle
|
||||
Alors en gratuit: 20 MB/h × 1h × 22 jours = 440 MB/mois
|
||||
Et en Premium: 30 MB/h × 1h × 22 jours = 660 MB/mois
|
||||
Et la différence est de 220 MB/mois (acceptable pour 4G/5G illimitée)
|
||||
|
||||
# ===== MODE OFFLINE =====
|
||||
|
||||
Scénario: Utilisateur gratuit limité à 50 contenus téléchargés
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Quand j'accède au mode offline
|
||||
Alors je peux télécharger jusqu'à 50 contenus maximum
|
||||
Et si j'essaie de télécharger un 51ème, je vois:
|
||||
"""
|
||||
Limite atteinte (50 contenus max en gratuit).
|
||||
Passez Premium pour des téléchargements illimités.
|
||||
"""
|
||||
|
||||
Scénario: Utilisateur Premium téléchargements illimités
|
||||
Étant donné que je suis un utilisateur Premium
|
||||
Quand j'accède au mode offline
|
||||
Alors je peux télécharger autant de contenus que je veux
|
||||
Et la seule limite est l'espace de stockage de mon device
|
||||
Et par exemple 500 contenus × 10 MB = 5 GB
|
||||
|
||||
Scénario: Justification limite 50 contenus gratuit
|
||||
Étant donné que 50 contenus de 10 minutes = ~8 heures d'écoute
|
||||
Quand un utilisateur gratuit prépare un road trip
|
||||
Alors 8 heures couvrent largement une journée de trajet
|
||||
Et cela permet un usage offline raisonnable sans abuser
|
||||
|
||||
Scénario: Justification illimité Premium pour longs road trips
|
||||
Étant donné qu'un road trip de plusieurs jours nécessite 20-50h de contenu
|
||||
Quand un utilisateur Premium télécharge 200 contenus
|
||||
Alors il peut partir serein sans connexion internet pendant 1 semaine
|
||||
Et cela justifie pleinement l'abonnement Premium
|
||||
|
||||
Scénario: Affichage compteur téléchargements gratuit
|
||||
Étant donné que je suis gratuit et j'ai téléchargé 37 contenus
|
||||
Quand j'accède à la page Téléchargements
|
||||
Alors je vois:
|
||||
"""
|
||||
📥 Téléchargements offline
|
||||
|
||||
37 / 50 contenus téléchargés
|
||||
|
||||
Passez Premium pour des téléchargements illimités
|
||||
[Découvrir Premium]
|
||||
```
|
||||
|
||||
Scénario: Pas de compteur pour Premium
|
||||
Étant donné que je suis Premium et j'ai téléchargé 187 contenus
|
||||
Quand j'accède à la page Téléchargements
|
||||
Alors je vois simplement:
|
||||
"""
|
||||
📥 Téléchargements offline
|
||||
|
||||
187 contenus téléchargés (illimité)
|
||||
Espace utilisé: 1.8 GB
|
||||
```
|
||||
Et aucune limite n'est affichée
|
||||
|
||||
# ===== HISTORIQUE ÉCOUTE =====
|
||||
|
||||
Scénario: Utilisateur gratuit historique limité à 100 derniers
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Quand j'accède à mon historique d'écoute
|
||||
Alors je vois les 100 derniers contenus écoutés
|
||||
Et les contenus plus anciens ne sont pas affichés
|
||||
Et je vois un message "Historique limité à 100 contenus. Passez Premium pour un historique illimité."
|
||||
|
||||
Scénario: Utilisateur Premium historique illimité
|
||||
Étant donné que je suis un utilisateur Premium
|
||||
Quand j'accède à mon historique d'écoute
|
||||
Alors je vois tous les contenus que j'ai écoutés depuis mon inscription
|
||||
Et je peux scroller jusqu'au premier contenu jamais écouté
|
||||
Et l'historique est complet et permanent
|
||||
|
||||
Scénario: Recherche dans historique Premium
|
||||
Étant donné que je suis Premium et j'ai 2 000 contenus dans mon historique
|
||||
Quand je recherche "Tesla" dans mon historique
|
||||
Alors tous les contenus écoutés contenant "Tesla" sont affichés
|
||||
Et je peux retrouver facilement un contenu écouté il y a 6 mois
|
||||
|
||||
Scénario: Justification limite 100 gratuit suffisante
|
||||
Étant donné que 100 contenus de 10 min = ~16 heures d'écoute
|
||||
Quand un utilisateur gratuit écoute 1h/jour
|
||||
Alors l'historique couvre les 16 derniers jours
|
||||
Et cela suffit pour retrouver un contenu récent
|
||||
|
||||
Scénario: Justification illimité Premium pour power users
|
||||
Étant donné qu'un power user écoute 3h/jour depuis 2 ans
|
||||
Quand il veut retrouver un contenu spécifique écouté il y a 1 an
|
||||
Alors l'historique illimité Premium lui permet de retrouver ce contenu
|
||||
Et cela apporte une vraie valeur ajoutée
|
||||
|
||||
Scénario: Export historique complet (Premium uniquement)
|
||||
Étant donné que je suis Premium
|
||||
Quand je demande l'export de mes données
|
||||
Alors l'historique complet est inclus dans l'export:
|
||||
```json
|
||||
{
|
||||
"listen_history": [
|
||||
{
|
||||
"content_title": "Mon épisode préféré",
|
||||
"creator_name": "JeanDupont",
|
||||
"listened_at": "2025-06-15T14:30:00Z",
|
||||
"completion_rate": 0.95
|
||||
},
|
||||
...
|
||||
],
|
||||
"total_listens": 2847
|
||||
}
|
||||
```
|
||||
|
||||
# ===== TABLEAU COMPARATIF =====
|
||||
|
||||
Scénario: Affichage tableau comparatif Gratuit vs Premium
|
||||
Étant donné que je consulte la page Premium
|
||||
Quand je vois le tableau comparatif
|
||||
Alors il affiche:
|
||||
```
|
||||
┌─────────────────────────┬──────────────┬──────────────┐
|
||||
│ Avantage │ Gratuit │ Premium │
|
||||
├─────────────────────────┼──────────────┼──────────────┤
|
||||
│ Publicités │ 1/5 contenus │ 0 (aucune) │
|
||||
│ Contenus exclusifs │ ❌ Bloqués │ ✅ Accès │
|
||||
│ Qualité audio │ 48 kbps Opus │ 64 kbps Opus │
|
||||
│ Mode offline │ 50 max │ Illimité │
|
||||
│ Historique écoute │ 100 derniers │ Illimité │
|
||||
│ Prix │ Gratuit │ 4.99€/mois │
|
||||
└─────────────────────────┴──────────────┴──────────────┘
|
||||
```
|
||||
|
||||
# ===== JUSTIFICATIONS GÉNÉRALES =====
|
||||
|
||||
Scénario: Justification 0 pub = argument principal
|
||||
Étant donné qu'une publicité de 30s tous les 5 contenus = 6 min/h de pub
|
||||
Quand un utilisateur écoute 1h/jour
|
||||
Alors il subit 180 min de pub/mois (3 heures !)
|
||||
Et payer 4.99€ pour éviter 3h de pub/mois est très rentable
|
||||
Et c'est l'argument de conversion n°1
|
||||
|
||||
Scénario: Justification qualité audio avantage tangible
|
||||
Étant donné que la différence 48 kbps → 64 kbps est audible
|
||||
Quand un audiophile compare les deux
|
||||
Alors il entend clairement la différence sur un bon système audio voiture
|
||||
Et cela justifie l'abonnement pour les exigeants
|
||||
|
||||
Scénario: Justification offline illimité pour road trips
|
||||
Étant donné qu'un road trip de 2 semaines nécessite 50-100h de contenu
|
||||
Quand un utilisateur Premium télécharge 300 contenus avant de partir
|
||||
Alors il peut partir en zone sans réseau sereinement
|
||||
Et cela apporte une vraie valeur pratique
|
||||
|
||||
Scénario: Justification pas d'over-engineering
|
||||
Étant donné que RoadWave se concentre sur l'essentiel
|
||||
Quand les avantages Premium sont définis
|
||||
Alors il n'y a pas de:
|
||||
| fonctionnalité superflue | raison exclusion |
|
||||
| Badges cosmétiques | Pas de valeur réelle |
|
||||
| Avatar Premium exclusif | Inutile pour audio |
|
||||
| Fonctionnalités sociales avancées | Pas prioritaire MVP |
|
||||
| Early access nouveaux contenus | Complexité > bénéfice |
|
||||
Et cela réduit la complexité et le coût de développement
|
||||
|
||||
# ===== CONVERSION ET INCITATION =====
|
||||
|
||||
Scénario: CTA Premium après 5ème publicité
|
||||
Étant donné que je suis gratuit et je viens d'entendre ma 5ème pub
|
||||
Quand la publicité se termine
|
||||
Alors je vois un message:
|
||||
"""
|
||||
😫 Marre des pubs ?
|
||||
|
||||
Passez Premium pour seulement 4.99€/mois :
|
||||
• 0 publicité
|
||||
• Qualité audio supérieure
|
||||
• Téléchargements illimités
|
||||
|
||||
[Essayer Premium] [Plus tard]
|
||||
```
|
||||
|
||||
Scénario: CTA Premium quand limite 50 téléchargements atteinte
|
||||
Étant donné que je suis gratuit et j'ai atteint 50 téléchargements
|
||||
Quand j'essaie de télécharger un 51ème contenu
|
||||
Alors je vois une popup:
|
||||
"""
|
||||
📥 Limite atteinte
|
||||
|
||||
Vous avez atteint la limite de 50 téléchargements.
|
||||
|
||||
Avec Premium (4.99€/mois), téléchargez autant de contenus que vous voulez
|
||||
pour vos longs road trips !
|
||||
|
||||
[Passer Premium] [Gérer mes téléchargements]
|
||||
```
|
||||
|
||||
Scénario: CTA Premium quand contenu exclusif bloqué
|
||||
Étant donné que je suis gratuit et je clique sur un contenu Premium
|
||||
Quand l'overlay bloquant apparaît
|
||||
Alors je vois:
|
||||
"""
|
||||
👑 Contenu Premium
|
||||
|
||||
Ce contenu est réservé aux abonnés Premium.
|
||||
|
||||
Débloquez 8,547 contenus Premium exclusifs pour 4.99€/mois !
|
||||
|
||||
[Passer Premium] [Découvrir d'autres contenus]
|
||||
```
|
||||
|
||||
Scénario: Statistiques conversion - Quel avantage convertit le mieux ?
|
||||
Étant donné qu'un admin consulte les statistiques de conversion
|
||||
Quand il analyse les sources de conversion
|
||||
Alors il voit:
|
||||
| source de conversion | % conversions |
|
||||
| CTA après 5ème pub | 42% |
|
||||
| CTA contenu Premium bloqué | 28% |
|
||||
| CTA limite 50 téléchargements | 18% |
|
||||
| Page Premium directe | 12% |
|
||||
Et cela aide à optimiser le placement des CTA
|
||||
|
||||
Scénario: A/B test message CTA
|
||||
Étant donné que RoadWave veut optimiser les conversions
|
||||
Quand un A/B test est lancé sur le CTA après pub
|
||||
Alors groupe A voit "Marre des pubs ?" (focus négatif)
|
||||
Et groupe B voit "Profitez de 0 publicité" (focus positif)
|
||||
Et le taux de conversion est mesuré
|
||||
Et le message le plus performant est déployé
|
||||
|
||||
Scénario: Notification Premium après 30 jours d'utilisation gratuite
|
||||
Étant donné que je suis utilisateur gratuit depuis 30 jours
|
||||
Et que j'écoute régulièrement (15h cumulées)
|
||||
Quand le 30ème jour arrive
|
||||
Alors je reçois une notification:
|
||||
"""
|
||||
🎉 Vous avez écouté 15h sur RoadWave !
|
||||
|
||||
Profitez encore plus avec Premium :
|
||||
• 0 publicité
|
||||
• Qualité supérieure
|
||||
• Téléchargements illimités
|
||||
|
||||
Offre découverte : -20% sur le premier mois (3.99€)
|
||||
[Découvrir Premium]
|
||||
```
|
||||
|
||||
Scénario: Trial gratuit refusé mais onboarding amélioré
|
||||
Étant donné qu'il n'y a pas de trial gratuit
|
||||
Quand un nouvel utilisateur s'inscrit
|
||||
Alors un onboarding explique clairement les avantages Premium
|
||||
Et il peut comparer gratuit vs Premium dès le premier lancement
|
||||
Et cela l'aide à décider rapidement s'il veut payer
|
||||
457
features/premium/gestion-abonnement.feature
Normal file
457
features/premium/gestion-abonnement.feature
Normal file
@@ -0,0 +1,457 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Gestion abonnement Premium
|
||||
En tant qu'utilisateur
|
||||
Je veux gérer facilement mon abonnement Premium
|
||||
Afin de souscrire, renouveler ou annuler en toute transparence
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis connecté à l'application RoadWave
|
||||
|
||||
# ===== SOUSCRIPTION =====
|
||||
|
||||
Scénario: Souscription via Web (desktop/mobile) avec Mangopay
|
||||
Étant donné que je consulte la page Premium sur le site web
|
||||
Quand je clique sur "S'abonner - Mensuel 4.99€"
|
||||
Alors je suis redirigé vers le formulaire de paiement Mangopay
|
||||
Et je saisis mes informations de carte bancaire
|
||||
Et le paiement de 4.99€ est prélevé immédiatement
|
||||
Et la commission Mangopay est de 1.8% + 0.18€ = 0.27€
|
||||
Et RoadWave reçoit 4.72€ net
|
||||
|
||||
Scénario: Calcul commission Mangopay
|
||||
Étant donné qu'un utilisateur paie 4.99€ via Mangopay
|
||||
Quand la commission est calculée
|
||||
Alors la commission est : 4.99€ × 1.8% + 0.18€ = 0.09€ + 0.18€ = 0.27€
|
||||
Et RoadWave reçoit : 4.99€ - 0.27€ = 4.72€
|
||||
Et la commission représente 5.4% du prix
|
||||
|
||||
Scénario: Souscription via iOS App avec Apple IAP
|
||||
Étant donné que j'utilise l'app iOS
|
||||
Quand je clique sur "S'abonner - Mensuel 5.99€"
|
||||
Alors je suis redirigé vers l'interface Apple In-App Purchase
|
||||
Et le prix affiché est 5.99€ (majoré de 20%)
|
||||
Et le paiement est effectué via mon compte Apple
|
||||
Et Apple prend 30% de commission = 1.80€
|
||||
Et RoadWave reçoit 4.19€ net
|
||||
|
||||
Scénario: Souscription via Android App avec Google Play Billing
|
||||
Étant donné que j'utilise l'app Android
|
||||
Quand je clique sur "S'abonner - Mensuel 5.99€"
|
||||
Alors je suis redirigé vers l'interface Google Play Billing
|
||||
Et le prix affiché est 5.99€ (majoré de 20%)
|
||||
Et le paiement est effectué via mon compte Google
|
||||
Et Google prend 30% de commission = 1.80€
|
||||
Et RoadWave reçoit 4.19€ net
|
||||
|
||||
Scénario: Majoration 20% sur mobile pour compenser commission 30%
|
||||
Étant donné que Apple/Google prennent 30% de commission
|
||||
Quand RoadWave fixe le prix mobile
|
||||
Alors le prix web est 4.99€ (commission Mangopay 5.4%)
|
||||
Et le prix mobile est 5.99€ (commission Apple/Google 30%)
|
||||
Et la majoration est de 1€ (+20%)
|
||||
Et cela compense partiellement la commission excessive
|
||||
|
||||
Scénario: Email incitation souscription web moins chère
|
||||
Étant donné que je consulte Premium depuis l'app mobile
|
||||
Quand je vois le prix 5.99€
|
||||
Alors je vois aussi un message:
|
||||
"""
|
||||
💡 Astuce : Abonnez-vous sur roadwave.com pour seulement 4.99€/mois
|
||||
Économisez 12€/an en évitant les frais Apple/Google !
|
||||
"""
|
||||
Et un lien vers le site web est fourni
|
||||
|
||||
Scénario: Calcul économie souscription web vs mobile
|
||||
Étant donné que le prix web est 4.99€/mois
|
||||
Et que le prix mobile est 5.99€/mois
|
||||
Quand je calcule l'économie annuelle
|
||||
Alors web : 4.99€ × 12 = 59.88€/an
|
||||
Et mobile : 5.99€ × 12 = 71.88€/an
|
||||
Et économie : 12€/an (soit 20% d'économie)
|
||||
|
||||
Scénario: Activation immédiate après paiement réussi
|
||||
Étant donné que je viens de payer mon abonnement Premium
|
||||
Quand le paiement est confirmé
|
||||
Alors mon statut passe immédiatement à "Premium"
|
||||
Et je peux accéder aux avantages Premium dès maintenant
|
||||
Et je reçois un email de confirmation
|
||||
|
||||
Scénario: Email confirmation souscription
|
||||
Étant donné que j'ai souscrit à Premium
|
||||
Quand la souscription est confirmée
|
||||
Alors je reçois un email:
|
||||
"""
|
||||
🎉 Bienvenue Premium !
|
||||
|
||||
Votre abonnement Premium est actif.
|
||||
|
||||
Formule: Mensuel 4.99€/mois
|
||||
Prochain renouvellement: 15 juillet 2025
|
||||
|
||||
Vos avantages:
|
||||
• 0 publicité
|
||||
• Contenus exclusifs
|
||||
• Qualité audio 64 kbps
|
||||
• Téléchargements illimités
|
||||
• Historique illimité
|
||||
|
||||
Profitez pleinement de RoadWave !
|
||||
|
||||
Gérer mon abonnement: [Lien]
|
||||
"""
|
||||
|
||||
# ===== RENOUVELLEMENT AUTOMATIQUE =====
|
||||
|
||||
Scénario: Email rappel 7 jours avant renouvellement
|
||||
Étant donné que mon abonnement mensuel se renouvelle le 15 juillet
|
||||
Quand le 8 juillet arrive (7 jours avant)
|
||||
Alors je reçois un email de rappel:
|
||||
"""
|
||||
📅 Votre abonnement Premium se renouvelle dans 7 jours
|
||||
|
||||
Formule: Mensuel 4.99€/mois
|
||||
Date de renouvellement: 15 juillet 2025
|
||||
Montant: 4.99€
|
||||
|
||||
Votre carte bancaire sera débitée automatiquement.
|
||||
|
||||
Vous souhaitez annuler ? [Gérer mon abonnement]
|
||||
"""
|
||||
|
||||
Scénario: Renouvellement automatique réussi
|
||||
Étant donné que mon abonnement mensuel arrive à échéance le 15 juillet
|
||||
Quand le 15 juillet arrive
|
||||
Alors Mangopay/Apple/Google prélève automatiquement 4.99€ (ou 5.99€)
|
||||
Et mon abonnement est renouvelé pour 1 mois supplémentaire
|
||||
Et je reçois un email de confirmation
|
||||
|
||||
Scénario: Email confirmation renouvellement
|
||||
Étant donné que mon abonnement vient d'être renouvelé
|
||||
Quand le paiement est confirmé
|
||||
Alors je reçois un email:
|
||||
"""
|
||||
✅ Abonnement Premium renouvelé
|
||||
|
||||
Votre abonnement a été renouvelé avec succès.
|
||||
|
||||
Montant débité: 4.99€
|
||||
Prochaine échéance: 15 août 2025
|
||||
|
||||
Merci de continuer à soutenir RoadWave et ses créateurs !
|
||||
|
||||
Gérer mon abonnement: [Lien]
|
||||
"""
|
||||
|
||||
Scénario: Échec paiement renouvellement - Tentative 1
|
||||
Étant donné que mon abonnement doit se renouveler le 15 juillet
|
||||
Mais que ma carte bancaire est expirée ou sans fonds
|
||||
Quand le prélèvement échoue
|
||||
Alors je reçois un email:
|
||||
"""
|
||||
⚠️ Échec renouvellement abonnement Premium
|
||||
|
||||
Le paiement de votre abonnement a échoué.
|
||||
Raison: Carte bancaire expirée
|
||||
|
||||
Nous allons réessayer automatiquement dans 3 jours.
|
||||
Veuillez mettre à jour vos informations de paiement: [Lien]
|
||||
|
||||
Votre accès Premium reste actif jusqu'au 22 juillet (7 jours).
|
||||
"""
|
||||
|
||||
Scénario: Retry automatique paiement après 3 jours
|
||||
Étant donné que le paiement a échoué le 15 juillet
|
||||
Quand le 18 juillet arrive (J+3)
|
||||
Alors Mangopay/Apple/Google tente automatiquement un nouveau prélèvement
|
||||
Et si le paiement réussit, l'abonnement est renouvelé normalement
|
||||
Et si le paiement échoue encore, un 2ème retry est programmé
|
||||
|
||||
Scénario: Retry automatique paiement après 7 jours
|
||||
Étant donné que 2 tentatives ont échoué (15 juillet et 18 juillet)
|
||||
Quand le 22 juillet arrive (J+7)
|
||||
Alors une 3ème et dernière tentative est effectuée
|
||||
Et si le paiement réussit, l'abonnement est sauvé
|
||||
Et si le paiement échoue, l'abonnement est annulé automatiquement
|
||||
|
||||
Scénario: Annulation automatique après 3 échecs paiement
|
||||
Étant donné que les 3 tentatives de renouvellement ont échoué (J+0, J+3, J+7)
|
||||
Quand la 3ème tentative échoue
|
||||
Alors mon abonnement Premium est annulé automatiquement
|
||||
Et mon statut repasse à "Gratuit"
|
||||
Et je perds accès aux avantages Premium
|
||||
Et je reçois un email d'annulation
|
||||
|
||||
Scénario: Email annulation automatique pour impayé
|
||||
Étant donné que mon abonnement a été annulé pour échec paiement
|
||||
Quand l'annulation devient effective
|
||||
Alors je reçois un email:
|
||||
"""
|
||||
❌ Abonnement Premium annulé
|
||||
|
||||
Votre abonnement a été annulé suite à 3 échecs de paiement.
|
||||
|
||||
Vous repassez en mode gratuit et perdez l'accès à:
|
||||
• Contenus Premium exclusifs
|
||||
• Qualité audio supérieure
|
||||
• Téléchargements illimités
|
||||
|
||||
Pour réactiver Premium, mettez à jour vos informations de paiement: [Lien]
|
||||
"""
|
||||
|
||||
# ===== ANNULATION =====
|
||||
|
||||
Scénario: Annulation self-service dans Settings
|
||||
Étant donné que je veux annuler mon abonnement
|
||||
Quand j'accède à "Paramètres > Abonnement"
|
||||
Alors je vois un bouton "Annuler l'abonnement"
|
||||
Et je peux annuler en 2 clics sans contacter le support
|
||||
|
||||
Scénario: Confirmation avant annulation
|
||||
Étant donné que je clique sur "Annuler l'abonnement"
|
||||
Quand une popup de confirmation apparaît
|
||||
Alors je vois:
|
||||
"""
|
||||
😢 Vous allez annuler votre abonnement Premium
|
||||
|
||||
Vous perdrez l'accès à:
|
||||
• 0 publicité
|
||||
• Contenus Premium exclusifs
|
||||
• Qualité audio supérieure
|
||||
• Téléchargements illimités
|
||||
|
||||
Accès maintenu jusqu'au: 15 juillet 2025 (fin période payée)
|
||||
Pas de remboursement prorata.
|
||||
|
||||
[Confirmer l'annulation] [Rester Premium]
|
||||
```
|
||||
|
||||
Scénario: Accès Premium maintenu jusqu'à fin période payée
|
||||
Étant donné que j'ai annulé mon abonnement le 1er juillet
|
||||
Et que mon abonnement mensuel était valable jusqu'au 15 juillet
|
||||
Quand l'annulation est confirmée
|
||||
Alors je garde l'accès Premium jusqu'au 15 juillet
|
||||
Et à partir du 16 juillet, je repasse en gratuit
|
||||
Et je ne suis pas remboursé pour les 14 jours restants
|
||||
|
||||
Scénario: Justification pas de remboursement prorata
|
||||
Étant donné que l'industrie (Spotify, Netflix, YouTube) ne rembourse pas prorata
|
||||
Quand RoadWave applique la même règle
|
||||
Alors c'est le standard accepté par les utilisateurs
|
||||
Et cela simplifie la gestion comptable
|
||||
Et évite les abus (souscription puis annulation immédiate pour remboursement)
|
||||
|
||||
Scénario: Email confirmation annulation
|
||||
Étant donné que j'ai annulé mon abonnement
|
||||
Quand l'annulation est enregistrée
|
||||
Alors je reçois un email:
|
||||
"""
|
||||
✅ Annulation confirmée
|
||||
|
||||
Votre abonnement Premium a été annulé.
|
||||
|
||||
Accès Premium maintenu jusqu'au: 15 juillet 2025
|
||||
Après cette date, vous repasserez en mode gratuit.
|
||||
|
||||
Pas de remboursement pour la période restante (standard industrie).
|
||||
|
||||
Vous pouvez vous réabonner à tout moment !
|
||||
|
||||
Nous espérons vous revoir bientôt.
|
||||
Réabonner: [Lien]
|
||||
"""
|
||||
|
||||
Scénario: Pas de renouvellement après annulation
|
||||
Étant donné que j'ai annulé mon abonnement le 1er juillet
|
||||
Quand le 15 juillet arrive (date de renouvellement prévue)
|
||||
Alors aucun prélèvement n'est effectué
|
||||
Et mon statut passe automatiquement à "Gratuit"
|
||||
Et je ne reçois pas d'email de renouvellement
|
||||
|
||||
# ===== RÉABONNEMENT =====
|
||||
|
||||
Scénario: Réabonnement possible immédiatement
|
||||
Étant donné que j'ai annulé mon abonnement il y a 5 jours
|
||||
Quand j'accède à la page Premium
|
||||
Alors je peux me réabonner immédiatement
|
||||
Et le processus de paiement est le même que la première fois
|
||||
|
||||
Scénario: Pas de nouvelle période d'essai au réabonnement
|
||||
Étant donné que j'ai annulé mon abonnement il y a 3 mois
|
||||
Quand je me réabonne
|
||||
Alors je paie immédiatement 4.99€ (pas d'essai gratuit)
|
||||
Car RoadWave ne propose jamais d'essai gratuit (ni première fois ni réabonnement)
|
||||
|
||||
Scénario: Offre win-back pour utilisateurs ayant annulé
|
||||
Étant donné que j'ai annulé mon abonnement il y a 1 mois
|
||||
Quand je reçois un email de win-back
|
||||
Alors je vois une offre spéciale:
|
||||
"""
|
||||
🎁 On vous a manqué ?
|
||||
|
||||
Revenez en Premium avec une offre exclusive:
|
||||
-30% sur les 3 premiers mois (3.49€/mois au lieu de 4.99€)
|
||||
|
||||
Offre valable jusqu'au 31 juillet.
|
||||
|
||||
[Réactiver Premium]
|
||||
```
|
||||
|
||||
# ===== ARCHITECTURE DONNÉES =====
|
||||
|
||||
Scénario: Table subscriptions en base PostgreSQL
|
||||
Étant donné qu'un utilisateur souscrit à Premium
|
||||
Quand les données sont enregistrées
|
||||
Alors la table subscriptions contient:
|
||||
```sql
|
||||
CREATE TABLE subscriptions (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id UUID NOT NULL REFERENCES users(id) UNIQUE,
|
||||
mangopay_recurring_payin_id VARCHAR(255), -- Null si IAP
|
||||
mangopay_user_id VARCHAR(255), -- Null si IAP
|
||||
apple_transaction_id VARCHAR(255), -- Null si Mangopay
|
||||
google_purchase_token VARCHAR(255), -- Null si Mangopay
|
||||
status VARCHAR(50) NOT NULL, -- 'active', 'cancelled', 'expired', 'past_due'
|
||||
plan VARCHAR(50) NOT NULL, -- 'monthly', 'yearly'
|
||||
current_period_start TIMESTAMP NOT NULL,
|
||||
current_period_end TIMESTAMP NOT NULL,
|
||||
cancelled_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
Scénario: Statuts possibles dans subscription.status
|
||||
Étant donné qu'un abonnement peut avoir différents statuts
|
||||
Quand le statut est stocké en base
|
||||
Alors les valeurs possibles sont:
|
||||
| statut | description |
|
||||
| active | Abonnement actif et payé |
|
||||
| cancelled | Annulé par utilisateur (accès jusqu'à fin période) |
|
||||
| expired | Période terminée, pas renouvelé |
|
||||
| past_due | Échec paiement, en retry automatique |
|
||||
|
||||
Scénario: Cache Redis pour vérification Premium temps réel
|
||||
Étant donné qu'un utilisateur lance un contenu
|
||||
Quand l'app vérifie s'il est Premium
|
||||
Alors une clé Redis est consultée:
|
||||
```
|
||||
Key: premium:{user_id}
|
||||
Value: true/false
|
||||
TTL: 1 heure
|
||||
```
|
||||
Et si la clé n'existe pas, elle est recalculée depuis PostgreSQL
|
||||
Et cela garantit des performances <10ms
|
||||
|
||||
Scénario: Refresh cache Redis via webhooks
|
||||
Étant donné qu'un paiement est confirmé par Mangopay/Apple/Google
|
||||
Quand un webhook est reçu par RoadWave
|
||||
Alors le cache Redis premium:{user_id} est mis à jour immédiatement
|
||||
Et l'utilisateur voit son statut Premium activé sans délai
|
||||
|
||||
Scénario: Webhooks Mangopay - PAYIN_NORMAL_SUCCEEDED
|
||||
Étant donné qu'un paiement Mangopay réussit
|
||||
Quand Mangopay envoie le webhook PAYIN_NORMAL_SUCCEEDED
|
||||
Alors RoadWave met à jour subscriptions.status = 'active'
|
||||
Et met à jour current_period_end = NOW() + 1 mois
|
||||
Et refresh le cache Redis premium:{user_id} = true
|
||||
|
||||
Scénario: Webhooks Mangopay - PAYIN_NORMAL_FAILED
|
||||
Étant donné qu'un paiement Mangopay échoue
|
||||
Quand Mangopay envoie le webhook PAYIN_NORMAL_FAILED
|
||||
Alors RoadWave met à jour subscriptions.status = 'past_due'
|
||||
Et programme un retry automatique dans 3 jours
|
||||
Et envoie un email à l'utilisateur
|
||||
|
||||
Scénario: Webhooks Apple - App Store Server Notifications
|
||||
Étant donné qu'un paiement Apple IAP change de statut
|
||||
Quand Apple envoie une notification serveur
|
||||
Alors RoadWave parse la notification (JSON)
|
||||
Et met à jour la subscription en conséquence
|
||||
Et refresh le cache Redis
|
||||
|
||||
Scénario: Webhooks Google - Real-time Developer Notifications
|
||||
Étant donné qu'un paiement Google Play change de statut
|
||||
Quand Google envoie une notification temps réel
|
||||
Alors RoadWave parse la notification (JSON)
|
||||
Et met à jour la subscription en conséquence
|
||||
Et refresh le cache Redis
|
||||
|
||||
# ===== STATISTIQUES ET MONITORING =====
|
||||
|
||||
Scénario: Dashboard admin - Métriques abonnements
|
||||
Étant donné qu'un admin consulte les métriques Premium
|
||||
Quand il accède au dashboard
|
||||
Alors il voit:
|
||||
| métrique | valeur |
|
||||
| Abonnés actifs | 12,547 |
|
||||
| Nouveaux abonnements ce mois | 1,234 |
|
||||
| Annulations ce mois | 287 (2.3%) |
|
||||
| Churn rate mensuel | 2.3% |
|
||||
| MRR (Revenus mensuels récurrents) | 58,890€ |
|
||||
| Taux conversion gratuit → Premium | 8.5% |
|
||||
|
||||
Scénario: Calcul churn rate mensuel
|
||||
Étant donné que 287 utilisateurs ont annulé ce mois
|
||||
Et qu'il y avait 12,547 abonnés au début du mois
|
||||
Quand le churn rate est calculé
|
||||
Alors churn = 287 / 12,547 = 2.3%
|
||||
Et un churn <5% est considéré comme excellent
|
||||
Et RoadWave surveille cette métrique de près
|
||||
|
||||
Scénario: Alerte si churn rate >5%
|
||||
Étant donné que le churn rate mensuel dépasse 5%
|
||||
Quand le système détecte cette anomalie
|
||||
Alors une alerte est envoyée à l'équipe:
|
||||
"""
|
||||
⚠️ Churn rate anormal: 6.2%
|
||||
|
||||
Nombre annulations ce mois: 778
|
||||
Causes principales:
|
||||
- Prix jugé trop élevé: 42%
|
||||
- Utilisation faible: 28%
|
||||
- Concurrent moins cher: 18%
|
||||
- Autre: 12%
|
||||
|
||||
Action recommandée: Enquête satisfaction + offres win-back
|
||||
"""
|
||||
|
||||
Scénario: Enquête satisfaction à l'annulation
|
||||
Étant donné que je viens d'annuler mon abonnement
|
||||
Quand l'annulation est confirmée
|
||||
Alors je vois un questionnaire rapide:
|
||||
"""
|
||||
Pourquoi annulez-vous Premium ?
|
||||
|
||||
☐ Prix trop élevé
|
||||
☐ Je n'utilise pas assez RoadWave
|
||||
☐ Pas assez de contenus exclusifs
|
||||
☐ Problèmes techniques
|
||||
☐ J'ai trouvé une alternative moins chère
|
||||
☐ Autre: [Texte libre]
|
||||
|
||||
[Envoyer] [Ignorer]
|
||||
```
|
||||
Et les réponses aident à améliorer l'offre Premium
|
||||
|
||||
Scénario: Répartition canaux souscription
|
||||
Étant donné qu'un admin analyse les canaux de souscription
|
||||
Quand il consulte les statistiques
|
||||
Alors il voit:
|
||||
| canal | abonnés | % total | revenus/mois |
|
||||
| Web (Mangopay) | 8,234 | 65.6% | 41,088€ |
|
||||
| iOS (Apple) | 2,845 | 22.7% | 17,042€ |
|
||||
| Android (Google)| 1,468 | 11.7% | 8,793€ |
|
||||
Et cela aide à orienter les efforts marketing (inciter web = moins de commission)
|
||||
|
||||
Scénario: Performance vérification Premium <10ms
|
||||
Étant donné que 100 000 utilisateurs consultent des contenus simultanément
|
||||
Quand chaque requête vérifie le statut Premium via Redis
|
||||
Alors le temps de réponse moyen est <10ms
|
||||
Et Redis gère facilement 100 000 requêtes/seconde
|
||||
Et l'expérience utilisateur est fluide
|
||||
|
||||
Scénario: Backup données abonnements
|
||||
Étant donné que les données d'abonnements sont critiques
|
||||
Quand un backup est effectué
|
||||
Alors PostgreSQL est répliqué en temps réel sur un replica
|
||||
Et un snapshot quotidien est stocké sur S3
|
||||
Et en cas de crash, les données peuvent être restaurées <5 minutes
|
||||
279
features/premium/multi-devices-detection.feature
Normal file
279
features/premium/multi-devices-detection.feature
Normal file
@@ -0,0 +1,279 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Multi-devices et détection simultanée
|
||||
En tant qu'abonné Premium
|
||||
Je veux utiliser mon compte sur plusieurs appareils
|
||||
Mais limité à 1 seul stream actif à la fois pour éviter le partage abusif
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis un utilisateur Premium actif
|
||||
Et que mon compte est valide
|
||||
|
||||
# ===== LIMITE 1 STREAM ACTIF =====
|
||||
|
||||
Scénario: 1 seul stream actif autorisé par compte
|
||||
Étant donné que je n'écoute rien actuellement
|
||||
Quand je lance un contenu sur mon iPhone
|
||||
Alors le stream démarre normalement
|
||||
Et Redis enregistre: active_streams:{user_id} = {device_id: "iPhone", started_at: timestamp}
|
||||
|
||||
Scénario: Détection connexion simultanée - Arrêt premier device
|
||||
Étant donné que j'écoute un contenu sur mon iPhone
|
||||
Quand je lance un contenu sur mon iPad
|
||||
Alors le système détecte une session active sur iPhone
|
||||
Et la lecture sur iPhone est arrêtée immédiatement (WebSocket close)
|
||||
Et je vois sur iPhone: "Lecture interrompue : votre compte est utilisé sur un autre appareil"
|
||||
Et la lecture démarre sur iPad normalement
|
||||
|
||||
Scénario: Message explicite sur device interrompu
|
||||
Étant donné que ma lecture sur iPhone vient d'être interrompue
|
||||
Quand je regarde l'écran de mon iPhone
|
||||
Alors je vois une overlay avec le message:
|
||||
"""
|
||||
🔴 Lecture interrompue
|
||||
|
||||
Votre compte Premium est utilisé sur un autre appareil.
|
||||
|
||||
Un seul stream actif est autorisé à la fois pour protéger
|
||||
les revenus des créateurs et éviter le partage de compte.
|
||||
"""
|
||||
Et un bouton "Reprendre ici" est disponible
|
||||
|
||||
Scénario: Reprendre lecture sur device interrompu
|
||||
Étant donné que ma lecture sur iPhone a été interrompue
|
||||
Et que je veux reprendre sur iPhone
|
||||
Quand je clique sur "Reprendre ici"
|
||||
Alors la lecture démarre sur iPhone
|
||||
Et l'iPad est à son tour interrompu avec le même message
|
||||
Et le "ping-pong" entre devices est possible (mais pénible)
|
||||
|
||||
# ===== IMPLÉMENTATION TECHNIQUE REDIS =====
|
||||
|
||||
Scénario: Enregistrement session active dans Redis
|
||||
Étant donné que je lance un contenu sur mon iPhone
|
||||
Quand la lecture démarre
|
||||
Alors une entrée Redis est créée:
|
||||
```
|
||||
Key: active_streams:{user_id}
|
||||
Value: {
|
||||
"device_id": "iPhone-ABC123",
|
||||
"started_at": "2025-06-15T14:30:00Z",
|
||||
"content_id": "xyz789"
|
||||
}
|
||||
TTL: 300 secondes (5 minutes)
|
||||
```
|
||||
|
||||
Scénario: Heartbeat toutes les 30 secondes pour maintenir session
|
||||
Étant donné que j'écoute un contenu sur mon iPhone
|
||||
Quand 30 secondes s'écoulent
|
||||
Alors l'app envoie un heartbeat au serveur
|
||||
Et le serveur refresh le TTL Redis à 300 secondes
|
||||
Et la session reste active
|
||||
|
||||
Scénario: Session considérée morte après 5 minutes sans heartbeat
|
||||
Étant donné que j'écoute un contenu sur mon iPhone
|
||||
Mais que l'app crash ou que le réseau coupe
|
||||
Quand 5 minutes s'écoulent sans heartbeat
|
||||
Alors l'entrée Redis expire automatiquement (TTL atteint)
|
||||
Et je peux relancer sur n'importe quel device sans conflit
|
||||
|
||||
Scénario: Vérification session avant démarrage lecture
|
||||
Étant donné que je veux lancer un contenu sur mon iPad
|
||||
Quand j'appuie sur Play
|
||||
Alors le serveur vérifie Redis: active_streams:{user_id}
|
||||
Et si une session existe sur un autre device, elle est tuée
|
||||
Et la nouvelle session iPad est enregistrée dans Redis
|
||||
|
||||
Scénario: Gestion multi-utilisateurs simultanés
|
||||
Étant donné que 100 000 utilisateurs Premium écoutent simultanément
|
||||
Quand Redis stocke 100 000 entrées active_streams
|
||||
Alors chaque entrée a un TTL de 5 minutes
|
||||
Et Redis gère facilement cette charge (~10 MB de RAM)
|
||||
Et les vérifications sont quasi-instantanées (O(1))
|
||||
|
||||
# ===== EXCEPTIONS ET CAS PARTICULIERS =====
|
||||
|
||||
Scénario: Contenus téléchargés (offline) ne comptent pas comme stream
|
||||
Étant donné que j'ai téléchargé 20 contenus en mode offline
|
||||
Quand j'écoute un contenu téléchargé sur mon iPhone sans réseau
|
||||
Alors aucune session active n'est enregistrée dans Redis
|
||||
Et je peux écouter offline pendant qu'un autre device stream online
|
||||
Car le contenu offline ne consomme pas de bande passante serveur
|
||||
|
||||
Scénario: Transition rapide device <10s tolérée
|
||||
Étant donné que j'écoute dans ma voiture sur mon iPhone
|
||||
Et que j'arrive chez moi
|
||||
Quand je lance la lecture sur mon iPad dans les 10 secondes
|
||||
Alors la transition est considérée comme un changement de device légitime
|
||||
Et aucun message d'erreur n'est affiché sur iPhone
|
||||
Et la lecture reprend exactement où j'étais sur iPad
|
||||
|
||||
Scénario: Détection transition rapide via timestamps
|
||||
Étant donné que la session iPhone a started_at = 14:30:00
|
||||
Quand je lance sur iPad à 14:30:05 (5 secondes après)
|
||||
Alors le serveur détecte: diff = 5s < 10s
|
||||
Et applique une "graceful transition" (pas de message d'erreur iPhone)
|
||||
Et Redis met à jour: active_streams:{user_id} = {device_id: "iPad", ...}
|
||||
|
||||
Scénario: Plusieurs devices disponibles mais 1 seul actif
|
||||
Étant donné que je possède:
|
||||
| device | status |
|
||||
| iPhone | Installé |
|
||||
| iPad | Installé |
|
||||
| MacBook (web) | Connecté |
|
||||
| Android (conjoint)| Installé |
|
||||
Quand je lance un stream sur n'importe quel device
|
||||
Alors seulement 1 peut être actif à la fois
|
||||
Et les autres devices sont en "standby"
|
||||
|
||||
# ===== JUSTIFICATIONS =====
|
||||
|
||||
Scénario: Justification anti-partage compte
|
||||
Étant donné qu'un utilisateur Premium partage son compte avec un ami
|
||||
Quand les 2 personnes essaient d'écouter simultanément
|
||||
Alors la lecture est constamment interrompue sur l'un ou l'autre
|
||||
Et l'expérience devient inutilisable
|
||||
Et cela décourage fortement le partage de compte
|
||||
|
||||
Scénario: Justification protection revenus créateurs
|
||||
Étant donné que 1 abonnement Premium = 4.99€/mois
|
||||
Quand 70% sont reversés aux créateurs (3.49€)
|
||||
Alors les créateurs sont rémunérés pour 1 personne
|
||||
Et si 2 personnes utilisent le même compte simultanément, c'est injuste
|
||||
Et la limite 1 stream protège l'équité du système
|
||||
|
||||
Scénario: Justification UX claire
|
||||
Étant donné qu'un stream est interrompu sur un device
|
||||
Quand l'utilisateur voit le message explicite
|
||||
Alors il comprend immédiatement pourquoi (autre device actif)
|
||||
Et il peut choisir de reprendre sur le device actuel ou l'autre
|
||||
Et il n'y a pas de confusion ou frustration
|
||||
|
||||
Scénario: Comparaison avec Spotify (limite 1 stream)
|
||||
Étant donné que Spotify Premium limite aussi à 1 stream actif
|
||||
Quand RoadWave applique la même règle
|
||||
Alors les utilisateurs connaissent déjà ce comportement
|
||||
Et cela paraît normal et accepté par l'industrie
|
||||
|
||||
Scénario: Comparaison avec Netflix (plusieurs streams selon formule)
|
||||
Étant donné que Netflix permet 1-4 streams selon la formule
|
||||
Quand RoadWave limite à 1 stream pour tous
|
||||
Alors c'est plus strict que Netflix
|
||||
Mais Netflix cible le foyer familial (TV partagée)
|
||||
Alors que RoadWave cible l'individu conducteur (usage personnel)
|
||||
|
||||
# ===== MONITORING ET DÉTECTION ABUS =====
|
||||
|
||||
Scénario: Détection pattern suspect - Changements devices fréquents
|
||||
Étant donné qu'un utilisateur change de device 50 fois en 1 heure
|
||||
Quand le système détecte ce pattern anormal
|
||||
Alors une alerte est générée pour l'équipe modération
|
||||
Et le compte peut être marqué pour surveillance
|
||||
Et si abus confirmé, suspension possible
|
||||
|
||||
Scénario: Logs des changements de device
|
||||
Étant donné que je change de device plusieurs fois par jour
|
||||
Quand les changements sont loggés
|
||||
Alors chaque événement est enregistré:
|
||||
| timestamp | from_device | to_device | content_id |
|
||||
| 2025-06-15 08:30:00 | null | iPhone | abc123 |
|
||||
| 2025-06-15 09:15:00 | iPhone | iPad | def456 |
|
||||
| 2025-06-15 18:30:00 | iPad | iPhone | ghi789 |
|
||||
Et ces logs aident à détecter les partages de compte
|
||||
|
||||
Scénario: Métriques admin - Changements devices par utilisateur
|
||||
Étant donné qu'un admin consulte les métriques de streaming
|
||||
Quand il accède au dashboard
|
||||
Alors il voit:
|
||||
| métrique | valeur |
|
||||
| Utilisateurs Premium actifs | 12,547 |
|
||||
| Changements de device/jour (médiane) | 2 |
|
||||
| Utilisateurs >10 changements/jour | 47 (0.4%) |
|
||||
| Comptes suspects (>20 changements/j) | 3 |
|
||||
|
||||
Scénario: Email d'avertissement si changements excessifs
|
||||
Étant donné que je change de device 30 fois par jour pendant 3 jours
|
||||
Quand le système détecte ce pattern
|
||||
Alors je reçois un email d'avertissement:
|
||||
"""
|
||||
⚠️ Activité inhabituelle détectée sur votre compte
|
||||
|
||||
Nous avons détecté un nombre anormalement élevé de changements de device (30/jour).
|
||||
|
||||
Rappel: Le partage de compte Premium est interdit selon nos CGU.
|
||||
Un seul stream actif est autorisé à la fois.
|
||||
|
||||
Si cette activité continue, votre compte pourra être suspendu.
|
||||
"""
|
||||
|
||||
Scénario: Suspension compte après avertissement ignoré
|
||||
Étant donné que j'ai reçu un email d'avertissement il y a 7 jours
|
||||
Mais que je continue à changer de device 30 fois par jour
|
||||
Quand l'équipe modération examine le compte
|
||||
Alors mon compte Premium peut être suspendu pour partage abusif
|
||||
Et je reçois un email de suspension avec justification
|
||||
|
||||
# ===== SUPPORT UTILISATEUR =====
|
||||
|
||||
Scénario: FAQ - Pourquoi ma lecture s'arrête quand j'utilise un autre device ?
|
||||
Étant donné que je consulte la FAQ Premium
|
||||
Quand je cherche "lecture interrompue"
|
||||
Alors je trouve la réponse:
|
||||
"""
|
||||
Q: Pourquoi ma lecture s'arrête quand j'utilise un autre appareil ?
|
||||
|
||||
R: Votre abonnement Premium autorise 1 seul stream actif à la fois.
|
||||
Si vous lancez la lecture sur un autre appareil, le premier est automatiquement arrêté.
|
||||
|
||||
Pourquoi cette limite ?
|
||||
- Protéger les revenus des créateurs (1 abonnement = 1 personne)
|
||||
- Éviter le partage de compte abusif
|
||||
|
||||
Vous pouvez utiliser autant d'appareils que vous voulez, mais un seul peut lire à la fois.
|
||||
"""
|
||||
|
||||
Scénario: Support - Utilisateur pense être piraté
|
||||
Étant donné qu'un utilisateur voit constamment "Lecture interrompue"
|
||||
Et qu'il pense que son compte est piraté
|
||||
Quand il contacte le support
|
||||
Alors le support vérifie les logs de changements de device
|
||||
Et peut identifier les devices (iPhone, iPad perso vs iPhone inconnu)
|
||||
Et conseille de changer le mot de passe si device inconnu détecté
|
||||
|
||||
Scénario: Changement mot de passe déconnecte tous les devices
|
||||
Étant donné que je pense que mon compte est compromis
|
||||
Quand je change mon mot de passe
|
||||
Alors tous mes devices sont déconnectés immédiatement
|
||||
Et les sessions actives dans Redis sont supprimées
|
||||
Et je dois me reconnecter sur chaque device
|
||||
Et cela sécurise mon compte
|
||||
|
||||
# ===== TESTS TECHNIQUES =====
|
||||
|
||||
Scénario: Test charge - 100 000 vérifications/seconde
|
||||
Étant donné que 100 000 utilisateurs Premium lancent des contenus
|
||||
Quand chaque lancement vérifie Redis (GET active_streams:{user_id})
|
||||
Alors Redis peut gérer facilement 100 000 requêtes/seconde
|
||||
Et le temps de réponse moyen est <1ms
|
||||
Et aucun ralentissement n'est constaté
|
||||
|
||||
Scénario: Test failover Redis
|
||||
Étant donné que le serveur Redis principal tombe en panne
|
||||
Quand le failover automatique vers le replica Redis s'active
|
||||
Alors les sessions actives peuvent être perdues temporairement (max 5 min)
|
||||
Mais les utilisateurs peuvent relancer immédiatement
|
||||
Et l'impact est minimal (pas de perte de données critiques)
|
||||
|
||||
Scénario: Test concurrence - Lancement simultané 2 devices
|
||||
Étant donné que je lance exactement au même instant sur iPhone et iPad
|
||||
Quand les 2 requêtes arrivent en parallèle au serveur
|
||||
Alors Redis utilise un lock (SETNX) pour atomicité
|
||||
Et 1 seul device gagne (par exemple iPhone)
|
||||
Et l'autre device (iPad) reçoit immédiatement une erreur
|
||||
Et l'utilisateur peut retry sur iPad si souhaité
|
||||
|
||||
Scénario: Nettoyage automatique sessions expirées
|
||||
Étant donné que 1000 sessions Redis ont expiré (TTL atteint)
|
||||
Quand Redis supprime automatiquement ces entrées
|
||||
Alors la mémoire est libérée
|
||||
Et les nouveaux streams peuvent démarrer sans conflit
|
||||
Et aucune intervention manuelle n'est nécessaire
|
||||
254
features/premium/offre-tarification.feature
Normal file
254
features/premium/offre-tarification.feature
Normal file
@@ -0,0 +1,254 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Offre et tarification Premium
|
||||
En tant qu'utilisateur
|
||||
Je veux pouvoir souscrire à un abonnement Premium
|
||||
Afin de profiter d'une expérience sans publicité avec des avantages exclusifs
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis connecté en tant qu'utilisateur
|
||||
|
||||
# ===== FORMULES DISPONIBLES =====
|
||||
|
||||
Scénario: Formule mensuelle à 4.99€/mois
|
||||
Étant donné que je consulte les offres Premium
|
||||
Quand je vois la formule mensuelle
|
||||
Alors le prix affiché est 4.99€/mois
|
||||
Et il n'y a aucune réduction
|
||||
Et le prix effectif par mois est 4.99€
|
||||
|
||||
Scénario: Formule annuelle à 49.99€/an (2 mois offerts)
|
||||
Étant donné que je consulte les offres Premium
|
||||
Quand je vois la formule annuelle
|
||||
Alors le prix affiché est 49.99€/an
|
||||
Et l'économie affichée est "2 mois offerts"
|
||||
Et le prix effectif par mois est 4.16€
|
||||
Et je vois le badge "Meilleure offre"
|
||||
|
||||
Scénario: Calcul économie formule annuelle
|
||||
Étant donné que la formule mensuelle coûte 4.99€/mois
|
||||
Quand je calcule le coût annuel en mensuel
|
||||
Alors 12 mois × 4.99€ = 59.88€/an
|
||||
Et la formule annuelle coûte 49.99€
|
||||
Et l'économie est de 9.89€ (≈ 2 mois gratuits)
|
||||
Et la réduction est de 16.5%
|
||||
|
||||
Scénario: Pas d'essai gratuit disponible
|
||||
Étant donné que je consulte les offres Premium
|
||||
Quand je recherche une option "Essai gratuit"
|
||||
Alors aucune option d'essai gratuit n'est proposée
|
||||
Et je dois payer dès le premier jour pour accéder au Premium
|
||||
|
||||
Scénario: Justification absence essai gratuit - Anti-abus vacances
|
||||
Étant donné que RoadWave ne propose pas d'essai gratuit
|
||||
Quand un utilisateur envisage un road trip de 14 jours
|
||||
Alors il ne peut pas s'abonner pour l'essai gratuit puis annuler
|
||||
Et cela évite les inscriptions opportunistes
|
||||
Et protège les revenus des créateurs
|
||||
|
||||
Scénario: Justification absence essai gratuit - Protection revenus créateurs
|
||||
Étant donné qu'un utilisateur Premium écoute des contenus
|
||||
Quand il génère des écoutes dès le jour 1
|
||||
Alors les créateurs sont rémunérés immédiatement (70% de 4.99€)
|
||||
Et il n'y a pas de "période gratuite" sans rémunération créateurs
|
||||
|
||||
Scénario: Justification absence essai gratuit - Simplicité
|
||||
Étant donné que RoadWave gère les abonnements
|
||||
Quand il n'y a pas d'essai gratuit
|
||||
Alors pas de gestion complexe de période trial
|
||||
Et pas de workflow de conversion trial → payant
|
||||
Et cela réduit la complexité technique
|
||||
|
||||
Scénario: Justification absence essai gratuit - Engagement
|
||||
Étant donné qu'un utilisateur paie dès le début
|
||||
Quand il souscrit à Premium
|
||||
Alors il est plus engagé qu'un utilisateur en essai gratuit
|
||||
Et le taux de churn est généralement plus faible
|
||||
Et la lifetime value (LTV) est plus élevée
|
||||
|
||||
Scénario: Pas de partage familial au MVP
|
||||
Étant donné que je consulte les offres Premium
|
||||
Quand je recherche une option "Famille" ou "Partage"
|
||||
Alors aucune option de partage familial n'est disponible
|
||||
Et seuls les abonnements individuels sont proposés
|
||||
|
||||
Scénario: Justification absence partage familial - Complexité technique
|
||||
Étant donné que le partage familial nécessite:
|
||||
| fonctionnalité | complexité |
|
||||
| Gestion invitations | Moyenne |
|
||||
| Validation liens famille | Moyenne |
|
||||
| Limite devices par membre | Élevée |
|
||||
| Dashboard admin famille | Élevée |
|
||||
Quand RoadWave évalue le ROI
|
||||
Alors le coût dev/support est trop élevé pour le MVP
|
||||
Et la fonctionnalité est reportée post-MVP
|
||||
|
||||
Scénario: Justification absence partage familial - Risque abus
|
||||
Étant donné qu'une offre famille permet 5-6 membres
|
||||
Quand il n'y a pas de vérification stricte de lien familial
|
||||
Alors des "familles" de 6 inconnus pourraient se former
|
||||
Et cela réduirait fortement les revenus (6 personnes pour 1 abonnement)
|
||||
|
||||
Scénario: Justification absence partage familial - Cible individuelle
|
||||
Étant donné que RoadWave cible principalement les conducteurs
|
||||
Quand chaque conducteur utilise l'app individuellement en voiture
|
||||
Alors le besoin de partage familial est limité
|
||||
Et la plupart des utilisateurs sont des individus (pas des familles)
|
||||
|
||||
Scénario: Post-MVP - Offre Famille à 9.99€/mois pour 5 comptes
|
||||
Étant donné que RoadWave envisage une offre Famille post-MVP
|
||||
Quand la fonctionnalité est spécifiée
|
||||
Alors le prix serait 9.99€/mois pour 5 comptes
|
||||
Et cela représente 2€/mois/personne
|
||||
Mais cette offre n'est pas disponible au MVP
|
||||
|
||||
Scénario: Comparaison tarif - Spotify à 10.99€/mois
|
||||
Étant donné que Spotify Premium coûte 10.99€/mois
|
||||
Quand RoadWave fixe son prix à 4.99€/mois
|
||||
Alors RoadWave est 54.5% moins cher que Spotify
|
||||
Et cela positionne RoadWave comme très accessible
|
||||
|
||||
Scénario: Comparaison tarif - YouTube Premium à 11.99€/mois
|
||||
Étant donné que YouTube Premium coûte 11.99€/mois
|
||||
Quand RoadWave fixe son prix à 4.99€/mois
|
||||
Alors RoadWave est 58.4% moins cher que YouTube Premium
|
||||
Et cela est un argument commercial fort
|
||||
|
||||
Scénario: Comparaison tarif - Apple Music à 10.99€/mois
|
||||
Étant donné qu'Apple Music coûte 10.99€/mois
|
||||
Quand RoadWave fixe son prix à 4.99€/mois
|
||||
Alors RoadWave est 54.5% moins cher qu'Apple Music
|
||||
Et cela attire les utilisateurs sensibles au prix
|
||||
|
||||
Scénario: Justification tarif bas - Cible conducteurs quotidiens
|
||||
Étant donné que RoadWave cible les trajets quotidiens domicile-travail
|
||||
Quand le prix est fixé à 4.99€/mois
|
||||
Alors c'est un budget raisonnable pour un conducteur
|
||||
Et équivalent à ~1-2 cafés/mois
|
||||
Et psychologiquement acceptable pour un usage quotidien
|
||||
|
||||
Scénario: Justification formule annuelle - Engagement long terme
|
||||
Étant donné que la formule annuelle offre 2 mois gratuits
|
||||
Quand un utilisateur souscrit pour 1 an
|
||||
Alors il s'engage sur le long terme
|
||||
Et RoadWave sécurise 49.99€ de revenus immédiatement
|
||||
Et le cash flow est amélioré
|
||||
|
||||
Scénario: Justification formule annuelle - Réduction churn
|
||||
Étant donné qu'un utilisateur paie 49.99€ pour l'année
|
||||
Quand il envisage d'arrêter après 3 mois
|
||||
Alors il a déjà payé pour 12 mois
|
||||
Et il continuera probablement à utiliser l'app
|
||||
Et le taux de churn est réduit significativement
|
||||
|
||||
Scénario: Affichage comparatif des deux formules
|
||||
Étant donné que je consulte la page Premium
|
||||
Quand je vois les deux formules côte à côte
|
||||
Alors je vois:
|
||||
```
|
||||
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
|
||||
│ MENSUEL │ │ ANNUEL ⭐ Meilleure offre │
|
||||
│ │ │ │
|
||||
│ 4.99€/mois │ │ 49.99€/an │
|
||||
│ │ │ soit 4.16€/mois │
|
||||
│ Engagement 1 mois │ │ │
|
||||
│ │ │ 💰 2 mois offerts ! │
|
||||
│ │ │ Économie: 9.89€/an │
|
||||
│ │ │ │
|
||||
│ [S'abonner] │ │ [S'abonner] │
|
||||
└─────────────────────────────────┘ └─────────────────────────────────┘
|
||||
```
|
||||
|
||||
Scénario: Mise en avant formule annuelle
|
||||
Étant donné que je consulte la page Premium
|
||||
Quand je vois les deux formules
|
||||
Alors la formule annuelle a un badge "Meilleure offre" ⭐
|
||||
Et elle est visuellement mise en avant (bordure colorée, taille plus grande)
|
||||
Et l'économie de 2 mois est affichée en gros
|
||||
Et cela incite à choisir la formule annuelle
|
||||
|
||||
Scénario: Lien "Pourquoi pas d'essai gratuit ?" en FAQ
|
||||
Étant donné que je consulte la page Premium
|
||||
Quand je clique sur "FAQ"
|
||||
Alors je vois une question "Pourquoi pas d'essai gratuit ?"
|
||||
Et la réponse explique:
|
||||
"""
|
||||
RoadWave ne propose pas d'essai gratuit pour 3 raisons:
|
||||
|
||||
1. Protection des créateurs: Vos écoutes rémunèrent les créateurs dès le premier jour.
|
||||
2. Engagement: Un abonnement payant dès le début garantit une meilleure expérience.
|
||||
3. Anti-abus: Éviter les inscriptions opportunistes (essai avant vacances puis annulation).
|
||||
|
||||
Le prix de 4.99€/mois reste très accessible (moitié prix de Spotify/YouTube Premium).
|
||||
"""
|
||||
|
||||
Scénario: A/B test formule annuelle (post-MVP)
|
||||
Étant donné que RoadWave veut optimiser la conversion annuelle
|
||||
Quand un A/B test est lancé
|
||||
Alors groupe A voit "2 mois offerts" (économie en durée)
|
||||
Et groupe B voit "Économisez 9.89€" (économie en argent)
|
||||
Et les taux de souscription sont mesurés
|
||||
Et le message le plus performant est déployé
|
||||
|
||||
Scénario: Promo temporaire exceptionnelle (Black Friday, etc.)
|
||||
Étant donné que c'est le Black Friday
|
||||
Quand une promo temporaire est activée
|
||||
Alors la formule annuelle peut passer à 39.99€/an (au lieu de 49.99€)
|
||||
Et l'économie affichée est "4 mois offerts !"
|
||||
Et la promo dure 3 jours uniquement
|
||||
Et cela génère un pic de souscriptions
|
||||
|
||||
Scénario: Code promo partenariat influenceur
|
||||
Étant donné qu'un influenceur promeut RoadWave
|
||||
Quand il partage un code promo "INFLUENCEUR20"
|
||||
Alors les utilisateurs obtiennent -20% sur le premier mois (3.99€ au lieu de 4.99€)
|
||||
Et le code est valable 1 mois
|
||||
Et les conversions sont trackées par code promo
|
||||
|
||||
Scénario: Statistiques admin - Répartition formules
|
||||
Étant donné qu'un admin consulte les métriques d'abonnements
|
||||
Quand il accède au dashboard
|
||||
Alors il voit:
|
||||
| métrique | valeur |
|
||||
| Abonnés Premium total | 12,547 |
|
||||
| Abonnés mensuels | 7,234 (58%)|
|
||||
| Abonnés annuels | 5,313 (42%)|
|
||||
| Revenus mensuels récurrents | 58,890€ |
|
||||
Et ces données aident à piloter la stratégie tarifaire
|
||||
|
||||
Scénario: Calcul revenus mensuels récurrents (MRR)
|
||||
Étant donné que RoadWave a:
|
||||
| formule | nombre abonnés | prix |
|
||||
| Mensuel | 7,234 | 4.99€/mois|
|
||||
| Annuel | 5,313 | 49.99€/an |
|
||||
Quand le MRR est calculé
|
||||
Alors MRR mensuel = 7,234 × 4.99€ = 36,098€
|
||||
Et MRR annuel ramené au mois = 5,313 × 49.99€ / 12 = 22,139€
|
||||
Et MRR total = 58,237€/mois
|
||||
|
||||
Scénario: Projection revenus annuels (ARR)
|
||||
Étant donné que le MRR est de 58,237€
|
||||
Quand l'ARR est calculé
|
||||
Alors ARR = 58,237€ × 12 = 698,844€/an
|
||||
Et cela aide à évaluer la valorisation de l'entreprise
|
||||
|
||||
Scénario: Affichage prix TTC (TVA incluse)
|
||||
Étant donné que RoadWave est une plateforme française
|
||||
Quand les prix sont affichés
|
||||
Alors tous les prix sont TTC (TVA 20% incluse)
|
||||
Et le prix 4.99€ inclut déjà la TVA
|
||||
Et cela respecte la réglementation française
|
||||
|
||||
Scénario: Performance page Premium avec cache
|
||||
Étant donné que la page Premium est consultée fréquemment
|
||||
Quand un utilisateur charge la page
|
||||
Alors les prix et avantages sont servis depuis un cache CDN
|
||||
Et le temps de chargement est <200ms
|
||||
Et cela garantit une expérience fluide
|
||||
|
||||
Scénario: Localisation prix selon pays (post-MVP)
|
||||
Étant donné que RoadWave se lance à l'international post-MVP
|
||||
Quand un utilisateur se connecte depuis l'Allemagne
|
||||
Alors les prix peuvent être ajustés (ex: 4.99€ en France, 4.49€ en Pologne)
|
||||
Et cela respecte le pouvoir d'achat local
|
||||
Mais cette fonctionnalité n'est pas au MVP (France uniquement)
|
||||
Reference in New Issue
Block a user