Initial commit
This commit is contained in:
263
features/abonnements/audio-guides-pieton.feature
Normal file
263
features/abonnements/audio-guides-pieton.feature
Normal file
@@ -0,0 +1,263 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Audio-guides multi-séquences pour piétons
|
||||
En tant qu'auditeur à pied
|
||||
Je veux profiter d'audio-guides structurés lors de mes visites
|
||||
Afin de découvrir des lieux de manière autonome et à mon rythme
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis connecté en tant qu'auditeur
|
||||
Et que je suis en mode piéton (vitesse <5 km/h)
|
||||
|
||||
Scénario: Détection d'audio-guide à proximité
|
||||
Étant donné que je me trouve à 80 mètres du Musée du Louvre
|
||||
Et que 3 audio-guides sont disponibles pour ce lieu
|
||||
Quand le système détecte ma position
|
||||
Alors je reçois une notification push:
|
||||
"""
|
||||
📍 Audio-guide disponible : Musée du Louvre
|
||||
Choisissez parmi 3 guides pour Musée du Louvre
|
||||
Tap pour explorer
|
||||
"""
|
||||
|
||||
Scénario: Rayon de détection de 100m
|
||||
Étant donné qu'un audio-guide est centré aux coordonnées GPS du Louvre
|
||||
Quand je suis à exactement 100m du centre
|
||||
Alors la notification est déclenchée
|
||||
Et quand je suis à 101m, aucune notification n'est envoyée
|
||||
|
||||
Scénario: Page de sélection des audio-guides
|
||||
Étant donné que j'ai tapé sur la notification audio-guide
|
||||
Quand la page de sélection s'affiche
|
||||
Alors je vois une liste de guides disponibles:
|
||||
| titre | créateur | nb_sequences | durée | note | écoutes |
|
||||
| Visite complète | Créateur A | 12 | 45 min | 4.8 | 1.2K |
|
||||
| Œuvres majeures | Créateur B | 5 | 20 min | 4.9 | 3.5K |
|
||||
| Visite famille | Créateur C | 8 | 30 min | 4.7 | 850 |
|
||||
|
||||
Scénario: Sélection d'un audio-guide
|
||||
Étant donné que je suis sur la page de sélection
|
||||
Quand je tape sur "Visite complète (45 min)"
|
||||
Alors l'interface de lecture d'audio-guide s'ouvre
|
||||
Et la séquence 1 commence automatiquement
|
||||
Et je vois la liste complète des 12 séquences
|
||||
|
||||
Scénario: Interface de lecture audio-guide
|
||||
Étant donné que j'ai sélectionné un audio-guide de 12 séquences
|
||||
Quand l'interface s'affiche
|
||||
Alors je vois:
|
||||
| élément | exemple |
|
||||
| Titre guide | 🎨 Visite complète • Musée du Louvre |
|
||||
| Piste actuelle | Piste 2/12 |
|
||||
| Titre séquence | "La Joconde - Histoire et mystères" |
|
||||
| Barre de progression | 3:24 / 6:50 |
|
||||
| Liste séquences | ✅ 1. Intro, ▶️ 2. Joconde, ⏸️ 3. Vénus... |
|
||||
| Boutons navigation | Précédent, Play/Pause, Suivant |
|
||||
|
||||
Scénario: Navigation vers séquence suivante
|
||||
Étant donné que j'écoute la séquence 2
|
||||
Quand je tape sur "Suivant"
|
||||
Alors la séquence 3 commence immédiatement
|
||||
Et le titre de la séquence s'affiche: "Vénus de Milo"
|
||||
Et la barre de progression se réinitialise
|
||||
|
||||
Scénario: Navigation vers séquence précédente
|
||||
Étant donné que j'écoute la séquence 5
|
||||
Quand je tape sur "Précédent"
|
||||
Alors la séquence 4 recommence depuis le début
|
||||
Et je peux réécouter cette séquence
|
||||
|
||||
Scénario: Saut direct à une séquence spécifique
|
||||
Étant donné que j'écoute la séquence 2
|
||||
Et que la liste des séquences est affichée
|
||||
Quand je tape sur "7. Peintures Renaissance"
|
||||
Alors la séquence 7 démarre immédiatement
|
||||
Et je passe directement de la séquence 2 à la 7
|
||||
|
||||
Scénario: Commande vocale "Suivant"
|
||||
Étant donné que j'écoute la séquence 3
|
||||
Quand je dis "Suivant" via la commande vocale
|
||||
Alors la séquence 4 démarre
|
||||
Et la commande vocale fonctionne même si l'écran est verrouillé
|
||||
|
||||
Scénario: Commande vocale "Précédent"
|
||||
Étant donné que j'écoute la séquence 6
|
||||
Quand je dis "Précédent" via la commande vocale
|
||||
Alors la séquence 5 démarre depuis le début
|
||||
|
||||
Scénario: Pause et reprise à la position exacte
|
||||
Étant donné que j'écoute la séquence 4 à la position 2:30
|
||||
Quand je mets en pause
|
||||
Et que j'attends 5 minutes
|
||||
Et que je reprends la lecture
|
||||
Alors la séquence reprend exactement à 2:30
|
||||
Et aucune donnée n'est perdue
|
||||
|
||||
Scénario: Guidage vocal automatique entre séquences
|
||||
Étant donné que la séquence 2 se termine
|
||||
Quand la transition vers la séquence 3 se produit
|
||||
Alors j'entends un message vocal:
|
||||
"""
|
||||
Vous avez terminé la séquence 2. Dirigez-vous vers la Vénus de Milo pour la séquence 3.
|
||||
"""
|
||||
Et la séquence 3 ne démarre pas automatiquement (navigation manuelle)
|
||||
|
||||
Scénario: Avertissement si éloignement du point d'intérêt
|
||||
Étant donné que je suis dans le guide du Louvre
|
||||
Et que je devrais être devant la Vénus de Milo (séquence 3)
|
||||
Quand je m'éloigne de plus de 50m de ce point
|
||||
Alors j'entends un message vocal:
|
||||
"""
|
||||
Vous vous éloignez de la prochaine étape. Consultez le plan.
|
||||
"""
|
||||
Et un bouton "Voir le plan" apparaît dans l'interface
|
||||
|
||||
Scénario: Sauvegarde automatique de la progression
|
||||
Étant donné que j'écoute la séquence 5 à la position 1:45
|
||||
Quand je ferme l'application brutalement
|
||||
Et que je la rouvre 10 minutes plus tard
|
||||
Alors je vois une popup "Reprendre la visite du Musée du Louvre ?"
|
||||
Et si je choisis "Reprendre", je retourne à la séquence 5 à 1:45
|
||||
|
||||
Scénario: Option de recommencer depuis le début
|
||||
Étant donné que j'ai une progression sauvegardée à la séquence 7
|
||||
Quand je rouvre le guide
|
||||
Alors je vois 2 options:
|
||||
| option | action |
|
||||
| Reprendre à la séquence 7 | Reprend à la position exacte |
|
||||
| Recommencer depuis le début | Retourne à la séquence 1 |
|
||||
|
||||
Scénario: Expiration de la sauvegarde après 30 jours
|
||||
Étant donné que j'ai une progression sauvegardée depuis 30 jours
|
||||
Quand j'essaie de reprendre le guide
|
||||
Alors la sauvegarde est considérée comme expirée
|
||||
Et je recommence depuis la séquence 1
|
||||
Et je vois le message "Votre précédente visite date de plus de 30 jours. Recommençons depuis le début."
|
||||
|
||||
Scénario: Synchronisation multi-device de la progression
|
||||
Étant donné que j'écoute un guide sur mon iPhone à la séquence 4
|
||||
Quand je ferme l'app et ouvre sur mon iPad
|
||||
Alors je vois la progression synchronisée
|
||||
Et je peux reprendre à la séquence 4 sur l'iPad
|
||||
|
||||
Scénario: Marquage "Terminé" après toutes les séquences
|
||||
Étant donné que j'écoute la dernière séquence (12/12)
|
||||
Quand cette séquence se termine
|
||||
Alors le guide est marqué "✅ Terminé" dans mon historique
|
||||
Et je vois un message de félicitation:
|
||||
"""
|
||||
Félicitations ! Vous avez terminé la visite complète du Musée du Louvre.
|
||||
"""
|
||||
Et le créateur gagne les statistiques d'écoute complète
|
||||
|
||||
Scénario: Création d'audio-guide par un créateur
|
||||
Étant donné que je suis un créateur
|
||||
Quand je crée un nouvel audio-guide
|
||||
Alors je dois:
|
||||
| étape | détail |
|
||||
| Uploader plusieurs fichiers | 1 fichier MP3 par séquence |
|
||||
| Numéroter les séquences | Séquence 1, Séquence 2, etc. |
|
||||
| Titrer chaque séquence | "Introduction", "La Joconde", etc. |
|
||||
| Définir point GPS unique | Centre du lieu (ex: Louvre) |
|
||||
| Définir rayon de détection | Par défaut 100m |
|
||||
Et la durée totale est calculée automatiquement
|
||||
|
||||
Scénario: Structure JSON de stockage audio-guide
|
||||
Étant donné qu'un créateur publie un audio-guide du Louvre
|
||||
Quand les métadonnées sont stockées en base
|
||||
Alors le format JSON contient:
|
||||
```json
|
||||
{
|
||||
"guide_id": "abc123",
|
||||
"title": "Visite complète Musée du Louvre",
|
||||
"location": {"lat": 48.8606, "lon": 2.3376, "radius": 200},
|
||||
"sequences": [
|
||||
{
|
||||
"sequence_number": 1,
|
||||
"title": "Introduction et architecture",
|
||||
"audio_url": "https://cdn.../seq1.mp3",
|
||||
"duration_seconds": 180
|
||||
},
|
||||
{
|
||||
"sequence_number": 2,
|
||||
"title": "La Joconde",
|
||||
"audio_url": "https://cdn.../seq2.mp3",
|
||||
"duration_seconds": 410
|
||||
}
|
||||
],
|
||||
"total_duration_seconds": 2700,
|
||||
"creator_id": "creator_xyz"
|
||||
}
|
||||
```
|
||||
|
||||
Scénario: Limitation du nombre de séquences
|
||||
Étant donné que je crée un audio-guide
|
||||
Quand j'essaie d'ajouter plus de 50 séquences
|
||||
Alors je vois le message "Maximum 50 séquences par audio-guide"
|
||||
Et je dois structurer mon contenu différemment ou créer plusieurs guides
|
||||
|
||||
Scénario: Quitter le guide et sauvegarder
|
||||
Étant donné que j'écoute la séquence 6
|
||||
Quand je tape sur le bouton "×" (fermer)
|
||||
Alors je vois une confirmation:
|
||||
"""
|
||||
Voulez-vous quitter ce guide ?
|
||||
Votre progression sera sauvegardée.
|
||||
"""
|
||||
Et si je confirme, la progression est enregistrée
|
||||
Et je retourne à l'écran principal
|
||||
|
||||
Scénario: Statistiques créateur pour audio-guides
|
||||
Étant donné que je suis créateur d'un audio-guide
|
||||
Quand je consulte mes statistiques
|
||||
Alors je vois:
|
||||
| métrique | exemple valeur |
|
||||
| Nombre de démarrages | 1250 |
|
||||
| Nombre de complétions (100%) | 387 (31%) |
|
||||
| Séquence la plus skippée | Séquence 8 |
|
||||
| Durée moyenne d'écoute | 28 min (sur 45) |
|
||||
|
||||
Scénario: Audio-guide multilingue (post-MVP)
|
||||
Étant donné qu'un créateur peut publier plusieurs versions linguistiques
|
||||
Quand un touriste anglophone visite le Louvre
|
||||
Alors il voit les guides disponibles en anglais
|
||||
Et peut choisir parmi les guides traduits
|
||||
Mais cette fonctionnalité n'est pas disponible en MVP
|
||||
|
||||
Scénario: Publicité entre séquences d'audio-guide
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Et que j'écoute un audio-guide
|
||||
Quand je passe de la séquence 5 à la séquence 6
|
||||
Alors une publicité peut être insérée (1 pub toutes les 5 séquences)
|
||||
Et la publicité est skippable après 5 secondes
|
||||
Et les utilisateurs Premium ne voient pas de publicité
|
||||
|
||||
Scénario: Audio-guide en mode offline
|
||||
Étant donné que j'ai téléchargé un audio-guide complet
|
||||
Quand je visite le lieu sans connexion internet
|
||||
Alors toutes les séquences sont disponibles hors ligne
|
||||
Et la navigation fonctionne normalement
|
||||
Et seule la sauvegarde cloud est différée jusqu'à reconnexion
|
||||
|
||||
Scénario: Notation d'un audio-guide après écoute
|
||||
Étant donné que j'ai terminé un audio-guide
|
||||
Quand je ferme l'interface
|
||||
Alors je vois une popup "Notez cette visite"
|
||||
Et je peux donner une note de 1 à 5 étoiles
|
||||
Et cette note contribue à la note globale visible par les autres utilisateurs
|
||||
|
||||
Scénario: Filtrage par langue dans la page de sélection
|
||||
Étant donné que plusieurs audio-guides sont disponibles en différentes langues
|
||||
Quand j'accède à la page de sélection
|
||||
Alors je peux filtrer par langue
|
||||
Et par défaut, les guides dans ma langue système sont affichés en premier
|
||||
|
||||
Scénario: Réutilisation de l'infrastructure existante
|
||||
Étant donné qu'un audio-guide est techniquement un contenu structuré
|
||||
Alors il réutilise:
|
||||
| composant | usage |
|
||||
| OVH Object Storage | Hébergement fichiers MP3 séquences |
|
||||
| Streaming HLS | Diffusion audio adaptative |
|
||||
| Cache Redis | Métadonnées guides + progressions |
|
||||
| PostgreSQL | Stockage structure JSON guides |
|
||||
Et aucune infrastructure dédiée n'est nécessaire
|
||||
146
features/abonnements/impact-algorithme.feature
Normal file
146
features/abonnements/impact-algorithme.feature
Normal file
@@ -0,0 +1,146 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Impact des abonnements sur l'algorithme
|
||||
En tant qu'auditeur
|
||||
Je veux que les contenus de mes créateurs suivis soient favorisés
|
||||
Afin de ne pas rater leurs publications tout en découvrant de nouveaux contenus
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis connecté en tant qu'auditeur
|
||||
Et que je suis abonné au créateur "JeanDupont"
|
||||
|
||||
Scénario: Boost de +30% appliqué au score final
|
||||
Étant donné un contenu du créateur "JeanDupont" avec:
|
||||
| score_geo | 0.5 |
|
||||
| score_interet | 0.6 |
|
||||
| score_engage | 0.5 |
|
||||
Quand le score final est calculé
|
||||
Alors le score de base est 0.53
|
||||
Et le boost abonnement de +30% est appliqué
|
||||
Et le score final avec boost est 0.69
|
||||
|
||||
Scénario: Contenu non-suivi peut battre contenu suivi
|
||||
Étant donné que je suis à Paris
|
||||
Et que 2 contenus sont disponibles:
|
||||
| contenu | createur_suivi | score_geo | score_interet | score_engage | score_final_base | score_avec_boost |
|
||||
| Contenu A | Non | 0.9 | 0.8 | 0.7 | 0.80 | 0.80 |
|
||||
| Contenu B | Oui | 0.5 | 0.6 | 0.5 | 0.53 | 0.69 |
|
||||
Quand l'algorithme sélectionne le prochain contenu
|
||||
Alors le Contenu A est proposé en premier
|
||||
Car son score (0.80) est supérieur au Contenu B avec boost (0.69)
|
||||
|
||||
Scénario: Contenu suivi remporte grâce au boost
|
||||
Étant donné que je suis à Paris
|
||||
Et que 2 contenus sont disponibles:
|
||||
| contenu | createur_suivi | score_final_base | score_avec_boost |
|
||||
| Contenu A | Non | 0.70 | 0.70 |
|
||||
| Contenu B | Oui | 0.60 | 0.78 |
|
||||
Quand l'algorithme sélectionne le prochain contenu
|
||||
Alors le Contenu B est proposé en premier
|
||||
Car le boost fait pencher la balance (0.78 > 0.70)
|
||||
|
||||
Scénario: Contenu suivi avec faible engagement ne domine pas
|
||||
Étant donné que je suis abonné au créateur "CreateurMoyen"
|
||||
Et qu'il publie un contenu avec très faible engagement (score 0.30)
|
||||
Et qu'un contenu viral d'un créateur non-suivi a un score de 0.85
|
||||
Quand l'algorithme sélectionne le prochain contenu
|
||||
Alors le contenu viral est proposé en premier (0.85)
|
||||
Car même avec boost, le contenu suivi obtient seulement 0.39 (0.30 × 1.3)
|
||||
|
||||
Scénario: Pas de file dédiée aux abonnements
|
||||
Étant donné que je suis abonné à 50 créateurs
|
||||
Quand l'algorithme génère ma file d'attente de 5 contenus
|
||||
Alors les contenus suivis et non-suivis sont mélangés
|
||||
Et tous entrent en compétition selon leurs scores (avec boost si abonnement)
|
||||
Et il n'y a pas de section séparée "Contenus de vos abonnements"
|
||||
|
||||
Scénario: Vérification du calcul du boost
|
||||
Étant donné un contenu d'un créateur suivi
|
||||
Et que le score final de base est calculé à 0.65
|
||||
Quand le boost abonnement est appliqué
|
||||
Alors le multiplicateur utilisé est exactement 1.3
|
||||
Et le score final avec boost est 0.845 (0.65 × 1.3)
|
||||
Et le résultat est arrondi à 2 décimales: 0.85
|
||||
|
||||
Scénario: Boost appliqué à tous les contenus du créateur suivi
|
||||
Étant donné que je suis abonné au créateur "JeanDupont"
|
||||
Et qu'il a publié 10 contenus différents
|
||||
Quand l'algorithme évalue chacun de ces contenus
|
||||
Alors le boost de +30% est appliqué à tous les 10 contenus
|
||||
Et chaque contenu bénéficie du même multiplicateur 1.3
|
||||
|
||||
Scénario: Plusieurs créateurs suivis en compétition
|
||||
Étant donné que je suis abonné à "Créateur A" et "Créateur B"
|
||||
Et que les 2 ont des contenus disponibles dans ma zone:
|
||||
| createur | score_base | score_avec_boost |
|
||||
| Créateur A | 0.70 | 0.91 |
|
||||
| Créateur B | 0.65 | 0.85 |
|
||||
Quand l'algorithme sélectionne le prochain contenu
|
||||
Alors le contenu du Créateur A est proposé en premier (0.91 > 0.85)
|
||||
Et les 2 bénéficient du boost, mais le meilleur score gagne
|
||||
|
||||
Scénario: Contenu national d'un créateur suivi
|
||||
Étant donné que je suis abonné à "MediaNational"
|
||||
Et qu'il publie un contenu de type "National" (score_geo 0.2)
|
||||
Quand le score est calculé avec:
|
||||
| score_geo | score_interet | score_engage |
|
||||
| 0.2 | 0.7 | 0.6 |
|
||||
Alors le score de base est environ 0.50
|
||||
Et avec le boost abonnement, le score devient 0.65
|
||||
Et le contenu peut être proposé malgré son score géo faible
|
||||
|
||||
Scénario: Transparence du boost dans les paramètres
|
||||
Quand j'accède aux paramètres de l'algorithme de recommandation
|
||||
Alors je vois l'information: "Les contenus de vos créateurs suivis bénéficient d'un boost de +30%"
|
||||
Et je comprends que ce n'est pas une priorité absolue
|
||||
Et que la découverte de nouveaux contenus reste possible
|
||||
|
||||
Scénario: Boost désactivé si désabonnement
|
||||
Étant donné que je suis abonné au créateur "JeanDupont"
|
||||
Et qu'un de ses contenus bénéficiait du boost +30%
|
||||
Quand je me désabonne de "JeanDupont"
|
||||
Alors ses contenus n'ont plus le boost
|
||||
Et leur score revient au score de base sans multiplicateur
|
||||
|
||||
Scénario: Contenu d'un créateur nouvellement suivi
|
||||
Étant donné que je viens de m'abonner à "NouveauCreateur"
|
||||
Et qu'il a publié un contenu il y a 2 jours
|
||||
Quand l'algorithme recalcule les scores
|
||||
Alors le boost de +30% est immédiatement appliqué à ce contenu
|
||||
Et il peut apparaître dans ma prochaine file d'attente
|
||||
|
||||
Scénario: Impact sur le taux de contenu suivi dans le feed
|
||||
Étant donné que je suis abonné à 30 créateurs
|
||||
Et que j'écoute 100 contenus sur une semaine
|
||||
Quand j'analyse la répartition
|
||||
Alors environ 40-50% des contenus proviennent de créateurs suivis
|
||||
Et 50-60% proviennent de créateurs non-suivis (découverte)
|
||||
Car le boost favorise sans dominer
|
||||
|
||||
Scénario: Contenu suivi hors zone géographique
|
||||
Étant donné que je suis à Paris
|
||||
Et que je suis abonné à un créateur de Marseille
|
||||
Et qu'il publie un contenu ancré à Marseille (hors de portée)
|
||||
Quand l'algorithme évalue ce contenu
|
||||
Alors le score géo est quasi nul (0.05)
|
||||
Et même avec boost +30%, le score reste très faible
|
||||
Et le contenu n'est probablement pas proposé
|
||||
|
||||
Scénario: Performance de calcul du boost
|
||||
Étant donné que je suis abonné à 100 créateurs
|
||||
Et que l'algorithme évalue 1000 contenus potentiels
|
||||
Quand le calcul des scores avec boost est effectué
|
||||
Alors le temps de calcul reste inférieur à 50ms
|
||||
Car le boost est une simple multiplication (opération O(1))
|
||||
Et la requête SQL utilise un JOIN sur la table abonnements
|
||||
|
||||
Scénario: Boost combiné avec d'autres facteurs
|
||||
Étant donné un contenu d'un créateur suivi
|
||||
Et que le contenu bénéficie aussi de:
|
||||
| facteur | impact |
|
||||
| Score d'engagement élevé | +20% |
|
||||
| Contenu récent (<24h) | +10% |
|
||||
| Boost abonnement | +30% |
|
||||
Quand le score final est calculé
|
||||
Alors le boost abonnement s'applique au score final (après tous les autres calculs)
|
||||
Et les boosts ne s'additionnent pas, le boost abonnement est un multiplicateur final
|
||||
244
features/abonnements/limites-desabonnement.feature
Normal file
244
features/abonnements/limites-desabonnement.feature
Normal file
@@ -0,0 +1,244 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Limites d'abonnements et désabonnement
|
||||
En tant qu'auditeur
|
||||
Je veux gérer mes abonnements de manière équilibrée
|
||||
Afin de suivre mes créateurs préférés sans être submergé
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis connecté en tant qu'auditeur
|
||||
|
||||
Scénario: Limite maximale de 200 abonnements
|
||||
Étant donné que je suis abonné à 199 créateurs
|
||||
Quand j'essaie de m'abonner à un 200ème créateur
|
||||
Alors l'abonnement réussit
|
||||
Et je suis maintenant abonné à 200 créateurs
|
||||
|
||||
Scénario: Impossible de dépasser 200 abonnements
|
||||
Étant donné que je suis déjà abonné à 200 créateurs
|
||||
Quand j'essaie de m'abonner à un nouveau créateur
|
||||
Alors l'action échoue
|
||||
Et je vois le message:
|
||||
"""
|
||||
Vous suivez déjà 200 créateurs. Désabonnez-vous d'un créateur pour en suivre un nouveau.
|
||||
"""
|
||||
|
||||
Scénario: Suggestion de désabonnement de créateurs inactifs
|
||||
Étant donné que je suis abonné à 200 créateurs
|
||||
Et que j'essaie de m'abonner à un nouveau créateur
|
||||
Quand je vois le message de limite atteinte
|
||||
Alors je vois aussi une suggestion:
|
||||
"""
|
||||
Vous n'avez pas écouté [Créateur X] depuis 6 mois, le désabonner ?
|
||||
"""
|
||||
Et un bouton "Désabonner" est proposé pour ce créateur
|
||||
|
||||
Scénario: Liste triable des abonnements
|
||||
Étant donné que je suis abonné à 150 créateurs
|
||||
Quand j'accède à ma liste d'abonnements
|
||||
Alors je peux trier par:
|
||||
| critère | ordre |
|
||||
| Date d'abonnement | Plus récent / Plus ancien |
|
||||
| Nombre de contenus écoutés| Plus écoutés / Moins écoutés |
|
||||
| Dernière activité créateur| Plus récent / Plus ancien |
|
||||
| Ordre alphabétique | A-Z / Z-A |
|
||||
|
||||
Scénario: Abonnement initial augmente les jauges de +5%
|
||||
Étant donné que mes jauges d'intérêt sont:
|
||||
| catégorie | valeur initiale |
|
||||
| Automobile | 60% |
|
||||
| Voyage | 55% |
|
||||
Et qu'un créateur tague ses contenus "Automobile" et "Voyage"
|
||||
Quand je m'abonne à ce créateur
|
||||
Alors mes jauges évoluent:
|
||||
| catégorie | nouvelle valeur |
|
||||
| Automobile | 65% (+5%) |
|
||||
| Voyage | 60% (+5%) |
|
||||
|
||||
Scénario: Abonnement avec créateur ayant 3 tags
|
||||
Étant donné qu'un créateur tague ses contenus:
|
||||
| tags |
|
||||
| Automobile, Voyage, Technologie |
|
||||
Et que mes jauges sont toutes à 50%
|
||||
Quand je m'abonne à ce créateur
|
||||
Alors les 3 jauges augmentent de +5%:
|
||||
| catégorie | nouvelle valeur |
|
||||
| Automobile | 55% |
|
||||
| Voyage | 55% |
|
||||
| Technologie | 55% |
|
||||
|
||||
Scénario: Désabonnement diminue les jauges de -5%
|
||||
Étant donné que je suis abonné à un créateur avec tags "Politique" et "Économie"
|
||||
Et que mes jauges sont:
|
||||
| catégorie | valeur actuelle |
|
||||
| Politique | 70% |
|
||||
| Économie | 65% |
|
||||
Quand je me désabonne de ce créateur
|
||||
Alors mes jauges évoluent:
|
||||
| catégorie | nouvelle valeur |
|
||||
| Politique | 65% (-5%) |
|
||||
| Économie | 60% (-5%) |
|
||||
|
||||
Scénario: Désabonnement sans confirmation
|
||||
Étant donné que je consulte le profil d'un créateur suivi
|
||||
Quand je clique sur "Se désabonner"
|
||||
Alors le désabonnement est immédiat
|
||||
Et aucune popup de confirmation n'apparaît
|
||||
Car l'action est réversible (je peux me réabonner)
|
||||
|
||||
Scénario: Réabonnement possible immédiatement
|
||||
Étant donné que je viens de me désabonner d'un créateur
|
||||
Quand je consulte à nouveau son profil
|
||||
Alors le bouton "S'abonner" est affiché
|
||||
Et je peux me réabonner immédiatement
|
||||
Et mes jauges augmentent à nouveau de +5%
|
||||
|
||||
Scénario: Effet symétrique abonnement/désabonnement
|
||||
Étant donné qu'un créateur a les tags "Musique" et "Culture"
|
||||
Et que ma jauge Musique est à 50%
|
||||
Quand je m'abonne puis me désabonne immédiatement
|
||||
Alors ma jauge revient exactement à 50%
|
||||
Et il n'y a pas de perte ou gain net
|
||||
|
||||
Scénario: Abonnement ne dépasse pas 100% de jauge
|
||||
Étant donné que ma jauge Automobile est à 97%
|
||||
Et qu'un créateur tague ses contenus "Automobile"
|
||||
Quand je m'abonne à ce créateur
|
||||
Alors ma jauge Automobile passe à 100% (limite max)
|
||||
Et l'augmentation effective est de +3% seulement
|
||||
|
||||
Scénario: Désabonnement ne descend pas sous 0%
|
||||
Étant donné que ma jauge Politique est à 3%
|
||||
Et que je suis abonné à un créateur avec tag "Politique"
|
||||
Quand je me désabonne de ce créateur
|
||||
Alors ma jauge Politique passe à 0% (limite min)
|
||||
Et la diminution effective est de -3% seulement
|
||||
|
||||
Scénario: Créateur ne voit pas qui est abonné (privacy)
|
||||
Étant donné que je suis abonné au créateur "JeanDupont"
|
||||
Quand "JeanDupont" consulte ses statistiques
|
||||
Alors il voit le nombre total d'abonnés (ex: "1,247 abonnés")
|
||||
Mais il ne voit pas la liste des utilisateurs abonnés
|
||||
Et mon identité reste privée
|
||||
|
||||
Scénario: Créateur voit uniquement le nombre total d'abonnés
|
||||
Étant donné que je suis créateur
|
||||
Et que j'ai 523 abonnés
|
||||
Quand je consulte mes statistiques
|
||||
Alors je vois "523 abonnés"
|
||||
Mais je ne peux pas:
|
||||
| action interdite |
|
||||
| Voir la liste des abonnés |
|
||||
| Contacter mes abonnés individuellement|
|
||||
| Voir leurs profils |
|
||||
|
||||
Scénario: Pas d'abonnement mutuel visible
|
||||
Étant donné que je suis abonné au créateur "Alice"
|
||||
Et qu'"Alice" est abonnée à mon compte créateur
|
||||
Quand je consulte le profil d'"Alice"
|
||||
Alors je ne vois pas d'indication qu'elle est abonnée à moi
|
||||
Et il n'y a pas de badge "Abonné mutuellement"
|
||||
|
||||
Scénario: Performance avec 200 abonnements
|
||||
Étant donné que je suis abonné à 200 créateurs
|
||||
Quand l'algorithme calcule ma recommandation
|
||||
Alors la requête SQL utilise un JOIN sur la table abonnements
|
||||
Et la table est indexée sur user_id et creator_id
|
||||
Et le temps de calcul reste inférieur à 50ms
|
||||
|
||||
Scénario: Impact sur la recommandation avec beaucoup d'abonnements
|
||||
Étant donné que je suis abonné à 150 créateurs très actifs
|
||||
Et qu'ils publient collectivement 100 contenus par jour
|
||||
Quand l'algorithme génère ma file de 5 contenus
|
||||
Alors environ 60-70% des contenus proviennent de créateurs suivis (grâce au boost +30%)
|
||||
Mais 30-40% proviennent de nouveaux créateurs (découverte)
|
||||
|
||||
Scénario: Notification de désabonnement au créateur (non implémenté)
|
||||
Étant donné que je me désabonne d'un créateur
|
||||
Alors le créateur ne reçoit aucune notification
|
||||
Et il ne peut pas savoir qui s'est désabonné
|
||||
Car cela préserve la privacy et évite le harcèlement
|
||||
|
||||
Scénario: Statistiques d'abonnements pour l'utilisateur
|
||||
Étant donné que je suis abonné à 87 créateurs
|
||||
Quand j'accède à mes statistiques d'abonnements
|
||||
Alors je vois:
|
||||
| métrique | exemple valeur |
|
||||
| Nombre total d'abonnements | 87 / 200 |
|
||||
| Créateurs les plus écoutés | Top 10 avec % écoute |
|
||||
| Créateurs non écoutés depuis 6 mois | 12 créateurs |
|
||||
| Nouveaux contenus non écoutés | 23 contenus |
|
||||
|
||||
Scénario: Recherche dans la liste d'abonnements
|
||||
Étant donné que je suis abonné à 120 créateurs
|
||||
Quand j'accède à ma liste d'abonnements
|
||||
Alors je peux chercher par nom de créateur
|
||||
Et les résultats sont filtrés en temps réel
|
||||
Et je trouve rapidement un créateur spécifique
|
||||
|
||||
Scénario: Export de la liste d'abonnements (RGPD)
|
||||
Étant donné que je demande l'export de mes données
|
||||
Quand l'export est généré
|
||||
Alors la liste de mes abonnements est incluse:
|
||||
```json
|
||||
{
|
||||
"subscriptions": [
|
||||
{
|
||||
"creator_name": "JeanDupont",
|
||||
"creator_id": "abc123",
|
||||
"subscribed_at": "2025-06-15T10:30:00Z"
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Scénario: Suppression compte utilisateur et impact sur abonnements
|
||||
Étant donné que je suis abonné à 50 créateurs
|
||||
Quand je supprime définitivement mon compte
|
||||
Alors tous mes abonnements sont supprimés
|
||||
Et le compteur d'abonnés de chaque créateur est décrémenté de -1
|
||||
Et les jauges n'existent plus (données supprimées)
|
||||
|
||||
Scénario: Suppression compte créateur et impact sur abonnés
|
||||
Étant donné que je suis abonné au créateur "Bob"
|
||||
Quand "Bob" supprime son compte créateur
|
||||
Alors je suis automatiquement désabonné
|
||||
Et mes jauges diminuent de -5% pour les tags de "Bob"
|
||||
Et je ne vois plus "Bob" dans ma liste d'abonnements
|
||||
|
||||
Scénario: Limite 200 justifiée par usage réaliste
|
||||
Étant donné que la moyenne d'abonnements sur YouTube est de ~50-100 chaînes
|
||||
Et que Twitter limite à 5000 follows (mais moyenne ~150)
|
||||
Quand RoadWave fixe la limite à 200
|
||||
Alors cela couvre largement 99% des utilisateurs
|
||||
Et évite les abus (comptes spam suivant tout le monde)
|
||||
|
||||
Scénario: Table PostgreSQL optimisée pour abonnements
|
||||
Étant donné la structure de table subscriptions:
|
||||
```sql
|
||||
CREATE TABLE subscriptions (
|
||||
user_id UUID,
|
||||
creator_id UUID,
|
||||
subscribed_at TIMESTAMP,
|
||||
PRIMARY KEY (user_id, creator_id)
|
||||
);
|
||||
CREATE INDEX idx_user_subscriptions ON subscriptions(user_id);
|
||||
CREATE INDEX idx_creator_subscribers ON subscriptions(creator_id);
|
||||
```
|
||||
Alors les requêtes d'abonnements sont O(1) avec index
|
||||
Et le count d'abonnés par créateur est rapide
|
||||
Et la vérification "est abonné ?" est instantanée
|
||||
|
||||
Scénario: Détection d'abonnements abusifs
|
||||
Étant donné qu'un utilisateur s'abonne à 200 créateurs en moins de 5 minutes
|
||||
Quand le système détecte cette activité suspecte
|
||||
Alors un rate limiting est appliqué (max 10 abonnements/minute)
|
||||
Et l'utilisateur voit "Trop d'actions rapides. Veuillez réessayer dans 1 minute"
|
||||
Et cela prévient les bots de spam
|
||||
|
||||
Scénario: Badge créateur vérifié visible dans abonnements
|
||||
Étant donné que je suis abonné à 3 créateurs dont 1 vérifié
|
||||
Quand je consulte ma liste d'abonnements
|
||||
Alors le créateur vérifié a un badge ✓ bleu
|
||||
Et les créateurs non vérifiés n'ont pas de badge
|
||||
239
features/abonnements/notifications-contextuelles.feature
Normal file
239
features/abonnements/notifications-contextuelles.feature
Normal file
@@ -0,0 +1,239 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Notifications contextuelles selon le mode de déplacement
|
||||
En tant qu'auditeur
|
||||
Je veux recevoir des notifications adaptées à mon contexte
|
||||
Afin d'être informé sans être distrait en conduisant
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis connecté en tant qu'auditeur
|
||||
Et que j'ai activé les notifications
|
||||
|
||||
Scénario: Détection automatique du contexte en voiture
|
||||
Étant donné que ma vitesse GPS est de 50 km/h
|
||||
Quand le système détecte mon contexte
|
||||
Alors je suis identifié comme "En voiture"
|
||||
Et les notifications push sont désactivées
|
||||
Et seules les notifications in-app sont actives
|
||||
|
||||
Scénario: Détection automatique du contexte à pied
|
||||
Étant donné que ma vitesse GPS est de 3 km/h
|
||||
Quand le système détecte mon contexte
|
||||
Alors je suis identifié comme "À pied"
|
||||
Et les notifications push sont activées
|
||||
Et l'interface tactile et vocale sont disponibles
|
||||
|
||||
Scénario: Zone de transition 5-10 km/h
|
||||
Étant donné que ma vitesse GPS varie entre 5 et 10 km/h
|
||||
Quand le système détecte mon contexte
|
||||
Alors un algorithme de lissage est appliqué sur 30 secondes
|
||||
Et le mode est déterminé selon la vitesse moyenne
|
||||
Et les changements de mode ne sont pas trop fréquents
|
||||
|
||||
Scénario: Nouveau contenu créateur suivi - Mode voiture
|
||||
Étant donné que je suis en voiture (vitesse >10 km/h)
|
||||
Et que je suis abonné au créateur "JeanDupont"
|
||||
Quand "JeanDupont" publie un nouveau contenu dans ma zone
|
||||
Alors je ne reçois pas de notification push
|
||||
Mais je vois un badge compteur in-app
|
||||
Et le contenu apparaît dans ma file avec boost +30%
|
||||
|
||||
Scénario: Nouveau contenu créateur suivi - Mode piéton
|
||||
Étant donné que je suis à pied (vitesse <5 km/h)
|
||||
Et que je suis abonné au créateur "JeanDupont"
|
||||
Et que je suis situé en Île-de-France
|
||||
Quand "JeanDupont" publie un contenu géolocalisé en Île-de-France
|
||||
Alors je reçois une notification push:
|
||||
"""
|
||||
🎧 JeanDupont a publié : "Titre du contenu"
|
||||
Tap pour écouter
|
||||
"""
|
||||
|
||||
Scénario: Live créateur suivi - Mode voiture
|
||||
Étant donné que je suis en voiture
|
||||
Et que je suis abonné au créateur "RadioLive"
|
||||
Quand "RadioLive" démarre un live dans ma zone
|
||||
Alors je ne reçois pas de notification push
|
||||
Mais je vois un badge compteur in-app
|
||||
Et le live peut apparaître dans ma recommandation automatiquement
|
||||
|
||||
Scénario: Live créateur suivi - Mode piéton
|
||||
Étant donné que je suis à pied
|
||||
Et que je suis abonné au créateur "RadioLive"
|
||||
Et que je suis situé dans la zone du live
|
||||
Quand "RadioLive" démarre un live
|
||||
Alors je reçois une notification push:
|
||||
"""
|
||||
🔴 RadioLive est en direct : "Titre du live"
|
||||
Tap pour rejoindre
|
||||
"""
|
||||
|
||||
Scénario: Audio-guide disponible à proximité - Mode piéton
|
||||
Étant donné que je suis à pied
|
||||
Quand je passe à moins de 100m d'un lieu avec audio-guides
|
||||
Alors je reçois une notification push:
|
||||
"""
|
||||
📍 Audio-guide disponible : Musée du Louvre
|
||||
Choisissez parmi 3 guides pour Musée du Louvre
|
||||
Tap pour explorer
|
||||
"""
|
||||
|
||||
Scénario: Audio-guide disponible à proximité - Mode voiture
|
||||
Étant donné que je suis en voiture
|
||||
Quand je passe à moins de 100m d'un lieu avec audio-guides
|
||||
Alors je reçois une notification audio (bip)
|
||||
Et une annonce vocale: "Audio-guide disponible"
|
||||
Mais pas de notification push (sécurité)
|
||||
|
||||
Scénario: Filtrage géographique des notifications
|
||||
Étant donné que je suis abonné au créateur "CreateurMarseille"
|
||||
Et que je suis situé à Paris
|
||||
Quand "CreateurMarseille" publie un contenu ancré à Marseille
|
||||
Alors je ne reçois pas de notification
|
||||
Car le contenu est hors de ma zone géographique
|
||||
Et cela évite la frustration de contenus non écoutables
|
||||
|
||||
Scénario: Contenu national notifie tous les abonnés
|
||||
Étant donné que je suis abonné au créateur "MediaNational"
|
||||
Et que je suis situé n'importe où en France
|
||||
Quand "MediaNational" publie un contenu de type "National"
|
||||
Alors je reçois une notification (si mode piéton)
|
||||
Car les contenus nationaux ne sont pas filtrés géographiquement
|
||||
|
||||
Scénario: Limite de 10 notifications push par jour
|
||||
Étant donné que je suis abonné à 50 créateurs actifs
|
||||
Et que j'ai déjà reçu 10 notifications push aujourd'hui
|
||||
Quand un 11ème contenu est publié
|
||||
Alors je ne reçois pas de notification push individuelle
|
||||
Mais une notification groupée: "🎧 3 nouveaux contenus de créateurs suivis"
|
||||
|
||||
Scénario: Paramétrage de la limite quotidienne
|
||||
Étant donné que la limite par défaut est de 10 notifications/jour
|
||||
Quand j'accède aux paramètres de notifications
|
||||
Alors je peux modifier la limite entre 5 et 20
|
||||
Et si je choisis 15, je recevrai jusqu'à 15 notifications/jour
|
||||
|
||||
Scénario: Mode silencieux nocturne par défaut
|
||||
Étant donné que le mode silencieux est activé de 22h à 8h par défaut
|
||||
Et qu'il est 23h30
|
||||
Quand un créateur suivi publie un contenu
|
||||
Alors je ne reçois pas de notification push
|
||||
Mais les notifications sont empilées
|
||||
Et je les vois le lendemain matin à 8h01
|
||||
|
||||
Scénario: Exception du mode silencieux pour les lives
|
||||
Étant donné que le mode silencieux est activé (22h-8h)
|
||||
Et qu'il est 23h00
|
||||
Et que j'ai activé "Notifications importantes uniquement" (lives uniquement)
|
||||
Quand un créateur suivi démarre un live
|
||||
Alors je reçois quand même la notification push du live
|
||||
Car les lives sont des événements temps réel prioritaires
|
||||
|
||||
Scénario: Désactivation complète des notifications
|
||||
Étant donné que j'accède aux paramètres de notifications
|
||||
Quand je désactive toutes les notifications
|
||||
Alors je ne reçois plus aucune notification push
|
||||
Et les badges in-app sont également désactivés
|
||||
Et seule la recommandation algorithmique reste active
|
||||
|
||||
Scénario: Notification "Nouveaux contenus" activée par défaut
|
||||
Étant donné que je crée un nouveau compte
|
||||
Et que je m'abonne à mon premier créateur
|
||||
Quand je consulte les préférences de notifications
|
||||
Alors "Nouveaux contenus" est activé par défaut
|
||||
Et "Lives" est activé par défaut
|
||||
Et "Audio-guides proximité" est activé par défaut
|
||||
|
||||
Scénario: Désactivation sélective par type de notification
|
||||
Étant donné que j'ai activé toutes les notifications
|
||||
Quand je désactive uniquement "Nouveaux contenus"
|
||||
Alors je ne reçois plus de notifications pour nouveaux contenus
|
||||
Mais je reçois toujours les notifications de lives
|
||||
Et les notifications d'audio-guides restent actives
|
||||
|
||||
Scénario: Notification groupée après limite dépassée
|
||||
Étant donné que j'ai reçu 10 notifications push aujourd'hui
|
||||
Et que 5 nouveaux contenus sont publiés dans l'heure suivante
|
||||
Quand la 11ème notification devrait être envoyée
|
||||
Alors les 5 contenus sont regroupés en une seule notification:
|
||||
"""
|
||||
🎧 5 nouveaux contenus de créateurs suivis
|
||||
Tap pour voir la liste
|
||||
"""
|
||||
|
||||
Scénario: Détail de la notification groupée
|
||||
Étant donné que j'ai reçu une notification groupée "3 nouveaux contenus"
|
||||
Quand je tape sur la notification
|
||||
Alors l'app s'ouvre sur une liste des 3 contenus:
|
||||
| créateur | titre |
|
||||
| JeanDupont | "Actualité du jour" |
|
||||
| MarieDurand | "Podcast économie" |
|
||||
| PaulMartin | "Anecdote historique" |
|
||||
Et je peux choisir lequel écouter en premier
|
||||
|
||||
Scénario: Personnalisation des plages horaires du mode silencieux
|
||||
Étant donné que le mode silencieux est 22h-8h par défaut
|
||||
Quand j'accède aux paramètres
|
||||
Alors je peux modifier les heures: par exemple 23h-7h
|
||||
Et le mode silencieux s'applique dans la nouvelle plage horaire
|
||||
|
||||
Scénario: Format notification nouveau contenu complet
|
||||
Étant donné que je suis à pied
|
||||
Et qu'un créateur suivi publie un contenu
|
||||
Quand je reçois la notification push
|
||||
Alors elle contient:
|
||||
| élément | exemple |
|
||||
| Emoji | 🎧 |
|
||||
| Créateur | JeanDupont |
|
||||
| Action | a publié |
|
||||
| Titre | "Les secrets du Louvre" |
|
||||
| CTA | Tap pour écouter |
|
||||
|
||||
Scénario: Format notification live complet
|
||||
Étant donné que je suis à pied
|
||||
Et qu'un créateur suivi démarre un live
|
||||
Quand je reçois la notification push
|
||||
Alors elle contient:
|
||||
| élément | exemple |
|
||||
| Emoji | 🔴 |
|
||||
| Créateur | RadioLive |
|
||||
| Action | est en direct |
|
||||
| Titre | "Débat politique ce soir" |
|
||||
| CTA | Tap pour rejoindre |
|
||||
|
||||
Scénario: Notification disparaît si contenu supprimé
|
||||
Étant donné que j'ai reçu une notification pour un contenu
|
||||
Et que je n'ai pas encore tapé dessus
|
||||
Quand le créateur supprime le contenu
|
||||
Alors la notification est automatiquement retirée de mon centre de notifications
|
||||
Et si je tape dessus par erreur, je vois "Contenu non disponible"
|
||||
|
||||
Scénario: Badge compteur in-app en mode voiture
|
||||
Étant donné que je suis en voiture
|
||||
Et que 5 créateurs suivis publient des contenus
|
||||
Quand j'ouvre l'application
|
||||
Alors je vois un badge "5" sur l'onglet "Nouveautés"
|
||||
Et en consultant l'onglet, je vois les 5 nouveaux contenus
|
||||
Et le badge disparaît après consultation
|
||||
|
||||
Scénario: Coût des notifications push Firebase
|
||||
Étant donné que je reçois 10 notifications push par jour
|
||||
Et que je suis actif 365 jours par an
|
||||
Quand le système calcule le coût
|
||||
Alors 3650 notifications/an sont envoyées
|
||||
Et Firebase Cloud Messaging est gratuit jusqu'à plusieurs millions de notifications
|
||||
Et le coût reste 0€ pour le volume MVP/Growth
|
||||
|
||||
Scénario: Deep link depuis notification push
|
||||
Étant donné que je reçois une notification push pour un contenu
|
||||
Quand je tape sur la notification
|
||||
Alors l'app s'ouvre directement sur le contenu
|
||||
Et la lecture démarre automatiquement (si j'étais à pied)
|
||||
Ou le contenu est ajouté en première position dans la file (si je suis en voiture)
|
||||
|
||||
Scénario: Notification refusée si permissions désactivées au niveau OS
|
||||
Étant donné que j'ai désactivé les notifications dans les paramètres iOS/Android
|
||||
Quand un créateur suivi publie un contenu
|
||||
Alors aucune notification push n'est envoyée
|
||||
Et l'app propose de réactiver les permissions dans les paramètres
|
||||
Mais les badges in-app continuent de fonctionner
|
||||
Reference in New Issue
Block a user