feat(bdd): réorganiser features en catégories api/ui/e2e et créer ADR-024

Résolution des incohérences #10, #11, et #12 de l'analyse d'architecture.

## Phase 1 : Réorganisation Features BDD (Point #10 - RÉSOLU)

- Créer structure features/{api,ui,e2e}
- Déplacer 83 features en 3 catégories via git mv (historique préservé)
  - features/api/ : 53 features (tests API backend)
  - features/ui/ : 22 features (tests UI mobile)
  - features/e2e/ : 8 features (tests end-to-end)

Domaines déplacés :
- API : authentication, recommendation, rgpd-compliance, content-creation,
  moderation, monetisation, premium, radio-live, publicites
- UI : audio-guides, navigation, interest-gauges, mode-offline,
  partage, profil, recherche
- E2E : abonnements, error-handling

## Phase 2 : Mise à jour Documentation

### ADR-007 - Tests BDD
- Ajouter section "Convention de Catégorisation des Features"
- Documenter règles api/ui/e2e avec exemples concrets
- Spécifier step definitions (backend Go, mobile Dart)

### ADR-024 - Stratégie CI/CD Monorepo (NOUVEAU)
- Créer ADR dédié pour stratégie CI/CD avec path filters
- Architecture workflows séparés (backend.yml, mobile.yml, shared.yml)
- Configuration path filters détaillée avec exemples YAML
- Matrice de déclenchement et optimisations (~70% gain temps CI)
- Plan d'implémentation (~2h, reporté jusqu'au développement)

### ADR-016 - Organisation Monorepo
- Simplifier en retirant section CI/CD détaillée
- Ajouter référence vers ADR-024 pour stratégie CI/CD

### INCONSISTENCIES-ANALYSIS.md
- Point #10 (Tests BDD synchronisés) :  RÉSOLU
  - Catégorisation features implémentée
  - ADR-007 mis à jour avec convention complète
- Point #11 (70/30 Split paiements) :  ANNULÉ (faux problème)
  - ADR-009 et Règle 18 parfaitement cohérents
  - Documentation exhaustive existante (formule, SQL, comparaisons)
- Point #12 (Monorepo path filters) : ⏸️ DOCUMENTÉ
  - Architecture CI/CD complète dans ADR-024
  - Implémentation reportée (projet en phase documentation)
- Métriques mises à jour :
  - MODERATE : 6/9 traités (4 résolus + 1 annulé + 1 documenté)
  - ADR à jour : 100% (19/19 avec ADR-024)

## Phase 3 : Validation

- Structure features validée (api/ui/e2e, aucun répertoire restant)
- Historique Git préservé (git mv, renommages détectés)
- 83 features total (API: 53, UI: 22, E2E: 8)

Closes: Point #10 (résolu), Point #11 (annulé), Point #12 (documenté)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
jpgiannetti
2026-02-01 11:31:41 +01:00
parent 841028d1b2
commit 37c62206ad
88 changed files with 625 additions and 67 deletions

View 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

View 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

View 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

View 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

View File

