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,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 71 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 71 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."