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:
36
docs/domains/advertising/README.md
Normal file
36
docs/domains/advertising/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Domaine : Advertising
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Le domaine **Advertising** gère la diffusion de publicités audio ciblées. C'est un **Generic Subdomain** qui constitue une source de revenus importante pour la plateforme.
|
||||
|
||||
## Responsabilités
|
||||
|
||||
- **Campagnes publicitaires** : Création et gestion des campagnes
|
||||
- **Ciblage** : Ciblage géographique et par centres d'intérêt
|
||||
- **Métriques** : Suivi des impressions, écoutes et performances
|
||||
- **Insertion dynamique** : Insertion de publicités dans les flux audio
|
||||
|
||||
## Règles métier
|
||||
|
||||
- [Publicités](rules/publicites.md)
|
||||
|
||||
## Modèle de données
|
||||
|
||||
- [Diagramme entités publicités](entities/modele-publicites.md) - Entités : AD_CAMPAIGNS, AD_METRICS, AD_IMPRESSIONS
|
||||
|
||||
## Ubiquitous Language
|
||||
|
||||
**Termes métier du domaine** :
|
||||
- **Ad Campaign** : Campagne publicitaire avec budget et durée
|
||||
- **Ad Impression** : Affichage/lecture d'une publicité
|
||||
- **Ad Targeting** : Critères de ciblage (geo + intérêts)
|
||||
- **CPM (Cost Per Mille)** : Coût pour 1000 impressions
|
||||
- **Ad Insertion** : Insertion dynamique dans le flux audio
|
||||
- **Skip Rate** : Taux de publicités sautées par les utilisateurs
|
||||
|
||||
## Dépendances
|
||||
|
||||
- ✅ Dépend de : `_shared` (users, listening history)
|
||||
- ✅ Dépend de : `recommendation` (ciblage par intérêts)
|
||||
- ⚠️ Bloqué par : `premium` (pas de pub pour abonnés premium)
|
||||
67
docs/domains/advertising/entities/modele-publicites.md
Normal file
67
docs/domains/advertising/entities/modele-publicites.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Modèle de données - Publicités
|
||||
|
||||
📖 Voir [Règles métier - Section 16 : Publicités](../rules/publicites.md) | [Entités globales](../../_shared/entities/modele-global.md)
|
||||
|
||||
## Diagramme
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
AD_CAMPAIGNS }o--|| USERS : "créée par"
|
||||
AD_CAMPAIGNS ||--o{ AD_METRICS : "métriques"
|
||||
AD_CAMPAIGNS ||--o{ AD_IMPRESSIONS : "diffusions"
|
||||
|
||||
AD_IMPRESSIONS }o--|| USERS : "vue par"
|
||||
AD_IMPRESSIONS }o--|| AD_CAMPAIGNS : "campagne"
|
||||
|
||||
AD_CAMPAIGNS {
|
||||
uuid id PK
|
||||
uuid advertiser_id FK
|
||||
string title
|
||||
string audio_url
|
||||
int duration_seconds
|
||||
string status
|
||||
string targeting_geo_type
|
||||
jsonb targeting_geo_data
|
||||
jsonb targeting_hours
|
||||
string[] targeting_interests
|
||||
string targeting_age_rating
|
||||
decimal budget_total_euros
|
||||
decimal budget_remaining_euros
|
||||
decimal cost_per_listen_euros
|
||||
timestamp start_date
|
||||
timestamp end_date
|
||||
timestamp validated_at
|
||||
timestamp created_at
|
||||
}
|
||||
|
||||
AD_METRICS {
|
||||
uuid id PK
|
||||
uuid campaign_id FK
|
||||
date metric_date
|
||||
int impressions_count
|
||||
int complete_listens_count
|
||||
int skips_count
|
||||
decimal avg_listen_duration_seconds
|
||||
int likes_count
|
||||
decimal total_cost_euros
|
||||
timestamp computed_at
|
||||
}
|
||||
|
||||
AD_IMPRESSIONS {
|
||||
uuid id PK
|
||||
uuid campaign_id FK
|
||||
uuid user_id FK
|
||||
decimal completion_rate
|
||||
boolean was_skipped
|
||||
int listen_duration_seconds
|
||||
timestamp displayed_at
|
||||
}
|
||||
```
|
||||
|
||||
## Légende
|
||||
|
||||
**Entités publicités** :
|
||||
|
||||
- **AD_CAMPAIGNS** : Campagnes publicitaires - Status : `draft`, `pending_validation`, `validated`, `active`, `paused`, `completed`, `cancelled` - Targeting_geo_type : `point` (GPS + rayon), `city`, `department`, `region`, `national` - Targeting_hours : Array heures locales [7, 8, 9, 17, 18, 19] (heure locale utilisateur) - Budget : Prépaiement obligatoire, déduction 0.05€/écoute complète ou 0.02€/skip après délai min - Validation manuelle obligatoire 24-48h
|
||||
- **AD_METRICS** : Métriques agrégées par jour - Calcul quotidien (batch nocturne) - Dashboard temps réel publicitaire - Export CSV/Excel disponible
|
||||
- **AD_IMPRESSIONS** : Impressions individuelles - Completion_rate ≥0.8 = écoute complète (facturée 0.05€) - Skip après délai min 5s = partiel (facturé 0.02€) - Skip <5s = non facturé (0€) - Rotation max 3 fois/jour par utilisateur - Limite 6 pubs/h par utilisateur
|
||||
@@ -0,0 +1,254 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Création de campagnes publicitaires
|
||||
En tant que publicitaire
|
||||
Je veux créer des campagnes avec ciblage précis et maîtrise du budget
|
||||
Afin d'optimiser mes investissements publicitaires
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et qu'un compte publicitaire est créé et vérifié
|
||||
|
||||
Scénario: Création d'une campagne publicitaire complète
|
||||
Étant donné que je suis connecté en tant que publicitaire
|
||||
Quand je crée une nouvelle campagne avec les paramètres:
|
||||
| Paramètre | Valeur |
|
||||
| Budget total | 300€ |
|
||||
| Date début | 2026-02-01 |
|
||||
| Date fin | 2026-02-14 |
|
||||
| Zone géographique | Département du Var |
|
||||
| Plages horaires | 7h-9h, 17h-19h |
|
||||
| Tags ciblés | Automobile, Voyage |
|
||||
| Tranche d'âge | 18+ |
|
||||
Alors la campagne est créée avec succès
|
||||
Et le budget quotidien calculé est de 21.43€/jour
|
||||
Et les diffusions estimées sont de ~430 écoutes complètes
|
||||
Et un statut "En attente de validation" est assigné
|
||||
|
||||
Scénario: Budget minimum 50€ requis
|
||||
Étant donné que je crée une nouvelle campagne
|
||||
Quand je définis un budget de 40€
|
||||
Alors une erreur s'affiche: "Budget minimum requis: 50€"
|
||||
Et la campagne n'est pas créée
|
||||
|
||||
Scénario: Budget de 50€ exactement accepté
|
||||
Étant donné que je crée une nouvelle campagne
|
||||
Quand je définis un budget de 50€
|
||||
Alors la campagne est créée avec succès
|
||||
Et aucune erreur n'est affichée
|
||||
|
||||
Scénario: Calcul automatique du budget quotidien
|
||||
Étant donné une campagne avec:
|
||||
| Budget total | 300€ |
|
||||
| Durée | 14 j |
|
||||
Quand le système calcule le budget quotidien
|
||||
Alors le budget/jour est de 21.43€
|
||||
Et le nombre estimé de diffusions/jour est de 430 (à 0.05€/écoute)
|
||||
|
||||
Scénario: Ciblage géographique point GPS précis
|
||||
Étant donné que je crée une campagne
|
||||
Quand je sélectionne "Point GPS" avec coordonnées (43.1234, 5.9234)
|
||||
Et que je définis un rayon de 5km
|
||||
Alors la campagne cible uniquement les utilisateurs dans ce rayon
|
||||
Et la zone est représentée par un cercle sur la carte
|
||||
|
||||
Scénario: Ciblage géographique ville
|
||||
Étant donné que je crée une campagne
|
||||
Quand je sélectionne "Ville" et choisis "Marseille"
|
||||
Alors la campagne cible tous les utilisateurs dans la commune de Marseille
|
||||
Et les limites administratives sont affichées sur la carte
|
||||
|
||||
Scénario: Ciblage géographique département
|
||||
Étant donné que je crée une campagne
|
||||
Quand je sélectionne "Département" et choisis "Var (83)"
|
||||
Alors la campagne cible tout le département du Var
|
||||
Et une estimation de population cible est affichée
|
||||
|
||||
Scénario: Ciblage géographique région
|
||||
Étant donné que je crée une campagne
|
||||
Quand je sélectionne "Région" et choisis "Provence-Alpes-Côte d'Azur"
|
||||
Alors la campagne cible toute la région PACA
|
||||
Et l'estimation de population cible est mise à jour
|
||||
|
||||
Scénario: Ciblage géographique national
|
||||
Étant donné que je crée une campagne
|
||||
Quand je sélectionne "National"
|
||||
Alors la campagne cible tous les utilisateurs en France
|
||||
Et aucune limite géographique n'est appliquée
|
||||
|
||||
Scénario: Ciblage horaire plages multiples
|
||||
Étant donné que je crée une campagne
|
||||
Quand je définis les plages horaires:
|
||||
| Plage |
|
||||
| 7h-9h |
|
||||
| 12h-14h |
|
||||
| 17h-19h |
|
||||
Alors la publicité est diffusée uniquement pendant ces plages
|
||||
Et elle n'est jamais diffusée en dehors (ex: 10h, 15h, 20h)
|
||||
|
||||
Scénario: Ciblage horaire toute la journée
|
||||
Étant donné que je crée une campagne
|
||||
Quand je ne définis aucune plage horaire spécifique
|
||||
Alors la publicité est diffusée 24h/24
|
||||
Et aucune restriction horaire n'est appliquée
|
||||
|
||||
Scénario: Ciblage par centres d'intérêt
|
||||
Étant donné que je crée une campagne pour un garage automobile
|
||||
Quand je sélectionne les tags:
|
||||
| Tag |
|
||||
| Automobile |
|
||||
| Mécanique |
|
||||
| Sport |
|
||||
Alors la publicité est prioritaire pour les utilisateurs avec jauges élevées sur ces tags
|
||||
Et elle peut quand même être diffusée à d'autres utilisateurs (ciblage non exclusif)
|
||||
|
||||
Scénario: Classification d'âge obligatoire
|
||||
Étant donné que je crée une campagne
|
||||
Quand j'essaie de valider sans sélectionner une tranche d'âge
|
||||
Alors une erreur s'affiche: "Classification d'âge obligatoire"
|
||||
Et les options proposées sont:
|
||||
| Option |
|
||||
| Tout public |
|
||||
| 13+ |
|
||||
| 16+ |
|
||||
| 18+ |
|
||||
|
||||
Scénario: Upload audio publicitaire formats acceptés
|
||||
Étant donné que je crée une campagne
|
||||
Quand j'upload un fichier audio format MP3
|
||||
Alors le fichier est accepté
|
||||
Quand j'upload un fichier audio format AAC (.aac ou .m4a)
|
||||
Alors le fichier est accepté
|
||||
Quand j'upload un fichier audio format WAV
|
||||
Alors une erreur s'affiche: "Format non supporté. Utilisez MP3 ou AAC"
|
||||
|
||||
Scénario: Durée audio publicitaire validée
|
||||
Étant donné que je crée une campagne
|
||||
Quand j'upload un audio de 8 secondes
|
||||
Alors une erreur s'affiche: "Durée minimale: 10 secondes"
|
||||
Quand j'upload un audio de 65 secondes
|
||||
Alors une erreur s'affiche: "Durée maximale: 60 secondes"
|
||||
Quand j'upload un audio de 30 secondes
|
||||
Alors le fichier est accepté
|
||||
|
||||
Scénario: Prépaiement obligatoire via Mangopay
|
||||
Étant donné que j'ai configuré une campagne à 300€
|
||||
Quand j'arrive à l'étape de paiement
|
||||
Alors je dois payer les 300€ avant validation
|
||||
Et le paiement est traité via Mangopay
|
||||
Et seule la carte bancaire est acceptée
|
||||
|
||||
Scénario: Recharge automatique optionnelle
|
||||
Étant donné que j'ai une campagne active
|
||||
Quand je configure la recharge automatique à 10% du budget
|
||||
Alors si le budget restant passe sous 30€ (10% de 300€)
|
||||
Et que la campagne recharge automatiquement 100€
|
||||
Et ma carte bancaire est débitée de 100€
|
||||
Et le budget total passe à 130€
|
||||
|
||||
Scénario: Désactivation recharge automatique
|
||||
Étant donné que j'ai activé la recharge automatique
|
||||
Quand je désactive cette option
|
||||
Alors aucune recharge ne se produit automatiquement
|
||||
Et la campagne s'arrête quand le budget atteint 0€
|
||||
|
||||
Scénario: Étalement budget sur période longue
|
||||
Étant donné une campagne avec:
|
||||
| Budget total | 1000€ |
|
||||
| Durée | 30 j |
|
||||
Quand le système calcule l'étalement
|
||||
Alors le budget/jour est de 33.33€
|
||||
Et si le budget se consomme plus vite (ex: 50€/jour)
|
||||
Alors une alerte "Budget épuisé dans 10 jours" est envoyée
|
||||
|
||||
Scénario: Estimation population cible selon zone
|
||||
Étant donné que je sélectionne la zone "Marseille"
|
||||
Quand le système calcule la population cible
|
||||
Alors l'estimation affichée est "~15 000 utilisateurs potentiels"
|
||||
Et un message "Estimation basée sur utilisateurs actifs dans la zone" s'affiche
|
||||
|
||||
Scénario: Campagne avec date de début différée
|
||||
Étant donné que je crée une campagne
|
||||
Quand je définis la date de début au 2026-03-01 (dans 1 mois)
|
||||
Alors la campagne a le statut "Programmée"
|
||||
Et elle démarre automatiquement le 2026-03-01 à 00h00
|
||||
Et le budget n'est pas consommé avant cette date
|
||||
|
||||
Scénario: Interface self-service accessible
|
||||
Étant donné que je suis un publicitaire
|
||||
Quand j'accède à l'interface publicitaire
|
||||
Alors je peux créer une campagne sans contact commercial RoadWave
|
||||
Et toutes les options sont configurables en autonomie
|
||||
Et un tutoriel guidé est disponible (première utilisation)
|
||||
|
||||
Scénario: Aperçu zone ciblée sur carte interactive
|
||||
Étant donné que je configure une zone géographique
|
||||
Quand je sélectionne "Département du Var"
|
||||
Alors une carte Leaflet affiche les limites du département en surbrillance
|
||||
Et un compteur "~50 000 utilisateurs actifs" est affiché
|
||||
Et je peux zoomer/dézoomer pour visualiser la zone
|
||||
|
||||
Scénario: Tags multiples pour ciblage affiné
|
||||
Étant donné que je crée une campagne pour un restaurant
|
||||
Quand je sélectionne les tags:
|
||||
| Tag |
|
||||
| Gastronomie |
|
||||
| Tourisme |
|
||||
| Famille |
|
||||
Alors la publicité est prioritaire pour utilisateurs intéressés par ces 3 thèmes
|
||||
Et le score de ciblage combine les 3 jauges d'intérêt
|
||||
|
||||
Scénario: Validation des dates de campagne
|
||||
Étant donné que je crée une campagne
|
||||
Quand je définis une date de début postérieure à la date de fin
|
||||
Alors une erreur s'affiche: "Date de fin doit être après date de début"
|
||||
Et la campagne n'est pas créée
|
||||
|
||||
Scénario: Durée minimale de campagne
|
||||
Étant donné que je crée une campagne
|
||||
Quand je définis une durée de moins de 24 heures
|
||||
Alors une erreur s'affiche: "Durée minimale: 1 jour"
|
||||
Et je dois ajuster les dates
|
||||
|
||||
Scénario: Durée maximale de campagne
|
||||
Étant donné que je crée une campagne
|
||||
Quand je définis une durée de plus de 90 jours
|
||||
Alors une erreur s'affiche: "Durée maximale: 90 jours"
|
||||
Et je dois ajuster les dates ou créer plusieurs campagnes
|
||||
|
||||
Plan du Scénario: Calcul budget quotidien selon durée
|
||||
Étant donné une campagne avec un budget de <budget>€
|
||||
Quand la durée est de <duree> jours
|
||||
Alors le budget quotidien est de <budget_jour>€/jour
|
||||
|
||||
Exemples:
|
||||
| budget | duree | budget_jour |
|
||||
| 100 | 10 | 10.00 |
|
||||
| 300 | 14 | 21.43 |
|
||||
| 500 | 30 | 16.67 |
|
||||
| 1000 | 60 | 16.67 |
|
||||
|
||||
Plan du Scénario: Estimation diffusions selon budget
|
||||
Étant donné un budget quotidien de <budget_jour>€
|
||||
Quand le coût par écoute complète est 0.05€
|
||||
Alors le nombre estimé de diffusions/jour est <diffusions>
|
||||
|
||||
Exemples:
|
||||
| budget_jour | diffusions |
|
||||
| 10.00 | 200 |
|
||||
| 21.43 | 429 |
|
||||
| 50.00 | 1000 |
|
||||
| 100.00 | 2000 |
|
||||
|
||||
Plan du Scénario: Formats audio acceptés/rejetés
|
||||
Étant donné que j'upload un fichier <fichier>
|
||||
Quand le format est <format>
|
||||
Alors le résultat est <resultat>
|
||||
|
||||
Exemples:
|
||||
| fichier | format | resultat |
|
||||
| pub.mp3 | MP3 | accepté |
|
||||
| pub.aac | AAC | accepté |
|
||||
| pub.m4a | AAC | accepté |
|
||||
| pub.wav | WAV | rejeté |
|
||||
| pub.ogg | OGG | rejeté |
|
||||
| pub.flac | FLAC | rejeté |
|
||||
@@ -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 |
|
||||
@@ -0,0 +1,238 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Ciblage horaire publicités et gestion fuseaux horaires
|
||||
En tant que publicitaire
|
||||
Je veux cibler mes publicités sur des plages horaires en heure locale utilisateur
|
||||
Afin d'optimiser mes campagnes selon les moments de la journée (rush matin/soir)
|
||||
|
||||
Contexte:
|
||||
Étant donné qu'un publicitaire crée une campagne publicitaire
|
||||
|
||||
# Règle 1 : Ciblage horaire = Heure locale utilisateur
|
||||
|
||||
Scénario: Campagne "7h-9h" diffuse selon heure locale de chaque utilisateur
|
||||
Étant donné qu'une campagne est configurée avec plage horaire "7h-9h"
|
||||
Et que nous sommes le 7 février 2026 à 8h00 UTC
|
||||
Quand le système vérifie la diffusion pour différents utilisateurs:
|
||||
| utilisateur | localisation | fuseau horaire | heure locale | diffusion ? |
|
||||
| User Marseille | Marseille | Europe/Paris | 9h00 | ✅ Oui |
|
||||
| User Guadeloupe | Pointe-à-Pitre | America/Guadeloupe | 4h00 | ❌ Non |
|
||||
| User Réunion | Saint-Denis | Indian/Reunion | 12h00 | ❌ Non |
|
||||
| User Lyon | Lyon | Europe/Paris | 9h00 | ✅ Oui |
|
||||
Alors la pub est diffusée uniquement aux utilisateurs dans la plage 7h-9h leur heure locale
|
||||
|
||||
Scénario: Campagne "17h-19h" (rush soir) - Heure locale de chaque utilisateur
|
||||
Étant donné qu'une campagne est configurée avec plage horaire "17h-19h"
|
||||
Et que nous sommes le 7 février 2026 à 17h30 UTC
|
||||
Quand le système vérifie la diffusion pour:
|
||||
| utilisateur | fuseau horaire | heure locale | diffusion ? |
|
||||
| User Paris | Europe/Paris | 18h30 | ✅ Oui |
|
||||
| User Martinique | America/Martinique | 13h30 | ❌ Non |
|
||||
| User Réunion | Indian/Reunion | 21h30 | ❌ Non |
|
||||
Alors la pub est diffusée uniquement à User Paris (18h30 dans 17h-19h)
|
||||
|
||||
Scénario: Campagne 24/7 (toute la journée) - Pas de restriction horaire
|
||||
Étant donné qu'une campagne n'a AUCUNE restriction horaire
|
||||
Quand le système vérifie la diffusion
|
||||
Alors la pub est diffusée à tout moment (0h-23h)
|
||||
Et tous les utilisateurs sont éligibles quelle que soit l'heure locale
|
||||
|
||||
# Détection fuseau horaire utilisateur
|
||||
|
||||
Scénario: Détection fuseau via GPS (méthode primaire)
|
||||
Étant donné qu'un utilisateur a le GPS activé
|
||||
Et que sa position GPS est (latitude: 48.8566, longitude: 2.3522)
|
||||
Quand le système détecte le fuseau horaire
|
||||
Alors le fuseau horaire déterminé est "Europe/Paris"
|
||||
Et l'heure locale est calculée avec ce fuseau
|
||||
|
||||
Scénario: Détection fuseau via paramètres device (si GPS désactivé)
|
||||
Étant donné qu'un utilisateur a le GPS désactivé
|
||||
Mais que les paramètres OS indiquent fuseau "America/Guadeloupe"
|
||||
Quand le système détecte le fuseau horaire
|
||||
Alors le fuseau horaire utilisé est "America/Guadeloupe"
|
||||
Et l'heure locale est calculée avec ce fuseau
|
||||
|
||||
Scénario: Fallback IP geolocation (si GPS désactivé ET paramètres indisponibles)
|
||||
Étant donné qu'un utilisateur a le GPS désactivé
|
||||
Et que les paramètres device ne sont pas accessibles
|
||||
Mais que l'IP est géolocalisée à La Réunion
|
||||
Quand le système détecte le fuseau horaire
|
||||
Alors le fuseau horaire approximatif est "Indian/Reunion"
|
||||
Et l'heure locale est calculée avec ce fuseau
|
||||
|
||||
# Règle 2 : Ciblage "France" = Métropole + DOM
|
||||
|
||||
Scénario: Ciblage "France entière" inclut Métropole + DOM
|
||||
Étant donné qu'une campagne cible "France (nationale)"
|
||||
Quand le système vérifie les utilisateurs éligibles
|
||||
Alors les utilisateurs inclus sont:
|
||||
| zone | départements / territoires |
|
||||
| France métropolitaine | 96 départements (01 à 95, 2A, 2B, etc.) |
|
||||
| Guadeloupe | 971 |
|
||||
| Martinique | 972 |
|
||||
| Guyane | 973 |
|
||||
| Réunion | 974 |
|
||||
| Mayotte | 976 |
|
||||
|
||||
Scénario: Publicitaire affine ciblage "Région Provence-Alpes-Côte d'Azur"
|
||||
Étant donné qu'une campagne cible "Région Provence-Alpes-Côte d'Azur"
|
||||
Quand le système vérifie les utilisateurs éligibles
|
||||
Alors seuls les utilisateurs en Métropole dans cette région sont ciblés
|
||||
Et les utilisateurs DOM (Guadeloupe, Réunion, etc.) ne sont PAS ciblés
|
||||
|
||||
Scénario: Publicitaire affine ciblage "Département 971 (Guadeloupe)"
|
||||
Étant donné qu'une campagne cible "Département 971"
|
||||
Quand le système vérifie les utilisateurs éligibles
|
||||
Alors seuls les utilisateurs en Guadeloupe sont ciblés
|
||||
Et les utilisateurs Métropole ne sont PAS ciblés
|
||||
|
||||
Scénario: Publicitaire affine ciblage "Ville Pointe-à-Pitre"
|
||||
Étant donné qu'une campagne cible "Ville Pointe-à-Pitre"
|
||||
Quand le système vérifie les utilisateurs éligibles
|
||||
Alors seuls les utilisateurs à Pointe-à-Pitre (Guadeloupe) sont ciblés
|
||||
|
||||
# Interface publicitaire
|
||||
|
||||
Scénario: Interface création campagne - Note explicite sur inclusion DOM
|
||||
Étant donné qu'un publicitaire accède au formulaire de création campagne
|
||||
Quand il sélectionne "National (France entière)"
|
||||
Alors une note informative s'affiche:
|
||||
"""
|
||||
ℹ️ Note : "National (France entière)" inclut les DOM
|
||||
(Guadeloupe, Martinique, Réunion, Guyane, Mayotte)
|
||||
"""
|
||||
|
||||
Scénario: Interface - Liste déroulante ciblage géographique
|
||||
Étant donné qu'un publicitaire configure le ciblage géographique
|
||||
Quand il consulte la liste déroulante
|
||||
Alors les options disponibles sont:
|
||||
| option | description |
|
||||
| National (France entière) | Métropole + DOM |
|
||||
| Région | Ex: Provence-Alpes-Côte d'Azur (Métropole)|
|
||||
| Département | Ex: 13 (Métropole) ou 971 (Guadeloupe) |
|
||||
| Ville | Ex: Marseille, Pointe-à-Pitre |
|
||||
| Point GPS + rayon | Latitude/Longitude + rayon en km |
|
||||
|
||||
# Cas d'usage publicitaire
|
||||
|
||||
Scénario: Restaurant local Guadeloupe - Ciblage département 971 + horaires 12h-14h
|
||||
Étant donné qu'un restaurant à Pointe-à-Pitre crée une campagne
|
||||
Et que le ciblage est "Département 971 (Guadeloupe)"
|
||||
Et que les horaires sont "12h-14h" (rush déjeuner)
|
||||
Quand le système diffuse les pubs à 12h30
|
||||
Alors les utilisateurs Guadeloupe à 12h30 heure locale reçoivent la pub
|
||||
Et les utilisateurs Métropole ne reçoivent PAS la pub (hors zone géo)
|
||||
Et les utilisateurs Martinique ne reçoivent PAS la pub (hors zone géo)
|
||||
|
||||
Scénario: Assureur national - Ciblage France + horaires 7h-9h + 17h-19h
|
||||
Étant donné qu'un assureur national crée une campagne
|
||||
Et que le ciblage est "France (nationale)"
|
||||
Et que les horaires sont "7h-9h" et "17h-19h" (rush matin/soir)
|
||||
Quand le système diffuse les pubs
|
||||
Alors à 8h locale Marseille, User Marseille reçoit la pub
|
||||
Et à 8h locale Réunion, User Réunion reçoit la pub
|
||||
Et User Réunion reçoit la pub à 8h locale (= 5h métropole, mais c'est son rush matin)
|
||||
|
||||
Scénario: Utilisateur en vacances change de fuseau horaire
|
||||
Étant donné qu'un utilisateur habite Paris (Europe/Paris)
|
||||
Et qu'il part en vacances à La Réunion
|
||||
Et qu'il télécharge 50 contenus + pubs avant de partir
|
||||
Quand l'utilisateur écoute à 8h locale Réunion (device détecte fuseau)
|
||||
Alors le filtrage des pubs utilise l'heure locale Réunion (8h)
|
||||
Et les pubs ciblées "7h-9h" sont diffusées normalement
|
||||
|
||||
# Implémentation technique
|
||||
|
||||
Scénario: Calcul heure locale via PostgreSQL AT TIME ZONE
|
||||
Étant donné qu'une campagne a une plage horaire "7h-9h"
|
||||
Et qu'un utilisateur a le fuseau "Indian/Reunion" (UTC+4)
|
||||
Quand le backend vérifie l'éligibilité à 08h00 UTC
|
||||
Alors la requête SQL utilise:
|
||||
"""sql
|
||||
SELECT
|
||||
EXTRACT(HOUR FROM NOW() AT TIME ZONE 'Indian/Reunion') AS local_hour
|
||||
-- Résultat: 12 (8h UTC + 4h = 12h locale)
|
||||
"""
|
||||
Et local_hour = 12 n'est PAS dans [7, 8, 9], donc pas de diffusion
|
||||
|
||||
Scénario: Base IANA Time Zone pour conversion GPS → fuseau
|
||||
Étant donné qu'un utilisateur a GPS (48.8566, 2.3522)
|
||||
Quand le système convertit GPS → fuseau horaire
|
||||
Alors la base IANA Time Zone est utilisée
|
||||
Et le fuseau déterminé est "Europe/Paris"
|
||||
Et la base est mise à jour régulièrement (changements DST, fuseaux)
|
||||
|
||||
# Justification
|
||||
|
||||
Scénario: Comparaison avec standard industrie - Google Ads, Facebook Ads
|
||||
Étant donné qu'on compare avec Google Ads et Facebook Ads
|
||||
Quand on évalue le comportement du ciblage horaire
|
||||
Alors RoadWave suit le standard:
|
||||
| plateforme | ciblage horaire | référence temporelle | norme |
|
||||
| Google Ads | 7h-9h | Heure locale user | ✅ Standard |
|
||||
| Facebook Ads | 7h-9h | Heure locale user | ✅ Standard |
|
||||
| RoadWave | 7h-9h | Heure locale user | ✅ Standard |
|
||||
|
||||
Scénario: Avantages UX intuitive pour publicitaires
|
||||
Étant donné qu'un publicitaire configure "7h-9h"
|
||||
Quand il pense "rush matin"
|
||||
Alors il n'a pas besoin de comprendre UTC
|
||||
Et "7h-9h" signifie "matin partout en France"
|
||||
Et l'UX est intuitive:
|
||||
| avantage | description |
|
||||
| UX intuitive publicitaires | "7h-9h" = matin partout, pas UTC compliqué |
|
||||
| Équité géographique | Pas de discrimination DOM-TOM |
|
||||
| Simplicité technique | Détection automatique fuseau (GPS/device) |
|
||||
| Standard industrie | Même comportement Google/Facebook |
|
||||
|
||||
# Cas limites
|
||||
|
||||
Scénario: Utilisateur change de fuseau pendant campagne active
|
||||
Étant donné qu'un utilisateur écoute des pubs en métropole (Europe/Paris)
|
||||
Et qu'une campagne cible "7h-9h"
|
||||
Quand l'utilisateur part en vacances Réunion (Indian/Reunion)
|
||||
Alors le système détecte le nouveau fuseau horaire automatiquement
|
||||
Et les pubs "7h-9h" sont filtrées selon l'heure locale Réunion
|
||||
Et l'utilisateur reçoit les pubs à 7h-9h heure locale Réunion
|
||||
|
||||
Scénario: Changement heure d'été/hiver (DST) - Gestion automatique
|
||||
Étant donné qu'une campagne cible "7h-9h" en Europe/Paris
|
||||
Et que le changement heure d'été arrive (dernier dimanche mars)
|
||||
Quand l'heure passe de 2h à 3h (UTC+1 → UTC+2)
|
||||
Alors le système utilise automatiquement le nouveau décalage UTC
|
||||
Et les pubs "7h-9h" continuent de se diffuser à 7h-9h heure locale
|
||||
Et PostgreSQL AT TIME ZONE gère automatiquement le DST
|
||||
|
||||
# Métriques dashboard publicitaire
|
||||
|
||||
Scénario: Dashboard publicitaire - Répartition géographique diffusions
|
||||
Étant donné qu'une campagne "France (nationale)" + "7h-9h" est active
|
||||
Quand le publicitaire consulte le dashboard
|
||||
Alors la répartition géographique affiche:
|
||||
| zone | impressions | % total |
|
||||
| Île-de-France | 45,000 | 60% |
|
||||
| Provence-Alpes | 15,000 | 20% |
|
||||
| Guadeloupe | 3,000 | 4% |
|
||||
| Réunion | 4,500 | 6% |
|
||||
| Autres | 7,500 | 10% |
|
||||
|
||||
Scénario: Dashboard publicitaire - Répartition horaire diffusions
|
||||
Étant donné qu'une campagne "7h-9h" est active
|
||||
Quand le publicitaire consulte le dashboard
|
||||
Alors un graphique horaire affiche:
|
||||
| heure locale | impressions |
|
||||
| 7h | 12,000 |
|
||||
| 8h | 18,000 |
|
||||
| 9h | 5,000 |
|
||||
Et les impressions hors plage (autres heures) = 0
|
||||
|
||||
Scénario: Validation création campagne - Cohérence géo + horaires
|
||||
Étant donné qu'un publicitaire crée une campagne
|
||||
Et qu'il sélectionne "Département 971 (Guadeloupe)"
|
||||
Et qu'il configure horaires "7h-9h"
|
||||
Quand il valide la campagne
|
||||
Alors le système confirme:
|
||||
"""
|
||||
Votre campagne sera diffusée à 7h-9h heure locale Guadeloupe (UTC-4).
|
||||
Estimation: 2,500 impressions/jour.
|
||||
"""
|
||||
@@ -0,0 +1,361 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Gestion du budget et alertes publicitaires
|
||||
En tant que publicitaire
|
||||
Je veux suivre en temps réel mon budget et recevoir des alertes
|
||||
Afin de maîtriser mes dépenses et optimiser mes campagnes
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et qu'un compte publicitaire est connecté
|
||||
Et qu'une campagne active est en cours
|
||||
|
||||
Scénario: Dashboard budget temps réel
|
||||
Étant donné que ma campagne a un budget de 300€
|
||||
Et que j'ai consommé 220€
|
||||
Quand je consulte le dashboard budget
|
||||
Alors je vois:
|
||||
| Métrique | Valeur |
|
||||
| Budget total | 300€ |
|
||||
| Budget consommé | 220€ |
|
||||
| Budget restant | 80€ |
|
||||
| Pourcentage | 73% consommé |
|
||||
|
||||
Scénario: Jauge visuelle budget consommé
|
||||
Étant donné que j'ai consommé 220€ sur 300€
|
||||
Quand je consulte le dashboard
|
||||
Alors une jauge de progression affiche 73%
|
||||
Et la couleur est orange (seuil 50-80%)
|
||||
Et un indicateur "80€ restants" est affiché clairement
|
||||
|
||||
Scénario: Couleur jauge selon seuil
|
||||
Étant donné un budget de 300€
|
||||
Quand j'ai consommé 150€ (50%)
|
||||
Alors la jauge est verte
|
||||
Quand j'ai consommé 240€ (80%)
|
||||
Alors la jauge est orange
|
||||
Quand j'ai consommé 285€ (95%)
|
||||
Alors la jauge est rouge
|
||||
Et un message "Budget presque épuisé" s'affiche
|
||||
|
||||
Scénario: Projection épuisement budget
|
||||
Étant donné que j'ai consommé 220€ en 10 jours
|
||||
Et qu'il reste 4 jours de campagne
|
||||
Quand le système calcule la projection
|
||||
Alors la consommation quotidienne moyenne est 22€/jour
|
||||
Et la projection affiche "Budget épuisé dans 3.6 jours"
|
||||
Et un avertissement "Campagne s'arrêtera avant la fin prévue" s'affiche
|
||||
|
||||
Scénario: Projection avec budget suffisant
|
||||
Étant donné que j'ai consommé 100€ en 10 jours
|
||||
Et qu'il reste 4 jours de campagne
|
||||
Et que le budget total est 300€
|
||||
Quand le système calcule la projection
|
||||
Alors la consommation quotidienne moyenne est 10€/jour
|
||||
Et la projection affiche "Budget suffisant pour toute la campagne"
|
||||
Et le budget restant estimé à la fin est 160€
|
||||
|
||||
Scénario: Alerte 80% budget consommé
|
||||
Étant donné que mon budget est de 300€
|
||||
Quand je consomme 240€ (80%)
|
||||
Alors je reçois immédiatement un email:
|
||||
"""
|
||||
⚠️ Alerte Budget - 80% consommé
|
||||
|
||||
Campagne: [Nom]
|
||||
Budget consommé: 240€ / 300€
|
||||
Budget restant: 60€
|
||||
|
||||
À ce rythme, votre budget sera épuisé dans X jours.
|
||||
Recommandation: Envisagez une recharge pour maintenir la diffusion.
|
||||
"""
|
||||
Et une notification push est envoyée
|
||||
Et une notification in-app s'affiche
|
||||
|
||||
Scénario: Alerte 90% budget consommé
|
||||
Étant donné que mon budget est de 300€
|
||||
Quand je consomme 270€ (90%)
|
||||
Alors je reçois immédiatement un email:
|
||||
"""
|
||||
🚨 Alerte Budget - 90% consommé
|
||||
|
||||
Campagne: [Nom]
|
||||
Budget consommé: 270€ / 300€
|
||||
Budget restant: 30€
|
||||
|
||||
ATTENTION: Votre campagne s'arrêtera sous peu.
|
||||
Actions possibles:
|
||||
- Recharger le budget
|
||||
- Laisser la campagne se terminer
|
||||
"""
|
||||
|
||||
Scénario: Alerte budget épuisé (100%)
|
||||
Étant donné que mon budget est de 300€
|
||||
Quand je consomme les 300€ (100%)
|
||||
Alors je reçois immédiatement un email:
|
||||
"""
|
||||
✅ Campagne terminée - Budget épuisé
|
||||
|
||||
Campagne: [Nom]
|
||||
Budget consommé: 300€
|
||||
Durée effective: 12 jours (sur 14 prévus)
|
||||
|
||||
Métriques finales:
|
||||
- Impressions: 6000
|
||||
- Écoutes complètes: 4000 (67%)
|
||||
- Coût par écoute: 0.05€
|
||||
|
||||
Voir le rapport complet: [Lien]
|
||||
Créer une nouvelle campagne: [Lien]
|
||||
"""
|
||||
Et la campagne est automatiquement mise en pause
|
||||
Et plus aucune diffusion ne se produit
|
||||
|
||||
Scénario: Pause manuelle de campagne
|
||||
Étant donné que ma campagne est active
|
||||
Et qu'il reste 150€ de budget
|
||||
Quand je clique sur "Mettre en pause"
|
||||
Alors le statut passe à "En pause"
|
||||
Et les diffusions s'arrêtent immédiatement
|
||||
Et le budget de 150€ est conservé
|
||||
Et je peux réactiver la campagne plus tard
|
||||
|
||||
Scénario: Reprise campagne pausée
|
||||
Étant donné que ma campagne est en pause
|
||||
Et qu'il reste 150€ de budget
|
||||
Quand je clique sur "Reprendre la campagne"
|
||||
Alors le statut passe à "Active"
|
||||
Et les diffusions reprennent immédiatement
|
||||
Et le budget restant de 150€ continue de se consommer
|
||||
|
||||
Scénario: Prolongation campagne avec recharge
|
||||
Étant donné que ma campagne se termine dans 2 jours
|
||||
Et qu'il reste 20€ de budget
|
||||
Quand je clique sur "Prolonger la campagne"
|
||||
Et que j'ajoute 200€ supplémentaires
|
||||
Alors le budget total passe à 220€
|
||||
Et la date de fin peut être prolongée de 10 jours
|
||||
Et un nouveau paiement Mangopay de 200€ est traité
|
||||
|
||||
Scénario: Recharge automatique activée
|
||||
Étant donné que j'ai configuré la recharge automatique
|
||||
Et que le seuil est fixé à 10% (30€ sur budget 300€)
|
||||
Et que le montant de recharge est 100€
|
||||
Quand le budget restant passe sous 30€
|
||||
Alors une recharge automatique de 100€ est déclenchée
|
||||
Et ma carte bancaire est débitée via Mangopay
|
||||
Et le budget total passe à budget_restant + 100€
|
||||
Et je reçois un email de confirmation
|
||||
|
||||
Scénario: Échec recharge automatique (carte expirée)
|
||||
Étant donné que la recharge automatique est activée
|
||||
Et que ma carte bancaire a expiré
|
||||
Quand le budget passe sous le seuil de 10%
|
||||
Alors la recharge automatique échoue
|
||||
Et je reçois un email urgent:
|
||||
"""
|
||||
❌ Échec recharge automatique
|
||||
|
||||
Votre carte bancaire a été refusée.
|
||||
Raison probable: carte expirée ou fonds insuffisants
|
||||
|
||||
Action requise: Mettez à jour vos informations de paiement
|
||||
Campagne en pause si budget épuisé: [Lien]
|
||||
"""
|
||||
Et la campagne continue jusqu'à épuisement du budget restant
|
||||
|
||||
Scénario: Modification ciblage si budget <50% consommé
|
||||
Étant donné que j'ai consommé 120€ sur 300€ (40%)
|
||||
Quand j'essaie de modifier le ciblage géographique
|
||||
Alors la modification est autorisée
|
||||
Et le ciblage est mis à jour immédiatement
|
||||
Et les nouvelles diffusions utilisent le nouveau ciblage
|
||||
|
||||
Scénario: Blocage modification ciblage si budget >50% consommé
|
||||
Étant donné que j'ai consommé 180€ sur 300€ (60%)
|
||||
Quand j'essaie de modifier le ciblage géographique
|
||||
Alors une erreur s'affiche:
|
||||
"""
|
||||
Modification bloquée - Budget >50% consommé
|
||||
|
||||
Les modifications de ciblage ne sont autorisées que si moins de 50% du budget est consommé.
|
||||
Raison: Cohérence des métriques et analytics.
|
||||
|
||||
Options:
|
||||
- Créer une nouvelle campagne avec le nouveau ciblage
|
||||
- Laisser cette campagne se terminer
|
||||
"""
|
||||
|
||||
Scénario: Modification audio nécessite nouvelle validation
|
||||
Étant donné que ma campagne est active
|
||||
Quand je veux modifier le fichier audio
|
||||
Alors un message s'affiche:
|
||||
"""
|
||||
Modification audio = Nouvelle validation
|
||||
|
||||
Changer l'audio nécessite une nouvelle validation manuelle (24-48h).
|
||||
Votre campagne sera mise en pause pendant la validation.
|
||||
|
||||
Recommandation: Créer une nouvelle campagne pour tester un nouveau créatif.
|
||||
"""
|
||||
|
||||
Scénario: Modification plages horaires autorisée
|
||||
Étant donné que ma campagne cible 7h-9h et 17h-19h
|
||||
Quand je modifie pour cibler 12h-14h aussi
|
||||
Alors la modification est appliquée immédiatement
|
||||
Et les diffusions suivantes incluent la nouvelle plage
|
||||
Et aucune re-validation n'est nécessaire
|
||||
|
||||
Scénario: Historique consommation budget jour par jour
|
||||
Étant donné que ma campagne a duré 10 jours
|
||||
Quand je consulte l'historique
|
||||
Alors je vois un graphique avec:
|
||||
| Jour | Consommation | Cumulé |
|
||||
| 1 | 22€ | 22€ |
|
||||
| 2 | 25€ | 47€ |
|
||||
| 3 | 20€ | 67€ |
|
||||
| ... | ... | ... |
|
||||
| 10 | 18€ | 220€ |
|
||||
Et je peux identifier les pics de consommation
|
||||
|
||||
Scénario: Notification fin de campagne programmée
|
||||
Étant donné que ma campagne se termine le 14/02
|
||||
Quand la date de fin est atteinte
|
||||
Alors je reçois un email:
|
||||
"""
|
||||
✅ Campagne terminée - Date de fin atteinte
|
||||
|
||||
Campagne: [Nom]
|
||||
Durée: 14 jours (comme prévu)
|
||||
Budget consommé: 280€ / 300€
|
||||
Budget non utilisé: 20€
|
||||
|
||||
Métriques finales:
|
||||
- Impressions: 5600
|
||||
- Écoutes complètes: 3800 (68%)
|
||||
- ROI: [Calcul si applicable]
|
||||
|
||||
Le budget non utilisé (20€) sera remboursé sous 5-7 jours.
|
||||
"""
|
||||
|
||||
Scénario: Remboursement budget non utilisé
|
||||
Étant donné que ma campagne avait 300€ de budget
|
||||
Et qu'elle s'est terminée avec 280€ consommés
|
||||
Quand la campagne se termine (date ou épuisement)
|
||||
Alors un remboursement de 20€ est initié via Mangopay
|
||||
Et le délai est de 5-7 jours ouvrés
|
||||
Et je reçois une notification de confirmation
|
||||
|
||||
Scénario: Aucun remboursement si budget entièrement consommé
|
||||
Étant donné que ma campagne avait 300€ de budget
|
||||
Et qu'elle s'est terminée avec 300€ consommés
|
||||
Quand la campagne se termine
|
||||
Alors aucun remboursement n'est initié
|
||||
Et le message final indique "Budget entièrement utilisé"
|
||||
|
||||
Scénario: Statistiques comparatives budget vs objectif
|
||||
Étant donné que j'avais défini un objectif de 5000 impressions
|
||||
Et que mon budget était 300€
|
||||
Quand je consulte les statistiques finales
|
||||
Alors je vois:
|
||||
| Métrique | Objectif | Réalisé | Écart |
|
||||
| Impressions | 5000 | 6000 | +20% |
|
||||
| Budget | 300€ | 280€ | -7% |
|
||||
| Coût/impression | 0.06€ | 0.047€ | -22% |
|
||||
Et une analyse "✅ Objectifs dépassés avec budget optimisé"
|
||||
|
||||
Scénario: Export rapport financier détaillé
|
||||
Étant donné que je veux analyser mes dépenses
|
||||
Quand je clique sur "Exporter rapport financier"
|
||||
Alors je télécharge un CSV avec:
|
||||
| Colonne |
|
||||
| Date/Heure |
|
||||
| Type écoute |
|
||||
| Coût unitaire |
|
||||
| Zone géographique |
|
||||
| Utilisateur (anonyme)|
|
||||
| Durée écoutée |
|
||||
Et je peux l'importer dans Excel pour analyses
|
||||
|
||||
Scénario: Tableau de bord multi-campagnes
|
||||
Étant donné que j'ai 3 campagnes actives
|
||||
Quand je consulte la vue d'ensemble
|
||||
Alors je vois un tableau récapitulatif:
|
||||
| Campagne | Budget | Consommé | % | Jours restants | Projection |
|
||||
| A | 300€ | 220€ | 73| 4j | Suffisant |
|
||||
| B | 500€ | 480€ | 96| 10j | Épuisé 2j |
|
||||
| C | 200€ | 50€ | 25| 20j | Suffisant |
|
||||
Et un badge alerte rouge sur la campagne B
|
||||
|
||||
Scénario: Alerte consolidée multi-campagnes
|
||||
Étant donné que j'ai 5 campagnes actives
|
||||
Et que 2 campagnes ont >80% budget consommé
|
||||
Quand je reçois les notifications
|
||||
Alors un email consolidé unique est envoyé:
|
||||
"""
|
||||
⚠️ Alerte Budget - 2 campagnes nécessitent attention
|
||||
|
||||
Campagne A: 85% consommé, épuisement dans 2j
|
||||
Campagne C: 92% consommé, épuisement dans 1j
|
||||
|
||||
Actions recommandées: [Liens]
|
||||
"""
|
||||
Et je ne reçois pas 2 emails séparés (évite spam)
|
||||
|
||||
Scénario: Configuration seuils alertes personnalisés
|
||||
Étant donné que je configure mes préférences d'alerte
|
||||
Quand je définis les seuils:
|
||||
| Seuil | Valeur |
|
||||
| Alerte 1 | 70% |
|
||||
| Alerte 2 | 85% |
|
||||
| Alerte 3 | 95% |
|
||||
Alors je reçois des alertes à 70%, 85% et 95%
|
||||
Et non aux seuils par défaut 80%, 90%, 100%
|
||||
|
||||
Scénario: Désactivation alertes email
|
||||
Étant donné que je préfère uniquement les notifications in-app
|
||||
Quand je désactive les alertes email dans mes préférences
|
||||
Alors je ne reçois plus d'emails d'alerte budget
|
||||
Mais les notifications in-app continuent
|
||||
Et les alertes critiques (échec paiement) sont toujours envoyées par email
|
||||
|
||||
Plan du Scénario: Couleur jauge selon pourcentage consommé
|
||||
Étant donné un budget de 300€
|
||||
Quand j'ai consommé <montant>€ (<pourcentage>%)
|
||||
Alors la couleur de la jauge est <couleur>
|
||||
|
||||
Exemples:
|
||||
| montant | pourcentage | couleur |
|
||||
| 100 | 33 | verte |
|
||||
| 150 | 50 | verte |
|
||||
| 180 | 60 | orange |
|
||||
| 240 | 80 | orange |
|
||||
| 270 | 90 | rouge |
|
||||
| 285 | 95 | rouge |
|
||||
| 300 | 100 | rouge |
|
||||
|
||||
Plan du Scénario: Projection épuisement selon consommation
|
||||
Étant donné un budget de 300€
|
||||
Et une consommation actuelle de <consomme>€
|
||||
Et une durée écoulée de <jours_ecoules> jours
|
||||
Quand je calcule la consommation quotidienne moyenne
|
||||
Alors elle est de <conso_jour>€/jour
|
||||
Et le budget sera épuisé dans <jours_restants> jours
|
||||
|
||||
Exemples:
|
||||
| consomme | jours_ecoules | conso_jour | jours_restants |
|
||||
| 100 | 5 | 20 | 10 |
|
||||
| 200 | 10 | 20 | 5 |
|
||||
| 150 | 10 | 15 | 10 |
|
||||
| 270 | 12 | 22.5 | 1.3 |
|
||||
|
||||
Plan du Scénario: Alertes envoyées selon seuils
|
||||
Étant donné un budget de 500€
|
||||
Quand je consomme <montant>€ (<pourcentage>%)
|
||||
Alors je reçois une alerte <niveau>
|
||||
|
||||
Exemples:
|
||||
| montant | pourcentage | niveau |
|
||||
| 350 | 70 | aucune |
|
||||
| 400 | 80 | alerte 80% |
|
||||
| 450 | 90 | alerte 90% |
|
||||
| 500 | 100 | budget épuisé|
|
||||
@@ -0,0 +1,271 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Insertion et fréquence des publicités
|
||||
En tant que système RoadWave
|
||||
Je veux insérer les publicités de manière équilibrée et non intrusive
|
||||
Afin de préserver l'expérience utilisateur tout en monétisant
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et qu'un utilisateur gratuit est connecté
|
||||
|
||||
Scénario: Fréquence par défaut 1 pub / 5 contenus
|
||||
Étant donné que la fréquence par défaut est configurée à 1/5
|
||||
Et que je suis un utilisateur gratuit
|
||||
Quand j'écoute 5 contenus
|
||||
Alors 1 publicité est insérée après le 5ème contenu
|
||||
Quand j'écoute 10 contenus
|
||||
Alors 2 publicités sont insérées (après les contenus 5 et 10)
|
||||
|
||||
Scénario: Aucune publicité pour utilisateurs Premium
|
||||
Étant donné que je suis un utilisateur Premium
|
||||
Quand j'écoute 100 contenus
|
||||
Alors aucune publicité n'est insérée
|
||||
Et je bénéficie d'une expérience sans interruption publicitaire
|
||||
|
||||
Scénario: Fréquence paramétrable par admin (1/3)
|
||||
Étant donné que l'admin configure la fréquence à 1/3
|
||||
Et que je suis un utilisateur gratuit
|
||||
Quand j'écoute 6 contenus
|
||||
Alors 2 publicités sont insérées (après contenus 3 et 6)
|
||||
|
||||
Scénario: Fréquence paramétrable par admin (1/10)
|
||||
Étant donné que l'admin configure la fréquence à 1/10
|
||||
Et que je suis un utilisateur gratuit
|
||||
Quand j'écoute 20 contenus
|
||||
Alors 2 publicités sont insérées (après contenus 10 et 20)
|
||||
|
||||
Scénario: Jamais d'interruption d'un contenu en cours
|
||||
Étant donné que j'écoute un contenu de 10 minutes
|
||||
Et que je suis à 5 minutes de lecture
|
||||
Et qu'une publicité devrait être insérée selon la fréquence
|
||||
Quand le système vérifie l'insertion
|
||||
Alors la publicité attend la fin du contenu actuel
|
||||
Et elle s'insère pendant le délai de transition (2s)
|
||||
Et le contenu n'est jamais interrompu
|
||||
|
||||
Scénario: Insertion entre deux contenus uniquement
|
||||
Étant donné que le contenu "A" se termine
|
||||
Et que le délai de transition de 2s démarre
|
||||
Quand le système détecte qu'une publicité doit être insérée
|
||||
Alors le message "Publicité (30s)" s'affiche
|
||||
Et la publicité démarre après les 2 secondes
|
||||
Et l'enchaînement est naturel et fluide
|
||||
|
||||
Scénario: Rotation limite 3 fois/jour par utilisateur
|
||||
Étant donné qu'un utilisateur a entendu la publicité "A" 3 fois aujourd'hui
|
||||
Quand le système sélectionne une nouvelle publicité à diffuser
|
||||
Alors la publicité "A" n'est plus éligible pour cet utilisateur aujourd'hui
|
||||
Et une autre publicité "B" est sélectionnée
|
||||
Et cela évite la saturation publicitaire
|
||||
|
||||
Scénario: Compteur de diffusions par pub et par utilisateur
|
||||
Étant donné qu'un utilisateur écoute la pub "RestaurantX"
|
||||
Quand la diffusion se termine
|
||||
Alors un compteur Redis "pub:RestaurantX:user:123:count" s'incrémente
|
||||
Et le TTL est de 24h (reset à minuit)
|
||||
Quand le compteur atteint 3
|
||||
Alors la pub "RestaurantX" est exclue des prochaines sélections aujourd'hui
|
||||
|
||||
Scénario: Limite max 6 pubs/heure par utilisateur
|
||||
Étant donné qu'un utilisateur a entendu 6 publicités dans la dernière heure
|
||||
Quand le système devrait insérer une 7ème pub
|
||||
Alors l'insertion est reportée à l'heure suivante
|
||||
Et un compteur horaire Redis "pub:user:123:hourly" est vérifié
|
||||
Et cela évite le spam publicitaire
|
||||
|
||||
Scénario: Ciblage géographique prioritaire - Point GPS
|
||||
Étant donné qu'une publicité cible un point GPS à 2km de ma position
|
||||
Et qu'une autre publicité cible ma ville entière
|
||||
Quand le système sélectionne une publicité
|
||||
Alors la publicité point GPS est priorisée (score géo plus élevé)
|
||||
Et le ciblage précis est favorisé
|
||||
|
||||
Scénario: Ciblage géographique prioritaire - Hiérarchie
|
||||
Étant donné que 4 publicités sont éligibles:
|
||||
| Publicité | Zone | Distance |
|
||||
| A | Point GPS | 1km |
|
||||
| B | Ville | 0km |
|
||||
| C | Département | 0km |
|
||||
| D | National | N/A |
|
||||
Quand le système sélectionne selon priorité géographique
|
||||
Alors l'ordre de priorité est: A > B > C > D
|
||||
Et la publicité A (Point GPS, la plus précise) est diffusée
|
||||
|
||||
Scénario: Ciblage centres d'intérêt secondaire
|
||||
Étant donné que 2 publicités ciblent ma zone géographique:
|
||||
| Publicité | Tags | Mes jauges |
|
||||
| A | Automobile | 80% |
|
||||
| B | Voyage | 40% |
|
||||
Quand le système applique le score centres d'intérêt
|
||||
Alors la publicité A est favorisée (meilleur match jauges)
|
||||
Et le ciblage thématique affine la sélection
|
||||
|
||||
Scénario: Ciblage horaire strict
|
||||
Étant donné qu'une campagne cible uniquement 7h-9h
|
||||
Et qu'il est 10h30
|
||||
Quand le système sélectionne une publicité
|
||||
Alors cette campagne n'est PAS éligible
|
||||
Et seules les campagnes "toute la journée" ou avec plage horaire actuelle sont considérées
|
||||
|
||||
Scénario: Ciblage horaire pendant plage active
|
||||
Étant donné qu'une campagne cible 7h-9h et 17h-19h
|
||||
Et qu'il est 8h15
|
||||
Quand le système sélectionne une publicité
|
||||
Alors cette campagne est éligible
|
||||
Et elle peut être diffusée
|
||||
|
||||
Scénario: Normalisation volume audio -14 LUFS
|
||||
Étant donné qu'une publicité est uploadée avec volume trop élevé (-6 LUFS)
|
||||
Quand le système encode l'audio via FFmpeg
|
||||
Alors le volume est normalisé automatiquement à -14 LUFS
|
||||
Et le publicitaire reçoit une notification "Volume audio ajusté pour conformité"
|
||||
Et cela évite l'effet "pub trop forte" frustrant
|
||||
|
||||
Scénario: Validation volume audio lors encodage
|
||||
Étant donné qu'une publicité est soumise
|
||||
Quand FFmpeg encode le fichier
|
||||
Alors une commande loudnorm est appliquée:
|
||||
```
|
||||
ffmpeg -i input.mp3 -filter:a loudnorm=I=-14:LRA=11:TP=-1 output.mp3
|
||||
```
|
||||
Et le fichier final respecte le standard broadcast -14 LUFS
|
||||
|
||||
Scénario: Sélection aléatoire si critères équivalents
|
||||
Étant donné que 3 publicités ont le même score géo
|
||||
Et qu'elles ont toutes des jauges centres d'intérêt équivalentes
|
||||
Et qu'aucune n'a été diffusée 3 fois aujourd'hui
|
||||
Quand le système sélectionne une publicité
|
||||
Alors une sélection aléatoire équitable est faite
|
||||
Et chaque campagne a 33% de chances d'être diffusée
|
||||
|
||||
Scénario: Exclusion publicités avec budget épuisé
|
||||
Étant donné qu'une campagne "A" a épuisé son budget
|
||||
Et qu'une campagne "B" a encore du budget disponible
|
||||
Quand le système sélectionne une publicité
|
||||
Alors seule la campagne "B" est éligible
|
||||
Et la campagne "A" est automatiquement exclue
|
||||
|
||||
Scénario: Exclusion publicités hors dates de campagne
|
||||
Étant donné qu'une campagne "A" est programmée du 01/02 au 14/02
|
||||
Et que nous sommes le 20/01
|
||||
Quand le système sélectionne une publicité
|
||||
Alors la campagne "A" n'est pas éligible
|
||||
Et seules les campagnes actives aujourd'hui sont considérées
|
||||
|
||||
Scénario: Publicité visible uniquement dans zone géographique
|
||||
Étant donné qu'une publicité cible "Marseille uniquement"
|
||||
Et que je suis à Lyon
|
||||
Quand le système sélectionne une publicité
|
||||
Alors cette publicité n'est jamais éligible pour moi
|
||||
Et je ne la verrai jamais tant que je reste à Lyon
|
||||
|
||||
Scénario: Tracking compteur horaire avec TTL
|
||||
Étant donné qu'un utilisateur entend une pub à 10h05
|
||||
Quand le compteur horaire est incrémenté
|
||||
Alors la clé Redis "pub:user:123:hourly:2026012110" est créée
|
||||
Et le TTL est de 1 heure (expire à 11h05)
|
||||
Et le système compte les pubs dans la fenêtre glissante d'1h
|
||||
|
||||
Scénario: Reset compteur quotidien à minuit
|
||||
Étant donné qu'un utilisateur a entendu la pub "A" 3 fois le 20/01
|
||||
Quand minuit passe et on est le 21/01
|
||||
Alors le compteur "pub:A:user:123:count" est expiré (TTL 24h)
|
||||
Et l'utilisateur peut à nouveau entendre la pub "A" jusqu'à 3 fois
|
||||
|
||||
Scénario: Aucune pub si aucune campagne éligible
|
||||
Étant donné qu'aucune campagne n'a de budget disponible
|
||||
Ou que toutes les campagnes ont déjà été diffusées 3 fois aujourd'hui
|
||||
Quand le système devrait insérer une publicité
|
||||
Alors aucune pub n'est insérée
|
||||
Et l'enchaînement de contenus continue normalement
|
||||
Et le prochain contenu démarre directement
|
||||
|
||||
Scénario: Priorisation campagnes avec budget important restant
|
||||
Étant donné que 2 campagnes sont éligibles:
|
||||
| Campagne | Budget restant | Jours restants |
|
||||
| A | 500€ | 2j |
|
||||
| B | 50€ | 10j |
|
||||
Quand le système applique la priorisation budgétaire
|
||||
Alors la campagne A est légèrement favorisée (urgence dépense)
|
||||
Et cela aide à épuiser les budgets avant fin de campagne
|
||||
|
||||
Scénario: Log des sélections pour analytics
|
||||
Étant donné qu'une publicité "RestaurantX" est sélectionnée
|
||||
Quand elle est diffusée à l'utilisateur "123"
|
||||
Alors un événement est loggé en base:
|
||||
| Champ | Valeur |
|
||||
| pub_id | RestaurantX |
|
||||
| user_id | 123 |
|
||||
| timestamp | 2026-01-21 10:30 |
|
||||
| zone_geo | Marseille |
|
||||
| score_geo | 0.85 |
|
||||
| score_interet | 0.70 |
|
||||
Et cela permet l'analytics publicitaire
|
||||
|
||||
Scénario: Détection changement statut utilisateur (gratuit → premium)
|
||||
Étant donné que je suis un utilisateur gratuit
|
||||
Et que j'entends des publicités
|
||||
Quand je souscris à Premium
|
||||
Alors le système détecte le changement de statut immédiatement
|
||||
Et plus aucune publicité n'est insérée dès le prochain contenu
|
||||
Et mon expérience devient sans pub instantanément
|
||||
|
||||
Scénario: Interface admin pour ajuster fréquence globale
|
||||
Étant donné que je suis admin RoadWave
|
||||
Quand j'accède aux paramètres publicitaires
|
||||
Alors je peux ajuster le curseur de fréquence:
|
||||
| Option | Fréquence |
|
||||
| 1/3 | Haute (agressif) |
|
||||
| 1/5 | Standard (défaut)|
|
||||
| 1/7 | Modérée |
|
||||
| 1/10 | Faible |
|
||||
Et le changement s'applique en temps réel à tous les utilisateurs
|
||||
|
||||
Scénario: A/B testing fréquence sur cohortes utilisateurs
|
||||
Étant donné que l'admin active un test A/B
|
||||
Quand 50% des utilisateurs ont fréquence 1/5
|
||||
Et 50% des utilisateurs ont fréquence 1/7
|
||||
Alors les métriques sont trackées séparément:
|
||||
| Cohorte | Fréquence | Taux désabonnement | Revenus/user |
|
||||
| A | 1/5 | 2.5% | 0.50€ |
|
||||
| B | 1/7 | 1.8% | 0.40€ |
|
||||
Et l'admin peut identifier la fréquence optimale
|
||||
|
||||
Plan du Scénario: Insertion publicité selon fréquence
|
||||
Étant donné que la fréquence est <frequence>
|
||||
Quand j'écoute <contenus> contenus
|
||||
Alors <pubs> publicités sont insérées
|
||||
|
||||
Exemples:
|
||||
| frequence | contenus | pubs |
|
||||
| 1/3 | 9 | 3 |
|
||||
| 1/5 | 10 | 2 |
|
||||
| 1/5 | 25 | 5 |
|
||||
| 1/7 | 14 | 2 |
|
||||
| 1/10 | 30 | 3 |
|
||||
|
||||
Plan du Scénario: Priorité géographique selon type zone
|
||||
Étant donné qu'une publicité cible <type_zone>
|
||||
Quand le système calcule le score géographique
|
||||
Alors la priorité est <score>
|
||||
|
||||
Exemples:
|
||||
| type_zone | score |
|
||||
| Point GPS | 1.0 |
|
||||
| Ville | 0.8 |
|
||||
| Département | 0.6 |
|
||||
| Région | 0.4 |
|
||||
| National | 0.2 |
|
||||
|
||||
Plan du Scénario: Exclusion publicité selon compteur quotidien
|
||||
Étant donné qu'une publicité a été entendue <fois> fois aujourd'hui
|
||||
Quand le système vérifie l'éligibilité
|
||||
Alors la publicité est <eligible>
|
||||
|
||||
Exemples:
|
||||
| fois | eligible |
|
||||
| 0 | éligible |
|
||||
| 1 | éligible |
|
||||
| 2 | éligible |
|
||||
| 3 | non éligible |
|
||||
| 4 | non éligible |
|
||||
@@ -0,0 +1,299 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Métriques d'engagement et dashboard publicitaire
|
||||
En tant que publicitaire
|
||||
Je veux consulter des métriques détaillées en temps réel
|
||||
Afin d'optimiser mes campagnes et mesurer leur ROI
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et qu'un compte publicitaire est connecté
|
||||
Et qu'une campagne active est en cours
|
||||
|
||||
Scénario: Dashboard temps réel avec métriques essentielles
|
||||
Étant donné que ma campagne a généré 1000 diffusions
|
||||
Quand je consulte le dashboard
|
||||
Alors je vois les métriques suivantes mises à jour en temps réel:
|
||||
| Métrique | Valeur |
|
||||
| Impressions | 1000 |
|
||||
| Écoutes complètes (>80%)| 400 |
|
||||
| Taux d'écoute complète | 40% |
|
||||
| Taux de skip | 60% |
|
||||
| Durée moyenne d'écoute | 18s |
|
||||
| Likes | 25 |
|
||||
| Abonnements | 5 |
|
||||
| Coût par écoute | 0.05€ |
|
||||
|
||||
Scénario: Calcul impressions totales
|
||||
Étant donné que ma publicité a été diffusée 2500 fois
|
||||
Quand je consulte le dashboard
|
||||
Alors le compteur "Impressions" affiche 2500
|
||||
Et il s'incrémente en temps réel à chaque nouvelle diffusion
|
||||
|
||||
Scénario: Calcul écoutes complètes (>80%)
|
||||
Étant donné que ma publicité de 30s a été:
|
||||
| Durée écoutée | Nombre |
|
||||
| 25s (83%) | 300 |
|
||||
| 20s (67%) | 200 |
|
||||
| 10s (33%) | 150 |
|
||||
| 5s (17%) | 50 |
|
||||
Quand je consulte les écoutes complètes
|
||||
Alors le compteur affiche 300 (uniquement ≥80%)
|
||||
Et le taux d'écoute complète est de 43% (300/700)
|
||||
|
||||
Scénario: Calcul taux de skip
|
||||
Étant donné 1000 diffusions totales
|
||||
Et 400 écoutes complètes
|
||||
Quand je consulte le taux de skip
|
||||
Alors il affiche 60% ((1000-400)/1000)
|
||||
Et il est calculé comme (total - complètes) / total
|
||||
|
||||
Scénario: Durée moyenne d'écoute calculée
|
||||
Étant donné que ma publicité de 30s a été écoutée:
|
||||
| Durée | Nombre d'utilisateurs |
|
||||
| 30s | 400 |
|
||||
| 20s | 300 |
|
||||
| 10s | 200 |
|
||||
| 5s | 100 |
|
||||
Quand je consulte la durée moyenne
|
||||
Alors le calcul est: (30×400 + 20×300 + 10×200 + 5×100) / 1000
|
||||
Et le résultat affiché est 21s
|
||||
|
||||
Scénario: Métriques de likes sur publicité
|
||||
Étant donné que 50 utilisateurs ont liké ma publicité
|
||||
Quand je consulte le dashboard
|
||||
Alors le compteur "Likes" affiche 50
|
||||
Et un taux de like de 5% est calculé (50/1000 impressions)
|
||||
Et cela indique une forte appréciation du contenu
|
||||
|
||||
Scénario: Métriques d'abonnements générés
|
||||
Étant donné que 10 utilisateurs se sont abonnés après avoir entendu ma pub
|
||||
Quand je consulte le dashboard
|
||||
Alors le compteur "Abonnements" affiche 10
|
||||
Et un taux de conversion de 1% est calculé (10/1000)
|
||||
Et cela représente un engagement très fort
|
||||
|
||||
Scénario: Calcul coût par écoute (CPE)
|
||||
Étant donné que j'ai dépensé 200€
|
||||
Et obtenu 4000 écoutes complètes
|
||||
Quand je consulte le coût par écoute
|
||||
Alors le CPE affiché est 0.05€ (200/4000)
|
||||
Et il correspond au tarif standard RoadWave
|
||||
|
||||
Scénario: Répartition géographique avec heatmap
|
||||
Étant donné que ma campagne cible le département du Var
|
||||
Et que j'ai 1000 diffusions réparties:
|
||||
| Zone | Diffusions | Pourcentage |
|
||||
| Toulon | 400 | 40% |
|
||||
| Hyères | 250 | 25% |
|
||||
| Fréjus | 200 | 20% |
|
||||
| Autres | 150 | 15% |
|
||||
Quand je consulte la heatmap géographique
|
||||
Alors une carte Leaflet affiche les zones avec intensité proportionnelle
|
||||
Et Toulon apparaît en rouge foncé (forte concentration)
|
||||
Et les autres villes en dégradé orange/jaune
|
||||
|
||||
Scénario: Répartition horaire avec graphique
|
||||
Étant donné que ma campagne cible les plages 7h-9h et 17h-19h
|
||||
Et que j'ai 1000 diffusions:
|
||||
| Plage horaire | Diffusions |
|
||||
| 7h-8h | 300 |
|
||||
| 8h-9h | 250 |
|
||||
| 17h-18h | 280 |
|
||||
| 18h-19h | 170 |
|
||||
Quand je consulte le graphique horaire
|
||||
Alors un histogramme Chart.js affiche les 4 barres
|
||||
Et je peux identifier que 7h-8h est le pic d'écoute
|
||||
Et optimiser mes futures campagnes sur cette plage
|
||||
|
||||
Scénario: Taux de complétion par tranche d'âge
|
||||
Étant donné que ma campagne est Tout Public
|
||||
Et que j'ai des écoutes sur différentes tranches:
|
||||
| Tranche d'âge | Écoutes complètes | Total diffusions | Taux |
|
||||
| 18-24 ans | 120 | 400 | 30% |
|
||||
| 25-34 ans | 200 | 400 | 50% |
|
||||
| 35-44 ans | 80 | 200 | 40% |
|
||||
Quand je consulte l'analyse par âge
|
||||
Alors je vois que les 25-34 ans ont le meilleur taux (50%)
|
||||
Et je peux cibler cette tranche pour mes prochaines campagnes
|
||||
|
||||
Scénario: Comparatif de campagnes A/B testing
|
||||
Étant donné que j'ai 2 campagnes actives:
|
||||
| Campagne | Budget | Écoutes complètes | Taux | CPE |
|
||||
| A | 300€ | 4000 | 40% | 0.075€|
|
||||
| B | 300€ | 6000 | 60% | 0.05€ |
|
||||
Quand je consulte le comparatif
|
||||
Alors je vois que la campagne B performe mieux
|
||||
Et le tableau recommande "Campagne B: +50% écoutes, -33% CPE"
|
||||
Et je peux allouer plus de budget à la campagne B
|
||||
|
||||
Scénario: Export données CSV pour analyse externe
|
||||
Étant donné que je veux analyser mes données dans Excel
|
||||
Quand je clique sur "Exporter CSV"
|
||||
Alors je télécharge un fichier avec les colonnes:
|
||||
| Colonne |
|
||||
| Date |
|
||||
| Heure |
|
||||
| Zone géographique |
|
||||
| Tranche d'âge |
|
||||
| Durée écoute |
|
||||
| Skip (Oui/Non) |
|
||||
| Like (Oui/Non) |
|
||||
| Abonnement (Oui/Non) |
|
||||
Et je peux faire des analyses personnalisées
|
||||
|
||||
Scénario: Export graphiques interactifs
|
||||
Étant donné que je consulte le dashboard
|
||||
Quand je clique sur un graphique Chart.js
|
||||
Alors je peux zoomer/filtrer interactivement
|
||||
Et je peux exporter le graphique en PNG
|
||||
Et l'image est en haute résolution pour présentations
|
||||
|
||||
Scénario: Rapport PDF automatique fin de campagne
|
||||
Étant donné que ma campagne de 14 jours se termine
|
||||
Quand la date de fin est atteinte
|
||||
Alors un rapport PDF est généré automatiquement
|
||||
Et il contient:
|
||||
| Section |
|
||||
| Résumé exécutif |
|
||||
| Métriques clés |
|
||||
| Graphiques de performance |
|
||||
| Heatmap géographique |
|
||||
| Répartition horaire |
|
||||
| Analyse tranches d'âge |
|
||||
| Recommandations optimisation |
|
||||
Et je reçois un email avec le PDF en pièce jointe
|
||||
|
||||
Scénario: Métriques temps réel rafraîchies automatiquement
|
||||
Étant donné que je consulte le dashboard à 10h00
|
||||
Quand une nouvelle diffusion se produit à 10h01
|
||||
Alors les métriques sont rafraîchies automatiquement (polling 30s)
|
||||
Et je vois les nouveaux chiffres sans recharger la page
|
||||
Et un badge "Mis à jour il y a 15s" s'affiche
|
||||
|
||||
Scénario: Alertes performance personnalisées
|
||||
Étant donné que je configure une alerte "Taux de skip >70%"
|
||||
Et que ma campagne atteint 72% de skip
|
||||
Quand le seuil est dépassé
|
||||
Alors je reçois un email d'alerte:
|
||||
"""
|
||||
Alerte Performance - Taux de skip élevé
|
||||
|
||||
Votre campagne a un taux de skip de 72%.
|
||||
Recommandations:
|
||||
- Réduire la durée de la publicité
|
||||
- Améliorer l'accroche des 5 premières secondes
|
||||
- Vérifier le ciblage (audience pertinente?)
|
||||
"""
|
||||
|
||||
Scénario: Benchmark vs moyennes RoadWave
|
||||
Étant donné que ma campagne a 45% d'écoutes complètes
|
||||
Quand je consulte le benchmark
|
||||
Alors je vois "Votre taux: 45% | Moyenne RoadWave: 40%"
|
||||
Et un badge "📊 Performance: +12% vs moyenne" s'affiche
|
||||
Et je sais que ma campagne performe au-dessus de la moyenne
|
||||
|
||||
Scénario: Coût total consommé vs budget
|
||||
Étant donné que j'ai un budget de 300€
|
||||
Et que j'ai consommé 220€
|
||||
Quand je consulte le dashboard
|
||||
Alors je vois une jauge "Budget consommé: 73%" (220/300)
|
||||
Et le montant restant "80€ restants"
|
||||
Et une projection "Épuisé dans 3 jours à ce rythme"
|
||||
|
||||
Scénario: Répartition coûts par type d'écoute
|
||||
Étant donné que j'ai dépensé 200€ avec:
|
||||
| Type d'écoute | Nombre | Coût unitaire | Total |
|
||||
| Écoute complète | 3000 | 0.05€ | 150€ |
|
||||
| Skip après 5s | 2000 | 0.02€ | 40€ |
|
||||
| Skip immédiat | 500 | 0€ | 0€ |
|
||||
Quand je consulte la répartition
|
||||
Alors un graphique camembert affiche:
|
||||
| Segment | Pourcentage |
|
||||
| Écoutes complètes | 75% (150€) |
|
||||
| Skips partiels | 20% (40€) |
|
||||
| Skips immédiats | 5% (0€) |
|
||||
|
||||
Scénario: Évolution performance dans le temps
|
||||
Étant donné une campagne de 30 jours
|
||||
Quand je consulte le graphique d'évolution
|
||||
Alors je vois une courbe Chart.js avec:
|
||||
| Axe | Donnée |
|
||||
| X | Jours (1-30) |
|
||||
| Y | Taux d'écoute complète (%) |
|
||||
Et je peux identifier les tendances (amélioration/dégradation)
|
||||
Et les jours avec pics d'engagement
|
||||
|
||||
Scénario: Métriques avancées - Taux de réécoute
|
||||
Étant donné qu'un utilisateur a entendu ma pub 3 fois
|
||||
Et qu'il l'a écoutée complètement les 3 fois
|
||||
Quand je consulte les métriques avancées
|
||||
Alors le "Taux de réécoute" affiche 100%
|
||||
Et cela indique que le contenu n'est pas perçu comme spam
|
||||
Et les utilisateurs tolèrent bien la répétition
|
||||
|
||||
Scénario: Recommandations automatiques d'optimisation
|
||||
Étant donné que ma campagne a un taux de skip de 75%
|
||||
Et que la durée moyenne d'écoute est de 8s sur 30s
|
||||
Quand je consulte les recommandations
|
||||
Alors le système suggère:
|
||||
"""
|
||||
🔍 Analyse de votre campagne
|
||||
|
||||
Problème identifié: Perte d'attention après 8 secondes
|
||||
|
||||
Recommandations:
|
||||
1. Placer votre message clé dans les 5 premières secondes
|
||||
2. Réduire la durée totale à 15-20 secondes
|
||||
3. Ajouter un appel à l'action plus tôt
|
||||
4. Tester un nouveau créatif avec accroche différente
|
||||
"""
|
||||
|
||||
Scénario: Suivi multi-campagnes avec vue consolidée
|
||||
Étant donné que j'ai 3 campagnes actives simultanément
|
||||
Quand je consulte la vue consolidée
|
||||
Alors je vois un tableau récapitulatif:
|
||||
| Campagne | Budget | Dépensé | Diffusions | Taux complète | CPE |
|
||||
| A | 300€ | 220€ | 4000 | 40% | 0.05€ |
|
||||
| B | 500€ | 150€ | 3000 | 60% | 0.05€ |
|
||||
| C | 200€ | 180€ | 3600 | 35% | 0.05€ |
|
||||
Et je peux comparer les performances d'un coup d'œil
|
||||
|
||||
Plan du Scénario: Calcul taux d'écoute complète
|
||||
Étant donné <total> diffusions totales
|
||||
Et <completes> écoutes complètes (≥80%)
|
||||
Quand je calcule le taux
|
||||
Alors le résultat est <taux>%
|
||||
|
||||
Exemples:
|
||||
| total | completes | taux |
|
||||
| 1000 | 400 | 40 |
|
||||
| 2000 | 1200 | 60 |
|
||||
| 500 | 100 | 20 |
|
||||
| 1000 | 850 | 85 |
|
||||
|
||||
Plan du Scénario: Calcul coût par écoute (CPE)
|
||||
Étant donné un budget dépensé de <depense>€
|
||||
Et <ecoutes> écoutes complètes
|
||||
Quand je calcule le CPE
|
||||
Alors le résultat est <cpe>€
|
||||
|
||||
Exemples:
|
||||
| depense | ecoutes | cpe |
|
||||
| 100 | 2000 | 0.05 |
|
||||
| 300 | 6000 | 0.05 |
|
||||
| 50 | 1000 | 0.05 |
|
||||
| 500 | 10000 | 0.05 |
|
||||
|
||||
Plan du Scénario: Classification performance vs benchmark
|
||||
Étant donné un taux d'écoute complète de <taux>%
|
||||
Et une moyenne RoadWave de 40%
|
||||
Quand je compare à la moyenne
|
||||
Alors la performance est <classification>
|
||||
|
||||
Exemples:
|
||||
| taux | classification |
|
||||
| 60 | Excellente (+50%) |
|
||||
| 50 | Bonne (+25%) |
|
||||
| 40 | Moyenne |
|
||||
| 30 | Faible (-25%) |
|
||||
| 20 | Très faible (-50%)|
|
||||
@@ -0,0 +1,261 @@
|
||||
# language: fr
|
||||
Fonctionnalité: Validation et modération des publicités
|
||||
En tant que modérateur RoadWave
|
||||
Je veux valider manuellement toutes les publicités avant diffusion
|
||||
Afin de garantir la qualité et la légalité des contenus publicitaires
|
||||
|
||||
Contexte:
|
||||
Étant donné que l'API RoadWave est disponible
|
||||
Et qu'un modérateur RoadWave est connecté
|
||||
|
||||
Scénario: Validation manuelle obligatoire avant diffusion
|
||||
Étant donné qu'un publicitaire a créé une campagne
|
||||
Et que le paiement de 300€ a été effectué
|
||||
Quand la campagne est soumise
|
||||
Alors elle passe en statut "En attente de validation"
|
||||
Et elle est ajoutée à la file d'attente des modérateurs
|
||||
Et la diffusion ne démarre PAS avant validation manuelle
|
||||
Et le publicitaire reçoit un email "Votre campagne est en cours de validation (24-48h)"
|
||||
|
||||
Scénario: Délai de validation 24-48h ouvrées
|
||||
Étant donné qu'une campagne est soumise le lundi 10h
|
||||
Quand le modérateur la valide le mardi 15h
|
||||
Alors le délai est de 29h (dans les 48h ouvrées)
|
||||
Et le publicitaire reçoit une notification "Votre campagne est approuvée"
|
||||
|
||||
Scénario: Validation dépassant 48h avec notification
|
||||
Étant donné qu'une campagne est soumise le lundi 10h
|
||||
Quand 48h ouvrées se sont écoulées
|
||||
Et que la campagne n'est toujours pas validée
|
||||
Alors le publicitaire reçoit un email automatique:
|
||||
"""
|
||||
Validation en cours - Délai prolongé
|
||||
|
||||
Votre campagne nécessite une analyse approfondie.
|
||||
Nous vous contacterons sous 24h supplémentaires.
|
||||
"""
|
||||
Et un modérateur senior est assigné automatiquement
|
||||
|
||||
Scénario: Acceptation de campagne publicitaire
|
||||
Étant donné qu'une campagne est en attente de validation
|
||||
Et que l'audio respecte toutes les règles
|
||||
Quand le modérateur clique sur "Approuver"
|
||||
Alors le statut passe à "Approuvée"
|
||||
Et la campagne démarre à la date programmée
|
||||
Et le publicitaire reçoit un email de confirmation
|
||||
Et le budget commence à être consommé dès le début
|
||||
|
||||
Scénario: Refus de campagne avec motif détaillé
|
||||
Étant donné qu'une campagne contient du contenu alcool
|
||||
Quand le modérateur clique sur "Refuser"
|
||||
Et qu'il sélectionne le motif "Contenu interdit: Alcool"
|
||||
Et qu'il ajoute le commentaire "La publicité pour l'alcool est interdite en France"
|
||||
Alors le statut passe à "Refusée"
|
||||
Et le publicitaire reçoit un email détaillé avec:
|
||||
| Champ | Valeur |
|
||||
| Motif | Contenu interdit: Alcool |
|
||||
| Commentaire | La publicité pour l'alcool est interdite en France |
|
||||
| Action requise | Modifier votre contenu et soumettre à nouveau |
|
||||
Et un remboursement automatique de 300€ est déclenché
|
||||
|
||||
Scénario: Remboursement automatique après refus
|
||||
Étant donné qu'une campagne à 500€ est refusée
|
||||
Quand le statut passe à "Refusée"
|
||||
Alors un remboursement Mangopay de 500€ est initié automatiquement
|
||||
Et le délai de remboursement est de 5-7 jours ouvrés
|
||||
Et le publicitaire reçoit un email "Remboursement en cours"
|
||||
|
||||
Scénario: Contenus interdits - Alcool
|
||||
Étant donné qu'une publicité mentionne "Whisky premium 40°"
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit refuser la campagne
|
||||
Et sélectionner le motif "Contenu interdit: Alcool"
|
||||
Car la publicité pour l'alcool est interdite en France
|
||||
|
||||
Scénario: Contenus interdits - Tabac
|
||||
Étant donné qu'une publicité mentionne "Cigarettes électroniques"
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit refuser la campagne
|
||||
Et sélectionner le motif "Contenu interdit: Tabac/Vape"
|
||||
Car la publicité pour le tabac et dérivés est interdite
|
||||
|
||||
Scénario: Contenus interdits - Jeux d'argent
|
||||
Étant donné qu'une publicité mentionne "Gagnez 10 000€ - Paris sportifs"
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit refuser la campagne
|
||||
Et sélectionner le motif "Contenu interdit: Jeux d'argent"
|
||||
Car la publicité pour les jeux d'argent est soumise à régulation stricte
|
||||
|
||||
Scénario: Contenus interdits - Politique pendant campagne électorale
|
||||
Étant donné qu'une publicité politique est soumise
|
||||
Et que nous sommes en période de campagne électorale officielle
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit refuser la campagne
|
||||
Et sélectionner le motif "Contenu interdit: Publicité politique (période électorale)"
|
||||
|
||||
Scénario: Contenus interdits - Contenu sexuel
|
||||
Étant donné qu'une publicité contient des propos sexuellement explicites
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit refuser la campagne
|
||||
Et sélectionner le motif "Contenu interdit: Contenu sexuel"
|
||||
|
||||
Scénario: Contenus interdits - Violence
|
||||
Étant donné qu'une publicité contient des descriptions violentes
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit refuser la campagne
|
||||
Et sélectionner le motif "Contenu interdit: Violence"
|
||||
|
||||
Scénario: Contenu légal autorisé - Commerce local
|
||||
Étant donné qu'une publicité pour un restaurant local dit "Découvrez notre menu du jour"
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit approuver la campagne
|
||||
Car le contenu est légal et conforme
|
||||
|
||||
Scénario: Contenu légal autorisé - Service professionnel
|
||||
Étant donné qu'une publicité pour un garage dit "Révision complète à partir de 99€"
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit approuver la campagne
|
||||
Car le contenu est légal et informatif
|
||||
|
||||
Scénario: Critères de validation - Qualité audio
|
||||
Étant donné qu'une publicité a une qualité audio très basse (bruits, saturation)
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il peut refuser avec le motif "Qualité audio insuffisante"
|
||||
Et recommander "Veuillez soumettre un fichier audio de meilleure qualité"
|
||||
|
||||
Scénario: Critères de validation - Classification d'âge correcte
|
||||
Étant donné qu'une publicité contient du langage familier
|
||||
Et qu'elle est classée "Tout public"
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il peut refuser avec le motif "Classification d'âge incorrecte"
|
||||
Et recommander "Reclasser en 13+ minimum"
|
||||
|
||||
Scénario: Critères de validation - Respect réglementation française
|
||||
Étant donné qu'une publicité fait des promesses mensongères "Perdez 10kg en 1 semaine"
|
||||
Quand le modérateur écoute l'audio
|
||||
Alors il doit refuser avec le motif "Non-conformité réglementaire: Publicité mensongère"
|
||||
Car cela viole la réglementation sur la publicité trompeuse
|
||||
|
||||
Scénario: File d'attente modération priorisée
|
||||
Étant donné que 10 campagnes sont en attente de validation
|
||||
Et que la campagne A a été soumise il y a 40h
|
||||
Et que la campagne B a été soumise il y a 2h
|
||||
Quand le modérateur consulte sa file
|
||||
Alors la campagne A apparaît en premier (priorité temporelle)
|
||||
Et un badge "Urgente - >40h" est affiché
|
||||
|
||||
Scénario: Dashboard modération - Vue d'ensemble
|
||||
Étant donné que je suis modérateur
|
||||
Quand j'accède au dashboard modération publicités
|
||||
Alors je vois:
|
||||
| Métrique | Exemple valeur |
|
||||
| Campagnes en attente | 5 |
|
||||
| Délai moyen de validation | 28h |
|
||||
| Campagnes validées aujourd'hui | 12 |
|
||||
| Campagnes refusées aujourd'hui | 3 |
|
||||
| Taux d'acceptation | 80% |
|
||||
|
||||
Scénario: Transcription automatique pour aide modération
|
||||
Étant donné qu'une publicité audio est soumise
|
||||
Quand le système traite l'audio
|
||||
Alors une transcription automatique est générée via Whisper
|
||||
Et elle est affichée au modérateur pour faciliter la revue
|
||||
Et elle permet une recherche par mots-clés (alcool, tabac, etc.)
|
||||
|
||||
Scénario: Détection automatique mots-clés interdits
|
||||
Étant donné qu'une publicité audio est soumise
|
||||
Quand la transcription contient "whisky" ou "vodka"
|
||||
Alors un flag automatique "⚠️ Alcool détecté" est ajouté
|
||||
Et la campagne est priorisée pour validation manuelle rapide
|
||||
Et le modérateur est alerté du contenu potentiellement interdit
|
||||
|
||||
Scénario: Historique modération publicitaire
|
||||
Étant donné qu'un publicitaire a eu 2 campagnes refusées
|
||||
Quand il soumet une 3ème campagne
|
||||
Alors le modérateur voit l'historique:
|
||||
| Date | Statut | Motif |
|
||||
| 2026-01-15 | Refusée | Contenu interdit: Alcool |
|
||||
| 2026-01-20 | Refusée | Qualité audio faible |
|
||||
Et il peut en tenir compte dans sa décision
|
||||
|
||||
Scénario: Appel possible après refus
|
||||
Étant donné que ma campagne a été refusée pour "Classification incorrecte"
|
||||
Quand je conteste la décision via le formulaire d'appel
|
||||
Alors un modérateur senior revoit la campagne
|
||||
Et il peut approuver si la classification est en fait correcte
|
||||
Et le délai de réponse est de 48-72h
|
||||
|
||||
Scénario: Notification temps réel pour modérateurs
|
||||
Étant donné que je suis modérateur connecté
|
||||
Quand une nouvelle campagne est soumise
|
||||
Alors je reçois une notification in-app
|
||||
Et le compteur "Campagnes en attente" s'incrémente en temps réel
|
||||
Et je peux cliquer pour consulter immédiatement
|
||||
|
||||
Scénario: Statistiques conformité par catégorie
|
||||
Étant donné que je suis admin modération
|
||||
Quand je consulte les statistiques mensuelles
|
||||
Alors je vois les motifs de refus:
|
||||
| Motif | Nombre | Pourcentage |
|
||||
| Alcool | 15 | 30% |
|
||||
| Qualité audio | 12 | 24% |
|
||||
| Classification erronée | 10 | 20% |
|
||||
| Publicité mensongère | 8 | 16% |
|
||||
| Autres | 5 | 10% |
|
||||
|
||||
Scénario: Export rapport modération
|
||||
Étant donné que je suis modérateur senior
|
||||
Quand j'exporte le rapport mensuel
|
||||
Alors je reçois un fichier CSV avec:
|
||||
| Colonne |
|
||||
| Campagne ID |
|
||||
| Publicitaire |
|
||||
| Date soumission |
|
||||
| Date décision |
|
||||
| Statut |
|
||||
| Motif (si refus) |
|
||||
| Modérateur |
|
||||
Et je peux l'analyser dans Excel
|
||||
|
||||
Scénario: Validation partielle avec demande modification
|
||||
Étant donné qu'une campagne a un contenu acceptable
|
||||
Mais que la classification d'âge est incorrecte
|
||||
Quand le modérateur clique sur "Demander modification"
|
||||
Alors le publicitaire reçoit un email:
|
||||
"""
|
||||
Modification requise
|
||||
|
||||
Votre campagne nécessite un ajustement:
|
||||
- Reclasser de "Tout public" à "13+"
|
||||
|
||||
Veuillez modifier et soumettre à nouveau.
|
||||
Budget conservé, pas de remboursement.
|
||||
"""
|
||||
Et le statut devient "Modification requise"
|
||||
Et le publicitaire peut modifier sans repayer
|
||||
|
||||
Plan du Scénario: Contenus interdits automatiquement détectés
|
||||
Étant donné qu'une publicité contient le mot <mot_cle>
|
||||
Quand la transcription automatique est analysée
|
||||
Alors un flag <flag> est ajouté
|
||||
Et le motif de refus suggéré est <motif>
|
||||
|
||||
Exemples:
|
||||
| mot_cle | flag | motif |
|
||||
| whisky | ⚠️ Alcool | Contenu interdit: Alcool |
|
||||
| vodka | ⚠️ Alcool | Contenu interdit: Alcool |
|
||||
| cigarette | ⚠️ Tabac | Contenu interdit: Tabac |
|
||||
| casino | ⚠️ Jeux argent | Contenu interdit: Jeux |
|
||||
| paris sportifs | ⚠️ Jeux argent | Contenu interdit: Jeux |
|
||||
|
||||
Plan du Scénario: Délais de validation selon soumission
|
||||
Étant donné qu'une campagne est soumise <jour> à <heure>
|
||||
Quand elle est validée <delai> heures plus tard
|
||||
Alors le statut est <conformite>
|
||||
|
||||
Exemples:
|
||||
| jour | heure | delai | conformite |
|
||||
| Lundi | 10h | 24 | Dans les délais (24h) |
|
||||
| Lundi | 10h | 48 | Dans les délais (48h) |
|
||||
| Lundi | 10h | 50 | Hors délais (>48h) |
|
||||
| Vendredi| 16h | 72 | Dans les délais (we) |
|
||||
289
docs/domains/advertising/rules/publicites.md
Normal file
289
docs/domains/advertising/rules/publicites.md
Normal file
@@ -0,0 +1,289 @@
|
||||
## 6. Publicités
|
||||
|
||||
### 6.1 Système de campagnes publicitaires
|
||||
|
||||
**Décision** : Interface self-service avec maîtrise budget et métriques détaillées
|
||||
|
||||
**Fonctionnalités publicitaire** :
|
||||
|
||||
#### Création de campagne
|
||||
|
||||
**Paramètres configurables** :
|
||||
|
||||
| Paramètre | Options | Justification |
|
||||
|-----------|---------|---------------|
|
||||
| **Budget total** | Montant libre (min 50€) | Maîtrise coût total |
|
||||
| **Durée campagne** | Date début/fin + étalement | Ex: 300€ sur 2 semaines |
|
||||
| **Ciblage géographique** | Point GPS / Ville / Département / Région / National | Précision selon besoin |
|
||||
| **Ciblage horaire** | Plages horaires (ex: 7h-9h, 17h-19h) - **Heure locale utilisateur** | Optimisation trajet domicile-travail |
|
||||
| **Centres d'intérêt** | Tags (ex: Automobile, Voyage) | Ciblage thématique |
|
||||
| **Tranche d'âge** | Tout public / 13+ / 16+ / 18+ | Respect classifications |
|
||||
|
||||
**Précision ciblage horaire** :
|
||||
|
||||
**Règle 1 : Ciblage horaire = Heure locale utilisateur**
|
||||
|
||||
Une campagne "7h-9h" diffuse entre 7h-9h **heure locale** de chaque utilisateur, quel que soit son fuseau horaire.
|
||||
|
||||
**Exemples** :
|
||||
```
|
||||
Campagne : 7h-9h (rush matin)
|
||||
|
||||
User Marseille (UTC+1) à 8h locale → ✅ Diffusion
|
||||
User Guadeloupe (UTC-4) à 8h locale → ✅ Diffusion
|
||||
User Réunion (UTC+4) à 8h locale → ✅ Diffusion
|
||||
User Métropole à 13h locale → ❌ Pas de diffusion (hors plage)
|
||||
```
|
||||
|
||||
**Implémentation technique** :
|
||||
|
||||
```javascript
|
||||
// Backend détecte fuseau horaire user (GPS ou device settings)
|
||||
const userTimezone = getUserTimezone(); // "Europe/Paris", "America/Guadeloupe", etc.
|
||||
const userLocalTime = DateTime.now().setZone(userTimezone);
|
||||
const userHour = userLocalTime.hour; // 0-23
|
||||
|
||||
// Campagne pub
|
||||
const campaign = {
|
||||
hours: [7, 8, 9], // 7h-9h inclut 7h, 8h (se termine à 9h)
|
||||
// ...
|
||||
};
|
||||
|
||||
// Vérification diffusion
|
||||
if (campaign.hours.includes(userHour)) {
|
||||
// ✅ Diffuser pub
|
||||
}
|
||||
```
|
||||
|
||||
**Détection fuseau horaire** :
|
||||
1. GPS (latitude/longitude) → déterminer fuseau via base IANA Time Zone
|
||||
2. Si GPS désactivé → paramètres device (timezone OS)
|
||||
3. Fallback : IP geolocation → fuseau approximatif
|
||||
|
||||
**Règle 2 : Ciblage "France" = Métropole + DOM**
|
||||
|
||||
**France entière inclut** :
|
||||
- France métropolitaine (96 départements)
|
||||
- Guadeloupe (971)
|
||||
- Martinique (972)
|
||||
- Guyane (973)
|
||||
- Réunion (974)
|
||||
- Mayotte (976)
|
||||
|
||||
**Publicitaire peut affiner** :
|
||||
- "Région Provence-Alpes-Côte d'Azur" → Métropole uniquement
|
||||
- "Département 971" → Guadeloupe uniquement
|
||||
- "Ville Pointe-à-Pitre" → Guadeloupe uniquement
|
||||
|
||||
**Interface publicitaire** :
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────┐
|
||||
│ Ciblage géographique │
|
||||
├────────────────────────────────────────┤
|
||||
│ ○ National (France entière) │
|
||||
│ ● Région │
|
||||
│ [Provence-Alpes-Côte d'Azur ▼] │
|
||||
│ │
|
||||
│ ○ Département │
|
||||
│ [13 - Bouches-du-Rhône ▼] │
|
||||
│ │
|
||||
│ ○ Ville │
|
||||
│ ○ Point GPS + rayon │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
ℹ️ Note : "National (France entière)" inclut les DOM
|
||||
(Guadeloupe, Martinique, Réunion, Guyane, Mayotte)
|
||||
```
|
||||
|
||||
**Cas d'usage et cohérence** :
|
||||
|
||||
**Cas 1 : Publicitaire local Guadeloupe**
|
||||
```
|
||||
Restaurant à Pointe-à-Pitre
|
||||
Campagne :
|
||||
- Zone : Guadeloupe (département 971)
|
||||
- Horaires : 12h-14h (rush déjeuner)
|
||||
|
||||
User Guadeloupe à 12h30 locale → ✅ Diffusion (dans zone + horaire)
|
||||
User Métropole à 12h30 locale → ❌ Pas diffusion (hors zone géo)
|
||||
User Martinique à 12h30 locale → ❌ Pas diffusion (hors zone géo)
|
||||
```
|
||||
|
||||
**Cas 2 : Campagne nationale rush matin**
|
||||
```
|
||||
Assureur national
|
||||
Campagne :
|
||||
- Zone : France (nationale)
|
||||
- Horaires : 7h-9h + 17h-19h
|
||||
|
||||
User Marseille 8h locale → ✅ Diffusion (rush matin métropole)
|
||||
User Réunion 8h locale → ✅ Diffusion (rush matin Réunion, UTC+4)
|
||||
→ En métropole il est 5h (nuit), mais user Réunion est bien en rush matin
|
||||
```
|
||||
|
||||
**Cas 3 : User en déplacement change de fuseau**
|
||||
```
|
||||
User en métropole
|
||||
→ Télécharge 50 contenus + pubs
|
||||
→ Part en vacances Réunion (UTC+4)
|
||||
→ Device détecte nouveau fuseau (GPS)
|
||||
→ Écoute à 8h locale Réunion
|
||||
|
||||
Filtrage pubs :
|
||||
→ Heure locale = 8h Réunion
|
||||
→ Campagne 7h-9h → ✅ Diffusion
|
||||
```
|
||||
|
||||
**Justification** :
|
||||
- ✅ **UX intuitive pour publicitaires** : "7h-9h" = matin partout (pas besoin comprendre UTC)
|
||||
- ✅ **Équité géographique** : pas de discrimination DOM-TOM, publicitaires locaux peuvent cibler local, campagnes nationales touchent tous Français
|
||||
- ✅ **Simplicité technique** : détection fuseau automatique (GPS ou device), PostgreSQL `AT TIME ZONE` pour calculs backend
|
||||
- ✅ **Standard industrie** : Google Ads, Facebook Ads = heure locale par défaut
|
||||
|
||||
**Étalement budget** :
|
||||
```
|
||||
Exemple campagne :
|
||||
- Budget : 300€
|
||||
- Durée : 14 jours
|
||||
- Zone : Département du Var
|
||||
- Horaires : 7h-9h + 17h-19h (rush)
|
||||
|
||||
Calcul automatique :
|
||||
→ Budget/jour = 300€ / 14 = 21.43€/jour
|
||||
→ Diffusions/jour estimées : ~430 (0.05€/écoute)
|
||||
→ Alerte si budget épuisé avant fin (réajustement possible)
|
||||
```
|
||||
|
||||
**Mode de paiement** :
|
||||
- ✅ Prépaiement obligatoire (évite impayés)
|
||||
- ✅ Carte bancaire uniquement (Mangopay)
|
||||
- ✅ Recharge automatique optionnelle (si budget <10%)
|
||||
|
||||
#### Validation et modération
|
||||
|
||||
**Processus** :
|
||||
1. Publicitaire upload audio pub (formats : MP3, AAC)
|
||||
2. **Validation manuelle obligatoire** (modérateur RoadWave)
|
||||
- Délai : 24-48h ouvrées
|
||||
- Critères : respect réglementation, qualité audio, classification correcte
|
||||
3. Si accepté → campagne démarre à la date choisie
|
||||
4. Si refusé → email avec raison + remboursement automatique
|
||||
|
||||
**Contenus interdits en pub** :
|
||||
- ❌ Alcool, tabac (réglementation française)
|
||||
- ❌ Jeux d'argent
|
||||
- ❌ Contenu politique (pendant campagnes électorales)
|
||||
- ❌ Contenu sexuel ou violence
|
||||
- ✅ Tous commerces/services légaux
|
||||
|
||||
#### Dashboard métriques engagement
|
||||
|
||||
**Indicateurs temps réel** :
|
||||
|
||||
| Métrique | Description | Utilité |
|
||||
|----------|-------------|---------|
|
||||
| **Impressions** | Nombre de diffusions | Volume exposition |
|
||||
| **Écoutes complètes** | Pub écoutée >80% | Engagement réel |
|
||||
| **Taux de skip** | % skip après délai min | Qualité contenu |
|
||||
| **Durée moyenne écoute** | Secondes écoutées | Rétention attention |
|
||||
| **Likes** | Nombre de likes | Appréciation contenu |
|
||||
| **Abonnements** | Abonnements au créateur pub | Conversion forte |
|
||||
| **Coût par écoute** | Budget / écoutes complètes | ROI campagne |
|
||||
| **Répartition géographique** | Heatmap diffusions | Validation ciblage |
|
||||
| **Répartition horaire** | Graphique par heure | Optimisation horaires |
|
||||
|
||||
**Métriques engagement avancées** :
|
||||
- **Taux complétion par tranche d'âge** : identifier audience réceptive
|
||||
- **Carte de chaleur GPS** : visualiser zones forte écoute
|
||||
- **Comparatif campagnes** : A/B testing créatifs publicitaires
|
||||
|
||||
**Export données** :
|
||||
- ✅ CSV/Excel pour analyse externe
|
||||
- ✅ Graphiques interactifs (Chart.js)
|
||||
- ✅ Rapport PDF automatique fin de campagne
|
||||
|
||||
#### Gestion budget et alertes
|
||||
|
||||
**Suivi temps réel** :
|
||||
- Dashboard : Budget restant, % consommé, jours restants
|
||||
- Projection : "À ce rythme, budget épuisé dans X jours"
|
||||
- Alerte email/push si :
|
||||
- Budget consommé à 80%
|
||||
- Budget consommé à 90%
|
||||
- Budget épuisé
|
||||
- Campagne terminée (rapport final)
|
||||
|
||||
**Ajustements en cours** :
|
||||
- ✅ Pause campagne (budget conservé)
|
||||
- ✅ Prolonger campagne (recharge budget)
|
||||
- ✅ Modifier ciblage horaire/géo (si <50% budget consommé)
|
||||
- ❌ Modifier audio (nécessite nouvelle validation)
|
||||
|
||||
#### Système d'enchères (post-MVP)
|
||||
|
||||
**Optionnel future** :
|
||||
- Enchère au CPM (coût pour 1000 impressions)
|
||||
- Priorité selon prix : pub prix élevé → diffusion privilégiée
|
||||
- Floor price : 2€ CPM minimum
|
||||
- Évite surcharge pub : max 1 pub / 5 contenus stricte
|
||||
|
||||
**Justification décision MVP** :
|
||||
- Tarif fixe simple : 0.05€/écoute complète
|
||||
- Pas de complexité enchères immédiatement
|
||||
- Scalable : passage enchères ultérieur si demande forte
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Insertion et fréquence
|
||||
|
||||
**Décision** : Paramétrable admin + respect expérience utilisateur
|
||||
|
||||
**Fréquence d'insertion** :
|
||||
- **Défaut : 1 pub / 5 contenus** (utilisateurs gratuits)
|
||||
- **Paramétrable admin** : curseur 1/3 à 1/10
|
||||
- **Utilisateurs Premium** : 0 pub (modèle sans publicité)
|
||||
|
||||
**Règles strictes** :
|
||||
- ⚠️ **Jamais d'interruption** contenu en cours
|
||||
- Pub s'insère uniquement **entre deux contenus** (pendant délai 2s)
|
||||
- Rotation : même pub max **3 fois/jour** par utilisateur (évite saturation)
|
||||
- Limite : max **6 pubs/heure** par utilisateur (évite spam)
|
||||
|
||||
**Ciblage intelligent** :
|
||||
- Géolocalisation prioritaire (point GPS > ville > département > région > national)
|
||||
- Centres d'intérêt secondaires (tags utilisateur)
|
||||
- Horaire (campagne 7h-9h → diffusion uniquement pendant plage **heure locale utilisateur**, voir section 6.1 pour détails fuseaux horaires et DOM-TOM)
|
||||
|
||||
**Volume audio normalisé** :
|
||||
- Pub normalisée à **-14 LUFS** (standard broadcast)
|
||||
- Évite effet "pub trop forte" (frustration utilisateur)
|
||||
- Validation automatique via FFmpeg lors encodage
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Caractéristiques publicités
|
||||
|
||||
**Durée** :
|
||||
- Minimum : **10 secondes**
|
||||
- Maximum : **60 secondes**
|
||||
- Recommandé : **15-30 secondes** (sweet spot engagement)
|
||||
|
||||
**Skippable** :
|
||||
- Délai minimum obligatoire : **5 secondes** (paramétrable admin : 3-10s)
|
||||
- Bouton "Passer la publicité" apparaît après délai
|
||||
- Durée minimale comptabilisée pour facturation
|
||||
|
||||
**Facturation** :
|
||||
- **Écoute complète** (>80%) : 0.05€ facturé publicitaire
|
||||
- **Skip après délai min** : 0.02€ (exposition partielle)
|
||||
- **Skip immédiat** (<5s) : 0€ (pas d'engagement)
|
||||
|
||||
**Justification modèle tarif** :
|
||||
- Incitatif qualité : pub engageante = coût réduit
|
||||
- Équitable : publicitaire paie pour attention réelle
|
||||
- Transparent : dashboard montre écoutes complètes vs skips
|
||||
|
||||
---
|
||||
|
||||
## Récapitulatif Section 6
|
||||
Reference in New Issue
Block a user