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:
400
features/ui/audio-guides/mode-voiture.feature
Normal file
400
features/ui/audio-guides/mode-voiture.feature
Normal file
@@ -0,0 +1,400 @@
|
||||
# language: fr
|
||||
|
||||
Fonctionnalité: Audio-guide mode voiture (GPS automatique)
|
||||
En tant qu'utilisateur en voiture
|
||||
Je veux que les séquences se déclenchent automatiquement selon ma position GPS
|
||||
Afin de profiter d'une expérience guidée hands-free
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'application RoadWave est démarrée
|
||||
Et que l'utilisateur "jean@example.com" est connecté (gratuit)
|
||||
Et qu'un audio-guide voiture "Safari du Paugre" est disponible avec 8 séquences
|
||||
Et que le GPS est activé
|
||||
|
||||
# 16.3.1 - Déclenchement et contrôles
|
||||
|
||||
Scénario: Distinction audio-guides vs contenus géolocalisés simples
|
||||
Étant donné que l'utilisateur est en mode voiture
|
||||
Quand il écoute un contenu géolocalisé simple (1 séquence unique)
|
||||
Alors une notification avec compteur 7→1 est affichée 7s avant le point
|
||||
Et il doit valider avec "Suivant" + décompte 5s
|
||||
Et ce contenu compte 1/6 dans le quota horaire
|
||||
Quand il démarre un audio-guide multi-séquences
|
||||
Alors les séquences se déclenchent au point GPS exact (rayon 30m)
|
||||
Et aucun compteur 7s n'est affiché (juste notification "Ding" + toast 2s)
|
||||
Et l'audio-guide entier compte 1/6 dans le quota
|
||||
|
||||
Scénario: Démarrage automatique au premier point GPS
|
||||
Étant donné que l'utilisateur démarre l'audio-guide "Safari du Paugre"
|
||||
Et que le point de départ est à (43.1234, 2.5678) avec rayon 30m
|
||||
Quand l'utilisateur entre dans le rayon de 30m
|
||||
Alors la séquence 1 "Introduction - Point d'accueil" démarre automatiquement
|
||||
Et une notification sonore "Ding" est jouée (non intrusif)
|
||||
Et un toast s'affiche brièvement pendant 2s: "Introduction - Point d'accueil"
|
||||
Et aucun compteur 7→1 n'est affiché (contrairement aux contenus géolocalisés simples)
|
||||
|
||||
Scénario: Déclenchement automatique séquence suivante
|
||||
Étant donné que la séquence 1 est terminée
|
||||
Et que l'utilisateur se déplace vers le point GPS 2 (43.1245, 2.5690)
|
||||
Quand l'utilisateur entre dans le rayon de 30m du point 2
|
||||
Alors la séquence 2 "Enclos des lions" démarre automatiquement
|
||||
Et une notification "Ding" + toast "Enclos des lions" s'affiche
|
||||
|
||||
Scénario: Navigation manuelle conservée (bouton Suivant actif)
|
||||
Étant donné que la séquence 1 est en cours
|
||||
Et que l'utilisateur est encore loin du point GPS 2 (distance 500m)
|
||||
Quand l'utilisateur clique sur [▶|] "Suivant"
|
||||
Alors la séquence 2 démarre immédiatement
|
||||
Et aucune vérification GPS n'est effectuée
|
||||
|
||||
Scénario: Navigation manuelle conservée (bouton Précédent actif)
|
||||
Étant donné que la séquence 3 est en cours
|
||||
Quand l'utilisateur clique sur [|◀] "Précédent"
|
||||
Alors la séquence 2 démarre depuis le début
|
||||
Et aucune vérification GPS n'est effectuée
|
||||
|
||||
Scénario: Tous les boutons de contrôle restent actifs
|
||||
Étant donné qu'un audio-guide voiture est en cours
|
||||
Quand l'utilisateur consulte les contrôles
|
||||
Alors les boutons suivants sont actifs:
|
||||
| bouton | état | comportement |
|
||||
| [▶\|] Suivant | ✅ | Passe séquence suivante immédiate |
|
||||
| [\|◀] Précédent | ✅ | Retour séquence précédente |
|
||||
| [⏸️] Pause | ✅ | Pause temporaire |
|
||||
| [📋] Liste | ✅ | Saut direct possible |
|
||||
|
||||
Scénario: Use case - Embouteillage (séquence finie, point GPS loin)
|
||||
Étant donné que la séquence 3 "Enclos des girafes" est terminée
|
||||
Et que le point GPS 4 est à 2 km de distance (embouteillage)
|
||||
Quand l'utilisateur clique manuellement sur [▶|] "Suivant"
|
||||
Alors la séquence 4 démarre immédiatement
|
||||
Et l'utilisateur peut continuer l'expérience sans attendre d'atteindre le point GPS
|
||||
|
||||
Scénario: Use case - Route fermée (point GPS inaccessible)
|
||||
Étant donné que le point GPS 5 est sur une route fermée
|
||||
Et que l'utilisateur ne peut pas s'en approcher
|
||||
Quand l'utilisateur clique sur [▶|] "Suivant"
|
||||
Alors la séquence 5 démarre quand même
|
||||
Et l'audio-guide continue normalement
|
||||
|
||||
Scénario: Use case - Passager manipule l'application
|
||||
Étant donné que l'utilisateur est passager (non conducteur)
|
||||
Et que la vitesse du véhicule est 45 km/h
|
||||
Quand le passager clique sur [▶|] "Suivant"
|
||||
Alors la séquence suivante démarre
|
||||
Et un avertissement s'affiche pendant 3 secondes
|
||||
|
||||
Scénario: Avertissement sécurité si vitesse >10 km/h
|
||||
Étant donné que la vitesse actuelle est 35 km/h
|
||||
Quand l'utilisateur clique sur un bouton (Suivant ou Précédent)
|
||||
Alors l'action est exécutée immédiatement (pas de blocage)
|
||||
Et un toast s'affiche pendant 3 secondes:
|
||||
"""
|
||||
⚠️ Manipulation en conduite détectée.
|
||||
Pour votre sécurité, demandez à un passager.
|
||||
"""
|
||||
|
||||
Plan du Scénario: Avertissement selon la vitesse
|
||||
Étant donné que la vitesse actuelle est <vitesse> km/h
|
||||
Quand l'utilisateur clique sur un bouton de navigation
|
||||
Alors l'avertissement est affiché : <avertissement>
|
||||
|
||||
Exemples:
|
||||
| vitesse | avertissement |
|
||||
| 5 | Non |
|
||||
| 10 | Non |
|
||||
| 11 | Oui |
|
||||
| 35 | Oui |
|
||||
| 90 | Oui |
|
||||
|
||||
# 16.3.2 - Affichage distance et guidage
|
||||
|
||||
Scénario: Affichage entre deux séquences avec progress bar
|
||||
Étant donné que la séquence 2 "Les lions" vient de se terminer
|
||||
Et que le prochain point GPS 3 "Enclos des girafes" est à 500m
|
||||
Quand l'interface bascule en mode "attente prochain point"
|
||||
Alors l'écran affiche:
|
||||
| élément | description |
|
||||
| Statut séquence | "✅ Séquence 2/8 terminée" |
|
||||
| Nom séquence | "Les lions" |
|
||||
| Progress bar | Barre dynamique remplie selon distance (0%) |
|
||||
| Distance prochain point| "500 mètres" |
|
||||
| ETA | "≈ 1 minute 30" |
|
||||
| Direction | ↗️ |
|
||||
| Vitesse actuelle | "28 km/h" |
|
||||
| Bouton "Rejouer séq." | Permet de réécouter la séquence qui vient de finir |
|
||||
|
||||
Scénario: Progress bar dynamique vers le prochain point
|
||||
Étant donné que la distance initiale vers le prochain point était 500m
|
||||
Et que la séquence précédente est terminée
|
||||
Quand l'utilisateur se rapproche du prochain point
|
||||
Et que la distance actuelle est 175m
|
||||
Alors la progress bar affiche "65%" remplie
|
||||
Et le calcul est: 100 - (175 / 500 * 100) = 65%
|
||||
Et la barre se met à jour chaque seconde
|
||||
|
||||
Scénario: Bouton "Rejouer séq." pour réécouter
|
||||
Étant donné que la séquence 3 vient de se terminer
|
||||
Et que l'interface "attente prochain point" est affichée
|
||||
Quand l'utilisateur clique sur [▶️ Rejouer séq.]
|
||||
Alors la séquence 3 redémarre depuis 0:00
|
||||
Et l'utilisateur peut la réécouter (utile si distraction)
|
||||
|
||||
Scénario: Interface en conduite avec distance et ETA
|
||||
Étant donné que la séquence 2 est en cours
|
||||
Et que le prochain point GPS 3 "Enclos des girafes" est à 320m
|
||||
Et que la vitesse actuelle est 28 km/h
|
||||
Quand l'interface est affichée
|
||||
Alors les informations suivantes sont visibles:
|
||||
| information | valeur |
|
||||
| Nom prochain point | "Enclos des girafes" |
|
||||
| Distance | "320 mètres" |
|
||||
| ETA | "≈ 40 secondes" |
|
||||
| Direction | ↗️ (flèche direction) |
|
||||
| Vitesse actuelle | "28 km/h" |
|
||||
| Vitesse recommandée | "20-30 km/h" |
|
||||
|
||||
Scénario: Mise à jour de la distance en temps réel
|
||||
Étant donné que la distance au prochain point est 500m
|
||||
Quand 10 secondes s'écoulent et que l'utilisateur se rapproche
|
||||
Alors la distance est mise à jour chaque seconde
|
||||
Et la nouvelle distance "450m" s'affiche
|
||||
|
||||
Scénario: Mise à jour de l'ETA en temps réel
|
||||
Étant donné que l'ETA est "≈ 2 minutes"
|
||||
Et que la vitesse est constante à 30 km/h
|
||||
Quand l'utilisateur se rapproche du point
|
||||
Alors l'ETA est recalculé chaque seconde
|
||||
Et il diminue progressivement: "≈ 1 minute 50", "≈ 1 minute 40", etc.
|
||||
|
||||
Plan du Scénario: Format d'affichage de la distance
|
||||
Étant donné que la distance au prochain point est <distance_metres>
|
||||
Quand l'interface est mise à jour
|
||||
Alors la distance affichée est "<affichage>"
|
||||
|
||||
Exemples:
|
||||
| distance_metres | affichage |
|
||||
| 50 | 50 m |
|
||||
| 320 | 320 m |
|
||||
| 980 | 980 m |
|
||||
| 1200 | 1.2 km |
|
||||
| 5400 | 5.4 km |
|
||||
|
||||
Plan du Scénario: Format d'affichage de l'ETA
|
||||
Étant donné que l'ETA calculé est <secondes> secondes
|
||||
Quand l'interface est mise à jour
|
||||
Alors l'ETA affiché est "<affichage>"
|
||||
|
||||
Exemples:
|
||||
| secondes | affichage |
|
||||
| 30 | ≈ 30 secondes |
|
||||
| 75 | ≈ 1 minute |
|
||||
| 150 | ≈ 2 minutes |
|
||||
| 400 | ≈ 6 minutes |
|
||||
|
||||
Scénario: Calcul de la direction (flèche 8 directions)
|
||||
Étant donné que la position actuelle est (43.1234, 2.5678)
|
||||
Et que le prochain point est au nord-est (angle 45°)
|
||||
Quand la direction est calculée
|
||||
Alors la flèche "↗" est affichée
|
||||
|
||||
Plan du Scénario: Flèches de direction selon l'angle
|
||||
Étant donné que l'angle vers le prochain point est <angle>°
|
||||
Quand la direction est calculée
|
||||
Alors la flèche "<fleche>" est affichée
|
||||
|
||||
Exemples:
|
||||
| angle | fleche |
|
||||
| 0 | ↑ |
|
||||
| 45 | ↗ |
|
||||
| 90 | → |
|
||||
| 135 | ↘ |
|
||||
| 180 | ↓ |
|
||||
| 225 | ↙ |
|
||||
| 270 | ← |
|
||||
| 315 | ↖ |
|
||||
|
||||
Scénario: Mise à jour de la direction toutes les 5 secondes
|
||||
Étant donné que la direction actuelle est ↑ (nord)
|
||||
Et que l'utilisateur tourne vers l'est
|
||||
Quand 5 secondes s'écoulent
|
||||
Alors la direction est recalculée
|
||||
Et la nouvelle flèche ↗ (nord-est) s'affiche
|
||||
|
||||
Scénario: Message "En attente de déplacement" si vitesse <5 km/h
|
||||
Étant donné que la vitesse actuelle est 2 km/h (arrêté)
|
||||
Quand l'ETA est calculé
|
||||
Alors le message "En attente de déplacement" s'affiche
|
||||
Et l'ETA n'est pas calculé (car vitesse insuffisante)
|
||||
|
||||
Scénario: Simplicité de l'interface (pas de carte miniature)
|
||||
Étant donné qu'un audio-guide voiture est en cours
|
||||
Quand l'interface est affichée
|
||||
Alors aucune carte miniature n'est présente
|
||||
Et seuls les éléments essentiels sont affichés:
|
||||
| élément |
|
||||
| Distance |
|
||||
| ETA |
|
||||
| Direction (flèche) |
|
||||
| Vitesse |
|
||||
| Contrôles audio |
|
||||
|
||||
# 16.3.3 - Rayon de déclenchement et tolérance
|
||||
|
||||
Scénario: Rayon de déclenchement par défaut en mode voiture
|
||||
Étant donné un audio-guide voiture
|
||||
Quand un point GPS est défini
|
||||
Alors le rayon de déclenchement est 30 mètres par défaut
|
||||
Et le rayon de tolérance "point manqué" est 100 mètres
|
||||
|
||||
Scénario: Déclenchement dans le rayon (30m)
|
||||
Étant donné que le point GPS 3 est défini avec rayon 30m
|
||||
Quand l'utilisateur entre à 25m du point
|
||||
Alors la séquence 3 se déclenche automatiquement
|
||||
|
||||
Scénario: Pas de déclenchement hors rayon
|
||||
Étant donné que le point GPS 3 a un rayon de 30m
|
||||
Quand l'utilisateur passe à 45m du point
|
||||
Alors la séquence 3 ne se déclenche pas automatiquement
|
||||
|
||||
Scénario: Point manqué dans rayon de tolérance (100m)
|
||||
Étant donné que l'utilisateur passe à 60m du point GPS 4 (hors rayon 30m)
|
||||
Et que 60m < 100m (rayon tolérance)
|
||||
Quand le point est détecté comme manqué
|
||||
Alors un toast s'affiche: "⚠️ Point manqué : Enclos des éléphants"
|
||||
Et une popup s'affiche pendant 5 secondes avec 3 options
|
||||
|
||||
Scénario: Popup "Point manqué" avec 3 actions
|
||||
Étant donné qu'un point GPS a été manqué (distance 60m)
|
||||
Quand la popup s'affiche
|
||||
Alors les options suivantes sont disponibles:
|
||||
| bouton | icône | comportement |
|
||||
| Écouter quand même | 🔊 | Lance séquence immédiatement (même hors zone) |
|
||||
| Passer au suivant | ⏭️ | Skip séquence, continue vers prochain point |
|
||||
| Faire demi-tour | 🔙 | Ouvre GPS externe (Google Maps/Waze) vers point |
|
||||
|
||||
Scénario: Action "Écouter quand même"
|
||||
Étant donné qu'un point GPS est manqué
|
||||
Quand l'utilisateur clique sur "🔊 Écouter quand même"
|
||||
Alors la séquence correspondante démarre immédiatement
|
||||
Et l'utilisateur peut continuer sa route
|
||||
|
||||
Scénario: Action "Passer au suivant"
|
||||
Étant donné qu'un point GPS 5 est manqué
|
||||
Quand l'utilisateur clique sur "⏭️ Passer au suivant"
|
||||
Alors la séquence 5 est ignorée (non écoutée)
|
||||
Et l'application attend le point GPS 6
|
||||
Et la distance vers le point 6 s'affiche
|
||||
|
||||
Scénario: Action "Faire demi-tour"
|
||||
Étant donné qu'un point GPS est manqué à (43.1250, 2.5700)
|
||||
Quand l'utilisateur clique sur "🔙 Faire demi-tour"
|
||||
Alors l'application détecte l'app GPS installée (Google Maps ou Waze)
|
||||
Et ouvre la navigation GPS externe vers (43.1250, 2.5700)
|
||||
|
||||
Scénario: Point manqué au-delà du rayon de tolérance (>100m)
|
||||
Étant donné que l'utilisateur passe à 150m du point GPS 6
|
||||
Quand la distance est détectée
|
||||
Alors aucune popup ne s'affiche (point trop loin)
|
||||
Et l'utilisateur peut naviguer manuellement avec [▶|]
|
||||
|
||||
Plan du Scénario: Gestion selon la distance au point
|
||||
Étant donné un point GPS avec rayon 30m et tolérance 100m
|
||||
Quand l'utilisateur passe à <distance> du point
|
||||
Alors le comportement est <comportement>
|
||||
|
||||
Exemples:
|
||||
| distance | comportement |
|
||||
| 20m | Déclenchement automatique séquence |
|
||||
| 40m | Rien (hors rayon, pas encore tolérance) |
|
||||
| 60m | Popup "Point manqué" avec 3 options |
|
||||
| 110m | Rien (trop loin, hors tolérance) |
|
||||
|
||||
Scénario: Configuration rayon personnalisé par le créateur
|
||||
Étant donné qu'un créateur définit un rayon de 50m (au lieu de 30m)
|
||||
Quand un utilisateur entre à 45m du point
|
||||
Alors la séquence se déclenche automatiquement
|
||||
Et le rayon personnalisé est respecté
|
||||
|
||||
Scénario: Rayon minimum et maximum configurables
|
||||
Étant donné qu'un créateur configure un rayon
|
||||
Quand il ajuste le curseur
|
||||
Alors les valeurs disponibles sont de 10m à 200m
|
||||
Et le rayon par défaut suggéré est 30m pour la voiture
|
||||
|
||||
# Cas d'usage réels
|
||||
|
||||
Scénario: Safari-parc avec déclenchement automatique fluide
|
||||
Étant donné qu'un utilisateur roule dans un safari à 20 km/h
|
||||
Quand il passe devant "Enclos des lions" (point GPS 2)
|
||||
Alors la séquence 2 démarre automatiquement sans intervention
|
||||
Et il peut se concentrer sur la conduite et l'observation
|
||||
|
||||
Scénario: Détour imprévu (travaux sur la route)
|
||||
Étant donné qu'un utilisateur prend un détour à cause de travaux
|
||||
Et que le point GPS 4 devient inaccessible
|
||||
Quand il est loin du point (>100m)
|
||||
Et qu'il clique manuellement sur [▶|]
|
||||
Alors la séquence 4 démarre quand même
|
||||
Et l'expérience continue sans blocage
|
||||
|
||||
Scénario: Passager qui navigue librement
|
||||
Étant donné qu'un passager utilise l'application
|
||||
Et que le conducteur roule à 50 km/h
|
||||
Quand le passager clique sur "Précédent" pour réécouter
|
||||
Alors l'action est exécutée immédiatement
|
||||
Et un warning apparaît brièvement (sensibilisation)
|
||||
|
||||
Scénario: Embouteillage prolongé
|
||||
Étant donné que la séquence 3 est terminée depuis 10 minutes
|
||||
Et que l'utilisateur est bloqué dans un embouteillage
|
||||
Et que le point GPS 4 est encore à 1.5 km
|
||||
Quand l'utilisateur clique sur [▶|]
|
||||
Alors la séquence 4 démarre immédiatement
|
||||
Et l'utilisateur peut passer le temps en écoutant
|
||||
|
||||
# Cas d'erreur
|
||||
|
||||
Scénario: GPS désactivé en mode voiture
|
||||
Étant donné qu'un audio-guide voiture est démarré
|
||||
Et que le GPS est désactivé
|
||||
Quand l'application détecte l'absence de GPS
|
||||
Alors une alerte s'affiche:
|
||||
"""
|
||||
⚠️ GPS requis pour le mode Voiture
|
||||
Activez la localisation pour profiter du déclenchement automatique.
|
||||
[Activer GPS] [Passer en mode Manuel]
|
||||
"""
|
||||
|
||||
Scénario: Action "Passer en mode Manuel"
|
||||
Étant donné que le GPS est désactivé
|
||||
Quand l'utilisateur clique sur "Passer en mode Manuel"
|
||||
Alors l'audio-guide bascule en navigation 100% manuelle
|
||||
Et les boutons [▶|] et [|◀] permettent de naviguer
|
||||
Et aucun déclenchement GPS n'est tenté
|
||||
|
||||
Scénario: Précision GPS insuffisante
|
||||
Étant donné que le signal GPS a une précision de ±150m
|
||||
Quand l'utilisateur approche d'un point GPS avec rayon 30m
|
||||
Alors un avertissement s'affiche:
|
||||
"""
|
||||
⚠️ Signal GPS imprécis (±150m)
|
||||
Le déclenchement automatique peut être perturbé.
|
||||
Utilisez les boutons manuels si nécessaire.
|
||||
"""
|
||||
|
||||
Scénario: Perte signal GPS en cours de route
|
||||
Étant donné qu'un audio-guide voiture est en cours
|
||||
Quand le signal GPS est perdu (tunnel, parking souterrain)
|
||||
Alors un toast s'affiche: "Signal GPS perdu. Navigation manuelle active."
|
||||
Et les boutons de navigation restent actifs
|
||||
Quand le signal GPS revient
|
||||
Alors un toast s'affiche: "Signal GPS rétabli"
|
||||
Et le déclenchement automatique est réactivé
|
||||
|
||||
Scénario: Dépassement de la vitesse recommandée
|
||||
Étant donné qu'un audio-guide recommande 20-30 km/h
|
||||
Et que l'utilisateur roule à 65 km/h
|
||||
Quand la vitesse est détectée
|
||||
Alors l'affichage vitesse est en orange: "⚠️ 65 km/h"
|
||||
Et un message info s'affiche: "Vitesse élevée. Risque de manquer des points."
|
||||
Reference in New Issue
Block a user