refactor(docs): réorganiser la documentation selon principes DDD
Réorganise la documentation du projet selon les principes du Domain-Driven Design (DDD) pour améliorer la cohésion, la maintenabilité et l'alignement avec l'architecture modulaire du backend. **Structure cible:** ``` docs/domains/ ├── README.md (Context Map) ├── _shared/ (Core Domain) ├── recommendation/ (Supporting Subdomain) ├── content/ (Supporting Subdomain) ├── moderation/ (Supporting Subdomain) ├── advertising/ (Generic Subdomain) ├── premium/ (Generic Subdomain) └── monetization/ (Generic Subdomain) ``` **Changements effectués:** Phase 1: Création de l'arborescence des 7 bounded contexts Phase 2: Déplacement des règles métier (01-19) vers domains/*/rules/ Phase 3: Déplacement des diagrammes d'entités vers domains/*/entities/ Phase 4: Déplacement des diagrammes flux/états/séquences vers domains/*/ Phase 5: Création des README.md pour chaque domaine Phase 6: Déplacement des features Gherkin vers domains/*/features/ Phase 7: Création du Context Map (domains/README.md) Phase 8: Mise à jour de mkdocs.yml pour la nouvelle navigation Phase 9: Correction automatique des liens internes (script fix-markdown-links.sh) Phase 10: Nettoyage de l'ancienne structure (regles-metier/, diagrammes/, features/) **Configuration des tests:** - Makefile: godog run docs/domains/*/features/ - scripts/generate-bdd-docs.py: features_dir → docs/domains **Avantages:** ✅ Cohésion forte: toute la doc d'un domaine au même endroit ✅ Couplage faible: domaines indépendants, dépendances explicites ✅ Navigabilité améliorée: README par domaine = entrée claire ✅ Alignement code/docs: miroir de backend/internal/ ✅ Onboarding facilité: exploration domaine par domaine ✅ Tests BDD intégrés: features au plus près des règles métier Voir docs/REFACTOR-DDD.md pour le plan complet.
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
# language: fr
|
||||
|
||||
Fonctionnalité: Intégration audio-guides avec autres fonctionnalités
|
||||
En tant qu'utilisateur
|
||||
Je veux utiliser les audio-guides avec toutes les fonctionnalités de l'app
|
||||
Afin d'avoir une expérience complète et cohérente
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'application RoadWave est démarrée
|
||||
Et que l'utilisateur "jean@example.com" est connecté
|
||||
|
||||
# 16.14 - Téléchargement offline
|
||||
|
||||
Scénario: Téléchargement complet d'un audio-guide
|
||||
Étant donné un audio-guide "Visite du Louvre" avec 12 séquences
|
||||
Quand l'utilisateur clique sur "⬇️ Télécharger pour écouter hors ligne"
|
||||
Alors toutes les 12 séquences sont téléchargées
|
||||
Et les métadonnées (titres, descriptions, GPS) sont sauvegardées
|
||||
Et les images (cover, miniatures) sont mises en cache
|
||||
|
||||
Scénario: Affichage de la progression du téléchargement
|
||||
Étant donné qu'un téléchargement d'audio-guide est en cours
|
||||
Quand l'utilisateur consulte l'état
|
||||
Alors la progression s'affiche:
|
||||
"""
|
||||
⬇️ Téléchargement en cours...
|
||||
Séquence 7/12 • 245 MB / 380 MB
|
||||
──────●──────── 64%
|
||||
"""
|
||||
|
||||
Scénario: Téléchargement uniquement en WiFi (par défaut)
|
||||
Étant donné que l'option "Télécharger uniquement en WiFi" est activée
|
||||
Quand l'utilisateur lance un téléchargement sur réseau mobile
|
||||
Alors un avertissement s'affiche:
|
||||
"""
|
||||
⚠️ Téléchargement nécessite WiFi
|
||||
Cet audio-guide pèse 380 MB.
|
||||
[Attendre WiFi] [Télécharger quand même]
|
||||
"""
|
||||
|
||||
Scénario: Gestion de l'espace de stockage
|
||||
Étant donné que l'appareil a 500 MB d'espace libre
|
||||
Et qu'un audio-guide pèse 380 MB
|
||||
Quand l'utilisateur lance le téléchargement
|
||||
Alors un avertissement s'affiche:
|
||||
"""
|
||||
⚠️ Espace de stockage limité
|
||||
Après téléchargement : 120 MB restants
|
||||
[Continuer] [Gérer stockage] [Annuler]
|
||||
"""
|
||||
|
||||
Scénario: Liste des audio-guides téléchargés
|
||||
Étant donné que l'utilisateur a téléchargé 3 audio-guides
|
||||
Quand il accède à "Bibliothèque > Téléchargés"
|
||||
Alors il voit:
|
||||
| audio_guide | taille | date_telechargement |
|
||||
| Visite du Louvre | 380 MB | 2026-01-20 |
|
||||
| Safari du Paugre | 245 MB | 2026-01-18 |
|
||||
| Circuit Loire à Vélo | 520 MB | 2026-01-15 |
|
||||
|
||||
Scénario: Lecture hors connexion complète
|
||||
Étant donné qu'un audio-guide est téléchargé
|
||||
Et que l'utilisateur active le mode avion
|
||||
Quand il lance l'audio-guide
|
||||
Alors toutes les séquences sont lisibles
|
||||
Et les métadonnées sont accessibles
|
||||
Et les images s'affichent normalement
|
||||
Et la progression est sauvegardée localement
|
||||
|
||||
Scénario: GPS fonctionne en mode avion (mode voiture)
|
||||
Étant donné qu'un audio-guide voiture est téléchargé
|
||||
Et que le mode avion est activé (avec GPS actif)
|
||||
Quand l'utilisateur se déplace
|
||||
Alors les déclenchements GPS fonctionnent normalement
|
||||
Et la distance/ETA sont calculés
|
||||
Parce que le GPS ne nécessite pas de connexion internet
|
||||
|
||||
Scénario: Suppression d'audio-guide téléchargé
|
||||
Étant donné qu'un audio-guide téléchargé pèse 380 MB
|
||||
Quand l'utilisateur clique sur "🗑️ Supprimer téléchargement"
|
||||
Alors une confirmation s'affiche
|
||||
Et si confirmé, les 380 MB sont libérés
|
||||
Et l'audio-guide reste accessible en streaming
|
||||
|
||||
Scénario: Mise à jour automatique si nouvelle version
|
||||
Étant donné qu'un audio-guide téléchargé a été mis à jour par le créateur
|
||||
Quand l'utilisateur se connecte en WiFi
|
||||
Alors une notification s'affiche:
|
||||
"""
|
||||
🔄 Mise à jour disponible
|
||||
"Visite du Louvre" - Nouvelle version
|
||||
[Mettre à jour] [Plus tard]
|
||||
"""
|
||||
|
||||
# 16.15 - Playlists et collections
|
||||
|
||||
Scénario: Ajout d'audio-guide à une playlist
|
||||
Étant donné que l'utilisateur consulte un audio-guide
|
||||
Quand il clique sur "➕ Ajouter à une playlist"
|
||||
Alors ses playlists s'affichent:
|
||||
| playlist |
|
||||
| 🗺️ Voyages en France |
|
||||
| 🏛️ Musées parisiens |
|
||||
| + Créer nouvelle playlist |
|
||||
|
||||
Scénario: Comportement audio-guide dans une playlist
|
||||
Étant donné une playlist contenant 2 audio-guides et 1 podcast
|
||||
Quand la lecture atteint un audio-guide
|
||||
Alors l'audio-guide démarre à la séquence 1 (ou progression sauvegardée)
|
||||
Et les séquences se jouent normalement
|
||||
Quand l'audio-guide se termine (dernière séquence)
|
||||
Alors le contenu suivant de la playlist démarre
|
||||
|
||||
Scénario: Audio-guide marqué comme "Favori"
|
||||
Étant donné qu'un utilisateur aime un audio-guide
|
||||
Quand il clique sur "⭐ Ajouter aux favoris"
|
||||
Alors l'audio-guide est ajouté à la section "Favoris"
|
||||
Et il est facilement accessible depuis le menu principal
|
||||
|
||||
Scénario: Collections thématiques d'audio-guides
|
||||
Étant donné que RoadWave propose des collections éditoriales
|
||||
Quand l'utilisateur accède à "Collections"
|
||||
Alors il voit des collections comme:
|
||||
| collection | nombre_audio_guides |
|
||||
| 🏛️ Musées de France | 12 |
|
||||
| 🦁 Parcs animaliers | 8 |
|
||||
| 🚴 Circuits vélo | 15 |
|
||||
| 🚗 Routes touristiques | 10 |
|
||||
|
||||
# 16.16 - Partage d'audio-guide
|
||||
|
||||
Scénario: Bouton partager sur page audio-guide
|
||||
Étant donné qu'un utilisateur consulte un audio-guide
|
||||
Quand il clique sur "⬆️ Partager"
|
||||
Alors le menu de partage natif s'ouvre
|
||||
Et le lien généré est "https://roadwave.fr/share/ag/louvre_123"
|
||||
|
||||
Scénario: Page web de partage pour audio-guide
|
||||
Étant donné qu'un lien d'audio-guide partagé est ouvert sur le web
|
||||
Quand la page se charge
|
||||
Alors elle affiche:
|
||||
| élément | exemple |
|
||||
| Cover image 16:9 | Photo du Louvre |
|
||||
| Titre | "Visite du Louvre" |
|
||||
| Créateur | "@art_guide ✓" |
|
||||
| Badge type | "🎧 Audio-guide • 12 séquences" |
|
||||
| Durée totale | "45 minutes" |
|
||||
| Mode | "🚶 Piéton" |
|
||||
| Description | Texte complet |
|
||||
| Preview séquence 1 | Player HTML5 (séquence intro) |
|
||||
| Carte avec points GPS | Leaflet avec 12 markers |
|
||||
| CTA téléchargement | Boutons App Store / Google Play |
|
||||
|
||||
Scénario: Deep link vers audio-guide spécifique
|
||||
Étant donné que l'app est installée
|
||||
Et qu'un lien "https://roadwave.fr/share/ag/louvre_123" est cliqué
|
||||
Quand le système détecte l'app
|
||||
Alors l'app s'ouvre directement sur l'audio-guide
|
||||
Et l'utilisateur peut démarrer immédiatement
|
||||
|
||||
Scénario: Partage avec séquence spécifique
|
||||
Étant donné qu'un utilisateur est sur la séquence 5 "La Joconde"
|
||||
Quand il partage l'audio-guide
|
||||
Alors le lien généré est "https://roadwave.fr/share/ag/louvre_123?seq=5"
|
||||
Et le destinataire est dirigé vers la séquence 5 directement
|
||||
|
||||
# 16.17 - Notations et commentaires
|
||||
|
||||
Scénario: Note globale de l'audio-guide
|
||||
Étant donné qu'un utilisateur termine un audio-guide
|
||||
Quand la dernière séquence se termine
|
||||
Alors une popup de notation s'affiche:
|
||||
"""
|
||||
Comment avez-vous trouvé cet audio-guide ?
|
||||
⭐⭐⭐⭐⭐
|
||||
[Ajouter un commentaire (optionnel)]
|
||||
"""
|
||||
|
||||
Scénario: Note moyenne affichée sur la page
|
||||
Étant donné qu'un audio-guide a reçu 150 notes
|
||||
Et que la moyenne est 4.3/5
|
||||
Quand la page est affichée
|
||||
Alors la note "⭐ 4.3 (150 avis)" est visible
|
||||
|
||||
Scénario: Commentaires triés par pertinence
|
||||
Étant donné qu'un audio-guide a 50 commentaires
|
||||
Quand l'utilisateur consulte les avis
|
||||
Alors les commentaires sont triés par défaut selon:
|
||||
| critère | poids |
|
||||
| Note élevée | 30% |
|
||||
| Récent | 30% |
|
||||
| Likes reçus | 40% |
|
||||
|
||||
Scénario: Réponse du créateur aux commentaires
|
||||
Étant donné qu'un utilisateur laisse un commentaire négatif
|
||||
Quand le créateur consulte son dashboard
|
||||
Alors il peut répondre au commentaire
|
||||
Et sa réponse apparaît en dessous avec badge "Créateur"
|
||||
|
||||
# 16.18 - Recommandations intelligentes
|
||||
|
||||
Scénario: Audio-guides similaires recommandés
|
||||
Étant donné qu'un utilisateur termine "Visite du Louvre"
|
||||
Quand il consulte les recommandations
|
||||
Alors l'algorithme suggère des audio-guides basés sur:
|
||||
| critère | exemple |
|
||||
| Tags similaires | #Art #Histoire #Musée |
|
||||
| Créateur identique | Autres audio-guides de @art_guide |
|
||||
| Localisation proche | Autres musées parisiens |
|
||||
| Mode de déplacement | Autres audio-guides piéton |
|
||||
|
||||
Scénario: Suggestion géographique contextuelle
|
||||
Étant donné qu'un utilisateur est à Paris (GPS détecté)
|
||||
Quand il ouvre l'onglet "Audio-guides"
|
||||
Alors les audio-guides parisiens sont mis en avant
|
||||
Et un filtre "🗺️ Autour de moi" est pré-appliqué
|
||||
|
||||
Scénario: Badge "Populaire dans votre région"
|
||||
Étant donné qu'un audio-guide a >100 écoutes dans la région Île-de-France
|
||||
Et que l'utilisateur est en Île-de-France
|
||||
Quand l'audio-guide est affiché
|
||||
Alors un badge "🔥 Populaire près de chez vous" est visible
|
||||
|
||||
# 16.19 - Optimisations techniques
|
||||
|
||||
Scénario: Préchargement de la séquence suivante
|
||||
Étant donné que la séquence 3 est en cours à 2:30/3:42
|
||||
Quand il reste 60 secondes de lecture
|
||||
Alors la séquence 4 est préchargée en arrière-plan
|
||||
Et la transition est instantanée (0 latence)
|
||||
|
||||
Scénario: Buffer adaptatif selon connexion
|
||||
Étant donné qu'un utilisateur est sur réseau 4G
|
||||
Quand la séquence démarre
|
||||
Alors 30 secondes d'audio sont bufferisées initialement
|
||||
Et le buffering continue en arrière-plan
|
||||
|
||||
Plan du Scénario: Buffer selon qualité réseau
|
||||
Étant donné qu'un utilisateur est sur réseau <reseau>
|
||||
Quand une séquence démarre
|
||||
Alors <buffer_secondes> secondes sont bufferisées
|
||||
|
||||
Exemples:
|
||||
| reseau | buffer_secondes |
|
||||
| WiFi | 60 |
|
||||
| 5G | 45 |
|
||||
| 4G | 30 |
|
||||
| 3G | 20 |
|
||||
|
||||
Scénario: Compression audio adaptative
|
||||
Étant donné qu'un utilisateur est sur connexion lente (3G)
|
||||
Quand une séquence est streamée
|
||||
Alors le CDN sert la version 64 kbps (au lieu de 128 kbps)
|
||||
Et la qualité reste acceptable pour la voix
|
||||
|
||||
Scénario: Cache intelligent des séquences jouées
|
||||
Étant donné qu'un utilisateur a écouté les séquences 1-5
|
||||
Quand il clique sur "Précédent" pour réécouter la séquence 4
|
||||
Alors la séquence 4 est chargée depuis le cache local
|
||||
Et le chargement est instantané (pas de stream)
|
||||
|
||||
Scénario: Nettoyage automatique du cache
|
||||
Étant donné que le cache audio occupe 500 MB
|
||||
Et que la limite configurée est 300 MB
|
||||
Quand le nettoyage automatique s'exécute
|
||||
Alors les séquences les plus anciennes (non téléchargées) sont supprimées
|
||||
Et le cache revient à 280 MB
|
||||
|
||||
# 16.20 - Analytics et tracking
|
||||
|
||||
Scénario: Tracking des événements clés
|
||||
Étant donné qu'un utilisateur écoute un audio-guide
|
||||
Quand il interagit avec l'application
|
||||
Alors les événements suivants sont trackés:
|
||||
| événement | données |
|
||||
| audio_guide_started | audio_guide_id, mode, user_id |
|
||||
| sequence_completed | sequence_id, completion_rate, duration |
|
||||
| audio_guide_completed | audio_guide_id, total_time, sequences_count|
|
||||
| point_gps_triggered | point_id, distance, auto_or_manual |
|
||||
| point_gps_missed | point_id, distance, action_taken |
|
||||
| paywall_displayed | audio_guide_id, sequence_number |
|
||||
| premium_conversion | source: audio_guide_paywall |
|
||||
|
||||
Scénario: Heatmap des abandons par séquence
|
||||
Étant donné qu'un audio-guide a été écouté 1000 fois
|
||||
Quand le créateur consulte la heatmap
|
||||
Alors il voit pour chaque séquence:
|
||||
| sequence | starts | completions | abandon_rate |
|
||||
| 1 | 1000 | 950 | 5% |
|
||||
| 2 | 950 | 920 | 3% |
|
||||
| 3 | 920 | 850 | 8% |
|
||||
| ... | ... | ... | ... |
|
||||
| 12 | 650 | 580 | 11% |
|
||||
|
||||
Scénario: Attribution GPS auto vs manuel
|
||||
Étant donné un audio-guide voiture avec 8 points GPS
|
||||
Quand les statistiques sont calculées
|
||||
Alors le créateur voit:
|
||||
| mode_declenchement | nombre |
|
||||
| GPS automatique | 542 |
|
||||
| Manuel | 123 |
|
||||
| Point manqué | 89 |
|
||||
|
||||
# Cas d'erreur et edge cases
|
||||
|
||||
Scénario: Audio-guide avec une seule séquence (edge case)
|
||||
Étant donné un audio-guide avec seulement 1 séquence
|
||||
Quand il est publié
|
||||
Alors un avertissement s'affiche:
|
||||
"""
|
||||
⚠️ Un audio-guide doit contenir au minimum 2 séquences
|
||||
Ajoutez au moins 1 séquence supplémentaire avant publication
|
||||
"""
|
||||
|
||||
Scénario: Séquence manquante ou corrompue
|
||||
Étant donné qu'une séquence 5 a un fichier audio corrompu
|
||||
Quand l'utilisateur tente de la lire
|
||||
Alors un message d'erreur s'affiche
|
||||
Et un bouton "⏭️ Passer à la suivante" est disponible
|
||||
Et le créateur reçoit une notification de l'erreur
|
||||
|
||||
Scénario: GPS désactivé puis réactivé en cours de route
|
||||
Étant donné un audio-guide voiture en cours
|
||||
Et que l'utilisateur désactive le GPS
|
||||
Quand il le réactive 10 minutes plus tard
|
||||
Alors le déclenchement automatique reprend
|
||||
Et les points GPS manqués entre-temps ne déclenchent pas de popup
|
||||
|
||||
Scénario: Modification d'audio-guide avec utilisateurs en cours
|
||||
Étant donné qu'un audio-guide a 50 utilisateurs en cours d'écoute
|
||||
Quand le créateur modifie une séquence
|
||||
Alors les utilisateurs actuels conservent l'ancienne version
|
||||
Et les nouveaux utilisateurs obtiennent la nouvelle version
|
||||
Et un message informe les utilisateurs lors de la prochaine ouverture
|
||||
|
||||
Scénario: Suppression d'audio-guide par le créateur
|
||||
Étant donné qu'un audio-guide a 20 utilisateurs avec progression
|
||||
Quand le créateur supprime l'audio-guide
|
||||
Alors une confirmation stricte est demandée
|
||||
Et si confirmé, les progressions utilisateurs sont archivées (30 jours)
|
||||
Et l'audio-guide devient inaccessible
|
||||
|
||||
Scénario: Signalement d'audio-guide pour contenu inapproprié
|
||||
Étant donné qu'un utilisateur signale un audio-guide
|
||||
Quand le signalement est modéré
|
||||
Et jugé valide
|
||||
Alors l'audio-guide est dépublié temporairement
|
||||
Et le créateur reçoit une notification d'explication
|
||||
Et il peut corriger puis republier
|
||||
Reference in New Issue
Block a user