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,266 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Commande "Précédent"
|
||||
En tant qu'auditeur
|
||||
Je veux que le bouton "Précédent" ait un comportement intelligent
|
||||
Afin de rejouer le contenu actuel ou revenir au précédent selon la progression
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et qu'un utilisateur est connecté
|
||||
|
||||
Scénario: Précédent après <10s revient au contenu précédent
|
||||
Étant donné que j'ai écouté le contenu "A" pendant 2 minutes
|
||||
Et que j'écoute maintenant le contenu "B" depuis 5 secondes
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors la lecture revient au contenu "A"
|
||||
Et la position de lecture est à 2 minutes (position exacte sauvegardée)
|
||||
Et le contenu "B" reste en historique
|
||||
|
||||
Scénario: Précédent après ≥10s rejoue le contenu actuel
|
||||
Étant donné que j'écoute le contenu "C" depuis 15 secondes
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors le contenu "C" rejoue depuis le début (position 0:00)
|
||||
Et la lecture ne revient pas au contenu précédent
|
||||
Et la progress bar revient à 0%
|
||||
|
||||
Scénario: Précédent exactement à 10s rejoue le contenu actuel
|
||||
Étant donné que j'écoute le contenu "D" depuis exactement 10 secondes
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors le contenu "D" rejoue depuis le début
|
||||
Et la lecture ne revient pas au contenu précédent
|
||||
|
||||
Scénario: Précédent sur le premier contenu de session
|
||||
Étant donné que je viens de démarrer l'application
|
||||
Et que j'écoute le contenu "Premier" depuis 3 secondes
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors le contenu "Premier" rejoue depuis le début
|
||||
Et aucun contenu précédent n'existe
|
||||
|
||||
Scénario: Historique de navigation limité à 10 contenus
|
||||
Étant donné que j'ai écouté 10 contenus [C1, C2, ..., C10]
|
||||
Et que l'historique Redis contient 10 entrées
|
||||
Quand je passe au contenu C11
|
||||
Alors le contenu C1 est supprimé de l'historique (FIFO)
|
||||
Et l'historique contient [C2, C3, ..., C10, C11]
|
||||
Et la taille reste à 10 contenus maximum
|
||||
|
||||
Scénario: Position exacte sauvegardée dans l'historique
|
||||
Étant donné que j'écoute le contenu "A" (durée 5 minutes)
|
||||
Quand j'atteins 2 minutes 30 secondes
|
||||
Et que j'appuie sur "Suivant"
|
||||
Alors l'historique enregistre:
|
||||
| content_id | position_seconds | listened_at |
|
||||
| A | 150 | 2026-01-21T10:30:00 |
|
||||
Quand je reviens au contenu "A" via "Précédent"
|
||||
Alors la lecture reprend exactement à 2 minutes 30 secondes
|
||||
|
||||
Scénario: Navigation arrière sur plusieurs contenus
|
||||
Étant donné que j'ai écouté dans l'ordre: A (2min), B (30s), C (3min)
|
||||
Et que j'écoute maintenant D depuis 1 seconde
|
||||
Quand j'appuie sur "Précédent" (1ère fois)
|
||||
Alors je reviens au contenu C à la position 3 minutes
|
||||
Quand j'appuie sur "Précédent" (<10s sur C)
|
||||
Alors je reviens au contenu B à la position 30 secondes
|
||||
Quand j'appuie sur "Précédent" (<10s sur B)
|
||||
Alors je reviens au contenu A à la position 2 minutes
|
||||
|
||||
Scénario: Précédent après milieu du contenu rejoue depuis début
|
||||
Étant donné que j'écoute un contenu de 5 minutes
|
||||
Quand j'atteins 2 minutes 30 secondes (milieu)
|
||||
Et que j'appuie sur "Précédent"
|
||||
Alors le contenu actuel rejoue depuis 0:00
|
||||
Et je ne reviens pas au contenu précédent
|
||||
|
||||
Scénario: Enchaînement Suivant puis Précédent rapide
|
||||
Étant donné que j'écoute le contenu "A" depuis 1 minute
|
||||
Quand j'appuie sur "Suivant"
|
||||
Alors le contenu "B" démarre
|
||||
Quand j'appuie immédiatement sur "Précédent" (2s après)
|
||||
Alors je reviens au contenu "A" à la position 1 minute
|
||||
Et le contenu "B" reste dans l'historique
|
||||
|
||||
Scénario: Transition fluide avec animation 0.3s
|
||||
Étant donné que j'appuie sur "Précédent"
|
||||
Quand le changement de contenu se produit
|
||||
Alors la transition audio utilise un fade out/in de 0.3 secondes
|
||||
Et la progress bar revient avec une animation fluide
|
||||
Et l'interface ne montre aucun message de confirmation
|
||||
|
||||
Scénario: Historique survit au changement de réseau
|
||||
Étant donné que j'ai un historique de 5 contenus en cache Redis
|
||||
Quand je perds la connexion réseau temporairement
|
||||
Et que je reviens en ligne
|
||||
Alors l'historique de navigation est toujours disponible
|
||||
Et je peux toujours utiliser "Précédent"
|
||||
|
||||
Scénario: Historique stocké en Redis avec structure complète
|
||||
Étant donné que j'ai écouté 3 contenus
|
||||
Quand je consulte le cache Redis
|
||||
Alors la structure est:
|
||||
"""
|
||||
user:{user_id}:history = [
|
||||
{content_id: "C3", position_seconds: 45, listened_at: "2026-01-21T10:33:00Z"},
|
||||
{content_id: "C2", position_seconds: 120, listened_at: "2026-01-21T10:30:00Z"},
|
||||
{content_id: "C1", position_seconds: 180, listened_at: "2026-01-21T10:27:00Z"}
|
||||
]
|
||||
"""
|
||||
Et l'ordre est du plus récent au plus ancien
|
||||
|
||||
Scénario: Précédent sur contenu en cours au début (<10s) du premier
|
||||
Étant donné que je démarre une session avec le contenu "Initial"
|
||||
Et que j'écoute depuis 3 secondes
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors le contenu "Initial" rejoue depuis le début
|
||||
Et aucune erreur n'est générée
|
||||
Et l'historique reste vide
|
||||
|
||||
Scénario: Compteur de temps respecte les seuils exacts
|
||||
Étant donné que j'écoute un contenu
|
||||
Quand le temps écoulé est de 9.9 secondes
|
||||
Et que j'appuie sur "Précédent"
|
||||
Alors je reviens au contenu précédent
|
||||
Quand le temps écoulé est de 10.0 secondes
|
||||
Et que j'appuie sur "Précédent"
|
||||
Alors le contenu actuel rejoue depuis le début
|
||||
|
||||
Scénario: Progress bar visuelle reflète le retour exact
|
||||
Étant donné que j'ai écouté le contenu "A" jusqu'à 75% (3min45 sur 5min)
|
||||
Et que je suis passé au contenu "B"
|
||||
Quand je reviens au contenu "A" via "Précédent"
|
||||
Alors la progress bar affiche 75%
|
||||
Et l'indicateur de temps affiche "3:45 / 5:00"
|
||||
Et la lecture reprend exactement à cet endroit
|
||||
|
||||
Scénario: Métadonnées d'historique incluent timestamp précis
|
||||
Étant donné que j'écoute un contenu "X" pendant 45 secondes à 10:30:15
|
||||
Quand je passe au contenu suivant
|
||||
Alors l'historique enregistre:
|
||||
| content_id | position_seconds | listened_at |
|
||||
| X | 45 | 2026-01-21T10:30:15Z |
|
||||
Et le timestamp précis permet l'analyse d'usage
|
||||
|
||||
Scénario: Suppression FIFO respecte l'ordre chronologique
|
||||
Étant donné un historique de [C1@10:00, C2@10:02, ..., C10@10:20]
|
||||
Quand j'ajoute C11 à 10:22
|
||||
Alors C1 (le plus ancien) est supprimé
|
||||
Et l'historique contient [C2@10:02, ..., C11@10:22]
|
||||
Et la taille reste exactement 10 entrées
|
||||
|
||||
Plan du Scénario: Comportement selon temps écouté
|
||||
Étant donné que j'écoute un contenu depuis <temps> secondes
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors l'action est <comportement>
|
||||
|
||||
Exemples:
|
||||
| temps | comportement |
|
||||
| 1 | revenir au contenu précédent |
|
||||
| 5 | revenir au contenu précédent |
|
||||
| 9 | revenir au contenu précédent |
|
||||
| 10 | rejouer le contenu actuel depuis 0:00 |
|
||||
| 11 | rejouer le contenu actuel depuis 0:00 |
|
||||
| 30 | rejouer le contenu actuel depuis 0:00 |
|
||||
| 180 | rejouer le contenu actuel depuis 0:00 |
|
||||
|
||||
Plan du Scénario: Positions de reprise exactes
|
||||
Étant donné que j'écoute un contenu de 10 minutes
|
||||
Quand j'atteins <position> et passe au suivant
|
||||
Et que je reviens via "Précédent"
|
||||
Alors la lecture reprend exactement à <position>
|
||||
|
||||
Exemples:
|
||||
| position |
|
||||
| 0:15 |
|
||||
| 1:30 |
|
||||
| 3:45 |
|
||||
| 5:00 |
|
||||
| 7:23 |
|
||||
| 9:50 |
|
||||
|
||||
# Comportement avec contenus géolocalisés
|
||||
|
||||
Scénario: Précédent après avoir écouté un contenu géolocalisé ≥10s
|
||||
Étant donné que j'écoute un contenu buffer "C1"
|
||||
Et qu'une notification géolocalisée "Tour Eiffel" apparaît
|
||||
Quand j'accepte la notification (décompte 5s)
|
||||
Et que le contenu géolocalisé démarre
|
||||
Et que je l'écoute pendant 42 secondes
|
||||
Quand j'appuie sur "Suivant" (skip)
|
||||
Alors le contenu buffer suivant "C2" démarre
|
||||
Et le contenu géolocalisé entre dans l'historique:
|
||||
"""json
|
||||
{
|
||||
"id": "geo_tour_eiffel",
|
||||
"position_seconds": 42,
|
||||
"type": "geo_anchored"
|
||||
}
|
||||
"""
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors le contenu géolocalisé reprend à 42 secondes
|
||||
Car j'ai écouté ≥ 10 secondes
|
||||
|
||||
Scénario: Précédent après avoir écouté un contenu géolocalisé <10s
|
||||
Étant donné que j'ai accepté un contenu géolocalisé "Château"
|
||||
Et que je l'ai écouté pendant 5 secondes uniquement
|
||||
Quand j'appuie sur "Suivant" (skip)
|
||||
Alors le contenu buffer suivant démarre
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors je reviens au contenu AVANT le géolocalisé
|
||||
Et le contenu géolocalisé n'est PAS rejoué
|
||||
Car j'ai écouté < 10 secondes
|
||||
|
||||
Scénario: Notification géolocalisée ignorée n'entre PAS dans historique
|
||||
Étant donné que j'écoute un contenu "A"
|
||||
Et qu'une notification géolocalisée apparaît (compteur 7→1)
|
||||
Quand je n'appuie PAS sur "Suivant" (notification ignorée)
|
||||
Alors le contenu "A" continue normalement
|
||||
Et le contenu géolocalisé n'entre PAS dans l'historique
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors je reviens au contenu précédent "A-1"
|
||||
Et le contenu géolocalisé ignoré n'apparaît jamais
|
||||
|
||||
Scénario: Annulation décompte géolocalisé n'entre PAS dans historique
|
||||
Étant donné qu'une notification géolocalisée est acceptée
|
||||
Et que le décompte "5" démarre (5→4→3...)
|
||||
Quand j'appuie sur "Suivant" pendant le décompte (annulation)
|
||||
Alors le décompte est annulé
|
||||
Et le contenu buffer suivant démarre
|
||||
Et le contenu géolocalisé n'entre PAS dans l'historique
|
||||
Quand j'appuie sur "Précédent"
|
||||
Alors je reviens au contenu avant le décompte
|
||||
Et le contenu géolocalisé annulé n'apparaît jamais
|
||||
|
||||
Scénario: Historique mixte contenus buffer et géolocalisés
|
||||
Étant donné que j'ai écouté dans l'ordre:
|
||||
| contenu | type | position_seconds |
|
||||
| Buffer 1 | contextuel | 180 |
|
||||
| Géo Tour Eiffel | geo_anchored | 42 |
|
||||
| Buffer 2 | neutre | 90 |
|
||||
| Buffer 3 | contextuel | 30 |
|
||||
Et que j'écoute maintenant "Buffer 4" depuis 2 secondes
|
||||
Quand j'appuie sur "Précédent" (1ère fois)
|
||||
Alors je reviens à "Buffer 3" à 30 secondes
|
||||
Quand j'appuie sur "Précédent" (2ème fois, <10s)
|
||||
Alors je reviens à "Buffer 2" à 90 secondes
|
||||
Quand j'appuie sur "Précédent" (3ème fois, <10s)
|
||||
Alors je reviens à "Géo Tour Eiffel" à 42 secondes
|
||||
Quand j'appuie sur "Précédent" (4ème fois, <10s)
|
||||
Alors je reviens à "Buffer 1" à 180 secondes
|
||||
|
||||
Scénario: Contenu géolocalisé dans limite FIFO 10 contenus
|
||||
Étant donné que j'ai un historique de 10 contenus incluant 3 géolocalisés:
|
||||
| position | contenu | type |
|
||||
| 1 | Buffer 1 | contextuel |
|
||||
| 2 | Géo A | geo_anchored |
|
||||
| 3 | Buffer 2 | neutre |
|
||||
| 4 | Géo B | geo_anchored |
|
||||
| 5-9 | Buffer 3-7 | contextuel |
|
||||
| 10 | Géo C | geo_anchored |
|
||||
Quand j'ajoute un 11ème contenu "Buffer 8"
|
||||
Alors "Buffer 1" (le plus ancien) est supprimé
|
||||
Et l'historique contient:
|
||||
| position | contenu |
|
||||
| 1 | Géo A |
|
||||
| 2 | Buffer 2 |
|
||||
| ... | ... |
|
||||
| 10 | Buffer 8 |
|
||||
Et les contenus géolocalisés suivent la même règle FIFO
|
||||
Reference in New Issue
Block a user