@@ -0,0 +1,115 @@
# language: fr
@error-handling @no-content
Fonctionnalité: Élargissement automatique de zone quand aucun contenu n'est disponible
Contexte:
Étant donné que je suis un utilisateur connecté
Et que la géolocalisation est activée
Et que je suis en mode écoute
# 12.1 - Élargissement progressif
Scénario: Aucun contenu dans rayon 50km - élargissement à 100km
Étant donné que je suis situé à la position GPS 48.8566, 2.3522
Et qu'aucun contenu n'existe dans un rayon de 50 km autour de ma position
Mais qu'au moins 1 contenu existe dans un rayon de 100 km
Quand le système recherche du contenu à me proposer
Alors le système élargit automatiquement la zone de recherche à 100 km
Et je reçois un message "Aucun contenu dans votre zone immédiate. Voici du contenu à proximité (100 km)"
Et un contenu dans le rayon de 100 km m'est proposé
Scénario: Aucun contenu dans rayon 100km - élargissement au département
Étant donné que je suis situé dans le département "75" (Paris)
Et qu'aucun contenu n'existe dans un rayon de 100 km autour de ma position
Mais qu'au moins 1 contenu existe avec la zone "département" pour "75"
Quand le système recherche du contenu à me proposer
Alors le système élargit automatiquement la zone de recherche au département
Et je reçois un message "Aucun contenu local disponible. Voici du contenu dans votre département"
Et un contenu départemental m'est proposé
Scénario: Aucun contenu départemental - élargissement à la région
Étant donné que je suis situé dans la région "Île-de-France"
Et qu'aucun contenu n'existe dans un rayon de 100 km autour de ma position
Et qu'aucun contenu départemental n'existe pour mon département
Mais qu'au moins 1 contenu existe avec la zone "région" pour "Île-de-France"
Quand le système recherche du contenu à me proposer
Alors le système élargit automatiquement la zone de recherche à la région
Et je reçois un message "Aucun contenu local disponible. Voici du contenu dans votre région"
Et un contenu régional m'est proposé
Scénario: Aucun contenu régional - basculement sur contenu national
Étant donné que je suis situé en France
Et qu'aucun contenu n'existe dans un rayon de 100 km autour de ma position
Et qu'aucun contenu départemental n'existe pour mon département
Et qu'aucun contenu régional n'existe pour ma région
Quand le système recherche du contenu à me proposer
Alors le système bascule automatiquement sur du contenu national
Et je reçois un message "Aucun contenu local disponible. Voici du contenu national qui pourrait vous intéresser"
Et un contenu national m'est proposé
Et je ne reste jamais sans contenu disponible
Scénario: Élargissement progressif avec plusieurs étapes
Étant donné que je suis situé dans une zone rurale isolée
Et qu'aucun contenu n'existe dans un rayon de 50 km
Et qu'aucun contenu n'existe dans un rayon de 100 km
Et qu'aucun contenu départemental n'existe
Et qu'aucun contenu régional n'existe
Quand le système recherche du contenu à me proposer
Alors le système essaie d'abord 50 km
Puis essaie 100 km
Puis essaie le département
Puis essaie la région
Puis bascule sur le contenu national
Et tout ce processus se fait de manière transparente et automatique
Et je reçois le message correspondant au dernier niveau trouvé
# Messages adaptatifs selon le niveau d'élargissement
Scénario: Message personnalisé selon la distance trouvée
Étant donné que je suis situé à la position GPS 43.6047, 1.4442
Et que <niveau_geo> contenu(s) est/sont trouvé(s)
Quand le système me propose du contenu
Alors je reçois le message "<message_attendu>"
Exemples:
| niveau_geo | message_attendu |
| 100 km | Aucun contenu dans votre zone immédiate. Voici du contenu à proximité (100 km) |
| département | Aucun contenu local disponible. Voici du contenu dans votre département |
| région | Aucun contenu local disponible. Voici du contenu dans votre région |
| national | Aucun contenu local disponible. Voici du contenu national qui pourrait vous intéresser|
# Filet de sécurité - toujours du contenu disponible
Scénario: Le contenu national sert de filet de sécurité
Étant donné que le système a épuisé toutes les zones géographiques locales
Quand le système bascule sur du contenu national
Alors je dois toujours avoir au moins 1 contenu disponible
Et ce contenu peut être:
| type_contenu |
| Actualités Le Monde |
| Podcasts génériques |
| Contenu éducatif national |
| Contenu culturel national |
# Pas de message d'erreur bloquant
Scénario: Pas d'écran d'erreur "Aucun contenu"
Étant donné que je lance l'application
Et qu'aucun contenu local n'est disponible dans ma zone
Quand le système recherche du contenu
Alors je ne dois jamais voir un message d'erreur "Aucun contenu disponible"
Et je ne dois jamais voir un écran vide
Et un contenu doit toujours m'être proposé, même si c'est du contenu national
# Comportement avec historique d'écoute
Scénario: Élargissement avec prise en compte des centres d'intérêt
Étant donné que je suis situé dans une zone rurale
Et qu'aucun contenu n'existe dans un rayon de 50 km
Et que mes centres d'intérêt incluent "Automobile" à 80% et "Voyage" à 70%
Et qu'un contenu national existe avec le tag "Automobile"
Et qu'un contenu national existe avec le tag "Politique"
Quand le système bascule sur du contenu national
Alors le contenu national proposé prend en compte mes centres d'intérêt
Et le contenu "Automobile" a un score supérieur au contenu "Politique"

