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,288 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Caractéristiques et facturation des publicités
|
||||
En tant que système RoadWave
|
||||
Je veux appliquer des règles précises de durée, skippabilité et facturation
|
||||
Afin d'équilibrer expérience utilisateur et rentabilité publicitaire
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et qu'un utilisateur gratuit écoute du contenu
|
||||
|
||||
Scénario: Durée minimale 10 secondes
|
||||
Étant donné qu'un publicitaire uploade une publicité de 8 secondes
|
||||
Quand le système valide la durée
|
||||
Alors une erreur s'affiche: "Durée minimale: 10 secondes"
|
||||
Et l'upload est rejeté
|
||||
|
||||
Scénario: Durée maximale 60 secondes
|
||||
Étant donné qu'un publicitaire uploade une publicité de 65 secondes
|
||||
Quand le système valide la durée
|
||||
Alors une erreur s'affiche: "Durée maximale: 60 secondes"
|
||||
Et l'upload est rejeté
|
||||
|
||||
Scénario: Durée recommandée 15-30 secondes
|
||||
Étant donné qu'un publicitaire crée une campagne
|
||||
Quand il voit les recommandations
|
||||
Alors un message s'affiche:
|
||||
"""
|
||||
💡 Durée recommandée: 15-30 secondes
|
||||
|
||||
Les publicités de cette durée ont:
|
||||
- Taux d'écoute complète: 45% (vs 35% pour 60s)
|
||||
- Meilleur engagement utilisateur
|
||||
- Coût par écoute optimisé
|
||||
"""
|
||||
|
||||
Scénario: Publicité de 10 secondes acceptée
|
||||
Étant donné qu'un publicitaire uploade une publicité de 10 secondes
|
||||
Quand le système valide la durée
|
||||
Alors le fichier est accepté
|
||||
Et aucune erreur n'est affichée
|
||||
|
||||
Scénario: Publicité de 60 secondes acceptée
|
||||
Étant donné qu'un publicitaire uploade une publicité de 60 secondes
|
||||
Quand le système valide la durée
|
||||
Alors le fichier est accepté
|
||||
Et un avertissement s'affiche: "⚠️ Durée longue: taux de skip potentiellement élevé"
|
||||
|
||||
Scénario: Délai minimum skippable 5 secondes par défaut
|
||||
Étant donné qu'une publicité de 30 secondes démarre
|
||||
Et que le délai minimal est configuré à 5 secondes
|
||||
Quand j'écoute pendant 3 secondes
|
||||
Alors le bouton "Passer" n'est pas visible
|
||||
Et je dois attendre 2 secondes supplémentaires
|
||||
Quand j'atteins 5 secondes d'écoute
|
||||
Alors le bouton "Passer" apparaît
|
||||
Et je peux cliquer pour passer au contenu suivant
|
||||
|
||||
Scénario: Délai minimum paramétrable admin (3 secondes)
|
||||
Étant donné que l'admin configure le délai à 3 secondes
|
||||
Et qu'une publicité démarre
|
||||
Quand j'écoute pendant 3 secondes
|
||||
Alors le bouton "Passer" apparaît immédiatement
|
||||
Et je peux skipper
|
||||
|
||||
Scénario: Délai minimum paramétrable admin (10 secondes)
|
||||
Étant donné que l'admin configure le délai à 10 secondes
|
||||
Et qu'une publicité démarre
|
||||
Quand j'écoute pendant 9 secondes
|
||||
Alors le bouton "Passer" n'est toujours pas visible
|
||||
Quand j'atteins 10 secondes
|
||||
Alors le bouton "Passer" apparaît
|
||||
|
||||
Scénario: Facturation écoute complète (>80%) - 0.05€
|
||||
Étant donné qu'une publicité de 30 secondes est diffusée
|
||||
Quand j'écoute pendant 25 secondes (83%)
|
||||
Alors l'écoute est considérée comme "complète"
|
||||
Et le publicitaire est facturé 0.05€
|
||||
Et le compteur "écoutes complètes" s'incrémente
|
||||
|
||||
Scénario: Facturation écoute complète exactement 80%
|
||||
Étant donné qu'une publicité de 30 secondes est diffusée
|
||||
Quand j'écoute pendant exactement 24 secondes (80%)
|
||||
Alors l'écoute est considérée comme "complète"
|
||||
Et le publicitaire est facturé 0.05€
|
||||
|
||||
Scénario: Facturation skip après délai minimal - 0.02€
|
||||
Étant donné qu'une publicité de 30 secondes est diffusée
|
||||
Et que le délai minimal est 5 secondes
|
||||
Quand j'écoute pendant 10 secondes (33%)
|
||||
Et que je clique sur "Passer"
|
||||
Alors l'écoute est considérée comme "partielle"
|
||||
Et le publicitaire est facturé 0.02€
|
||||
Car il y a eu une exposition partielle
|
||||
|
||||
Scénario: Facturation skip immédiat (<5s) - 0€
|
||||
Étant donné qu'une publicité de 30 secondes est diffusée
|
||||
Et que le délai minimal est 5 secondes
|
||||
Quand j'écoute pendant 3 secondes
|
||||
Et que je clique sur "Suivant" (pas de bouton skip encore)
|
||||
Alors l'écoute est considérée comme "non engagée"
|
||||
Et le publicitaire n'est PAS facturé (0€)
|
||||
Car l'exposition est trop courte
|
||||
|
||||
Scénario: Comptabilisation écoute complète à 79%
|
||||
Étant donné qu'une publicité de 30 secondes est diffusée
|
||||
Quand j'écoute pendant 23 secondes (77%)
|
||||
Alors l'écoute est considérée comme "partielle" (pas complète)
|
||||
Et le publicitaire est facturé 0.02€
|
||||
Car le seuil 80% n'est pas atteint
|
||||
|
||||
Scénario: Comptabilisation écoute complète à 100%
|
||||
Étant donné qu'une publicité de 30 secondes est diffusée
|
||||
Quand j'écoute les 30 secondes complètes (100%)
|
||||
Alors l'écoute est considérée comme "complète"
|
||||
Et le publicitaire est facturé 0.05€
|
||||
|
||||
Scénario: Budget consommé selon mix écoutes
|
||||
Étant donné qu'une campagne à 300€ a généré:
|
||||
| Type écoute | Nombre | Coût unitaire | Total |
|
||||
| Complète (>80%) | 4000 | 0.05€ | 200€ |
|
||||
| Partielle (5-80%) | 2000 | 0.02€ | 40€ |
|
||||
| Skip immédiat | 1000 | 0€ | 0€ |
|
||||
Quand je calcule le budget consommé
|
||||
Alors le total est 240€
|
||||
Et il reste 60€ de budget disponible
|
||||
|
||||
Scénario: Affichage compteur secondes restantes
|
||||
Étant donné qu'une publicité de 30s démarre
|
||||
Et que le délai minimal est 5s
|
||||
Quand j'écoute pendant 2 secondes
|
||||
Alors un compteur s'affiche: "Passer dans 3s..."
|
||||
Quand j'atteins 5 secondes
|
||||
Alors le compteur disparaît
|
||||
Et le bouton "Passer la publicité" s'affiche
|
||||
|
||||
Scénario: Progress bar publicité visible
|
||||
Étant donné qu'une publicité de 30s est en lecture
|
||||
Quand 10 secondes se sont écoulées
|
||||
Alors la progress bar affiche 33% (10/30)
|
||||
Et l'indicateur temporel affiche "0:10 / 0:30"
|
||||
Et l'utilisateur visualise la progression
|
||||
|
||||
Scénario: Message "Publicité" clairement affiché
|
||||
Étant donné qu'une publicité démarre
|
||||
Quand l'audio commence
|
||||
Alors un badge "Publicité" est affiché en haut de l'écran
|
||||
Et la durée totale est indiquée: "Publicité (30s)"
|
||||
Et la transparence est maximale (utilisateur sait que c'est une pub)
|
||||
|
||||
Scénario: Transition fluide après publicité
|
||||
Étant donné qu'une publicité de 30s se termine
|
||||
Quand la lecture atteint 30 secondes
|
||||
Alors le délai de transition de 2s démarre
|
||||
Et le contenu normal suivant est annoncé
|
||||
Et l'enchaînement est naturel (même UX que entre contenus)
|
||||
|
||||
Scénario: Like autorisé sur publicité
|
||||
Étant donné qu'une publicité est en lecture
|
||||
Et que le véhicule est à l'arrêt
|
||||
Quand je clique sur le bouton cœur
|
||||
Alors un like explicite (+2%) est enregistré
|
||||
Et mes jauges d'intérêt sont mises à jour selon les tags de la pub
|
||||
Et le publicitaire voit un compteur "Likes" incrémenté
|
||||
|
||||
Scénario: Abonnement autorisé sur publicité
|
||||
Étant donné qu'une publicité est diffusée par un créateur
|
||||
Et que le véhicule est à l'arrêt
|
||||
Quand je clique sur "S'abonner"
|
||||
Alors l'abonnement est enregistré (+5% jauges)
|
||||
Et le publicitaire bénéficie de l'engagement fort
|
||||
Et cela compte comme une conversion majeure
|
||||
|
||||
Scénario: Bouton skip visible et accessible
|
||||
Étant donné qu'une publicité a dépassé le délai minimal
|
||||
Quand le bouton "Passer" s'affiche
|
||||
Alors il est positionné en bas à droite de l'écran
|
||||
Et il a une taille de clic confortable (44×44px minimum iOS)
|
||||
Et il est clairement visible (contraste élevé)
|
||||
|
||||
Scénario: Analytics tracking précis par type
|
||||
Étant donné qu'une publicité est diffusée
|
||||
Quand un événement se produit
|
||||
Alors il est tracké en temps réel:
|
||||
| Événement | Données enregistrées |
|
||||
| Impression | timestamp, user_id, pub_id, zone_geo |
|
||||
| Écoute complète | durée_ecoutee, pourcentage, coût (0.05€) |
|
||||
| Skip après délai | durée_ecoutee, pourcentage, coût (0.02€) |
|
||||
| Skip immédiat | durée_ecoutee, pourcentage, coût (0€) |
|
||||
| Like | timestamp, tags impactés |
|
||||
| Abonnement | timestamp, creator_id |
|
||||
|
||||
Scénario: Recommandation sweet spot 15-30s
|
||||
Étant donné les statistiques RoadWave globales:
|
||||
| Durée pub | Taux complétion moyen |
|
||||
| 10s | 65% |
|
||||
| 15s | 55% |
|
||||
| 30s | 45% |
|
||||
| 45s | 30% |
|
||||
| 60s | 20% |
|
||||
Quand un publicitaire consulte les recommandations
|
||||
Alors le sweet spot affiché est "15-30 secondes"
|
||||
Et l'explication est "Meilleur compromis engagement/message"
|
||||
|
||||
Scénario: Optimisation durée selon taux de skip campagne
|
||||
Étant donné qu'une campagne de 60s a un taux de skip de 85%
|
||||
Quand le publicitaire consulte les recommandations
|
||||
Alors le système suggère:
|
||||
"""
|
||||
⚠️ Taux de skip élevé (85%)
|
||||
|
||||
Recommandation: Réduire la durée à 30s maximum
|
||||
Impact estimé: Taux de skip attendu 55% (-30%)
|
||||
"""
|
||||
|
||||
Scénario: Coût effectif moyen (CEM) calculé
|
||||
Étant donné une campagne avec:
|
||||
| Type écoute | Nombre | Coût unitaire | Total |
|
||||
| Complète | 2000 | 0.05€ | 100€ |
|
||||
| Partielle | 3000 | 0.02€ | 60€ |
|
||||
| Skip immédiat | 1000 | 0€ | 0€ |
|
||||
Quand je calcule le coût effectif moyen
|
||||
Alors CEM = 160€ / 6000 impressions = 0.027€/impression
|
||||
Et cette métrique aide à comparer avec CPM industrie
|
||||
|
||||
Scénario: Publicité non skippable interdite
|
||||
Étant donné qu'un publicitaire demande "Publicité non skippable"
|
||||
Quand il configure sa campagne
|
||||
Alors cette option n'existe pas
|
||||
Et toutes les publicités sont obligatoirement skippables après 5s minimum
|
||||
Car l'expérience utilisateur est prioritaire
|
||||
|
||||
Scénario: Délai minimal jamais <3 secondes
|
||||
Étant donné qu'un admin essaie de configurer le délai à 2 secondes
|
||||
Quand il valide le paramètre
|
||||
Alors une erreur s'affiche: "Délai minimal: 3 secondes minimum"
|
||||
Car un délai trop court dégrade trop l'expérience
|
||||
|
||||
Scénario: Délai minimal jamais >10 secondes
|
||||
Étant donné qu'un admin essaie de configurer le délai à 15 secondes
|
||||
Quand il valide le paramètre
|
||||
Alors une erreur s'affiche: "Délai maximal: 10 secondes maximum"
|
||||
Car un délai trop long réduit les revenus publicitaires
|
||||
|
||||
Plan du Scénario: Facturation selon durée écoutée
|
||||
Étant donné qu'une publicité de 30s est diffusée
|
||||
Quand j'écoute pendant <duree>s (<pourcentage>%)
|
||||
Alors le type d'écoute est <type>
|
||||
Et le coût facturé est <cout>€
|
||||
|
||||
Exemples:
|
||||
| duree | pourcentage | type | cout |
|
||||
| 3 | 10 | skip immédiat| 0 |
|
||||
| 5 | 17 | partielle | 0.02 |
|
||||
| 10 | 33 | partielle | 0.02 |
|
||||
| 20 | 67 | partielle | 0.02 |
|
||||
| 24 | 80 | complète | 0.05 |
|
||||
| 27 | 90 | complète | 0.05 |
|
||||
| 30 | 100 | complète | 0.05 |
|
||||
|
||||
Plan du Scénario: Budget consommé selon distribution écoutes
|
||||
Étant donné <completes> écoutes complètes à 0.05€
|
||||
Et <partielles> écoutes partielles à 0.02€
|
||||
Et <skips> skips immédiats à 0€
|
||||
Quand je calcule le budget total consommé
|
||||
Alors le résultat est <budget_total>€
|
||||
|
||||
Exemples:
|
||||
| completes | partielles | skips | budget_total |
|
||||
| 1000 | 500 | 100 | 60 |
|
||||
| 2000 | 1000 | 500 | 120 |
|
||||
| 5000 | 2000 | 1000 | 290 |
|
||||
| 0 | 1000 | 0 | 20 |
|
||||
| 1000 | 0 | 0 | 50 |
|
||||
|
||||
Plan du Scénario: Apparition bouton skip selon délai configuré
|
||||
Étant donné que le délai minimal est configuré à <delai>s
|
||||
Quand j'écoute pendant <temps_ecoute>s
|
||||
Alors le bouton "Passer" est <visible>
|
||||
|
||||
Exemples:
|
||||
| delai | temps_ecoute | visible |
|
||||
| 5 | 3 | non visible |
|
||||
| 5 | 5 | visible |
|
||||
| 5 | 10 | visible |
|
||||
| 10 | 8 | non visible |
|
||||
| 10 | 10 | visible |
|
||||
| 3 | 2 | non visible |
|
||||
| 3 | 3 | visible |
|
||||
Reference in New Issue
Block a user