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,59 @@
|
||||
# language: fr
|
||||
|
||||
@api @content-creation @copyright @mvp
|
||||
Fonctionnalité: Fair use 30 secondes musique
|
||||
|
||||
En tant que créateur
|
||||
Je veux utiliser jusqu'à 30 secondes de musique protégée
|
||||
Afin d'enrichir mon contenu dans le cadre du fair use
|
||||
|
||||
Scénario: Détection automatique de musique dans l'upload
|
||||
Étant donné un créateur "alice@roadwave.fr" qui upload un audio
|
||||
Quand le fichier contient de la musique
|
||||
Alors le système détecte via fingerprinting audio (ACRCloud)
|
||||
Et identifie les morceaux présents
|
||||
Et mesure la durée de chaque extrait
|
||||
Et un événement "MUSIC_DETECTED" est enregistré
|
||||
|
||||
Scénario: Validation automatique si < 30 secondes
|
||||
Étant donné un audio avec 25 secondes de musique protégée
|
||||
Quand la validation automatique s'exécute
|
||||
Alors le contenu est approuvé (fair use)
|
||||
Et un badge "Fair use" est appliqué
|
||||
Et un événement "FAIR_USE_APPROVED" est enregistré
|
||||
|
||||
Scénario: Blocage automatique si > 30 secondes
|
||||
Étant donné un audio avec 45 secondes de musique protégée
|
||||
Quand la validation s'exécute
|
||||
Alors le contenu est bloqué
|
||||
Et le créateur voit: "Extrait musical trop long (45s). Max: 30s"
|
||||
Et il peut éditer et re-uploader
|
||||
Et un événement "FAIR_USE_REJECTED" est enregistré
|
||||
|
||||
Scénario: Liste des morceaux détectés avec durée
|
||||
Étant donné un créateur "bob@roadwave.fr" avec musique détectée
|
||||
Alors il voit la liste:
|
||||
| Morceau | Artiste | Durée | Statut |
|
||||
| Bohemian Rhapsody | Queen | 28s | ✓ OK |
|
||||
| Imagine | John Lennon | 15s | ✓ OK |
|
||||
Et la durée totale: 43s
|
||||
Et un avertissement si total > 30s
|
||||
Et un événement "MUSIC_DETECTION_RESULTS_DISPLAYED" est enregistré
|
||||
|
||||
Scénario: Suggestions de musique libre de droits
|
||||
Étant donné un créateur "charlie@roadwave.fr"
|
||||
Quand son audio dépasse les 30s de musique protégée
|
||||
Alors le système suggère des alternatives libres:
|
||||
| Morceau | Licence | Style |
|
||||
| Acoustic Breeze | CC BY | Acoustique |
|
||||
| Epic Cinematic | Royalty-free| Épique |
|
||||
Et un lien vers une bibliothèque musicale
|
||||
Et un événement "FREE_MUSIC_SUGGESTED" est enregistré
|
||||
|
||||
Scénario: Limitation cumulative par audio-guide
|
||||
Étant donné un créateur "david@roadwave.fr" avec audio-guide de 10 séquences
|
||||
Quand il utilise de la musique protégée
|
||||
Alors chaque séquence peut contenir max 30s
|
||||
Mais le total cumulé est limité à 3 minutes par audio-guide
|
||||
Et un compteur affiche: "2min 15s / 3min utilisés"
|
||||
Et un événement "CUMULATIVE_MUSIC_LIMIT_TRACKED" est enregistré
|
||||
@@ -0,0 +1,41 @@
|
||||
# language: fr
|
||||
|
||||
@api @content-creation @media @mvp
|
||||
Fonctionnalité: Génération automatique d'image de couverture
|
||||
|
||||
En tant que créateur
|
||||
Je veux générer automatiquement une image de couverture
|
||||
Afin de gagner du temps et avoir un visuel professionnel
|
||||
|
||||
Scénario: Génération automatique depuis position GPS
|
||||
Étant donné un créateur "alice@roadwave.fr"
|
||||
Quand il crée un audio-guide centré sur "Notre-Dame"
|
||||
Alors le système propose une image de Notre-Dame via API (Unsplash/Pexels)
|
||||
Et 5 suggestions d'images sont affichées
|
||||
Et le créateur peut choisir ou uploader la sienne
|
||||
Et un événement "COVER_AUTO_GENERATED" est enregistré
|
||||
|
||||
Scénario: Ajout automatique de texte sur l'image
|
||||
Étant donné un créateur "bob@roadwave.fr" qui valide une image
|
||||
Quand l'image est sélectionnée
|
||||
Alors le titre de l'audio-guide est ajouté automatiquement
|
||||
Et un filtre sombre est appliqué pour lisibilité
|
||||
Et le texte est centré et optimisé
|
||||
Et un événement "COVER_TEXT_OVERLAY_ADDED" est enregistré
|
||||
|
||||
Scénario: Templates prédéfinis par catégorie
|
||||
Étant donné un créateur "charlie@roadwave.fr"
|
||||
Quand il sélectionne la catégorie "Tourisme"
|
||||
Alors des templates touristiques sont proposés
|
||||
Et il peut personnaliser couleurs et polices
|
||||
Et un événement "COVER_TEMPLATE_USED" est enregistré
|
||||
|
||||
Scénario: Optimisation automatique pour mobile et web
|
||||
Étant donné un créateur "david@roadwave.fr" qui valide une couverture
|
||||
Alors 3 versions sont générées:
|
||||
| Format | Dimensions |
|
||||
| Mobile | 1080x1920 |
|
||||
| Tablette | 2048x2732 |
|
||||
| Web | 1920x1080 |
|
||||
Et toutes sont optimisées en WebP
|
||||
Et un événement "COVER_OPTIMIZED" est enregistré
|
||||
@@ -0,0 +1,250 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Métadonnées et publication de contenu
|
||||
En tant que créateur
|
||||
Je veux remplir les métadonnées de mon contenu
|
||||
Afin de le publier sur RoadWave
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis un créateur connecté
|
||||
Et que mon fichier audio est encodé et prêt
|
||||
|
||||
Scénario: Publication avec toutes les métadonnées obligatoires
|
||||
Quand je remplis les métadonnées suivantes:
|
||||
| champ | valeur |
|
||||
| Titre | Histoire de la Tour Eiffel |
|
||||
| Type géo | Ancré |
|
||||
| Zone | Point GPS (48.8584, 2.2945, 500m) |
|
||||
| Tags | Voyage, Culture générale |
|
||||
| Classification âge | Tout public |
|
||||
Alors la publication réussit
|
||||
Et mon contenu est soumis pour validation
|
||||
|
||||
Scénario: Titre valide entre 5 et 100 caractères
|
||||
Quand je saisis un titre de 50 caractères
|
||||
Alors le titre est accepté
|
||||
Et la validation passe
|
||||
|
||||
Scénario: Titre trop court (<5 caractères)
|
||||
Quand je saisis un titre de 4 caractères "Test"
|
||||
Alors la publication échoue
|
||||
Et je vois le message "Le titre doit contenir entre 5 et 100 caractères"
|
||||
|
||||
Scénario: Titre trop long (>100 caractères)
|
||||
Quand je saisis un titre de 101 caractères
|
||||
Alors la publication échoue
|
||||
Et je vois le message "Le titre doit contenir entre 5 et 100 caractères"
|
||||
|
||||
Scénario: Titre à exactement 5 caractères accepté
|
||||
Quand je saisis un titre de exactement 5 caractères "Titre"
|
||||
Alors le titre est accepté
|
||||
|
||||
Scénario: Titre à exactement 100 caractères accepté
|
||||
Quand je saisis un titre de exactement 100 caractères
|
||||
Alors le titre est accepté
|
||||
|
||||
Scénario: Sélectionner type géo "Ancré"
|
||||
Quand je sélectionne le type géo "Ancré"
|
||||
Alors le système applique une pondération géo de 0.7
|
||||
Et je dois définir une zone de diffusion précise
|
||||
|
||||
Scénario: Sélectionner type géo "Contextuel"
|
||||
Quand je sélectionne le type géo "Contextuel"
|
||||
Alors le système applique une pondération géo de 0.5
|
||||
Et je peux définir une zone ville/département/région
|
||||
|
||||
Scénario: Sélectionner type géo "Neutre"
|
||||
Quand je sélectionne le type géo "Neutre"
|
||||
Alors le système applique une pondération géo de 0.2
|
||||
Et je peux définir une zone nationale
|
||||
|
||||
Scénario: Zone diffusion - Point GPS avec rayon
|
||||
Quand je choisis "Point GPS"
|
||||
Et que je définis les coordonnées (48.8584, 2.2945)
|
||||
Et que je définis un rayon de 500 mètres
|
||||
Alors la zone est validée
|
||||
Et le contenu sera diffusé dans un rayon de 500m autour du point
|
||||
|
||||
Scénario: Zone diffusion - Rayon minimum 100m
|
||||
Quand je définis un rayon de 50 mètres (< 100m)
|
||||
Alors la validation échoue
|
||||
Et je vois le message "Le rayon doit être entre 100m et 10km"
|
||||
|
||||
Scénario: Zone diffusion - Rayon maximum 10km
|
||||
Quand je définis un rayon de 15 km (> 10km)
|
||||
Alors la validation échoue
|
||||
Et je vois le message "Le rayon doit être entre 100m et 10km"
|
||||
|
||||
Scénario: Zone diffusion - Ville depuis référentiel INSEE
|
||||
Quand je choisis "Ville"
|
||||
Alors je vois une liste de villes du référentiel INSEE
|
||||
Quand je sélectionne "Paris (75000)"
|
||||
Alors la zone est définie sur toute la ville de Paris
|
||||
|
||||
Scénario: Zone diffusion - Département
|
||||
Quand je choisis "Département"
|
||||
Et que je sélectionne "Ille-et-Vilaine (35)"
|
||||
Alors la zone couvre tout le département 35
|
||||
|
||||
Scénario: Zone diffusion - Région
|
||||
Quand je choisis "Région"
|
||||
Et que je sélectionne "Bretagne"
|
||||
Alors la zone couvre toute la région Bretagne
|
||||
|
||||
Scénario: Zone diffusion - National
|
||||
Quand je choisis "National"
|
||||
Alors la zone couvre toute la France
|
||||
Et aucune restriction géographique n'est appliquée
|
||||
|
||||
Scénario: Zones mutuellement exclusives
|
||||
Étant donné que j'ai sélectionné "Point GPS"
|
||||
Quand j'essaie de sélectionner également "Ville"
|
||||
Alors la première sélection est remplacée
|
||||
Et seule "Ville" reste active
|
||||
|
||||
Scénario: Sélectionner 1 tag minimum
|
||||
Quand je sélectionne 1 tag "Voyage"
|
||||
Alors la validation passe
|
||||
Et le contenu est tagué "Voyage"
|
||||
|
||||
Scénario: Sélectionner 3 tags maximum
|
||||
Quand je sélectionne 3 tags "Automobile", "Technologie", "Sport"
|
||||
Alors la validation passe
|
||||
Et le contenu est tagué avec les 3 tags
|
||||
|
||||
Scénario: Impossible de sélectionner 0 tag
|
||||
Quand j'essaie de publier sans sélectionner de tag
|
||||
Alors la publication échoue
|
||||
Et je vois le message "Vous devez sélectionner entre 1 et 3 tags"
|
||||
|
||||
Scénario: Impossible de sélectionner 4 tags
|
||||
Quand j'essaie de sélectionner 4 tags
|
||||
Alors le 4ème tag ne peut pas être ajouté
|
||||
Et je vois le message "Maximum 3 tags"
|
||||
|
||||
Scénario: Tags disponibles dans la liste
|
||||
Quand je consulte la liste des tags
|
||||
Alors je vois les tags suivants:
|
||||
| tag |
|
||||
| Automobile |
|
||||
| Voyage |
|
||||
| Famille |
|
||||
| Amour |
|
||||
| Musique |
|
||||
| Économie |
|
||||
| Cryptomonnaie |
|
||||
| Politique |
|
||||
| Culture générale |
|
||||
| Sport |
|
||||
| Technologie |
|
||||
| Santé |
|
||||
|
||||
Scénario: Classification âge obligatoire
|
||||
Quand j'essaie de publier sans classification âge
|
||||
Alors la publication échoue
|
||||
Et je vois le message "Vous devez sélectionner une classification d'âge"
|
||||
|
||||
Plan du Scénario: Sélectionner classification âge
|
||||
Quand je sélectionne la classification "<classification>"
|
||||
Alors le contenu sera visible pour "<public_cible>"
|
||||
|
||||
Exemples:
|
||||
| classification | public_cible |
|
||||
| Tout public | Tous les utilisateurs |
|
||||
| 13+ | Utilisateurs 13 ans et plus |
|
||||
| 16+ | Utilisateurs 16 ans et plus |
|
||||
| 18+ | Utilisateurs 18 ans et plus |
|
||||
|
||||
Scénario: Image de couverture auto-générée selon type géo
|
||||
Étant donné que je choisis le type géo "Ancré"
|
||||
Et que mon tag principal est "Voyage"
|
||||
Quand la publication est soumise
|
||||
Alors une image de couverture est générée automatiquement:
|
||||
| paramètre | valeur |
|
||||
| Icône | 📍 (Ancré) |
|
||||
| Couleur | Bleu-vert (Voyage) |
|
||||
| Format | 800×800px PNG |
|
||||
|
||||
Scénario: Image de couverture type Contextuel
|
||||
Étant donné que je choisis "Contextuel"
|
||||
Quand l'image est générée
|
||||
Alors l'icône est 🌍 (Contextuel)
|
||||
|
||||
Scénario: Image de couverture type Neutre
|
||||
Étant donné que je choisis "Neutre"
|
||||
Quand l'image est générée
|
||||
Alors l'icône est 🎧 (Neutre)
|
||||
|
||||
Plan du Scénario: Couleur selon tag principal
|
||||
Étant donné que mon tag principal est "<tag>"
|
||||
Quand l'image est générée
|
||||
Alors la couleur de fond est "<couleur>"
|
||||
|
||||
Exemples:
|
||||
| tag | couleur |
|
||||
| Automobile | Bleu |
|
||||
| Voyage | Vert |
|
||||
| Musique | Rouge |
|
||||
| Économie | Gris |
|
||||
| Sport | Orange |
|
||||
|
||||
Scénario: Champs optionnels non obligatoires
|
||||
Quand je publie sans description
|
||||
Et sans image de couverture personnalisée
|
||||
Alors la publication réussit
|
||||
Et les champs optionnels restent vides
|
||||
Et une image par défaut est générée
|
||||
|
||||
Scénario: Temps de publication estimé 2 minutes
|
||||
Étant donné que mon fichier audio est prêt
|
||||
Quand je commence à remplir les métadonnées
|
||||
Alors je peux publier en environ 2 minutes
|
||||
Car il n'y a que 5 champs obligatoires
|
||||
|
||||
Scénario: Publication rapide sans friction
|
||||
Quand je publie mon premier contenu
|
||||
Alors aucun champ complexe n'est demandé
|
||||
Et je ne suis pas bloqué sur description ou image
|
||||
Et la publication est fluide
|
||||
|
||||
Scénario: Prévisualisation avant publication
|
||||
Étant donné que j'ai rempli toutes les métadonnées
|
||||
Quand je clique sur "Prévisualiser"
|
||||
Alors je vois un aperçu de mon contenu:
|
||||
| élément | affiché |
|
||||
| Titre | ✅ |
|
||||
| Image couverture | ✅ |
|
||||
| Tags | ✅ |
|
||||
| Zone diffusion | ✅ |
|
||||
| Durée audio | ✅ |
|
||||
| Classification | ✅ |
|
||||
|
||||
Scénario: Enregistrer brouillon
|
||||
Étant donné que j'ai commencé à remplir les métadonnées
|
||||
Quand je clique sur "Enregistrer brouillon"
|
||||
Alors mes métadonnées sont sauvegardées
|
||||
Et je peux reprendre la publication plus tard
|
||||
|
||||
Scénario: Reprendre brouillon
|
||||
Étant donné que j'ai un brouillon sauvegardé
|
||||
Quand j'accède à mes contenus
|
||||
Alors je vois le brouillon avec statut "📝 Brouillon"
|
||||
Et je peux reprendre la publication
|
||||
|
||||
Scénario: Impossible de publier pendant encodage en cours
|
||||
Étant donné que mon fichier est en cours d'encodage
|
||||
Quand j'essaie de remplir les métadonnées
|
||||
Alors je vois le message "Encodage en cours, veuillez patienter"
|
||||
Et l'interface de publication est désactivée
|
||||
|
||||
Scénario: Limite de 10 brouillons maximum
|
||||
Étant donné que j'ai déjà 10 brouillons sauvegardés
|
||||
Quand j'essaie de créer un 11ème brouillon
|
||||
Alors le brouillon est refusé
|
||||
Et je vois le message "Maximum 10 brouillons. Publiez ou supprimez un brouillon existant."
|
||||
|
||||
Scénario: Suppression automatique brouillons après 30 jours
|
||||
Étant donné que j'ai un brouillon de plus de 30 jours
|
||||
Quand le système effectue le nettoyage automatique
|
||||
Alors le brouillon est supprimé automatiquement
|
||||
Et je reçois une notification "Brouillon '[Titre]' supprimé (>30 jours)"
|
||||
@@ -0,0 +1,235 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Modification et suppression de contenu
|
||||
En tant que créateur
|
||||
Je veux pouvoir modifier ou supprimer mes contenus
|
||||
Afin de garder le contrôle sur mes publications
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis un créateur connecté
|
||||
Et que j'ai publié un contenu
|
||||
|
||||
Scénario: Modifier le titre d'un contenu
|
||||
Étant donné que mon contenu a le titre "Histoire de Paris"
|
||||
Quand je modifie le titre en "Histoire fascinante de Paris"
|
||||
Alors la modification est enregistrée immédiatement
|
||||
Et je vois le message "Titre modifié avec succès"
|
||||
|
||||
Scénario: Correction de coquilles dans le titre
|
||||
Étant donné que mon titre contient une faute "Histoore de Paris"
|
||||
Quand je corrige en "Histoire de Paris"
|
||||
Alors la modification est acceptée
|
||||
Et le titre corrigé est affiché
|
||||
|
||||
Scénario: Ajouter une description ultérieurement
|
||||
Étant donné que j'ai publié sans description
|
||||
Quand j'ajoute une description "Découvrez l'histoire de la capitale"
|
||||
Alors la description est enregistrée
|
||||
Et elle est visible sur la page du contenu
|
||||
|
||||
Scénario: Modifier la description existante
|
||||
Étant donné que mon contenu a déjà une description
|
||||
Quand je modifie la description
|
||||
Alors la nouvelle description remplace l'ancienne
|
||||
Et la modification est immédiate
|
||||
|
||||
Scénario: Modifier les tags pour ajuster pertinence
|
||||
Étant donné que mon contenu est tagué "Sport", "Musique"
|
||||
Quand je change les tags en "Sport", "Santé"
|
||||
Alors les nouveaux tags sont appliqués
|
||||
Et l'algorithme utilise les nouveaux tags pour recommandations
|
||||
|
||||
Scénario: Personnaliser l'image de couverture
|
||||
Étant donné que mon contenu a une image auto-générée
|
||||
Quand j'uploade une image personnalisée 800×800px
|
||||
Alors l'image personnalisée remplace l'image par défaut
|
||||
Et elle est visible sur le contenu
|
||||
|
||||
Scénario: Impossible de modifier l'audio
|
||||
Étant donné que mon contenu audio est publié
|
||||
Quand j'essaie de remplacer le fichier audio
|
||||
Alors la modification est refusée
|
||||
Et je vois le message "L'audio ne peut pas être modifié après publication"
|
||||
|
||||
Scénario: Raison - Éviter fraude audio
|
||||
Étant donné que je veux changer l'audio après validation
|
||||
Quand j'essaie de modifier
|
||||
Alors le système refuse pour éviter:
|
||||
| risque |
|
||||
| Uploader contenu validé puis remplacer spam |
|
||||
| Fraude sur l'intégrité du contenu |
|
||||
|
||||
Scénario: Impossible de modifier la zone de diffusion
|
||||
Étant donné que mon contenu est diffusé à Paris
|
||||
Quand j'essaie de changer la zone en "National"
|
||||
Alors la modification est refusée
|
||||
Et je vois le message "La zone de diffusion ne peut pas être modifiée"
|
||||
|
||||
Scénario: Raison - Éviter manipulation algorithme
|
||||
Étant donné que je veux changer ma zone
|
||||
Quand j'essaie de modifier
|
||||
Alors le système refuse pour éviter:
|
||||
| manipulation |
|
||||
| Créer "Local Paris" puis changer en "National" |
|
||||
| Boost artificiel de visibilité |
|
||||
|
||||
Scénario: Impossible de modifier le type géo
|
||||
Étant donné que mon contenu est type "Neutre" (pondération 0.2)
|
||||
Quand j'essaie de changer en "Ancré" (pondération 0.7)
|
||||
Alors la modification est refusée
|
||||
Et je vois le message "Le type géographique ne peut pas être modifié"
|
||||
|
||||
Scénario: Raison - Éviter abus de pondération
|
||||
Étant donné que je veux changer le type géo
|
||||
Quand j'essaie de modifier
|
||||
Alors le système refuse pour éviter:
|
||||
| abus |
|
||||
| Créer "Neutre" puis passer en "Ancré" |
|
||||
| Manipulation de la pondération algorithme |
|
||||
|
||||
Scénario: Impossible de modifier la classification âge
|
||||
Étant donné que mon contenu est classé "Tout public"
|
||||
Quand j'essaie de changer en "18+"
|
||||
Alors la modification est refusée
|
||||
Et je vois le message "La classification d'âge ne peut pas être modifiée"
|
||||
|
||||
Scénario: Raison - Sécurité mineurs
|
||||
Étant donné que je veux changer la classification
|
||||
Quand j'essaie de modifier
|
||||
Alors le système refuse pour garantir:
|
||||
| protection |
|
||||
| Classification vérifiée en modération |
|
||||
| Pas de contournement validation |
|
||||
| Sécurité des mineurs |
|
||||
|
||||
Scénario: Solution si besoin de changer audio/zone/classification
|
||||
Étant donné que je veux absolument changer l'audio
|
||||
Quand je consulte les options
|
||||
Alors je vois "Supprimer et republier le contenu"
|
||||
Et c'est la seule solution disponible
|
||||
|
||||
Scénario: Republication après suppression - créateur <3 validations
|
||||
Étant donné que je suis un nouveau créateur (2 contenus validés)
|
||||
Et que je supprime puis republie un contenu
|
||||
Quand je republie avec les modifications
|
||||
Alors le contenu repasse en file de validation
|
||||
Et une nouvelle validation est effectuée
|
||||
|
||||
Scénario: Republication après suppression - créateur vérifié
|
||||
Étant donné que je suis créateur vérifié (≥3 contenus validés)
|
||||
Et que je supprime puis republie un contenu
|
||||
Quand je republie avec les modifications
|
||||
Alors le contenu est publié immédiatement
|
||||
Et aucune validation préalable n'est requise
|
||||
|
||||
Scénario: Suppression de contenu immédiate
|
||||
Quand je clique sur "Supprimer le contenu"
|
||||
Et que je confirme la suppression
|
||||
Alors le contenu est supprimé immédiatement
|
||||
Et disparaît de la liste publique
|
||||
|
||||
Scénario: Confirmation avant suppression
|
||||
Quand je clique sur "Supprimer"
|
||||
Alors je vois un message de confirmation:
|
||||
| titre | Êtes-vous sûr ? |
|
||||
| message | Cette action est définitive |
|
||||
| warning | Le contenu sera supprimé définitivement |
|
||||
| actions | Confirmer / Annuler |
|
||||
|
||||
Scénario: Suppression définitive et non réversible
|
||||
Étant donné que j'ai supprimé un contenu
|
||||
Quand j'essaie de le récupérer
|
||||
Alors la récupération est impossible
|
||||
Et le contenu est définitivement perdu
|
||||
|
||||
Scénario: Suppression BDD + Cache sous 5 minutes
|
||||
Quand je supprime un contenu
|
||||
Alors l'entrée en base de données est marquée "deleted"
|
||||
Et les fichiers sont marqués pour suppression
|
||||
Et la suppression effective a lieu sous 5 minutes
|
||||
|
||||
Scénario: Historique auditeurs conservé anonymisé
|
||||
Étant donné que 1000 personnes ont écouté mon contenu
|
||||
Quand je supprime le contenu
|
||||
Alors leur historique est conservé
|
||||
Mais marqué "Contenu supprimé par créateur"
|
||||
Et la durée d'écoute est conservée pour leurs stats
|
||||
|
||||
Scénario: Analytics plateforme anonymisées conservées
|
||||
Étant donné que mon contenu a généré 10K écoutes
|
||||
Quand je supprime le contenu
|
||||
Alors les métriques globales sont conservées anonymement:
|
||||
| métrique | conservée |
|
||||
| Total écoutes | ✅ (anonyme) |
|
||||
| Durée totale | ✅ (anonyme) |
|
||||
| Catégorie | ✅ (anonyme) |
|
||||
| Auteur | ❌ (anonymisé) |
|
||||
Et c'est conforme RGPD
|
||||
|
||||
Scénario: Fichiers Cache + Storage supprimés sous 24h
|
||||
Étant donné que mon contenu est supprimé
|
||||
Quand 24 heures s'écoulent
|
||||
Alors tous les fichiers audio sont purgés du NGINX Cache
|
||||
Et tous les fichiers sont supprimés de OVH Object Storage
|
||||
Et l'espace de stockage est libéré
|
||||
|
||||
Scénario: Pas de notification aux auditeurs
|
||||
Étant donné que 500 utilisateurs ont écouté mon contenu
|
||||
Quand je supprime le contenu
|
||||
Alors aucune notification n'est envoyée aux auditeurs
|
||||
Et il n'y a pas d'effet Streisand
|
||||
|
||||
Scénario: Auditeur tente de réécouter contenu supprimé
|
||||
Étant donné qu'un auditeur a écouté mon contenu
|
||||
Et que j'ai supprimé ce contenu
|
||||
Quand l'auditeur tente de le réécouter depuis son historique
|
||||
Alors il voit le message "Ce contenu n'est plus disponible"
|
||||
Et la lecture est impossible
|
||||
|
||||
Scénario: Historique auditeur conserve trace
|
||||
Étant donné qu'un auditeur a écouté mon contenu le 15 janvier
|
||||
Et que je supprime le contenu le 20 janvier
|
||||
Quand l'auditeur consulte son historique
|
||||
Alors il voit "Vous avez écouté ce contenu le 15 janvier 2026"
|
||||
Et le titre est remplacé par "Contenu supprimé"
|
||||
Et la date d'écoute est conservée
|
||||
|
||||
Scénario: Statistiques créateur après suppression
|
||||
Étant donné que j'ai publié 10 contenus
|
||||
Et que je supprime 2 contenus
|
||||
Quand je consulte mes statistiques globales
|
||||
Alors je vois:
|
||||
| métrique | valeur |
|
||||
| Contenus publiés | 8 (actifs) |
|
||||
| Total historique | 10 |
|
||||
| Suppressions | 2 |
|
||||
Et l'historique des suppressions est visible
|
||||
|
||||
Scénario: Limite de modifications par contenu
|
||||
Étant donné que j'ai modifié un titre 10 fois
|
||||
Quand j'essaie de modifier une 11ème fois
|
||||
Alors la modification est acceptée
|
||||
Car il n'y a pas de limite de modifications pour champs autorisés
|
||||
|
||||
Scénario: Historique des modifications visible
|
||||
Étant donné que j'ai modifié un contenu plusieurs fois
|
||||
Quand je consulte l'historique
|
||||
Alors je vois:
|
||||
| date | modification |
|
||||
| 21/01/2026 | Titre changé |
|
||||
| 20/01/2026 | Tags modifiés |
|
||||
| 19/01/2026 | Description ajoutée |
|
||||
Et je peux tracer toutes les modifications
|
||||
|
||||
Scénario: Suppression d'un contenu en cours d'encodage
|
||||
Étant donné que mon contenu est en cours d'encodage (50%)
|
||||
Quand je supprime le contenu
|
||||
Alors l'encodage est annulé immédiatement
|
||||
Et le fichier temporaire est supprimé
|
||||
Et je vois le message "Contenu et encodage supprimés"
|
||||
|
||||
Scénario: Impossible de modifier un contenu en cours de validation
|
||||
Étant donné que mon contenu est en file de validation
|
||||
Quand j'essaie de modifier le titre
|
||||
Alors la modification est refusée
|
||||
Et je vois le message "Impossible de modifier pendant la validation"
|
||||
@@ -0,0 +1,53 @@
|
||||
# language: fr
|
||||
|
||||
@api @content-creation @rules @mvp
|
||||
Fonctionnalité: Restrictions de modification de contenu publié
|
||||
|
||||
En tant que plateforme
|
||||
Je veux restreindre les modifications après publication
|
||||
Afin de maintenir l'intégrité du contenu et des statistiques
|
||||
|
||||
Scénario: Modification limitée du contenu après publication
|
||||
Étant donné un créateur "alice@roadwave.fr" avec contenu publié
|
||||
Quand il tente de modifier le contenu
|
||||
Alors il peut modifier:
|
||||
| Champ modifiable | Restrictions |
|
||||
| Titre | Max 1 fois par mois |
|
||||
| Description | Illimité |
|
||||
| Image de couverture | Max 3 fois par an |
|
||||
| Fichiers audio | Impossible après 100 écoutes|
|
||||
| Prix | Max 1 baisse par trimestre |
|
||||
Et un événement "CONTENT_MODIFICATION_RESTRICTED" est enregistré
|
||||
|
||||
Scénario: Blocage de modification des séquences très écoutées
|
||||
Étant donné un créateur "bob@roadwave.fr"
|
||||
Et une séquence avec 1000+ écoutes
|
||||
Quand il tente de remplacer le fichier audio
|
||||
Alors la modification est bloquée
|
||||
Et un message explique: "Contenu verrouillé après 1000 écoutes"
|
||||
Et il peut créer une nouvelle version à la place
|
||||
Et un événement "AUDIO_MODIFICATION_BLOCKED" est enregistré
|
||||
|
||||
Scénario: Historique des modifications
|
||||
Étant donné un créateur "charlie@roadwave.fr"
|
||||
Quand il consulte l'historique
|
||||
Alors il voit toutes les modifications:
|
||||
| Date | Champ modifié | Ancienne valeur | Nouvelle valeur |
|
||||
| 2026-02-01 | Titre | Visite Paris | Visite Paris 2026|
|
||||
| 2026-01-15 | Prix | 5€ | 3€ |
|
||||
Et un événement "MODIFICATION_HISTORY_VIEWED" est enregistré
|
||||
|
||||
Scénario: Délai de modération avant republication
|
||||
Étant donné un créateur "david@roadwave.fr"
|
||||
Quand il modifie substantiellement un contenu publié
|
||||
Alors le contenu repasse en modération
|
||||
Et reste accessible pendant la modération
|
||||
Et un événement "CONTENT_REMODERATION_QUEUED" est enregistré
|
||||
|
||||
Scénario: Versioning automatique des contenus
|
||||
Étant donné un créateur "eve@roadwave.fr"
|
||||
Quand il publie une modification importante
|
||||
Alors une nouvelle version (v2) est créée
|
||||
Et les utilisateurs ayant commencé v1 la terminent
|
||||
Et les nouveaux utilisateurs obtiennent v2
|
||||
Et un événement "CONTENT_VERSION_CREATED" est enregistré
|
||||
@@ -0,0 +1,62 @@
|
||||
# language: fr
|
||||
|
||||
@api @content-creation @deletion @mvp
|
||||
Fonctionnalité: Suppression et marquage de contenu
|
||||
|
||||
En tant que créateur ou modérateur
|
||||
Je veux pouvoir supprimer ou marquer du contenu
|
||||
Afin de gérer le cycle de vie du contenu sur la plateforme
|
||||
|
||||
Scénario: Suppression douce avec période de grâce de 30 jours
|
||||
Étant donné un créateur "alice@roadwave.fr"
|
||||
Quand il supprime son audio-guide
|
||||
Alors le contenu est marqué "Supprimé" (soft delete)
|
||||
Et reste dans la base pendant 30 jours
|
||||
Et disparaît des recherches immédiatement
|
||||
Et peut être restauré dans les 30 jours
|
||||
Et un événement "CONTENT_SOFT_DELETED" est enregistré
|
||||
|
||||
Scénario: Suppression définitive après 30 jours
|
||||
Étant donné un contenu supprimé il y a 31 jours
|
||||
Quand le job de nettoyage s'exécute
|
||||
Alors le contenu est définitivement supprimé (hard delete)
|
||||
Et tous les fichiers associés sont supprimés de S3
|
||||
Et les statistiques sont archivées
|
||||
Et un événement "CONTENT_HARD_DELETED" est enregistré
|
||||
|
||||
Scénario: Restauration d'un contenu supprimé
|
||||
Étant donné un créateur "bob@roadwave.fr"
|
||||
Et un contenu supprimé il y a 10 jours
|
||||
Quand il accède à "Contenus supprimés"
|
||||
Et clique sur "Restaurer"
|
||||
Alors le contenu redevient actif immédiatement
|
||||
Et réapparaît dans les recherches
|
||||
Et un événement "CONTENT_RESTORED" est enregistré
|
||||
|
||||
Scénario: Marquage de contenu obsolète
|
||||
Étant donné un créateur "charlie@roadwave.fr"
|
||||
Quand il marque un contenu comme "Obsolète"
|
||||
Alors un badge "⚠️ Contenu obsolète" s'affiche
|
||||
Et il reste accessible mais avec avertissement
|
||||
Et n'apparaît plus dans les recommandations
|
||||
Et un événement "CONTENT_MARKED_OBSOLETE" est enregistré
|
||||
|
||||
Scénario: Blocage par modération
|
||||
Étant donné un modérateur qui détecte un contenu problématique
|
||||
Quand il bloque le contenu
|
||||
Alors il devient immédiatement invisible
|
||||
Et le créateur est notifié avec raison
|
||||
Et peut faire appel de la décision
|
||||
Et un événement "CONTENT_BLOCKED_BY_MODERATION" est enregistré
|
||||
|
||||
Scénario: Statistiques avant suppression définitive
|
||||
Étant donné un créateur "david@roadwave.fr"
|
||||
Quand il consulte un contenu avant suppression définitive
|
||||
Alors il voit les statistiques finales:
|
||||
| Métrique | Valeur |
|
||||
| Total écoutes | 1,234 |
|
||||
| Note moyenne | 4.2/5 |
|
||||
| Revenus générés | 156€ |
|
||||
| Période active | 8 mois |
|
||||
Et peut exporter ces données
|
||||
Et un événement "DELETION_STATS_VIEWED" est enregistré
|
||||
@@ -0,0 +1,231 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Upload et encodage de contenu audio
|
||||
En tant que créateur
|
||||
Je veux uploader mon contenu audio
|
||||
Afin qu'il soit encodé et disponible pour les auditeurs
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis un créateur connecté
|
||||
|
||||
Scénario: Upload fichier MP3 valide
|
||||
Quand j'uploade un fichier MP3 de 50 MB et 30 minutes
|
||||
Alors l'upload réussit
|
||||
Et le fichier est envoyé vers OVH Object Storage temporaire
|
||||
Et un job d'encodage asynchrone est lancé
|
||||
|
||||
Scénario: Upload fichier AAC valide (.aac)
|
||||
Quand j'uploade un fichier AAC de 80 MB et 1 heure
|
||||
Alors l'upload réussit
|
||||
Et le fichier est accepté
|
||||
Et l'encodage démarre
|
||||
|
||||
Scénario: Upload fichier M4A valide
|
||||
Quand j'uploade un fichier M4A de 100 MB et 2 heures
|
||||
Alors l'upload réussit
|
||||
Et le fichier est traité comme AAC
|
||||
Et l'encodage démarre
|
||||
|
||||
Scénario: Rejet fichier WAV (non supporté)
|
||||
Quand j'essaie d'uploader un fichier WAV
|
||||
Alors l'upload échoue
|
||||
Et je vois le message "Format non supporté. Utilisez MP3 ou AAC (.mp3, .aac, .m4a)"
|
||||
|
||||
Scénario: Rejet fichier FLAC (non supporté)
|
||||
Quand j'essaie d'uploader un fichier FLAC
|
||||
Alors l'upload échoue
|
||||
Et je vois le message "Format non supporté. Utilisez MP3 ou AAC (.mp3, .aac, .m4a)"
|
||||
|
||||
Scénario: Validation taille maximale 200 MB
|
||||
Quand j'essaie d'uploader un fichier MP3 de 201 MB
|
||||
Alors l'upload échoue
|
||||
Et je vois le message "Fichier trop volumineux (max 200 MB)"
|
||||
|
||||
Scénario: Upload à la limite de 200 MB accepté
|
||||
Quand j'uploade un fichier MP3 de exactement 200 MB
|
||||
Alors l'upload réussit
|
||||
Et le fichier est accepté
|
||||
|
||||
Scénario: Validation durée maximale 4 heures
|
||||
Quand j'essaie d'uploader un fichier de 4h 10min
|
||||
Alors l'upload échoue
|
||||
Et je vois le message "Durée trop longue (max 4 heures)"
|
||||
|
||||
Scénario: Upload à la limite de 4h accepté
|
||||
Quand j'uploade un fichier de exactement 4 heures
|
||||
Alors l'upload réussit
|
||||
Et le fichier est accepté
|
||||
|
||||
Scénario: Validation format côté client
|
||||
Quand je sélectionne un fichier dans l'interface
|
||||
Alors la validation du format est faite immédiatement côté client
|
||||
Et je suis informé avant même de lancer l'upload si le format est invalide
|
||||
|
||||
Scénario: Double validation côté backend
|
||||
Étant donné qu'un fichier a passé la validation client
|
||||
Quand le backend reçoit le fichier
|
||||
Alors une validation supplémentaire est effectuée
|
||||
Et le format et l'intégrité sont vérifiés
|
||||
|
||||
Scénario: Pipeline d'encodage - étape 1 upload
|
||||
Quand j'uploade un fichier MP3 valide
|
||||
Alors le fichier est stocké temporairement dans OVH Object Storage
|
||||
Et un job d'encodage est mis en file d'attente
|
||||
|
||||
Scénario: Pipeline d'encodage - validation format
|
||||
Étant donné qu'un job d'encodage est lancé
|
||||
Quand le worker Go traite le fichier
|
||||
Alors le format est validé avec FFmpeg
|
||||
Et l'intégrité du fichier est vérifiée
|
||||
|
||||
Scénario: Pipeline d'encodage - génération 3 profils Opus
|
||||
Étant donné qu'un fichier audio est validé
|
||||
Quand l'encodage démarre
|
||||
Alors 3 profils Opus sont générés:
|
||||
| qualité | bitrate | usage |
|
||||
| Basse | 24 kbps | 2G/Edge |
|
||||
| Standard | 48 kbps | 3G |
|
||||
| Haute | 64 kbps | 4G/5G |
|
||||
|
||||
Scénario: Pipeline d'encodage - génération segments HLS
|
||||
Étant donné que les profils Opus sont générés
|
||||
Quand l'encodage continue
|
||||
Alors un fichier manifest .m3u8 est créé
|
||||
Et des segments .ts sont générés
|
||||
Et le contenu est prêt pour streaming HLS
|
||||
|
||||
Scénario: Pipeline d'encodage - génération image par défaut
|
||||
Étant donné que l'encodage est en cours
|
||||
Quand les métadonnées sont traitées
|
||||
Alors une image de couverture par défaut est générée
|
||||
Et l'image fait 800×800px au format PNG
|
||||
|
||||
Scénario: Pipeline d'encodage - suppression fichier original
|
||||
Étant donné que l'encodage est terminé avec succès
|
||||
Quand tous les fichiers de sortie sont générés
|
||||
Alors le fichier original MP3/AAC est supprimé
|
||||
Et seuls les profils Opus et HLS sont conservés
|
||||
Et l'espace de stockage est économisé
|
||||
|
||||
Scénario: Temps d'encodage contenu 5 minutes
|
||||
Étant donné qu'un fichier de 5 minutes est uploadé
|
||||
Quand l'encodage démarre
|
||||
Alors l'encodage prend environ 30 secondes
|
||||
Et je reçois une notification "Contenu prêt à publier"
|
||||
|
||||
Scénario: Temps d'encodage podcast 1 heure
|
||||
Étant donné qu'un fichier de 1 heure est uploadé
|
||||
Quand l'encodage démarre
|
||||
Alors l'encodage prend environ 5 minutes
|
||||
Et une barre de progression est affichée
|
||||
|
||||
Scénario: Temps d'encodage podcast 4 heures
|
||||
Étant donné qu'un fichier de 4 heures est uploadé
|
||||
Quand l'encodage démarre
|
||||
Alors l'encodage prend environ 20 minutes
|
||||
Et je peux fermer l'app (traitement asynchrone)
|
||||
|
||||
Scénario: Notification "Contenu prêt à publier"
|
||||
Étant donné que mon contenu est en cours d'encodage
|
||||
Quand l'encodage se termine avec succès
|
||||
Alors je reçois une notification push "✅ Votre contenu est prêt à publier"
|
||||
Et je peux accéder à l'interface de publication
|
||||
|
||||
Scénario: Échec d'encodage - fichier corrompu
|
||||
Étant donné qu'un fichier MP3 corrompu est uploadé
|
||||
Quand l'encodage démarre
|
||||
Alors l'encodage échoue
|
||||
Et je reçois une notification "❌ Erreur d'encodage: fichier corrompu"
|
||||
Et le fichier temporaire est supprimé
|
||||
|
||||
Scénario: Écoute accélérée - vitesses disponibles
|
||||
Étant donné qu'un contenu est publié
|
||||
Quand un auditeur écoute le contenu
|
||||
Alors il peut choisir parmi les vitesses:
|
||||
| vitesse | usage |
|
||||
| 0.75x | Compréhension difficile |
|
||||
| 1.0x | Normal (défaut) |
|
||||
| 1.25x | Gain léger |
|
||||
| 1.5x | Podcasts longs |
|
||||
| 2.0x | Survol rapide |
|
||||
|
||||
Scénario: Écoute accélérée pour modérateurs
|
||||
Étant donné que je suis un modérateur
|
||||
Et qu'un contenu de 30 secondes est à valider
|
||||
Quand je l'écoute à 2.0x
|
||||
Alors je termine l'écoute en 15 secondes
|
||||
Et ma productivité est doublée
|
||||
|
||||
Scénario: Écoute accélérée pour auditeurs
|
||||
Étant donné que je suis un auditeur
|
||||
Et qu'un podcast de 1 heure est disponible
|
||||
Quand je configure la vitesse à 1.5x
|
||||
Alors j'écoute le podcast en 40 minutes
|
||||
Et je gagne 20 minutes
|
||||
|
||||
Scénario: Sauvegarde préférence vitesse d'écoute
|
||||
Étant donné que je configure la vitesse à 1.5x
|
||||
Quand j'écoute plusieurs contenus
|
||||
Alors tous les contenus sont lus à 1.5x par défaut
|
||||
Et ma préférence est sauvegardée
|
||||
|
||||
Scénario: Scalabilité horizontale des workers
|
||||
Étant donné que 100 contenus sont uploadés simultanément
|
||||
Quand les jobs d'encodage sont distribués
|
||||
Alors plusieurs workers Go traitent les jobs en parallèle
|
||||
Et Kubernetes scale automatiquement les pods
|
||||
Et tous les contenus sont encodés sans délai excessif
|
||||
|
||||
Scénario: Statut d'encodage visible
|
||||
Étant donné que mon contenu est en cours d'encodage
|
||||
Quand je consulte mes contenus
|
||||
Alors je vois le statut:
|
||||
| état | affichage |
|
||||
| En attente | ⏳ File d'attente |
|
||||
| En cours | ⚙️ Encodage en cours (45%) |
|
||||
| Terminé | ✅ Prêt à publier |
|
||||
| Échec | ❌ Erreur - Réessayer |
|
||||
|
||||
Scénario: Réessayer après échec d'encodage
|
||||
Étant donné que l'encodage de mon contenu a échoué
|
||||
Quand je clique sur "Réessayer"
|
||||
Alors un nouveau job d'encodage est lancé
|
||||
Et je peux tenter à nouveau
|
||||
|
||||
Scénario: Timeout upload après 30 minutes
|
||||
Étant donné que mon upload dure plus de 30 minutes
|
||||
Quand le timeout est atteint
|
||||
Alors l'upload est annulé
|
||||
Et je vois le message "Upload interrompu, veuillez réessayer"
|
||||
Et je peux reprendre l'upload
|
||||
|
||||
Scénario: Reprise upload après interruption réseau
|
||||
Étant donné que mon upload a échoué à 75%
|
||||
Quand je clique sur "Reprendre"
|
||||
Alors l'upload reprend à partir de 75%
|
||||
Et le fichier partiel est conservé temporairement
|
||||
|
||||
Scénario: Limite de 3 uploads simultanés
|
||||
Étant donné que j'ai déjà 3 uploads en cours
|
||||
Quand j'essaie d'uploader un 4ème fichier
|
||||
Alors l'upload est refusé
|
||||
Et je vois le message "Maximum 3 uploads simultanés. Attendez qu'un upload se termine."
|
||||
|
||||
Scénario: Détection fichier corrompu pendant upload
|
||||
Étant donné que j'uploade un fichier MP3 corrompu
|
||||
Quand le backend détecte la corruption
|
||||
Alors l'upload est rejeté immédiatement
|
||||
Et je vois le message "Fichier corrompu, veuillez vérifier votre fichier"
|
||||
Et je n'attends pas la fin de l'encodage
|
||||
|
||||
Scénario: Fichier original conservé pendant 48h après échec
|
||||
Étant donné que mon encodage a échoué
|
||||
Quand je clique sur "Réessayer" dans les 48h
|
||||
Alors le fichier original est encore disponible
|
||||
Et un nouvel encodage démarre sans réupload
|
||||
|
||||
Scénario: Fichier original supprimé après 48h
|
||||
Étant donné que mon encodage a échoué il y a 48h
|
||||
Quand j'essaie de réessayer
|
||||
Alors je dois réuploader le fichier
|
||||
Et je vois le message "Fichier original expiré, veuillez réuploader"
|
||||
@@ -0,0 +1,62 @@
|
||||
# language: fr
|
||||
|
||||
@api @content-creation @copyright @mvp
|
||||
Fonctionnalité: Validation et détection automatique de musique
|
||||
|
||||
En tant que plateforme
|
||||
Je veux détecter automatiquement la musique protégée
|
||||
Afin de respecter les droits d'auteur
|
||||
|
||||
Scénario: Analyse audio automatique lors de l'upload
|
||||
Étant donné un créateur upload un fichier audio
|
||||
Quand le fichier est uploadé sur S3
|
||||
Alors une tâche asynchrone d'analyse est lancée
|
||||
Et l'audio est comparé à la base ACRCloud
|
||||
Et les résultats sont disponibles en < 30 secondes
|
||||
Et un événement "MUSIC_ANALYSIS_STARTED" est enregistré
|
||||
|
||||
Scénario: Identification précise avec métadonnées
|
||||
Étant donné un audio analysé
|
||||
Quand de la musique est détectée
|
||||
Alors le système retourne:
|
||||
| Métadonnée | Exemple |
|
||||
| Titre | Bohemian Rhapsody |
|
||||
| Artiste | Queen |
|
||||
| Album | A Night at the Opera |
|
||||
| ISRC | GBUM71029604 |
|
||||
| Timestamp | 00:02:15 - 00:02:43 |
|
||||
| Durée | 28 secondes |
|
||||
| Confiance | 98% |
|
||||
Et un événement "MUSIC_IDENTIFIED" est enregistré
|
||||
|
||||
Scénario: Faux positifs - validation manuelle
|
||||
Étant donné un audio avec détection incertaine (confiance < 80%)
|
||||
Quand le créateur conteste la détection
|
||||
Alors une review manuelle est déclenchée
|
||||
Et un modérateur écoute et valide
|
||||
Et un événement "MUSIC_MANUAL_REVIEW_REQUESTED" est enregistré
|
||||
|
||||
Scénario: Mise en queue pendant l'analyse
|
||||
Étant donné un créateur qui upload un audio
|
||||
Quand l'analyse est en cours
|
||||
Alors le statut affiche "Analyse en cours..."
|
||||
Et le créateur peut continuer la création
|
||||
Et est notifié quand l'analyse est terminée
|
||||
Et un événement "MUSIC_ANALYSIS_PENDING" est enregistré
|
||||
|
||||
Scénario: Détection de musique transformée (pitch, tempo)
|
||||
Étant donné un audio avec musique modifiée (accélérée/ralentie)
|
||||
Quand l'analyse s'exécute
|
||||
Alors le système détecte quand même le morceau original
|
||||
Et applique les mêmes règles de fair use
|
||||
Et un événement "MODIFIED_MUSIC_DETECTED" est enregistré
|
||||
|
||||
Scénario: Statistiques de détection pour la plateforme
|
||||
Étant donné que 10 000 audios ont été analysés
|
||||
Alors les indicateurs suivants sont disponibles:
|
||||
| Métrique | Valeur |
|
||||
| Taux de détection de musique | 35% |
|
||||
| Taux de conformité fair use | 88% |
|
||||
| Taux de faux positifs | 2% |
|
||||
| Temps moyen d'analyse | 18s |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
@@ -0,0 +1,217 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Validation des 3 premiers contenus
|
||||
En tant que nouveau créateur
|
||||
Je veux que mes 3 premiers contenus soient validés
|
||||
Afin de devenir créateur vérifié
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et que je suis un nouveau créateur
|
||||
|
||||
Scénario: Premier contenu passe en file de validation
|
||||
Quand je publie mon premier contenu
|
||||
Alors le contenu passe en file d'attente modération
|
||||
Et je vois le message "Votre contenu est en cours de validation (24-48h)"
|
||||
Et le contenu n'est pas encore visible publiquement
|
||||
|
||||
Scénario: Deuxième contenu passe également en validation
|
||||
Étant donné que mon premier contenu a été validé
|
||||
Quand je publie mon deuxième contenu
|
||||
Alors le contenu passe en file d'attente modération
|
||||
Et le délai estimé est 24-48h
|
||||
|
||||
Scénario: Troisième contenu - dernière validation
|
||||
Étant donné que mes 2 premiers contenus ont été validés
|
||||
Quand je publie mon troisième contenu
|
||||
Alors le contenu passe en file d'attente modération
|
||||
Et je vois "Dernière validation avant statut vérifié ✓"
|
||||
|
||||
Scénario: Modérateur écoute 30 secondes du contenu
|
||||
Étant donné qu'un contenu est en file de validation
|
||||
Quand le modérateur junior l'examine
|
||||
Alors il écoute les 30 premières secondes
|
||||
Ou 15 secondes à vitesse 2x
|
||||
Et il vérifie les métadonnées
|
||||
|
||||
Scénario: Validation - Qualité audio acceptable
|
||||
Étant donné qu'un contenu a une qualité audio claire
|
||||
Quand le modérateur l'écoute
|
||||
Alors il vérifie que l'audio est compréhensible
|
||||
Et qu'il n'y a pas de grésillement excessif
|
||||
|
||||
Scénario: Rejet - Qualité audio insuffisante
|
||||
Étant donné qu'un contenu a un audio très grésillant
|
||||
Quand le modérateur l'écoute
|
||||
Alors le contenu est rejeté
|
||||
Et la raison est "Qualité audio insuffisante"
|
||||
|
||||
Scénario: Validation - Respect des règles
|
||||
Étant donné qu'un contenu respecte les règles
|
||||
Quand le modérateur l'examine
|
||||
Alors il vérifie qu'il n'y a pas de contenu prohibé:
|
||||
| type prohibé |
|
||||
| Haine |
|
||||
| Violence |
|
||||
| Spam |
|
||||
| Illégalité |
|
||||
|
||||
Scénario: Rejet - Contenu haineux détecté
|
||||
Étant donné qu'un contenu contient des propos haineux
|
||||
Quand le modérateur l'écoute
|
||||
Alors le contenu est rejeté immédiatement
|
||||
Et la raison est "Contenu haineux (violation des règles)"
|
||||
Et le créateur peut recevoir un strike
|
||||
|
||||
Scénario: Validation - Classification âge cohérente
|
||||
Étant donné qu'un contenu familial est classé "Tout public"
|
||||
Quand le modérateur l'écoute
|
||||
Alors il vérifie que la classification correspond au contenu
|
||||
Et le contenu est accepté
|
||||
|
||||
Scénario: Rejet - Classification incorrecte
|
||||
Étant donné qu'un contenu adulte est classé "Tout public"
|
||||
Quand le modérateur détecte l'incohérence
|
||||
Alors le contenu est rejeté
|
||||
Et la raison est "Classification d'âge incorrecte"
|
||||
|
||||
Scénario: Validation - Tags pertinents
|
||||
Étant donné qu'un contenu sur l'automobile est tagué "Automobile", "Technologie"
|
||||
Quand le modérateur vérifie les tags
|
||||
Alors il confirme que les tags correspondent au contenu
|
||||
Et le contenu est accepté
|
||||
|
||||
Scénario: Rejet - Tags non pertinents
|
||||
Étant donné qu'un contenu musical est tagué "Automobile", "Sport"
|
||||
Quand le modérateur détecte l'incohérence
|
||||
Alors le contenu est rejeté
|
||||
Et la raison est "Tags non pertinents avec le contenu"
|
||||
|
||||
Scénario: Validation - Zone diffusion cohérente
|
||||
Étant donné qu'un audio-guide de la Tour Eiffel est en "Point GPS" Paris
|
||||
Quand le modérateur vérifie la cohérence
|
||||
Alors la zone est appropriée
|
||||
Et le contenu est accepté
|
||||
|
||||
Scénario: Rejet - Zone incohérente
|
||||
Étant donné qu'un audio-guide de la Tour Eiffel est en zone "National"
|
||||
Quand le modérateur détecte l'incohérence
|
||||
Alors le contenu est rejeté
|
||||
Et la raison est "Zone de diffusion incohérente (devrait être Point GPS)"
|
||||
|
||||
Scénario: Délai de validation 24-48h jours ouvrés
|
||||
Étant donné que je publie un contenu un lundi
|
||||
Quand le contenu entre en file de validation
|
||||
Alors le délai estimé est 24-48h (mercredi maximum)
|
||||
|
||||
Scénario: Délai étendu le weekend
|
||||
Étant donné que je publie un contenu un vendredi soir
|
||||
Quand le contenu entre en file de validation
|
||||
Alors le délai peut atteindre 72h (lundi)
|
||||
Et je vois "Validation en cours, délai 24-72h (weekend)"
|
||||
|
||||
Scénario: Priorité FIFO (First In First Out)
|
||||
Étant donné que 10 contenus sont en file de validation
|
||||
Quand les modérateurs traitent la file
|
||||
Alors les contenus sont traités dans l'ordre d'arrivée
|
||||
Et pas de traitement prioritaire
|
||||
|
||||
Scénario: Notification acceptation
|
||||
Étant donné que mon contenu est validé et accepté
|
||||
Alors je reçois un email "✅ Votre contenu '[Titre]' est en ligne !"
|
||||
Et je reçois une notification push
|
||||
Et je vois un lien direct vers le contenu
|
||||
|
||||
Scénario: Compteur de validation
|
||||
Étant donné que mon premier contenu est accepté
|
||||
Alors je vois "1/3 contenus validés pour devenir créateur vérifié"
|
||||
Quand mon deuxième contenu est accepté
|
||||
Alors je vois "2/3 contenus validés pour devenir créateur vérifié"
|
||||
|
||||
Scénario: Notification refus avec raison détaillée
|
||||
Étant donné que mon contenu est rejeté
|
||||
Alors je reçois un email "❌ Contenu '[Titre]' refusé"
|
||||
Et je reçois une notification push
|
||||
Et je vois la raison exacte: "Qualité audio insuffisante"
|
||||
Et je vois un lien vers les règles de publication
|
||||
|
||||
Scénario: Possibilité de correction et resoumission
|
||||
Étant donné que mon contenu a été rejeté pour "Tags non pertinents"
|
||||
Quand je corrige les tags
|
||||
Et que je resoumets le contenu
|
||||
Alors le contenu repasse en file de validation
|
||||
Et une nouvelle validation est effectuée
|
||||
|
||||
Scénario: Après 3 validations - Statut vérifié obtenu
|
||||
Étant donné que mes 3 premiers contenus ont été validés
|
||||
Alors j'obtiens le statut "Créateur Vérifié"
|
||||
Et je reçois une notification "🎉 Vous êtes maintenant créateur vérifié !"
|
||||
Et un badge ✓ apparaît sur mon profil
|
||||
|
||||
Scénario: Badge vérifié visible publiquement
|
||||
Étant donné que j'ai le statut vérifié
|
||||
Quand un utilisateur consulte mon profil
|
||||
Alors il voit le badge ✓ à côté de mon pseudo
|
||||
Et une mention "Créateur vérifié"
|
||||
|
||||
Scénario: Contenus futurs publiés immédiatement
|
||||
Étant donné que je suis créateur vérifié
|
||||
Quand je publie un 4ème contenu
|
||||
Alors le contenu est publié immédiatement
|
||||
Et il n'y a pas de validation préalable
|
||||
Et je vois "✅ Contenu publié"
|
||||
|
||||
Scénario: Modération a posteriori uniquement
|
||||
Étant donné que je suis créateur vérifié
|
||||
Et que je publie un contenu
|
||||
Quand le contenu est en ligne
|
||||
Alors il peut être signalé par les utilisateurs
|
||||
Et sera modéré uniquement si signalé
|
||||
|
||||
Scénario: Interface modérateur - Queue de contenus
|
||||
Étant donné que je suis un modérateur junior
|
||||
Quand j'accède à l'interface de modération
|
||||
Alors je vois la file des contenus à valider
|
||||
Et je vois le nombre total en attente
|
||||
Et les contenus sont triés par ordre FIFO
|
||||
|
||||
Scénario: Interface modérateur - Écoute accélérée
|
||||
Étant donné que je suis un modérateur
|
||||
Quand j'écoute un contenu de 30 secondes
|
||||
Alors je peux choisir la vitesse 1.5x ou 2.0x
|
||||
Et je termine l'écoute en 15 secondes à 2x
|
||||
Et ma productivité est doublée
|
||||
|
||||
Scénario: Interface modérateur - Raccourcis clavier
|
||||
Étant donné que je modère un contenu
|
||||
Quand j'utilise les raccourcis clavier
|
||||
Alors je peux:
|
||||
| touche | action |
|
||||
| A | Accepter |
|
||||
| R | Rejeter |
|
||||
| Espace | Play/Pause |
|
||||
Et la modération est accélérée
|
||||
|
||||
Scénario: Historique créateur visible
|
||||
Étant donné qu'un créateur soumet son 2ème contenu
|
||||
Quand le modérateur examine le contenu
|
||||
Alors il voit l'historique:
|
||||
| contenu | statut |
|
||||
| Contenu 1 | Validé |
|
||||
| Contenu 2 | En cours|
|
||||
Et il peut juger la cohérence du créateur
|
||||
|
||||
Scénario: Temps de modération estimé 1.5 min/créateur
|
||||
Étant donné qu'un créateur soumet 3 contenus
|
||||
Quand les modérateurs traitent ces contenus
|
||||
Alors le temps total est environ:
|
||||
| action | temps |
|
||||
| Écoute 30s × 3 | 90s |
|
||||
| Vérification metadata| 15s |
|
||||
| Décision | 5s |
|
||||
| Total | 110s |
|
||||
|
||||
Scénario: Verrouillage contenu pendant traitement modérateur
|
||||
Étant donné que le modérateur A ouvre un contenu pour validation
|
||||
Quand le modérateur B essaie d'ouvrir le même contenu
|
||||
Alors le modérateur B voit le message "Contenu en cours de traitement par [Modérateur A]"
|
||||
Et le contenu est verrouillé pour éviter doublon
|
||||
Reference in New Issue
Block a user