View File

@@ -0,0 +1,116 @@
# language: fr
@error-handling @content-removal
Fonctionnalité: Gestion d'un contenu supprimé pendant l'écoute
Contexte:
Étant donné que je suis un utilisateur connecté
Et que je suis en mode écoute
Et qu'un contenu "C123" est en cours de lecture
# 12.2 - Pas d'interruption brutale
Scénario: Contenu supprimé pendant lecture - fin de lecture sans interruption
Étant donné que j'écoute le contenu "C123" depuis 30 secondes
Et que la durée totale du contenu est de 120 secondes
Quand le contenu est supprimé par la modération côté backend
Alors la lecture du contenu continue sans interruption
Et je peux écouter le contenu jusqu'à la fin
Et aucune interruption brutale ne se produit
Scénario: Passage automatique après fin du contenu supprimé
Étant donné que le contenu "C123" a été supprimé pendant ma lecture
Et que j'ai écouté le contenu jusqu'à la fin
Quand le contenu se termine
Alors le système attend 2 secondes
Et passe automatiquement au contenu suivant
Et je reçois une notification toast discrète "Contenu précédent retiré (violation règles)"
Scénario: Bouton Précédent désactivé après suppression
Étant donné que le contenu "C123" a été supprimé pendant ma lecture
Et que je suis passé au contenu suivant "C456"
Quand j'essaie d'appuyer sur le bouton "Précédent"
Alors le bouton "Précédent" ne me ramène pas au contenu supprimé
Et je reçois un message "Ce contenu n'est plus disponible"
Et la lecture du contenu actuel "C456" continue
Scénario: Tentative de retour manuel au contenu supprimé
Étant donné que je suis sur le contenu "C456"
Et que le contenu précédent "C123" a été supprimé
Quand j'appuie sur le bouton "Précédent" pour revenir au contenu supprimé
Alors je reçois un message "Ce contenu n'est plus disponible"
Et la lecture reste sur le contenu actuel "C456"
Et aucune action n'est effectuée
# Sécurité routière - pas d'alerte intrusive
Scénario: Notification discrète pendant la conduite
Étant donné que je conduis à une vitesse de 60 km/h
Et que le contenu "C123" est supprimé pendant ma lecture
Quand le contenu se termine
Alors la notification "Contenu précédent retiré (violation règles)" s'affiche en toast discret
Et la notification disparaît automatiquement après 5 secondes
Et aucune popup modale n'interrompt ma conduite
Et le contenu suivant démarre automatiquement après 2 secondes
Scénario: Message informatif mais non alarmiste
Étant donné que le contenu "C123" a été supprimé
Et que je passe au contenu suivant
Quand la notification s'affiche
Alors le message doit être informatif: "Contenu précédent retiré (violation règles)"
Et le ton ne doit pas être alarmiste
Et le message doit être bref et compréhensible
Et aucun détail technique n'est affiché pendant la conduite
# Empêche la réécoute du contenu modéré
Scénario: Contenu supprimé retiré de l'historique
Étant donné que le contenu "C123" a été supprimé
Quand je consulte mon historique d'écoute
Alors le contenu "C123" n'apparaît plus dans mon historique
Et je ne peux pas relancer la lecture de ce contenu
Et l'historique affiche "[Contenu retiré]" à la place du titre
Scénario: Contenu supprimé non accessible via lien direct
Étant donné que le contenu "C123" a été supprimé
Et que j'ai un lien de partage "roadwave.fr/share/c/C123"
Quand je clique sur le lien de partage
Alors je reçois un message "Ce contenu a été retiré pour violation des règles de la communauté"
Et je suis redirigé vers l'accueil de l'application
Et aucune lecture n'est possible
# Gestion de plusieurs contenus supprimés consécutivement
Scénario: Plusieurs contenus supprimés dans l'historique récent
Étant donné que j'ai écouté les contenus suivants:
| id | statut |
| C123 | supprimé |
| C456 | actif |
| C789 | supprimé |
Et que je suis actuellement sur le contenu "C456"
Quand j'appuie plusieurs fois sur "Précédent"
Alors je ne peux pas revenir aux contenus "C123" ou "C789"
Et le système saute automatiquement les contenus supprimés
Et je reviens au dernier contenu actif disponible avant "C456"
# Comportement à l'arrêt du véhicule
Scénario: Consultation détaillée du contenu supprimé à l'arrêt
Étant donné que je suis à l'arrêt
Et que le contenu "C123" a été supprimé pendant ma session
Quand j'ouvre les détails de la notification de suppression
Alors je peux voir les informations suivantes:
| information |
| Titre du contenu |
| Créateur |
| Raison de suppression |
| Date de suppression |
Et je peux signaler une erreur de modération si je pense qu'elle est injustifiée
Scénario: Pas d'impact sur les jauges d'intérêt lors de la suppression
Étant donné que j'ai écouté le contenu "C123" pendant 80 secondes (66%)
Et que mes jauges d'intérêt ont été mises à jour pendant l'écoute
Quand le contenu est supprimé après mon écoute
Alors les modifications de mes jauges d'intérêt sont conservées
Et l'écoute déjà effectuée reste comptabilisée
Et seules les futures écoutes de ce contenu sont bloquées

