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:
285
docs/domains/content/rules/creation-publication.md
Normal file
285
docs/domains/content/rules/creation-publication.md
Normal file
@@ -0,0 +1,285 @@
|
||||
## 4. Création et publication de contenu
|
||||
|
||||
### 4.1 Upload et encodage
|
||||
|
||||
**Décision** : Formats universels avec encodage asynchrone
|
||||
|
||||
**Formats acceptés** :
|
||||
- ✅ MP3 (`.mp3`)
|
||||
- ✅ AAC (`.aac`, `.m4a`)
|
||||
- ❌ WAV, FLAC (trop lourds, inutiles en voiture)
|
||||
|
||||
**Limites** :
|
||||
|
||||
| Paramètre | Valeur | Justification |
|
||||
|-----------|--------|---------------|
|
||||
| **Taille maximale** | 200 MB | ~4h de podcast à 128 kbps |
|
||||
| **Durée maximale** | 4 heures | Suffisant pour podcasts longs |
|
||||
| **Validation format** | Client + backend | Double sécurité |
|
||||
|
||||
**Pipeline d'encodage** :
|
||||
|
||||
```
|
||||
1. Upload fichier (MP3/AAC) → OVH Object Storage temporaire
|
||||
2. Job asynchrone (worker Go + FFmpeg) :
|
||||
- Validation format et intégrité
|
||||
- Réencodage Opus 3 profils (24/48/64 kbps)
|
||||
- Génération segments HLS (.m3u8 + .ts)
|
||||
- Génération image couverture par défaut
|
||||
3. Suppression fichier original (économie stockage)
|
||||
4. Notification créateur : "Contenu prêt à publier"
|
||||
```
|
||||
|
||||
**Temps d'encodage estimé** :
|
||||
- Contenu 5 min → ~30 secondes
|
||||
- Podcast 1h → ~5 minutes
|
||||
- Podcast 4h → ~20 minutes
|
||||
|
||||
**Profils Opus générés** :
|
||||
|
||||
| Qualité | Bitrate | Usage |
|
||||
|---------|---------|-------|
|
||||
| Basse | 24 kbps | 2G/Edge |
|
||||
| Standard | 48 kbps | 3G (défaut) |
|
||||
| Haute | 64 kbps | 4G/5G |
|
||||
|
||||
**Écoute accélérée** :
|
||||
|
||||
| Vitesse | Usage |
|
||||
|---------|-------|
|
||||
| 0.75x | Compréhension difficile (accent, technique) |
|
||||
| 1.0x | Normal (défaut) |
|
||||
| 1.25x | Gain léger |
|
||||
| 1.5x | Podcasts longs |
|
||||
| 2.0x | Survol rapide (modérateurs) |
|
||||
|
||||
**Disponible pour** :
|
||||
- ✅ Modérateurs (validation rapide : 30s → 15s à 2x)
|
||||
- ✅ Auditeurs (tous les contenus)
|
||||
- ✅ Standard industrie (YouTube, Spotify, Apple Podcasts)
|
||||
|
||||
**Justification** :
|
||||
- **Simplicité** : 2 formats couvrent 95% des cas d'usage
|
||||
- **Coût optimisé** : pas de conversion WAV/FLAC lourds
|
||||
- **Stockage réduit** : suppression original après encodage
|
||||
- **Scalabilité** : workers horizontalement (Kubernetes jobs)
|
||||
- **Productivité** : écoute accélérée = double productivité modération
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Métadonnées obligatoires
|
||||
|
||||
**Décision** : Minimaliste pour réduire friction
|
||||
|
||||
**Champs obligatoires** :
|
||||
|
||||
| Champ | Format | Validation |
|
||||
|-------|--------|------------|
|
||||
| **Titre** | 5-100 caractères | Alphanumérique + ponctuation basique |
|
||||
| **Type géo** | Enum | Ancré / Contextuel / Neutre |
|
||||
| **Zone diffusion** | Composite | Voir détails ci-dessous |
|
||||
| **Tags** | Enum | 1 à 3 parmi liste prédéfinie |
|
||||
| **Classification âge** | Enum | Tout public / 13+ / 16+ / 18+ |
|
||||
|
||||
**Zone de diffusion (obligatoire)** :
|
||||
|
||||
Options mutuellement exclusives :
|
||||
- **Point GPS** : latitude + longitude + rayon (100m à 10km)
|
||||
- **Ville** : sélection dans référentiel INSEE
|
||||
- **Département** : sélection liste
|
||||
- **Région** : sélection liste
|
||||
- **National** : France entière
|
||||
|
||||
**Tags disponibles** (1 à 3 obligatoires) :
|
||||
- Automobile
|
||||
- Voyage
|
||||
- Famille
|
||||
- Amour
|
||||
- Musique
|
||||
- Économie
|
||||
- Cryptomonnaie
|
||||
- Politique
|
||||
- Culture générale
|
||||
- Sport
|
||||
- Technologie
|
||||
- Santé
|
||||
|
||||
**Champs optionnels** :
|
||||
- ❌ Description (ajout ultérieur)
|
||||
- ❌ Image couverture (génération auto)
|
||||
|
||||
**Image de couverture par défaut** :
|
||||
|
||||
Génération automatique selon règles :
|
||||
- Icône selon type géo : 📍 Ancré / 🌍 Contextuel / 🎧 Neutre
|
||||
- Couleur selon tag principal : bleu (Auto), vert (Voyage), rouge (Musique), etc.
|
||||
- Format 800×800px, PNG
|
||||
- Personnalisable ultérieurement (post-MVP)
|
||||
|
||||
**Exemple de publication** :
|
||||
```
|
||||
Titre : "Histoire de la Tour Eiffel"
|
||||
Type géo : Ancré
|
||||
Zone : Point GPS (48.8584, 2.2945, rayon 500m)
|
||||
Tags : Voyage, Culture générale
|
||||
Classification : Tout public
|
||||
→ Image auto : 📍 fond bleu-vert (Voyage)
|
||||
```
|
||||
|
||||
**Justification** :
|
||||
- **Friction minimale** : 5 champs max = 2 min de publication
|
||||
- **Publication rapide** : pas de blocage sur description/image
|
||||
- **Coût 0** : pas de génération IA au MVP
|
||||
- **Évolutif** : champs optionnels ajoutables ultérieurement
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Validation des 3 premiers contenus
|
||||
|
||||
**Décision** : Validation manuelle par équipe modération RoadWave
|
||||
|
||||
**Processus nouveau créateur** :
|
||||
|
||||
1. Créateur upload ses 3 premiers contenus
|
||||
2. Contenus passent en **file d'attente modération**
|
||||
3. Modérateur junior RoadWave :
|
||||
- Écoute 30 secondes (ou 15s à 2x)
|
||||
- Vérifie métadonnées
|
||||
- Valide ou rejette avec raison
|
||||
4. Si accepté : contenu publié + notification créateur
|
||||
5. Si refusé : notification avec raison détaillée + lien vers règles
|
||||
6. Après 3 contenus validés : créateur passe en **statut vérifié**
|
||||
|
||||
**Critères de validation** :
|
||||
|
||||
| Critère | Détails |
|
||||
|---------|---------|
|
||||
| **Qualité audio** | Compréhensible (pas de grésillement excessif) |
|
||||
| **Respect règles** | Pas de contenu prohibé évident (haine, spam, illégal) |
|
||||
| **Classification âge** | Cohérente avec contenu écouté |
|
||||
| **Tags pertinents** | Correspondance minimale avec contenu |
|
||||
| **Zone diffusion** | Cohérente (pas "Tour Eiffel" avec zone "National") |
|
||||
|
||||
**Délai de validation** :
|
||||
- Objectif : **24-48h** (jours ouvrés)
|
||||
- Priorité : FIFO (First In First Out)
|
||||
- Weekend : délai peut atteindre 72h
|
||||
- Message au créateur : "Validation en cours, délai estimé 24-48h"
|
||||
|
||||
**Notification créateur** :
|
||||
|
||||
**Si accepté** :
|
||||
- Email + push : "✅ Votre contenu '[Titre]' est en ligne !"
|
||||
- Lien direct vers le contenu
|
||||
- Compteur : "2/3 contenus validés pour devenir créateur vérifié"
|
||||
|
||||
**Si refusé** :
|
||||
- Email + push : "❌ Contenu '[Titre]' refusé"
|
||||
- Raison détaillée : "Qualité audio insuffisante" / "Tags non pertinents" / "Classification incorrecte" / etc.
|
||||
- Lien vers règles de publication
|
||||
- Possibilité de correction + resoumission
|
||||
|
||||
**Après 3 validations** :
|
||||
|
||||
Créateur obtient **statut "Vérifié"** :
|
||||
- Badge ✓ visible sur profil
|
||||
- Contenus futurs publiés **immédiatement** (modération a posteriori uniquement)
|
||||
- Modération seulement si signalé par utilisateurs
|
||||
|
||||
**Outils modérateur** :
|
||||
- Écoute accélérée (1.5x ou 2x) = double productivité
|
||||
- Interface dédiée : queue de contenus à valider
|
||||
- Raccourcis clavier : A (Accepter), R (Rejeter), Espace (Pause)
|
||||
- Historique créateur visible (si déjà 1-2 contenus validés)
|
||||
|
||||
**Modération communautaire (post-MVP)** :
|
||||
|
||||
⚠️ **Non implémenté au MVP** (complexité juridique)
|
||||
|
||||
Vision future (envisageable) :
|
||||
- Créateurs établis peuvent opt-in "Modérateur communautaire"
|
||||
- Formation obligatoire (30 min) + quiz (80%)
|
||||
- Pré-validation uniquement (validation finale toujours par équipe RoadWave)
|
||||
- Compensation : badges, premium offert
|
||||
- Attribution aléatoire (pas de collusion)
|
||||
|
||||
**Justification décision MVP** :
|
||||
- **Responsabilité juridique** : plateforme reste responsable (DSA EU)
|
||||
- **Qualité garantie** : modérateurs formés et mandatés
|
||||
- **Anti-spam efficace** : bloque 95% des abus dès le début
|
||||
- **Coût raisonnable** : 30s × 3 contenus = 1.5 min/créateur
|
||||
- **UX acceptable** : délai 24-48h expliqué clairement
|
||||
- **Pas de validation par pairs** au MVP = évite risques juridiques (collusion, compétence, conflits)
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Modification et suppression
|
||||
|
||||
**Décision** : Modification métadonnées uniquement, suppression immédiate
|
||||
|
||||
**Modification autorisée** :
|
||||
|
||||
| Élément | Modifiable | Justification |
|
||||
|---------|------------|---------------|
|
||||
| **Titre** | ✅ | Correction coquilles |
|
||||
| **Description** | ✅ | Si ajoutée ultérieurement |
|
||||
| **Tags** | ✅ | Ajustement pertinence |
|
||||
| **Image couverture** | ✅ | Personnalisation |
|
||||
| **Audio** | ❌ | Intégrité contenu |
|
||||
| **Zone diffusion** | ❌ | Évite manipulation algo |
|
||||
| **Type géo** | ❌ | Évite manipulation algo |
|
||||
| **Classification âge** | ❌ | Sécurité mineurs |
|
||||
|
||||
**Raisons restrictions** :
|
||||
|
||||
**Audio non modifiable** :
|
||||
- Évite fraude : uploader contenu validé → remplacer par spam
|
||||
- Intégrité : auditeurs doivent écouter ce qui a été validé
|
||||
|
||||
**Zone/Type non modifiables** :
|
||||
- Évite manipulation : créer "Local Paris" → changer en "National" pour boost visibilité
|
||||
- Évite abus : créer "Neutre" (faible pondération géo) → changer en "Ancré" (forte pondération)
|
||||
|
||||
**Classification non modifiable** :
|
||||
- Évite contournement : uploader "Tout public" → passer en "18+" sans revalidation
|
||||
- Sécurité : garantit que classification a été vérifiée
|
||||
|
||||
**Si besoin de changer audio/zone/classification** :
|
||||
- Action : **Supprimer contenu + republier**
|
||||
- Si créateur <3 contenus validés : retourne en file validation
|
||||
- Si créateur ≥3 contenus validés : publication immédiate
|
||||
|
||||
**Suppression de contenu** :
|
||||
|
||||
| Aspect | Comportement |
|
||||
|--------|--------------|
|
||||
| **Délai** | Immédiat | Suppression BDD + cache sous 5 min |
|
||||
| **Réversibilité** | Non | Suppression définitive |
|
||||
| **Historique auditeurs** | Marqué "Contenu supprimé par créateur" | Conserve écoute dans historique |
|
||||
| **Analytics plateforme** | Anonymisé et conservé | Métriques globales (RGPD compliant) |
|
||||
| **Fichiers cache** | Supprimés sous 24h | Purge NGINX Cache (OVH VPS) et OVH Object Storage |
|
||||
|
||||
**Exemple scénario suppression** :
|
||||
```
|
||||
Créateur supprime podcast écouté par 1000 personnes
|
||||
→ Cache/Storage : fichiers purgés sous 24h (NGINX Cache + OVH Object Storage)
|
||||
→ BDD : entrée marquée "deleted", auteur anonymisé
|
||||
→ Historique auditeurs : "Contenu supprimé" (conserve durée écoute pour stats)
|
||||
→ Analytics : métriques globales conservées (anonymes, RGPD OK)
|
||||
```
|
||||
|
||||
**Notifications suppression** :
|
||||
- Pas de notification aux auditeurs (pour éviter effet Streisand)
|
||||
- Historique reste consultable : "Vous avez écouté ce contenu le [date]"
|
||||
- Si auditeur tente de réécouter : "Ce contenu n'est plus disponible"
|
||||
|
||||
**Justification** :
|
||||
- **Simplicité** : règles claires et non-ambiguës
|
||||
- **Sécurité** : évite manipulations algorithme et contournements modération
|
||||
- **Contrôle créateur** : liberté totale de supprimer (RGPD)
|
||||
- **Traçabilité** : historique conservé pour analytics (anonymisé)
|
||||
- **Coût 0** : pas de revalidation métadonnées
|
||||
|
||||
---
|
||||
|
||||
## Récapitulatif Section 4
|
||||
Reference in New Issue
Block a user