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>
311 lines
13 KiB
Gherkin
311 lines
13 KiB
Gherkin
# language: fr
|
||
|
||
Fonctionnalité: Sauvegarde et reprise de progression audio-guide
|
||
En tant qu'utilisateur
|
||
Je veux que ma progression soit sauvegardée automatiquement
|
||
Afin de pouvoir reprendre mon audio-guide là où je me suis arrêté
|
||
|
||
Contexte:
|
||
Étant donné que l'application RoadWave est démarrée
|
||
Et que l'utilisateur "jean@example.com" est connecté
|
||
|
||
# 16.5 - Sauvegarde de progression
|
||
|
||
Scénario: Sauvegarde automatique toutes les 10 secondes
|
||
Étant donné qu'un audio-guide "Visite du Louvre" est en cours
|
||
Et que la séquence 3 est à la position 1:24
|
||
Quand 10 secondes s'écoulent
|
||
Alors la progression est sauvegardée automatiquement:
|
||
| donnée | valeur |
|
||
| audio_guide_id | louvre_123 |
|
||
| sequence_actuelle | 3 |
|
||
| position_audio | 1:24 |
|
||
| timestamp | 2026-01-22 14:35:42 |
|
||
| sequences_ecoutees | [1, 2] |
|
||
|
||
Scénario: Sauvegarde locale (SQLite) pour rapidité
|
||
Étant donné qu'une sauvegarde est déclenchée
|
||
Quand la progression est enregistrée
|
||
Alors les données sont écrites en SQLite local
|
||
Et l'écriture prend moins de 50ms
|
||
Et l'application reste fluide
|
||
|
||
Scénario: Synchronisation cloud en arrière-plan
|
||
Étant donné qu'une sauvegarde locale est effectuée
|
||
Quand 30 secondes s'écoulent
|
||
Alors la progression est synchronisée vers PostgreSQL cloud
|
||
Et la synchronisation s'effectue en arrière-plan
|
||
Et elle n'impacte pas les performances
|
||
|
||
Scénario: Sauvegarde immédiate lors de la fermeture
|
||
Étant donné qu'un audio-guide est en cours à la séquence 4 position 2:15
|
||
Quand l'utilisateur ferme l'application
|
||
Alors la progression est sauvegardée immédiatement (local + cloud)
|
||
Et les données sont écrites avant la fermeture complète
|
||
|
||
Scénario: Sauvegarde des séquences complétées
|
||
Étant donné qu'un audio-guide de 12 séquences est en cours
|
||
Et que les séquences 1, 2, 4, 5 ont été écoutées à >80%
|
||
Quand la progression est sauvegardée
|
||
Alors les séquences complétées sont enregistrées:
|
||
"""json
|
||
{
|
||
"audio_guide_id": "louvre_123",
|
||
"completed_sequences": [1, 2, 4, 5],
|
||
"current_sequence": 6,
|
||
"current_position": "0:42",
|
||
"last_played_at": "2026-01-22T14:35:42Z"
|
||
}
|
||
"""
|
||
|
||
Scénario: Historique des écoutes pour statistiques
|
||
Étant donné qu'un utilisateur a écouté 3 séquences d'un audio-guide
|
||
Quand les données sont sauvegardées
|
||
Alors l'historique d'écoute inclut:
|
||
| sequence_id | started_at | completed_at | completion_rate |
|
||
| 1 | 2026-01-22 14:10:00 | 2026-01-22 14:12:15 | 100% |
|
||
| 2 | 2026-01-22 14:12:20 | 2026-01-22 14:14:08 | 100% |
|
||
| 3 | 2026-01-22 14:14:15 | 2026-01-22 14:17:45 | 92% |
|
||
|
||
# 16.6 - Reprise de progression
|
||
|
||
Scénario: Popup de reprise au redémarrage
|
||
Étant donné que l'utilisateur a quitté l'app à la séquence 6 position 2:34
|
||
Quand il rouvre l'audio-guide "Visite du Louvre"
|
||
Alors une popup s'affiche:
|
||
"""
|
||
Continuer où vous vous étiez arrêté ?
|
||
|
||
📍 Séquence 6/12 : "Vénus de Milo"
|
||
⏱️ Position : 2:34 / 4:10
|
||
|
||
[▶️ Reprendre] [🔄 Recommencer]
|
||
"""
|
||
|
||
Scénario: Action "Reprendre" - Position exacte restaurée
|
||
Étant donné qu'une popup de reprise est affichée
|
||
Quand l'utilisateur clique sur "▶️ Reprendre"
|
||
Alors la séquence 6 "Vénus de Milo" se charge
|
||
Et la position exacte 2:34 est restaurée
|
||
Et la lecture démarre automatiquement après 1 seconde
|
||
|
||
Scénario: Action "Recommencer" - Réinitialisation complète
|
||
Étant donné qu'une popup de reprise est affichée
|
||
Quand l'utilisateur clique sur "🔄 Recommencer"
|
||
Alors l'audio-guide redémarre depuis la séquence 1 position 0:00
|
||
Et toutes les séquences sont marquées ⭕ "À écouter"
|
||
Et l'historique d'écoute est réinitialisé pour cette session
|
||
|
||
Scénario: Reprise après 7 jours d'inactivité
|
||
Étant donné qu'un utilisateur a arrêté un audio-guide le 15/01/2026
|
||
Et qu'il le rouvre le 22/01/2026 (7 jours plus tard)
|
||
Quand l'audio-guide se charge
|
||
Alors la popup de reprise s'affiche normalement
|
||
Et toutes les données de progression sont conservées
|
||
|
||
Scénario: Reprise sur un autre appareil (synchronisation cloud)
|
||
Étant donné qu'un utilisateur écoute un audio-guide sur iPhone
|
||
Et qu'il quitte à la séquence 4 position 1:20
|
||
Quand il ouvre le même audio-guide sur iPad
|
||
Alors la popup de reprise s'affiche avec la progression iPhone
|
||
Et il peut reprendre exactement où il s'était arrêté
|
||
|
||
Scénario: Conflit de synchronisation (dernier appareil gagne)
|
||
Étant donné qu'un utilisateur écoute sur iPhone à la séquence 3
|
||
Et simultanément sur iPad à la séquence 7
|
||
Quand les deux appareils synchronisent
|
||
Alors la progression la plus récente (timestamp) est conservée
|
||
Et l'appareil avec ancienne progression affiche une notification:
|
||
"""
|
||
ℹ️ Progression mise à jour
|
||
Une écoute plus récente a été détectée.
|
||
Séquence 7 restaurée.
|
||
"""
|
||
|
||
Scénario: Mode hors-ligne - Sauvegarde locale uniquement
|
||
Étant donné qu'un utilisateur écoute un audio-guide hors connexion
|
||
Et qu'il atteint la séquence 5
|
||
Quand la progression est sauvegardée
|
||
Alors les données sont écrites localement (SQLite)
|
||
Et une icône "☁️ Non synchronisé" s'affiche discrètement
|
||
|
||
Scénario: Synchronisation automatique à la reconnexion
|
||
Étant donné que l'utilisateur a écouté hors ligne jusqu'à la séquence 8
|
||
Et que 5 progressions locales ne sont pas synchronisées
|
||
Quand la connexion réseau est rétablie
|
||
Alors les 5 progressions sont synchronisées automatiquement
|
||
Et un toast s'affiche brièvement: "✅ Progression synchronisée"
|
||
|
||
Scénario: Suppression de la progression (recommencer proprement)
|
||
Étant donné qu'un utilisateur est à la séquence 10/12
|
||
Quand il ouvre les paramètres de l'audio-guide
|
||
Et qu'il clique sur "🔄 Réinitialiser progression"
|
||
Alors une confirmation s'affiche:
|
||
"""
|
||
Réinitialiser cet audio-guide ?
|
||
Toutes les séquences seront marquées comme non écoutées.
|
||
[Annuler] [Réinitialiser]
|
||
"""
|
||
Et si confirmé, la progression est effacée
|
||
|
||
# 16.7 - Statistiques d'écoute
|
||
|
||
Scénario: Taux de complétion global de l'audio-guide
|
||
Étant donné un audio-guide de 12 séquences
|
||
Et que l'utilisateur a écouté complètement 8 séquences
|
||
Et partiellement 1 séquence (45%)
|
||
Quand les statistiques sont calculées
|
||
Alors le taux de complétion affiché est "67%" (8/12)
|
||
|
||
Scénario: Badge "Audio-guide complété" à 100%
|
||
Étant donné un audio-guide de 12 séquences
|
||
Quand l'utilisateur écoute la 12ème séquence à 100%
|
||
Alors un badge "✅ Audio-guide complété" s'affiche
|
||
Et une notification de félicitations est envoyée
|
||
Et le statut "Complété le 22/01/2026" est visible dans l'historique
|
||
|
||
Scénario: Temps total passé sur l'audio-guide
|
||
Étant donné qu'un utilisateur a écouté un audio-guide sur 2 sessions:
|
||
| session | durée |
|
||
| 1 | 25 min |
|
||
| 2 | 18 min |
|
||
Quand les statistiques sont calculées
|
||
Alors le temps total est "43 minutes"
|
||
Et il est affiché dans l'historique personnel
|
||
|
||
Scénario: Liste des audio-guides "En cours" dans le profil
|
||
Étant donné qu'un utilisateur a 3 audio-guides en cours:
|
||
| audio_guide | progression |
|
||
| Visite du Louvre | 6/12 |
|
||
| Safari du Paugre | 3/8 |
|
||
| Circuit Loire à Vélo | 12/15 |
|
||
Quand il consulte son profil "Audio-guides"
|
||
Alors la section "📍 En cours" affiche les 3 audio-guides
|
||
Et chaque élément montre la progression sous forme de barre
|
||
|
||
Scénario: Liste des audio-guides "Complétés" dans le profil
|
||
Étant donné qu'un utilisateur a complété 2 audio-guides:
|
||
| audio_guide | date_completion |
|
||
| Tour de Paris | 2026-01-15 |
|
||
| Découverte de Lyon | 2026-01-20 |
|
||
Quand il consulte son profil "Audio-guides"
|
||
Alors la section "✅ Complétés" affiche les 2 audio-guides
|
||
Et la date de complétion est visible
|
||
|
||
Scénario: Badge "Complétiste" pour 10 audio-guides complétés
|
||
Étant donné qu'un utilisateur complète son 10ème audio-guide
|
||
Quand la complétion est enregistrée
|
||
Alors un badge "🏆 Complétiste" est débloqué
|
||
Et il apparaît sur son profil
|
||
Et une notification est envoyée:
|
||
"""
|
||
🎉 Badge débloqué : Complétiste
|
||
Vous avez complété 10 audio-guides !
|
||
"""
|
||
|
||
Plan du Scénario: Niveaux de badges selon nombre d'audio-guides complétés
|
||
Étant donné qu'un utilisateur complète <nombre> audio-guides
|
||
Quand le badge est attribué
|
||
Alors il reçoit le badge "<badge>"
|
||
|
||
Exemples:
|
||
| nombre | badge |
|
||
| 1 | 🎧 Premier audio-guide |
|
||
| 5 | 🗺️ Explorateur |
|
||
| 10 | 🏆 Complétiste |
|
||
| 25 | 🌟 Expert |
|
||
| 50 | 💎 Maître audio-guideur |
|
||
|
||
# 16.8 - Métriques créateur
|
||
|
||
Scénario: Dashboard créateur - Statistiques par audio-guide
|
||
Étant donné qu'un créateur a publié l'audio-guide "Visite du Louvre"
|
||
Quand il consulte son dashboard
|
||
Alors les métriques suivantes sont affichées:
|
||
| métrique | valeur |
|
||
| Écoutes totales | 1542 |
|
||
| Écoutes complètes (>80%) | 892 |
|
||
| Taux de complétion moyen | 58% |
|
||
| Temps d'écoute total | 423h |
|
||
| Séquence la plus écoutée | Séq. 3 |
|
||
| Séquence la moins écoutée | Séq. 11 |
|
||
|
||
Scénario: Graphique de complétion par séquence
|
||
Étant donné un audio-guide de 12 séquences
|
||
Quand le créateur consulte les statistiques détaillées
|
||
Alors un graphique en barres affiche:
|
||
| séquence | taux_completion |
|
||
| 1 | 100% |
|
||
| 2 | 95% |
|
||
| 3 | 89% |
|
||
| ... | ... |
|
||
| 12 | 58% |
|
||
|
||
Scénario: Détection des points d'abandon
|
||
Étant donné qu'un audio-guide a un taux de complétion de 58%
|
||
Et que 35% des utilisateurs abandonnent à la séquence 7
|
||
Quand le créateur consulte les insights
|
||
Alors un avertissement s'affiche:
|
||
"""
|
||
⚠️ Point d'abandon détecté
|
||
35% des utilisateurs abandonnent à la séquence 7 "Aile Richelieu"
|
||
Durée : 8 min
|
||
Suggestion : Réduire la durée ou rendre plus captivant
|
||
"""
|
||
|
||
Scénario: Heatmap géographique des écoutes
|
||
Étant donné un audio-guide géolocalisé
|
||
Quand le créateur consulte la heatmap
|
||
Alors une carte affiche:
|
||
| élément | description |
|
||
| Densité d'écoutes | Zones rouge/orange/jaune selon écoutes |
|
||
| Points GPS | Marqueurs sur chaque point |
|
||
| Statistiques par point | Nombre d'écoutes par zone |
|
||
|
||
Scénario: Temps moyen par séquence
|
||
Étant donné qu'un créateur analyse son audio-guide
|
||
Quand il consulte les statistiques temporelles
|
||
Alors il voit pour chaque séquence:
|
||
| séquence | durée_audio | temps_ecoute_moyen | ecart |
|
||
| 1 | 2:15 | 2:10 | -5s |
|
||
| 2 | 1:48 | 1:30 | -18s |
|
||
| 3 | 3:42 | 3:40 | -2s |
|
||
|
||
Scénario: Notification créateur pour milestone
|
||
Étant donné qu'un audio-guide atteint 1000 écoutes
|
||
Quand le seuil est franchi
|
||
Alors une notification est envoyée au créateur:
|
||
"""
|
||
🎉 Félicitations !
|
||
Votre audio-guide "Visite du Louvre" a atteint 1000 écoutes !
|
||
Taux de complétion : 58%
|
||
"""
|
||
|
||
# Cas d'erreur et limites
|
||
|
||
Scénario: Corruption de données de sauvegarde
|
||
Étant donné qu'une sauvegarde locale (SQLite) est corrompue
|
||
Quand l'application tente de charger la progression
|
||
Alors une récupération depuis le cloud est tentée
|
||
Et si réussie, les données cloud sont restaurées
|
||
Et la base locale est reconstruite
|
||
|
||
Scénario: Échec de synchronisation cloud
|
||
Étant donné que l'API cloud est indisponible
|
||
Quand une tentative de synchronisation est effectuée
|
||
Alors l'application continue avec sauvegarde locale uniquement
|
||
Et un retry automatique est programmé dans 5 minutes
|
||
Et l'icône "☁️ Non synchronisé" reste affichée
|
||
|
||
Scénario: Suppression accidentelle de progression (récupération)
|
||
Étant donné qu'un utilisateur réinitialise un audio-guide par erreur
|
||
Quand il contacte le support dans les 7 jours
|
||
Alors l'équipe peut restaurer la progression depuis les backups
|
||
Et les données sont récupérables (backup quotidien conservé 30 jours)
|
||
|
||
Scénario: Nettoyage automatique des vieilles progressions
|
||
Étant donné qu'une progression n'a pas été mise à jour depuis 6 mois
|
||
Quand le nettoyage automatique s'exécute
|
||
Alors la progression est archivée (mais pas supprimée)
|
||
Et l'utilisateur peut la restaurer via l'historique
|