View File

@@ -0,0 +1,210 @@
# language: fr
@error-handling @gps-disabled
Fonctionnalité: Mode dégradé sans géolocalisation
Contexte:
Étant donné que je suis un utilisateur connecté
Et que j'ai refusé ou désactivé l'accès à la géolocalisation
# 12.4 - Mode dégradé automatique
Scénario: Types de contenu disponibles sans géolocalisation
Étant donné que la géolocalisation est désactivée
Quand j'ouvre l'application
Alors les types de contenu suivants sont disponibles:
| type_contenu | disponible |
| Contenu national | oui |
| Contenu téléchargé (offline) | oui |
| Contenus "Neutre" géographiquement | oui |
| Contenu géolocalisé Ancré | non |
| Contenu géolocalisé Contextuel | non |
| Audio-guides | non |
| Notifications push géo-déclenchées | non |
# Popup au premier lancement
Scénario: Popup d'information au premier lancement sans GPS
Étant donné que c'est mon premier lancement de l'application
Et que j'ai refusé l'accès à la géolocalisation
Quand l'application détecte que le GPS est désactivé
Alors une popup s'affiche avec le message:
"""
RoadWave fonctionne mieux avec la géolocalisation activée. Sans elle, seul le contenu national sera disponible.
"""
Et la popup contient les boutons suivants:
| bouton | action |
| Activer | Redirection vers paramètres OS |
| Continuer sans | Ferme popup et lance en mode dégradé |
Et une checkbox "Ne plus me demander" est disponible
Scénario: Popup non affichée si case "Ne plus me demander" cochée
Étant donné que j'ai déjà vu la popup de géolocalisation
Et que j'ai coché "Ne plus me demander"
Quand je lance l'application avec le GPS désactivé
Alors la popup de géolocalisation ne s'affiche pas
Et l'application démarre directement en mode dégradé
Et le banner permanent de rappel s'affiche
Scénario: Redirection vers paramètres OS lors du clic sur "Activer"
Étant donné que la popup de géolocalisation est affichée
Quand je clique sur "Activer"
Alors je suis redirigé vers les paramètres de géolocalisation de mon OS
Et sur iOS, j'arrive dans "Réglages > RoadWave > Localisation"
Et sur Android, j'arrive dans "Paramètres > Applications > RoadWave > Autorisations > Position"
# Banner permanent en mode dégradé
Scénario: Banner de rappel permanent sans GPS
Étant donné que j'ai cliqué sur "Continuer sans" géolocalisation
Quand l'application s'affiche
Alors un bandeau s'affiche en haut de l'écran
Et le bandeau contient le texte: "Mode limité : géolocalisation désactivée. [Activer]"
Et le bandeau a un fond de couleur avertissement (jaune/orange)
Et le bandeau n'est pas intrusif mais reste visible
Et le bandeau reste affiché sur toutes les pages de l'application
Scénario: Clic sur le bouton "Activer" du banner
Étant donné que le banner "Mode limité" est affiché
Quand je clique sur le lien "[Activer]" dans le banner
Alors je suis redirigé vers les paramètres de géolocalisation de mon OS
Scénario: Disparition du banner après activation GPS
Étant donné que le banner "Mode limité" est affiché
Et que je reviens dans l'application après avoir activé le GPS dans les paramètres
Quand l'application détecte que la géolocalisation est maintenant active
Alors le banner disparaît automatiquement
Et l'application bascule en mode normal avec contenu géolocalisé
Et un toast de confirmation s'affiche: "Géolocalisation activée"
# Contenu disponible en mode dégradé
Scénario: Lecture de contenu national sans GPS
Étant donné que la géolocalisation est désactivée
Et que du contenu national existe (actualités Le Monde, podcasts génériques)
Quand je lance la lecture
Alors je peux écouter le contenu national sans restriction
Et l'algorithme de recommandation se base uniquement sur:
| critère |
| Mes centres d'intérêt |
| Mon historique d'écoute |
| Popularité générale |
Et la proximité géographique n'est pas prise en compte
Scénario: Lecture de contenu téléchargé sans GPS
Étant donné que la géolocalisation est désactivée
Et que j'ai téléchargé 30 contenus quand j'avais le GPS activé
Quand j'accède à mes contenus téléchargés
Alors je peux lire tous mes contenus téléchargés normalement
Et les contenus géolocalisés téléchargés restent accessibles
Et le filtre géographique n'est pas appliqué pour les contenus offline
Scénario: Contenu "Neutre" géographiquement disponible
Étant donné que la géolocalisation est désactivée
Et qu'un créateur a publié du contenu avec la classification géographique "Neutre"
Quand je recherche du contenu
Alors les contenus "Neutre" sont inclus dans les résultats
Et ils sont mélangés avec le contenu national
Et l'algorithme les priorise selon mes centres d'intérêt
# Restrictions de contenu sans GPS
Scénario: Audio-guides inaccessibles sans GPS
Étant donné que la géolocalisation est désactivée
Quand je recherche un audio-guide spécifique
Alors les audio-guides apparaissent dans les résultats de recherche
Mais un badge "GPS requis" est affiché sur chaque audio-guide
Et quand je clique sur un audio-guide, un message s'affiche:
"""
Les audio-guides nécessitent la géolocalisation pour fonctionner. Voulez-vous activer le GPS ?
"""
Et je peux choisir "Activer" ou "Annuler"
Scénario: Notifications push géo-déclenchées désactivées
Étant donné que la géolocalisation est désactivée
Et que je suis abonné à un créateur qui diffuse du contenu géolocalisé
Quand le créateur publie un nouveau contenu géolocalisé
Alors je ne reçois pas de notification push géo-déclenchée
Mais je reçois une notification push standard (non géo-déclenchée) si le créateur publie du contenu national
Et la notification précise: "Nouveau contenu national de [Créateur]"
Scénario: Contenu géolocalisé non proposé dans le feed
Étant donné que la géolocalisation est désactivée
Quand le système génère mon feed de contenu
Alors aucun contenu "Ancré" ou "Contextuel" n'est inclus
Et seuls les contenus "Neutre" et "National" sont proposés
Et mon feed contient au minimum 20 contenus disponibles
# RGPD: Respect du consentement libre
Scénario: Application fonctionnelle sans GPS (pas de blocage)
Étant donné que la géolocalisation est désactivée
Quand j'utilise l'application
Alors je ne suis jamais bloqué par un écran "GPS requis"
Et toutes les fonctionnalités non-géolocalisées restent accessibles:
| fonctionnalité |
| Écoute contenu national |
| Gestion profil |
| Abonnements créateurs |
| Recherche textuelle |
| Historique d'écoute |
| Paramètres |
| Mode offline |
Et je peux créer et publier du contenu national
Scénario: Respect du choix utilisateur de ne pas activer GPS
Étant donné que j'ai coché "Ne plus me demander" pour la géolocalisation
Quand j'utilise l'application pendant plusieurs semaines
Alors la popup de demande GPS ne s'affiche plus jamais automatiquement
Et seul le banner permanent reste affiché
Et l'application ne force jamais l'activation du GPS
# Réactivation GPS et bascule en mode normal
Scénario: Bascule automatique en mode normal après activation GPS
Étant donné que j'utilise l'application en mode dégradé depuis 1 semaine
Et que je décide d'activer la géolocalisation
Quand l'application détecte que le GPS est maintenant actif
Alors le mode dégradé est désactivé automatiquement
Et le banner "Mode limité" disparaît
Et le contenu géolocalisé devient disponible immédiatement
Et mon feed se rafraîchit avec du contenu local pertinent
Et un toast de confirmation s'affiche: "Géolocalisation activée - Contenu local disponible"
Scénario: Demande de permission GPS lors de l'utilisation d'une fonctionnalité géo
Étant donné que la géolocalisation est désactivée
Quand j'essaie d'accéder à une fonctionnalité nécessitant le GPS (ex: audio-guide)
Alors une popup contextuelle s'affiche:
"""
Cette fonctionnalité nécessite la géolocalisation. Voulez-vous l'activer ?
"""
Et je peux accepter ou refuser
Et si j'accepte, je suis redirigé vers les paramètres OS
Et si je refuse, je reste en mode dégradé sans message d'erreur répétitif
# Incitation à activer GPS sans être intrusif
Scénario: Statistiques de contenu local disponible non affiché
Étant donné que la géolocalisation est désactivée
Quand je navigue dans l'application
Alors le banner peut afficher occasionnellement:
"""
Mode limité : géolocalisation désactivée. Plus de 500 contenus locaux disponibles près de vous. [Activer]
"""
Et ce message incitatif change tous les 3 jours
Et il reste non intrusif (pas de popup, juste le banner)
Scénario: Onboarding différent pour utilisateurs sans GPS
Étant donné que c'est ma première utilisation de RoadWave
Et que j'ai refusé la géolocalisation
Quand l'onboarding se termine
Alors un écran explicatif s'affiche:
"""
Vous utilisez RoadWave sans géolocalisation. Voici ce qui est disponible :
- Contenu national (actualités, podcasts)
- Contenus téléchargés
- Tous les créateurs et abonnements
Pour profiter pleinement de RoadWave (contenu local, audio-guides), activez la géolocalisation à tout moment.
"""
Et je peux continuer avec un bouton "Compris"

