Files
roadwave/docs/domains/advertising/rules/publicites.md
jpgiannetti 5e5fcf4714 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.
2026-02-07 17:15:02 +01:00

290 lines
10 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 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