Files
roadwave/features/ui/navigation/commandes-volant.feature
jpgiannetti 37c62206ad 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>
2026-02-01 11:31:41 +01:00

206 lines
9.0 KiB
Gherkin

# language: fr
Fonctionnalité: Commandes au volant et interactions simplifiées
En tant que conducteur en sécurité
Je veux utiliser uniquement les commandes simplifiées au volant
Afin de naviguer sans distraction et en toute sécurité
Contexte:
Étant donné que l'API RoadWave est disponible
Et qu'un utilisateur est connecté
Et que l'application est connectée via CarPlay ou Android Auto
Scénario: Trois commandes disponibles au volant uniquement
Étant donné que je conduis à 50 km/h
Quand je consulte les commandes physiques disponibles
Alors seules 3 actions sont disponibles:
| Commande | Action |
| Suivant | Passer au contenu suivant |
| Précédent | Revenir au précédent (règle 10s) |
| Play/Pause | Pause/reprise avec fade 0.3s |
Et aucune commande complexe n'est proposée
Scénario: Commande "Suivant" au volant
Étant donné que j'écoute un contenu "A"
Quand j'appuie sur le bouton physique "Suivant" au volant
Alors le contenu "B" démarre immédiatement
Et aucune action supplémentaire n'est requise
Et l'interface ne demande aucune confirmation
Scénario: Commande "Précédent" au volant respecte règle 10s
Étant donné que j'écoute un contenu depuis 5 secondes
Quand j'appuie sur "Précédent" au volant
Alors je reviens au contenu précédent (règle <10s)
Étant donné que j'écoute un contenu depuis 15 secondes
Quand j'appuie sur "Précédent" au volant
Alors le contenu actuel rejoue depuis le début (règle ≥10s)
Scénario: Commande "Play/Pause" avec fade audio
Étant donné qu'un contenu est en lecture
Quand j'appuie sur "Pause" au volant
Alors la lecture se met en pause avec un fade out de 0.3 secondes
Et la position de lecture est sauvegardée
Quand j'appuie sur "Play" au volant
Alors la lecture reprend avec un fade in de 0.3 secondes
Et la reprise se fait à la position exacte
Scénario: Aucune commande complexe supportée
Étant donné que je conduis
Quand j'essaie un appui long sur "Suivant"
Alors l'action n'est pas détectée (non supporté iOS/Android)
Quand j'essaie un double-appui sur "Pause"
Alors l'action n'est pas détectée
Et seules les actions simples (clic simple) fonctionnent
Scénario: Compatibilité 100% tous véhicules
Étant donné que je conduis une voiture avec commandes basiques
Et que mon véhicule a seulement Suivant/Précédent/Pause
Quand j'utilise RoadWave
Alors toutes les fonctions essentielles sont accessibles
Et je n'ai pas besoin de boutons supplémentaires
Scénario: Feedback visuel discret après action
Étant donné que j'appuie sur "Suivant"
Quand le contenu change
Alors l'interface CarPlay/Android Auto affiche le nouveau titre
Et aucune popup ne bloque la vue
Et le changement est fluide et immédiat
Scénario: Like automatique renforcé après écoute ≥80%
Étant donné que j'écoute un contenu de 5 minutes tagué "Automobile"
Quand j'écoute pendant 4 minutes 30 secondes (90%)
Alors un like automatique renforcé (+2 points) est enregistré
Et un badge discret "♥ Ajouté à vos favoris" s'affiche 2 secondes
Et aucune action manuelle n'est requise
Scénario: Like automatique standard après écoute 30-79%
Étant donné que j'écoute un contenu de 5 minutes tagué "Voyage"
Quand j'écoute pendant 2 minutes (40%)
Et que j'appuie sur "Suivant"
Alors un like automatique standard (+1 point) est enregistré
Et un badge discret s'affiche brièvement
Et je peux continuer à conduire sans interruption
Scénario: Signal négatif après skip rapide <10s
Étant donné que j'écoute un contenu tagué "Politique"
Quand j'appuie sur "Suivant" après seulement 5 secondes
Alors un signal négatif (-0.5 point) est enregistré
Et la jauge "Politique" diminue légèrement
Et aucun message n'est affiché (transparence)
Scénario: Pas de like si écoute <30%
Étant donné que j'écoute un contenu de 10 minutes
Quand j'écoute pendant 2 minutes (20%)
Et que j'appuie sur "Suivant"
Alors aucun like n'est enregistré
Et les jauges ne changent pas
Et le système considère l'écoute comme neutre
Scénario: Badge de feedback visuel disparaît après 2 secondes
Étant donné que je reçois un like automatique
Quand le badge "♥ Ajouté à vos favoris" apparaît
Alors il reste visible 2 secondes en bas de l'écran
Et il disparaît automatiquement sans action
Et il ne bloque pas la vue de la route
Scénario: Tracking du temps d'écoute précis côté client
Étant donné que je démarre la lecture d'un contenu
Quand le player audio iOS/Android enregistre le temps
Alors le startTime est enregistré à la milliseconde
Quand j'arrête la lecture (Suivant, Pause, ou fin)
Alors la durée exacte écoutée est calculée
Et le pourcentage (durée / durée_totale * 100) est envoyé à l'API
Scénario: API reçoit les événements d'écoute pour calcul
Étant donné que j'écoute un contenu de 5 minutes à 80%
Quand l'événement est envoyé à l'API
Alors le backend reçoit:
"""
{
"content_id": "abc123",
"duration": 240,
"content_total": 300,
"percentage": 80.0,
"action": "completed"
}
"""
Et le backend calcule le like automatique (+2 points)
Et les jauges sont mises à jour immédiatement (Redis + PostgreSQL)
Scénario: Actions différentes selon arrêt du contenu
Étant donné que j'écoute un contenu
Quand j'appuie sur "Suivant"
Alors l'action envoyée est "skipped"
Quand le contenu se termine naturellement
Alors l'action envoyée est "completed"
Quand j'appuie sur "Pause"
Alors l'action envoyée est "paused"
Et le backend traite chaque action différemment
Scénario: Calcul immédiat côté backend sans délai
Étant donné que l'API reçoit un événement d'écoute
Quand le backend traite l'événement
Alors les jauges sont mises à jour immédiatement (< 100ms)
Et les nouvelles recommandations utilisent les valeurs actualisées
Et il n'y a aucun batch différé
Scénario: Compatibilité iOS avec AVPlayer
Étant donné que l'app iOS utilise AVPlayer
Quand les commandes physiques sont interceptées
Alors les événements MPRemoteCommandCenter sont capturés:
| Commande | Événement iOS |
| Suivant | nextTrackCommand |
| Précédent | previousTrackCommand |
| Play/Pause | playCommand / pauseCommand |
Et le tracking du temps utilise CMTime
Scénario: Compatibilité Android avec MediaSession
Étant donné que l'app Android utilise MediaPlayer
Quand les commandes physiques sont interceptées
Alors les événements MediaSession sont capturés:
| Commande | Action Android |
| Suivant | ACTION_SKIP_TO_NEXT |
| Précédent | ACTION_SKIP_TO_PREVIOUS |
| Play/Pause | ACTION_PLAY / ACTION_PAUSE |
Et le tracking du temps utilise SystemClock.elapsedRealtime()
Scénario: Sécurité maximale - pas de distraction
Étant donné que je conduis à 80 km/h
Quand j'utilise RoadWave avec les commandes au volant
Alors je n'ai jamais besoin de regarder mon téléphone
Et je n'ai jamais besoin de toucher l'écran CarPlay/Android Auto
Et toutes les actions sont accessibles via boutons physiques
Et les likes sont enregistrés automatiquement
Plan du Scénario: Calcul du like automatique selon pourcentage
Étant donné que j'écoute un contenu tagué "Sport"
Quand j'écoute pendant <pourcentage>%
Alors le like automatique est <type>
Et l'impact sur la jauge est <points>
Exemples:
| pourcentage | type | points |
| 10 | aucun | 0 |
| 25 | aucun | 0 |
| 29 | aucun | 0 |
| 30 | standard | +1 |
| 50 | standard | +1 |
| 79 | standard | +1 |
| 80 | renforcé | +2 |
| 90 | renforcé | +2 |
| 100 | renforcé | +2 |
Plan du Scénario: Signal négatif uniquement si skip très rapide
Étant donné que j'écoute un contenu
Quand je skip après <secondes> secondes
Alors le signal est <type>
Et l'impact est <points>
Exemples:
| secondes | type | points |
| 3 | négatif | -0.5 |
| 5 | négatif | -0.5 |
| 9 | négatif | -0.5 |
| 10 | neutre | 0 |
| 15 | neutre | 0 |
| 30 | neutre | 0 |