View File

@@ -0,0 +1,179 @@
# language: fr
@error-handling @network-loss
Fonctionnalité: Gestion de la perte de réseau et buffering adaptatif
Contexte:
Étant donné que je suis un utilisateur connecté
Et que je suis en mode écoute
Et qu'un contenu est en cours de lecture
# 12.3 - Buffer adaptatif selon type de réseau (cf. TECHNICAL.md et ADR-002)
Plan du Scénario: Paramètres de buffer selon le type de réseau
Étant donné que je suis connecté en "<type_reseau>"
Quand le système initialise le buffer audio
Alors le buffer minimum est de <buffer_min> secondes
Et le buffer cible est de <buffer_cible> secondes
Et le buffer maximum est de <buffer_max> secondes
Exemples:
| type_reseau | buffer_min | buffer_cible | buffer_max |
| WiFi | 5 | 30 | 120 |
| 4G | 10 | 45 | 120 |
| 5G | 10 | 45 | 120 |
| 3G | 30 | 90 | 300 |
# Phase 1: Connexion instable
Scénario: Connexion instable avec latence élevée - aucun message immédiat
Étant donné que je suis connecté en 4G
Et que le buffer contient 45 secondes de contenu
Quand la latence réseau dépasse 500ms
Alors aucun message n'est affiché immédiatement
Et la lecture continue normalement sur le buffer
Et le système tente de continuer le téléchargement en arrière-plan
Scénario: Connexion instable pendant plus de 10 secondes - toast discret
Étant donné que je suis connecté en 4G
Et que la latence réseau dépasse 500ms depuis 10 secondes
Quand le système détecte la latence prolongée
Alors un toast discret s'affiche: "Connexion instable"
Et le toast disparaît automatiquement après 3 secondes
Et la lecture continue normalement
# Phase 2: Perte totale réseau
Scénario: Perte totale de réseau - lecture sur buffer
Étant donné que je suis connecté en WiFi
Et que le buffer contient 30 secondes de contenu
Quand je perds totalement la connexion réseau
Alors la lecture continue sur le buffer disponible
Et un toast s'affiche: "Hors ligne, lecture sur buffer (30s restantes)"
Et un compte à rebours du temps de buffer restant est visible
Scénario: Buffer qui s'épuise pendant la perte réseau
Étant donné que je suis hors ligne
Et que le buffer contient 30 secondes de contenu
Quand le contenu continue de jouer
Alors le compte à rebours diminue en temps réel
Et le toast affiche "Hors ligne, lecture sur buffer (15s restantes)" après 15 secondes
Et le toast affiche "Hors ligne, lecture sur buffer (5s restantes)" après 25 secondes
# Phase 3: Buffer épuisé sans reconnexion
Scénario: Pause automatique après épuisement du buffer
Étant donné que je suis hors ligne depuis 30 secondes
Et que le buffer est complètement épuisé
Quand il n'y a plus de contenu audio à lire
Alors la lecture se met en pause automatiquement
Et un overlay s'affiche: "Connexion perdue. Reconnexion en cours..."
Et le système tente de se reconnecter automatiquement
Scénario: Tentatives de reconnexion automatique
Étant donné que la lecture est en pause suite à l'épuisement du buffer
Quand le système tente de se reconnecter
Alors une tentative de reconnexion est effectuée toutes les 5 secondes
Et un maximum de 6 tentatives sont effectuées (30 secondes au total)
Et l'overlay affiche "Tentative de reconnexion... (X/6)"
# Phase 4: Basculement mode offline après échec reconnexion
Scénario: Proposition du mode offline après 30 secondes d'échec
Étant donné que 6 tentatives de reconnexion ont échoué
Et que cela fait 30 secondes que je suis déconnecté
Quand la 6ème tentative échoue
Alors une popup s'affiche: "Voulez-vous continuer avec vos contenus téléchargés ?"
Et la popup contient deux boutons:
| bouton | action |
| Réessayer | Nouvelle série de 6 tentatives |
| Mode offline | Bascule sur contenus téléchargés |
Scénario: Basculement réussi vers le mode offline
Étant donné que la popup de mode offline est affichée
Et que j'ai téléchargé 20 contenus dans ma zone géographique
Quand je clique sur "Mode offline"
Alors le système bascule sur les contenus téléchargés
Et un nouveau contenu téléchargé démarre automatiquement
Et un bandeau permanent indique "Mode hors ligne - Contenus téléchargés"
Scénario: Aucun contenu téléchargé disponible
Étant donné que la popup de mode offline est affichée
Et que je n'ai aucun contenu téléchargé
Quand je clique sur "Mode offline"
Alors un message s'affiche: "Aucun contenu téléchargé disponible"
Et je suis invité à me connecter en WiFi pour télécharger du contenu
Et le bouton "Réessayer" reste la seule option
# Reconnexion réussie
Scénario: Reprise automatique après reconnexion
Étant donné que la lecture est en pause depuis 15 secondes
Et que j'étais à 02:35 du contenu en cours
Quand la connexion réseau est rétablie
Alors la lecture reprend automatiquement au point d'arrêt exact (02:35)
Et un toast s'affiche: "Connexion rétablie"
Et le toast disparaît après 3 secondes
Et le buffer se remplit progressivement selon le type de réseau
Scénario: Reconnexion avec changement de type de réseau
Étant donné que j'étais connecté en WiFi
Et que j'ai perdu la connexion
Quand je me reconnecte en 4G
Alors le système ajuste automatiquement les paramètres de buffer
Et le buffer minimum passe de 5s à 10s
Et le buffer cible passe de 30s à 45s
Et la lecture reprend normalement
# Cas spécifique: tunnel routier
Scénario: Passage dans un tunnel avec perte de signal
Étant donné que je conduis à 90 km/h sur autoroute
Et que je suis connecté en 4G avec un buffer de 45 secondes
Quand j'entre dans un tunnel et perds le signal
Alors la lecture continue sur le buffer pendant 45 secondes maximum
Et aucune notification n'est affichée pendant les 10 premières secondes
Et un toast discret s'affiche après 10 secondes: "Connexion instable"
Scénario: Sortie du tunnel avant épuisement du buffer
Étant donné que je suis dans un tunnel depuis 30 secondes
Et qu'il reste 15 secondes de buffer
Quand je sors du tunnel et récupère le signal 4G
Alors la lecture continue sans interruption
Et le buffer se remplit à nouveau
Et un toast s'affiche: "Connexion rétablie"
# Handoff réseau (changement de cellule mobile)
Scénario: Changement de cellule 4G pendant la lecture
Étant donné que je conduis et change de cellule mobile toutes les 5-10 minutes
Et que le buffer contient 45 secondes de contenu
Quand un handoff de cellule se produit
Alors la lecture continue sans interruption grâce au buffer
Et la connexion à la nouvelle cellule se fait de manière transparente
Et aucune notification n'est affichée si le handoff réussit en moins de 5 secondes
# Mode offline préventif avant perte réseau
Scénario: Téléchargement préventif en WiFi avant trajet
Étant donné que je suis connecté en WiFi
Et que j'ai activé le téléchargement automatique
Quand le système détecte que je suis à l'arrêt en WiFi
Alors le système me propose de télécharger du contenu pour mon trajet
Et je peux sélectionner une zone géographique à télécharger
Et le téléchargement se fait en arrière-plan
# Métriques et monitoring
Scénario: Tracking des événements de perte réseau pour amélioration
Étant donné que je perds la connexion réseau
Quand l'événement de perte est détecté
Alors le système enregistre les métriques suivantes:
| métrique |
| Type de réseau avant perte |
| Durée de la coupure |
| Buffer disponible |
| Position GPS approximative |
| Heure de la journée |
Et ces métriques sont anonymisées et envoyées en batch lors de la prochaine connexion WiFi
Et les données servent à améliorer les paramètres de buffer