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:
51
docs/domains/moderation/README.md
Normal file
51
docs/domains/moderation/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Domaine : Moderation
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Le domaine **Moderation** gère la modération des contenus et des utilisateurs, les signalements, les sanctions et le système de badges de confiance. C'est un **Supporting Subdomain** critique pour la qualité et la sécurité de la plateforme.
|
||||
|
||||
## Responsabilités
|
||||
|
||||
- **Signalements** : Workflow de traitement des signalements utilisateurs
|
||||
- **Sanctions** : Système de strikes et bannissements
|
||||
- **Appels** : Processus de contestation des sanctions
|
||||
- **Badges de confiance** : Attribution de badges aux créateurs fiables
|
||||
- **Modération communautaire** : Implication des utilisateurs dans la modération
|
||||
|
||||
## Règles métier
|
||||
|
||||
- [Moderation flows](rules/moderation-flows.md) - Workflows de modération
|
||||
- [Modération communautaire](rules/moderation-communautaire.md)
|
||||
- [Autres comportements](rules/autres-comportements.md) - Comportements sanctionnables
|
||||
|
||||
## Modèle de données
|
||||
|
||||
- [Diagramme entités modération](entities/modele-moderation.md) - Entités : REPORTS, SANCTIONS, APPEALS, STRIKES, BADGES
|
||||
|
||||
## Diagrammes
|
||||
|
||||
- [Flux : Modération et signalement](flows/moderation-signalement.md)
|
||||
- [États : Lifecycle d'un signalement](states/signalement-lifecycle.md)
|
||||
- [Séquence : Processus d'appel](sequences/processus-appel-moderation.md)
|
||||
|
||||
## Tests BDD
|
||||
|
||||
- Features de modération *(voir Phase 6)*
|
||||
|
||||
## Ubiquitous Language
|
||||
|
||||
**Termes métier du domaine** :
|
||||
- **Report** : Signalement d'un contenu ou utilisateur problématique
|
||||
- **Strike** : Avertissement comptabilisé (3 strikes = ban)
|
||||
- **Sanction** : Mesure disciplinaire (warning, suspension, ban)
|
||||
- **Appeal** : Contestation d'une sanction par l'utilisateur
|
||||
- **Trust Badge** : Badge de confiance attribué aux créateurs fiables
|
||||
- **Community Moderation** : Modération participative par les utilisateurs
|
||||
- **Moderator** : Utilisateur avec droits de modération
|
||||
- **Auto-Moderation** : Modération automatique (IA, filtres)
|
||||
|
||||
## Dépendances
|
||||
|
||||
- ✅ Dépend de : `_shared` (users, contents)
|
||||
- ⚠️ Interactions avec : `content` (modération de contenus)
|
||||
- ⚠️ Interactions avec : `monetization` (démonétisation en cas de sanction)
|
||||
117
docs/domains/moderation/entities/modele-moderation.md
Normal file
117
docs/domains/moderation/entities/modele-moderation.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Modèle de données - Modération
|
||||
|
||||
📖 Voir [Règles métier - Section 14 : Modération Flows](../rules/moderation-flows.md) | [Entités globales](../../_shared/entities/modele-global.md)
|
||||
|
||||
## Diagramme
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
REPORTS }o--|| USERS : "signalé par"
|
||||
REPORTS }o--|| CONTENTS : "concerne"
|
||||
REPORTS }o--|| MODERATORS : "traité par"
|
||||
REPORTS ||--o| SANCTIONS : "génère"
|
||||
REPORTS ||--o| APPEALS : "fait l'objet de"
|
||||
|
||||
SANCTIONS }o--|| CONTENTS : "sanctionne"
|
||||
SANCTIONS }o--|| USERS : "sanctionne créateur"
|
||||
SANCTIONS ||--o{ STRIKES : "crée"
|
||||
|
||||
APPEALS }o--|| REPORTS : "conteste"
|
||||
APPEALS }o--|| USERS : "soumis par"
|
||||
APPEALS }o--|| MODERATORS : "examiné par"
|
||||
|
||||
STRIKES }o--|| USERS : "attribué à"
|
||||
STRIKES }o--|| SANCTIONS : "provient de"
|
||||
|
||||
MODERATION_BADGES }o--|| USERS : "possédé par"
|
||||
|
||||
REPORTS {
|
||||
uuid id PK
|
||||
uuid content_id FK
|
||||
uuid reporter_id FK
|
||||
uuid moderator_id FK
|
||||
string category
|
||||
text comment
|
||||
string status
|
||||
text transcription
|
||||
int ai_score
|
||||
int priority
|
||||
string decision
|
||||
timestamp created_at
|
||||
timestamp reviewed_at
|
||||
timestamp closed_at
|
||||
boolean is_auto_action
|
||||
}
|
||||
|
||||
SANCTIONS {
|
||||
uuid id PK
|
||||
uuid report_id FK
|
||||
uuid content_id FK
|
||||
uuid creator_id FK
|
||||
string sanction_type
|
||||
int duration_days
|
||||
text reason
|
||||
text excerpt_timestamp
|
||||
timestamp applied_at
|
||||
timestamp expires_at
|
||||
boolean is_active
|
||||
}
|
||||
|
||||
STRIKES {
|
||||
uuid id PK
|
||||
uuid creator_id FK
|
||||
uuid sanction_id FK
|
||||
int strike_number
|
||||
timestamp applied_at
|
||||
timestamp expires_at
|
||||
boolean is_active
|
||||
}
|
||||
|
||||
APPEALS {
|
||||
uuid id PK
|
||||
uuid report_id FK
|
||||
uuid creator_id FK
|
||||
uuid moderator_id FK
|
||||
string ticket_number UK
|
||||
string status
|
||||
text reason
|
||||
text arguments
|
||||
text moderator_justification
|
||||
string decision
|
||||
timestamp created_at
|
||||
timestamp reviewed_at
|
||||
timestamp closed_at
|
||||
}
|
||||
|
||||
MODERATORS {
|
||||
uuid id PK
|
||||
string name
|
||||
string role
|
||||
int reviews_count
|
||||
decimal avg_review_time_minutes
|
||||
timestamp last_active
|
||||
}
|
||||
|
||||
MODERATION_BADGES {
|
||||
uuid id PK
|
||||
uuid user_id FK
|
||||
string badge_type
|
||||
int reports_validated
|
||||
int reports_rejected
|
||||
decimal accuracy_rate
|
||||
timestamp obtained_at
|
||||
timestamp last_audit_at
|
||||
boolean is_active
|
||||
}
|
||||
```
|
||||
|
||||
## Légende
|
||||
|
||||
**Entités spécifiques modération** :
|
||||
|
||||
- **REPORTS** : Signalements - 7 catégories (`hate_violence`, `sexual_content`, `illegal`, `copyright`, `spam`, `misinformation`, `other`) - Status : `received` → `transcribing` → `analyzing` → `pending_review` → `in_review` → `validated`/`rejected` → `closed` - Scoring IA 0-100%, priorité calculée
|
||||
- **SANCTIONS** : Sanctions créateurs - Types : `warning`, `strike`, `suspension_7d`, `suspension_30d`, `ban_permanent` - Durée selon type (7j, 30j, permanent)
|
||||
- **STRIKES** : Compteur strikes - 1/4 à 4/4 (Strike 4 = ban permanent) - Expiration après 6 mois
|
||||
- **APPEALS** : Appels sanctions - Ticket format `#MOD-YYYY-XXXXX` - Status : `pending`, `in_review`, `accepted`, `rejected`, `expired` - Délai soumission 7j, traitement 72h (standard) ou 5j (complexe)
|
||||
- **MODERATORS** : Modérateurs - Rôles : `junior_moderator`, `senior_moderator`, `admin_moderation`
|
||||
- **MODERATION_BADGES** : Badges contributeurs - Types : `bronze` (5 validés, 70%), `silver` (20 validés, 80%), `gold` (50 validés, 90%) - Audit trimestriel révocation si critères non respectés
|
||||
@@ -0,0 +1,349 @@
|
||||
# language: fr
|
||||
|
||||
@admin @moderation @dashboard
|
||||
Fonctionnalité: Dashboard modération pour modérateurs
|
||||
En tant que modérateur
|
||||
Je veux accéder à un dashboard centralisé de modération
|
||||
Afin de traiter efficacement les signalements et gérer les sanctions
|
||||
|
||||
# 14.4 - Outils modérateurs - Dashboard
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis connecté en tant que modérateur
|
||||
Et que j'ai accès au dashboard de modération
|
||||
|
||||
# Vue d'ensemble du dashboard
|
||||
|
||||
Scénario: Affichage du dashboard principal
|
||||
Étant donné que j'accède au dashboard de modération
|
||||
Quand la page se charge
|
||||
Alors je vois les sections principales:
|
||||
| section | position | contenu |
|
||||
| En-tête | Haut | Logo, nom utilisateur, rôle (Junior/Senior)|
|
||||
| Statistiques globales | Bandeau haut | Signalements en attente, traités aujourd'hui, temps moyen |
|
||||
| File d'attente prioritaire | Gauche | Signalements CRITIQUES et HAUTE priorité |
|
||||
| File d'attente normale | Centre | Signalements MOYENNE et BASSE priorité |
|
||||
| Fil d'activité | Droite | Actions récentes de l'équipe |
|
||||
| Navigation | Sidebar gauche | Signalements, Sanctions, Appels, Stats |
|
||||
Et toutes les sections sont chargées en <2 secondes
|
||||
|
||||
Scénario: Statistiques globales en temps réel
|
||||
Étant donné que je consulte les statistiques du dashboard
|
||||
Quand je vérifie les KPIs affichés
|
||||
Alors je vois les métriques suivantes:
|
||||
| métrique | valeur exemple | mise à jour |
|
||||
| Signalements en attente | 42 | Temps réel |
|
||||
| Signalements traités aujourd'hui | 138 | Temps réel |
|
||||
| Temps moyen de traitement | 45 min | Toutes les 5min|
|
||||
| Mon temps moyen (personnel) | 38 min | Toutes les 5min|
|
||||
| SLA respecté (24h) | 94% | Temps réel |
|
||||
Et les métriques s'actualisent automatiquement
|
||||
Et un badge de notification clignote si >50 signalements en attente
|
||||
|
||||
# Files d'attente séparées par priorité
|
||||
|
||||
Scénario: File d'attente CRITIQUE (24/7)
|
||||
Étant donné que 5 signalements de priorité CRITIQUE sont en attente
|
||||
Quand j'affiche la file CRITIQUE
|
||||
Alors je vois une liste rouge avec les signalements:
|
||||
| colonne | contenu exemple | ordre tri |
|
||||
| Priorité score | 95 (badge rouge "URGENT") | Score décroissant|
|
||||
| Titre contenu | "Podcast #42" | - |
|
||||
| Catégorie IA | 🚫 Haine & violence (97%) | - |
|
||||
| Signalé par | @user123 (⭐ Or) + 3 autres | - |
|
||||
| Temps écoulé | "Il y a 45 min" (rouge si >1h) | - |
|
||||
| Actions rapides | [Écouter] [Valider] [Rejeter] | - |
|
||||
Et la file CRITIQUE est toujours visible en haut de page
|
||||
Et une alerte sonore se déclenche si nouveau signalement CRITIQUE
|
||||
|
||||
Scénario: File d'attente HAUTE priorité
|
||||
Étant donné que 15 signalements de priorité HAUTE sont en attente
|
||||
Quand j'affiche la file HAUTE
|
||||
Alors je vois une liste orange avec les mêmes colonnes
|
||||
Et les signalements sont triés par score de priorité décroissant
|
||||
Et un compteur "⏰ 23h restantes pour SLA 24h" s'affiche
|
||||
Et la file s'actualise toutes les 30 secondes
|
||||
|
||||
Scénario: File d'attente MOYENNE et BASSE
|
||||
Étant donné que 20 signalements MOYENNE et 10 BASSE sont en attente
|
||||
Quand j'affiche ces files
|
||||
Alors elles sont regroupées dans un onglet "Autres signalements"
|
||||
Et je peux filtrer par priorité MOYENNE ou BASSE
|
||||
Et ces signalements sont traités après les priorités hautes
|
||||
|
||||
# Badge qualité du signaleur
|
||||
|
||||
Scénario: Identification des signaleurs de confiance
|
||||
Étant donné qu'un signalement provient d'un utilisateur Badge Or
|
||||
Quand j'affiche la file d'attente
|
||||
Alors je vois le badge "⭐ Or" à côté du pseudo
|
||||
Et un tooltip s'affiche:
|
||||
"""
|
||||
Utilisateur de confiance
|
||||
Score fiabilité: 95/100
|
||||
Historique: 54 signalements validés / 60 envoyés (90%)
|
||||
"""
|
||||
Et je sais que ce signalement est probablement pertinent
|
||||
|
||||
Scénario: Signalements multiples du même contenu
|
||||
Étant donné qu'un contenu a été signalé par 6 utilisateurs
|
||||
Quand j'affiche le signalement
|
||||
Alors je vois "Signalé par @user1 + 5 autres"
|
||||
Et je peux cliquer pour voir la liste complète:
|
||||
| signaleur | badge | catégorie choisie | commentaire |
|
||||
| @user1 | Or | Haine & violence | "Propos à 2:30" |
|
||||
| @user2 | Argent| Haine & violence | "Discriminatoire" |
|
||||
| @user3 | - | Haine & violence | "" |
|
||||
| @user4 | Bronze| Fausse info | "Désinformation" |
|
||||
| @user5 | - | Autre | "Contenu choquant" |
|
||||
| @user6 | Or | Haine & violence | "Passage 2:25-2:45" |
|
||||
Et je vois que 5/6 signaleurs ont choisi la même catégorie
|
||||
Et cela renforce la probabilité de violation
|
||||
|
||||
# Filtres et recherche
|
||||
|
||||
Scénario: Filtrer les signalements par catégorie
|
||||
Étant donné que je suis sur le dashboard
|
||||
Quand je clique sur le filtre "Catégorie"
|
||||
Alors je vois les 7 catégories:
|
||||
| catégorie | nombre en attente |
|
||||
| 🚫 Haine & violence | 12 |
|
||||
| 🔞 Contenu sexuel | 5 |
|
||||
| ⚖️ Illégalité | 2 |
|
||||
| 🎵 Droits d'auteur | 8 |
|
||||
| 📧 Spam | 15 |
|
||||
| ❌ Fausse information | 7 |
|
||||
| 🔧 Autre | 3 |
|
||||
Et je peux cliquer pour filtrer par catégorie
|
||||
Et le filtre s'applique instantanément
|
||||
|
||||
Scénario: Rechercher un signalement spécifique
|
||||
Étant donné que je veux rechercher un signalement
|
||||
Quand je tape "podcast" dans la barre de recherche
|
||||
Alors les résultats s'affichent en temps réel:
|
||||
| recherche dans |
|
||||
| Titre du contenu |
|
||||
| Pseudo du créateur |
|
||||
| Commentaires signaleurs |
|
||||
| Numéro de ticket |
|
||||
Et les résultats sont mis en évidence
|
||||
Et je peux cliquer pour ouvrir le signalement
|
||||
|
||||
Scénario: Filtrer par assignation
|
||||
Étant donné que je suis modérateur junior
|
||||
Quand je clique sur le filtre "Assignation"
|
||||
Alors je vois les options:
|
||||
| option | nombre |
|
||||
| Assignés à moi | 8 |
|
||||
| Non assignés | 25 |
|
||||
| Assignés à d'autres | 9 |
|
||||
| Tous | 42 |
|
||||
Et je peux voir uniquement mes signalements
|
||||
Et je peux m'auto-assigner un signalement non assigné
|
||||
|
||||
# Actions rapides depuis la liste
|
||||
|
||||
Scénario: Actions rapides sans ouvrir le détail
|
||||
Étant donné que je vois un signalement évident (spam)
|
||||
Et que le score IA est de 98%
|
||||
Quand j'utilise les actions rapides
|
||||
Alors je peux cliquer sur:
|
||||
| action | raccourci clavier | effet |
|
||||
| Écouter | E | Lance le player audio |
|
||||
| Approuver | A | Valide le signalement |
|
||||
| Rejeter | R | Rejette le signalement |
|
||||
| Escalade | S (Senior) | Transfère à un modérateur senior|
|
||||
| Détails | D | Ouvre la page détaillée |
|
||||
Et l'action est immédiate
|
||||
Et le signalement disparaît de la liste
|
||||
|
||||
Scénario: Validation rapide avec confirmation
|
||||
Étant donné que je clique sur "Approuver" (A)
|
||||
Quand l'action est déclenchée
|
||||
Alors une modal de confirmation s'affiche:
|
||||
"""
|
||||
Valider ce signalement ?
|
||||
|
||||
Action: Retirer le contenu + Strike 1 au créateur
|
||||
Contenu: "Podcast #42" par @createur
|
||||
|
||||
[Annuler] [Confirmer]
|
||||
"""
|
||||
Et je peux confirmer avec Entrée ou cliquer
|
||||
Et si je confirme, l'action est immédiate
|
||||
Et le signalement passe en "Traité"
|
||||
|
||||
# Fil d'activité en temps réel
|
||||
|
||||
Scénario: Affichage du fil d'activité de l'équipe
|
||||
Étant donné que je consulte le fil d'activité
|
||||
Quand je vérifie les dernières actions
|
||||
Alors je vois les actions récentes de l'équipe en temps réel:
|
||||
"""
|
||||
Il y a 2 min - @mod_alice a validé signalement #12345 (Spam)
|
||||
Il y a 5 min - @mod_bob a rejeté signalement #12344 (Non fondé)
|
||||
Il y a 8 min - @mod_charlie a escaladé signalement #12343 (Complexe)
|
||||
Il y a 12 min - @mod_alice a approuvé appel #APP-456
|
||||
"""
|
||||
Et le fil se met à jour en temps réel (WebSocket)
|
||||
Et je vois qui travaille sur quoi
|
||||
Et cela améliore la collaboration
|
||||
|
||||
Scénario: Collaboration sur cas complexes
|
||||
Étant donné qu'un modérateur senior travaille sur un cas complexe
|
||||
Quand il ajoute un commentaire interne
|
||||
Alors le commentaire apparaît dans le fil d'activité:
|
||||
"""
|
||||
@mod_senior a commenté le signalement #12350:
|
||||
"Besoin d'un second avis sur ce cas. Passage 3:42 borderline."
|
||||
"""
|
||||
Et je peux cliquer pour voir le signalement
|
||||
Et je peux répondre au commentaire
|
||||
Et cela facilite l'entraide entre modérateurs
|
||||
|
||||
# Statistiques personnelles
|
||||
|
||||
Scénario: Voir mes statistiques personnelles
|
||||
Étant donné que je clique sur mon profil modérateur
|
||||
Quand j'accède à mes statistiques
|
||||
Alors je vois:
|
||||
| métrique | valeur | période |
|
||||
| Signalements traités | 342 | Ce mois |
|
||||
| Temps moyen de traitement | 38 min | Ce mois |
|
||||
| Précision (appels rejetés) | 94% | Ce mois |
|
||||
| Signalements/jour | 18 | Moyenne 30j |
|
||||
| Médaille de performance | 🥈 Argent | - |
|
||||
Et je peux comparer avec la moyenne de l'équipe
|
||||
Et cela me motive à améliorer mes performances
|
||||
|
||||
Plan du Scénario: Médailles de performance modérateur
|
||||
Étant donné que mon temps moyen est de <temps> min
|
||||
Et que ma précision est de <precision>%
|
||||
Quand le système calcule ma médaille
|
||||
Alors je reçois la médaille "<medaille>"
|
||||
|
||||
Exemples:
|
||||
| temps | precision | medaille |
|
||||
| 25 | 97 | 🥇 Or (Top performer) |
|
||||
| 35 | 92 | 🥈 Argent (Bon) |
|
||||
| 50 | 85 | 🥉 Bronze (Standard) |
|
||||
|
||||
# Notifications et alertes
|
||||
|
||||
Scénario: Alerte sonore pour signalement CRITIQUE
|
||||
Étant donné que je travaille sur le dashboard
|
||||
Quand un nouveau signalement CRITIQUE arrive
|
||||
Alors une alerte sonore se déclenche (bip urgent)
|
||||
Et une notification desktop s'affiche:
|
||||
"""
|
||||
🚨 Nouveau signalement CRITIQUE
|
||||
Contenu: "Podcast #XX" - Violence
|
||||
[Traiter maintenant]
|
||||
"""
|
||||
Et le signalement apparaît en tête de liste (fond rouge)
|
||||
Et je suis immédiatement alerté
|
||||
|
||||
Scénario: Notification si SLA bientôt dépassé
|
||||
Étant donné qu'un signalement HAUTE priorité est en attente depuis 22h
|
||||
Quand il reste 2h avant le SLA de 24h
|
||||
Alors une notification s'affiche:
|
||||
"""
|
||||
⚠️ SLA bientôt dépassé
|
||||
Signalement #12345 - Haine & violence
|
||||
Deadline dans 2h
|
||||
[Prendre en charge]
|
||||
"""
|
||||
Et le signalement est mis en évidence en orange
|
||||
Et je peux cliquer pour le traiter en priorité
|
||||
|
||||
# Auto-refresh et temps réel
|
||||
|
||||
Scénario: Actualisation automatique des données
|
||||
Étant donné que je suis sur le dashboard
|
||||
Quand de nouvelles données arrivent
|
||||
Alors le dashboard s'actualise automatiquement:
|
||||
| donnée | fréquence actualisation |
|
||||
| File d'attente | 30 secondes |
|
||||
| Statistiques globales | 5 minutes |
|
||||
| Fil d'activité | Temps réel (WebSocket) |
|
||||
| Mon temps moyen | 5 minutes |
|
||||
Et je n'ai pas besoin de rafraîchir manuellement
|
||||
Et les changements s'affichent avec une animation subtile
|
||||
|
||||
# Responsive et performance
|
||||
|
||||
Scénario: Dashboard responsive pour écrans larges
|
||||
Étant donné que j'utilise un écran 27" (2560x1440)
|
||||
Quand j'affiche le dashboard
|
||||
Alors les 3 colonnes sont affichées côte à côte:
|
||||
| colonne | largeur |
|
||||
| File prioritaire | 30% |
|
||||
| File normale | 45% |
|
||||
| Fil d'activité | 25% |
|
||||
Et je vois tout en un seul coup d'œil
|
||||
Et je peux travailler efficacement
|
||||
|
||||
Scénario: Dashboard sur écran standard (1920x1080)
|
||||
Étant donné que j'utilise un écran Full HD
|
||||
Quand j'affiche le dashboard
|
||||
Alors les colonnes s'adaptent:
|
||||
| colonne | largeur | position |
|
||||
| File prioritaire | 60% | Gauche |
|
||||
| Fil d'activité | 40% | Droite |
|
||||
Et je peux basculer entre files avec onglets
|
||||
Et l'UX reste fluide
|
||||
|
||||
Scénario: Performance du dashboard
|
||||
Étant donné que 100 signalements sont en attente
|
||||
Quand je charge le dashboard
|
||||
Alors le chargement initial prend <2 secondes
|
||||
Et l'affichage est fluide (60 FPS)
|
||||
Et la pagination charge 20 signalements à la fois
|
||||
Et le scroll est instantané
|
||||
Et la mémoire utilisée reste <500 MB
|
||||
|
||||
# Dark mode pour modérateurs
|
||||
|
||||
Scénario: Support du dark mode
|
||||
Étant donné que je travaille de nuit
|
||||
Quand j'active le dark mode
|
||||
Alors les couleurs s'adaptent:
|
||||
| élément | couleur light | couleur dark |
|
||||
| Fond page | Blanc | Noir (#1E1E1E) |
|
||||
| Cartes signalements | Gris clair | Gris foncé |
|
||||
| Badge CRITIQUE | Rouge vif | Rouge (#FF4444) |
|
||||
| Badge HAUTE | Orange | Orange (#FFA500) |
|
||||
| Texte principal | Noir | Blanc |
|
||||
Et le contraste reste optimal
|
||||
Et mes yeux sont moins fatigués
|
||||
|
||||
# Accessibilité
|
||||
|
||||
Scénario: Raccourcis clavier pour productivité
|
||||
Étant donné que je suis sur le dashboard
|
||||
Quand j'utilise les raccourcis clavier
|
||||
Alors je peux naviguer rapidement:
|
||||
| raccourci | action |
|
||||
| A | Approuver le signalement sélectionné|
|
||||
| R | Rejeter le signalement sélectionné |
|
||||
| E | Écouter le contenu |
|
||||
| D | Ouvrir les détails |
|
||||
| S | Escalader (modérateur senior) |
|
||||
| ↑ / ↓ | Naviguer dans la liste |
|
||||
| Entrée | Ouvrir le signalement sélectionné |
|
||||
| Échap | Fermer la modal/retour |
|
||||
Et je gagne en productivité (×2-3)
|
||||
|
||||
# Coût infrastructure
|
||||
|
||||
Scénario: Coût du dashboard de modération
|
||||
Étant donné que le dashboard est développé et déployé
|
||||
Quand on évalue le coût
|
||||
Alors le coût de développement est:
|
||||
| composant | technologie | coût |
|
||||
| Frontend | React + TanStack Table | 0€ (interne) |
|
||||
| Backend API | Go (existant) | 0€ |
|
||||
| WebSocket temps réel | Go + Redis | 0-20€/mois |
|
||||
| Hébergement dashboard | OVH (serveur existant) | 0€ (mutualisé) |
|
||||
Et le coût total est de 0-20€/mois
|
||||
Et c'est inclus dans l'infrastructure existante
|
||||
461
docs/domains/moderation/features/admin/outils-moderateur.feature
Normal file
461
docs/domains/moderation/features/admin/outils-moderateur.feature
Normal file
@@ -0,0 +1,461 @@
|
||||
# language: fr
|
||||
|
||||
@admin @moderation @outils
|
||||
Fonctionnalité: Outils modérateur - Player audio et actions
|
||||
En tant que modérateur
|
||||
Je veux disposer d'outils performants pour traiter les signalements
|
||||
Afin de travailler efficacement et prendre des décisions éclairées
|
||||
|
||||
# 14.4 - Outils modérateurs - Player audio, historique créateur, etc.
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis connecté en tant que modérateur
|
||||
Et que j'examine un signalement
|
||||
|
||||
# Page détaillée d'un signalement
|
||||
|
||||
Scénario: Affichage de la page détails signalement
|
||||
Étant donné que je clique sur un signalement
|
||||
Quand la page de détails s'affiche
|
||||
Alors je vois toutes les sections:
|
||||
| section | position | contenu |
|
||||
| En-tête | Haut | Titre contenu, créateur, priorité |
|
||||
| Analyse IA | Bandeau | Score IA, catégorie détectée, confiance |
|
||||
| Player audio + waveform | Centre-haut | Lecture audio avec visualisation |
|
||||
| Transcription | Centre | Texte avec passages surlignés |
|
||||
| Détails signalements | Droite | Liste signaleurs + commentaires |
|
||||
| Historique créateur | Bas-droite | Contenus précédents, strikes, stats |
|
||||
| Actions modérateur | Bas | Approuver, Rejeter, Escalader, Commenter |
|
||||
Et toutes les sections sont chargées en <1 seconde
|
||||
|
||||
Scénario: En-tête avec informations clés
|
||||
Étant donné que j'affiche les détails d'un signalement
|
||||
Quand je consulte l'en-tête
|
||||
Alors je vois:
|
||||
| information | exemple | position |
|
||||
| Numéro ticket | #MOD-2026-00142 | Haut gauche |
|
||||
| Titre du contenu | "Podcast #42 - Titre" | Titre principal|
|
||||
| Créateur | @pseudo_createur (lien profil) | Sous-titre |
|
||||
| Catégorie contenu | 🎙️ Podcast | Tag |
|
||||
| Date publication | Publié le 15/01/2026 | Sous-titre |
|
||||
| Durée audio | 12:34 | Badge |
|
||||
| Priorité signalement | 🔴 CRITIQUE (score 95) | Haut droite |
|
||||
| Temps écoulé | Signalé il y a 2h | Badge orange |
|
||||
| Assigné à | @mod_alice (si assigné) | Badge bleu |
|
||||
Et je vois en un coup d'œil les informations essentielles
|
||||
|
||||
# Analyse IA avec détails
|
||||
|
||||
Scénario: Bandeau analyse IA
|
||||
Étant donné que l'IA a analysé le contenu
|
||||
Quand j'affiche le bandeau d'analyse
|
||||
Alors je vois les résultats:
|
||||
"""
|
||||
🤖 Analyse IA
|
||||
|
||||
Score de confiance: 97% 🔴 (Très élevé)
|
||||
Catégorie détectée: 🚫 Haine & violence
|
||||
Passages problématiques: 3 détectés
|
||||
|
||||
Détails analyses:
|
||||
- Analyse sentiment: Négatif (score: -0.85)
|
||||
- Détection haine: Positif (score: 0.92)
|
||||
- Mots-clés interdits: 5 occurrences
|
||||
|
||||
[Voir détails techniques]
|
||||
"""
|
||||
Et un fond rouge clair indique un score élevé (>90%)
|
||||
Et je peux avoir confiance dans l'analyse IA
|
||||
|
||||
Scénario: Détails techniques de l'analyse IA
|
||||
Étant donné que je clique sur "Voir détails techniques"
|
||||
Quand la modal s'affiche
|
||||
Alors je vois les détails complets:
|
||||
| analyse | modèle | score | timestamp analyse |
|
||||
| Transcription | Whisper large-v3 | 100% | 14:32:15 |
|
||||
| Analyse sentiment | distilbert-base-uncased | -0.85 | 14:33:42 |
|
||||
| Détection haine | facebook/roberta-hate-speech | 0.92 | 14:33:58 |
|
||||
| Mots-clés interdits | Liste noire FR/EN | 5 hits | 14:34:01 |
|
||||
Et je peux vérifier la fiabilité de l'analyse
|
||||
Et cela m'aide à prendre une décision
|
||||
|
||||
# Player audio avec waveform
|
||||
|
||||
Scénario: Affichage du player audio Wavesurfer.js
|
||||
Étant donné que j'ouvre la page de détails
|
||||
Quand le player audio se charge
|
||||
Alors je vois le player avec waveform:
|
||||
| élément | description |
|
||||
| Waveform | Visualisation audio complète |
|
||||
| Passages surlignés | Zones détectées par IA en rouge |
|
||||
| Contrôles | Play/Pause, volume, vitesse |
|
||||
| Timeline | 00:00 / 12:34 |
|
||||
| Marqueurs | Annotations aux timestamps problématiques |
|
||||
| Vitesse lecture | 0.75x, 1x, 1.5x, 2x |
|
||||
Et je peux écouter le contenu directement
|
||||
Et je peux me concentrer sur les passages signalés
|
||||
|
||||
Scénario: Navigation rapide vers passages problématiques
|
||||
Étant donné que l'IA a détecté 3 passages problématiques
|
||||
Quand j'affiche le player
|
||||
Alors je vois 3 marqueurs rouges sur la waveform:
|
||||
| timestamp | type marqueur | description |
|
||||
| 02:15 | Rouge IA (97%) | "Insulte discriminatoire" |
|
||||
| 03:42 | Rouge IA (92%) | "Propos haineux" |
|
||||
| 08:20 | Orange signaleur | "Commentaire @user: 'ici aussi'"|
|
||||
Et je peux cliquer sur un marqueur pour sauter directement
|
||||
Et je gagne un temps précieux (pas besoin d'écouter tout)
|
||||
|
||||
Scénario: Lecture accélérée pour gain productivité
|
||||
Étant donné que le contenu dure 30 minutes
|
||||
Quand je sélectionne la vitesse 2x
|
||||
Alors l'audio est accéléré sans déformation
|
||||
Et je peux écouter en 15 minutes au lieu de 30
|
||||
Et je peux revenir à 1x si nécessaire
|
||||
Et cela multiplie ma productivité par 2
|
||||
|
||||
Scénario: Annotations directes sur la waveform
|
||||
Étant donné que j'écoute le contenu
|
||||
Et que je détecte un passage problématique à 05:30
|
||||
Quand je clique sur la waveform à 05:30
|
||||
Alors une modal s'affiche:
|
||||
"""
|
||||
Ajouter une annotation
|
||||
|
||||
Timestamp: 05:30
|
||||
Type: [Passage problématique ▼]
|
||||
Note: [Champ texte]
|
||||
|
||||
[Annuler] [Ajouter]
|
||||
"""
|
||||
Et je peux marquer le passage pour référence
|
||||
Et l'annotation apparaît sur la waveform
|
||||
Et elle sera visible dans le rapport de modération
|
||||
|
||||
# Transcription avec surlignage
|
||||
|
||||
Scénario: Affichage de la transcription complète
|
||||
Étant donné que l'IA a transcrit l'audio
|
||||
Quand j'affiche la transcription
|
||||
Alors je vois le texte complet:
|
||||
"""
|
||||
[00:00] Bonjour à tous, bienvenue dans ce podcast...
|
||||
[02:15] ...et c'est pourquoi je pense que [ROUGE: phrase discriminatoire] mais bon...
|
||||
[03:42] ...vraiment, ces gens [ROUGE: propos haineux], vous voyez...
|
||||
[08:20] ...en conclusion, [ORANGE: passage signalé par @user]...
|
||||
"""
|
||||
Et les passages problématiques sont surlignés
|
||||
Et je peux lire sans écouter (plus rapide)
|
||||
Et je peux copier/coller pour le rapport
|
||||
|
||||
Scénario: Synchronisation transcription - audio
|
||||
Étant donné que je lis la transcription
|
||||
Quand je clique sur un timestamp dans la transcription
|
||||
Alors le player audio saute à ce timestamp
|
||||
Et la lecture démarre automatiquement
|
||||
Et la transcription scroll pour suivre la lecture
|
||||
Et je peux alterner lecture et écoute facilement
|
||||
|
||||
Scénario: Recherche dans la transcription
|
||||
Étant donné que la transcription est affichée
|
||||
Quand je recherche un mot-clé "discriminatoire"
|
||||
Alors toutes les occurrences sont surlignées en jaune
|
||||
Et je vois "3 résultats trouvés"
|
||||
Et je peux naviguer entre les résultats avec ←/→
|
||||
Et je trouve rapidement les passages pertinents
|
||||
|
||||
# Détails des signalements
|
||||
|
||||
Scénario: Liste des signaleurs et leurs commentaires
|
||||
Étant donné qu'un contenu a été signalé par 6 utilisateurs
|
||||
Quand j'affiche la section "Signalements"
|
||||
Alors je vois la liste complète:
|
||||
| signaleur | badge | fiabilité | catégorie | commentaire | date |
|
||||
| @user1 | 🥇 Or | 95% | Haine & violence | "Propos à 2:30" | Il y a 2h |
|
||||
| @user2 | 🥈 Ag | 87% | Haine & violence | "Discriminatoire 2:15" | Il y a 1h |
|
||||
| @user3 | - | 45% | Haine & violence | "" | Il y a 45min|
|
||||
| @user4 | 🥉 Br | 72% | Fausse info | "Désinformation santé" | Il y a 30min|
|
||||
| @user5 | - | 20% | Autre | "Contenu choquant" | Il y a 15min|
|
||||
| @user6 | 🥇 Or | 92% | Haine & violence | "Passage 2:25-2:45" | Il y a 10min|
|
||||
Et je vois que 5/6 ont choisi "Haine & violence"
|
||||
Et les utilisateurs de confiance sont mis en évidence
|
||||
Et je peux cliquer sur un commentaire pour sauter au timestamp
|
||||
|
||||
Scénario: Consensus des signaleurs
|
||||
Étant donné que 6 signalements sont affichés
|
||||
Quand je consulte l'analyse de consensus
|
||||
Alors je vois:
|
||||
"""
|
||||
📊 Consensus des signaleurs
|
||||
|
||||
Catégorie majoritaire: 🚫 Haine & violence (5/6 = 83%)
|
||||
Signaleurs de confiance: 3/6 (Or × 2, Argent × 1)
|
||||
Timestamps mentionnés: 2:15, 2:25-2:45, 2:30
|
||||
|
||||
→ Fort consensus sur la catégorie et les timestamps
|
||||
"""
|
||||
Et je peux prendre une décision plus facilement
|
||||
|
||||
# Historique créateur - Vue 360°
|
||||
|
||||
Scénario: Affichage de l'historique du créateur
|
||||
Étant donné que j'examine un signalement
|
||||
Quand j'affiche l'historique du créateur @pseudo
|
||||
Alors je vois sa vue 360°:
|
||||
| section | contenu |
|
||||
| Statistiques globales | 42 contenus, 12K écoutes, membre depuis 8 mois |
|
||||
| Strikes actuels | 1/4 strikes (1 actif, 0 réhabilité) |
|
||||
| Historique sanctions | Liste des 3 dernières sanctions |
|
||||
| Contenus récents | 10 derniers contenus publiés |
|
||||
| Score de confiance | 65/100 (Créateur suspect) |
|
||||
| Signalements reçus | 8 signalements dont 3 validés |
|
||||
Et je vois si c'est un récidiviste ou un premier incident
|
||||
|
||||
Scénario: Historique des strikes
|
||||
Étant donné que le créateur a 1 strike actif
|
||||
Quand je consulte les détails des strikes
|
||||
Alors je vois:
|
||||
"""
|
||||
Strikes: 1/4 actifs
|
||||
|
||||
Historique:
|
||||
✓ Strike 1 - Il y a 3 mois
|
||||
Catégorie: Spam
|
||||
Sanction: Avertissement
|
||||
Statut: Actif (réhabilitation dans 3 mois si pas de récidive)
|
||||
|
||||
Strikes réhabilités:
|
||||
[Aucun]
|
||||
|
||||
Escalade suivante:
|
||||
- Strike 2: Suspension 7 jours
|
||||
- Strike 3: Suspension 30 jours
|
||||
- Strike 4: Ban définitif
|
||||
"""
|
||||
Et je vois l'historique complet
|
||||
Et je peux décider de la sanction appropriée
|
||||
|
||||
Scénario: Contenus récents du créateur
|
||||
Étant donné que j'affiche les contenus récents
|
||||
Quand je consulte la liste
|
||||
Alors je vois les 10 derniers contenus:
|
||||
| titre | date | écoutes | signalements | statut |
|
||||
| Podcast #42 | 15/01/2026 | 342 | 6 (en cours) | Signalé |
|
||||
| Podcast #41 | 10/01/2026 | 521 | 0 | Publié |
|
||||
| Podcast #40 | 05/01/2026 | 678 | 1 (rejeté) | Publié |
|
||||
| Podcast #39 | 01/01/2026 | 445 | 0 | Publié |
|
||||
Et je peux écouter rapidement un contenu précédent
|
||||
Et je peux détecter un pattern de comportement
|
||||
|
||||
Scénario: Détection de pattern récidiviste
|
||||
Étant donné que le créateur a 3 contenus signalés validés en 2 mois
|
||||
Quand le système analyse le pattern
|
||||
Alors une alerte s'affiche:
|
||||
"""
|
||||
⚠️ Pattern récidiviste détecté
|
||||
|
||||
3 signalements validés en 2 mois:
|
||||
- 15/01: Haine & violence (en cours)
|
||||
- 28/12: Spam (validé - Strike 1)
|
||||
- 10/12: Fausse info (validé)
|
||||
|
||||
Recommandation: Sanction renforcée suggérée
|
||||
"""
|
||||
Et je peux décider d'une sanction plus sévère
|
||||
Et je protège la communauté des récidivistes
|
||||
|
||||
# Actions modérateur
|
||||
|
||||
Scénario: Actions disponibles pour modérateur junior
|
||||
Étant donné que je suis modérateur junior
|
||||
Quand j'affiche les actions disponibles
|
||||
Alors je vois les boutons:
|
||||
| action | raccourci | couleur | description |
|
||||
| Approuver | A | Rouge | Valider le signalement + sanction |
|
||||
| Rejeter | R | Gris | Rejeter le signalement (non fondé) |
|
||||
| Escalader senior | S | Orange | Transférer à un modérateur senior |
|
||||
| Commenter | C | Bleu | Ajouter un commentaire interne |
|
||||
| Mettre en attente | W | Jaune | Reporter la décision (max 24h) |
|
||||
Et je peux traiter les cas simples
|
||||
Et je peux escalader les cas complexes
|
||||
|
||||
Scénario: Actions supplémentaires pour modérateur senior
|
||||
Étant donné que je suis modérateur senior
|
||||
Quand j'affiche les actions disponibles
|
||||
Alors je vois des actions supplémentaires:
|
||||
| action | description |
|
||||
| Approuver avec sanction | Valider + choisir sanction personnalisée |
|
||||
| Ban temporaire | Suspendre le créateur (7j/30j) |
|
||||
| Ban définitif | Bannir définitivement le créateur |
|
||||
| Réhabiliter strike | Retirer un strike (après appel) |
|
||||
| Contacter autorités | Signaler aux autorités (cas graves) |
|
||||
Et je peux gérer les cas complexes et graves
|
||||
|
||||
Scénario: Workflow approbation signalement
|
||||
Étant donné que je clique sur "Approuver" (A)
|
||||
Quand le workflow s'affiche
|
||||
Alors je vois les étapes:
|
||||
"""
|
||||
1️⃣ Choisir la sanction
|
||||
|
||||
Sanction suggérée (IA): Strike 2 + Suspension 7j
|
||||
[Radio buttons]
|
||||
○ Strike 1 - Avertissement
|
||||
● Strike 2 - Suspension 7 jours (recommandé)
|
||||
○ Strike 3 - Suspension 30 jours
|
||||
○ Autre (personnalisé)
|
||||
|
||||
2️⃣ Confirmer l'action
|
||||
|
||||
Actions qui seront effectuées:
|
||||
✓ Contenu retiré de la plateforme
|
||||
✓ Strike 2 ajouté au créateur
|
||||
✓ Créateur suspendu 7 jours
|
||||
✓ Notifications envoyées (push + email)
|
||||
✓ Signaleurs notifiés (validation)
|
||||
|
||||
[Annuler] [Confirmer et appliquer]
|
||||
"""
|
||||
Et je peux personnaliser la sanction si nécessaire
|
||||
Et je confirme avant d'appliquer
|
||||
|
||||
Scénario: Workflow rejet signalement
|
||||
Étant donné que je clique sur "Rejeter" (R)
|
||||
Quand le workflow s'affiche
|
||||
Alors je dois fournir une raison:
|
||||
"""
|
||||
Rejeter ce signalement
|
||||
|
||||
Raison du rejet: [Liste déroulante]
|
||||
▼ Choisir une raison
|
||||
- Contenu conforme aux règles
|
||||
- Contexte éducatif/artistique
|
||||
- Signalement abusif
|
||||
- Autre (préciser)
|
||||
|
||||
Commentaire (optionnel): [Champ texte]
|
||||
|
||||
Actions qui seront effectuées:
|
||||
✓ Signalement marqué comme "Rejeté"
|
||||
✓ Contenu reste en ligne
|
||||
✓ Signaleurs notifiés avec raison
|
||||
✓ Fiabilité signaleur ajustée (-5%)
|
||||
|
||||
[Annuler] [Confirmer le rejet]
|
||||
"""
|
||||
Et la raison est obligatoire
|
||||
Et les signaleurs recevront une explication
|
||||
|
||||
# Commentaires internes modérateurs
|
||||
|
||||
Scénario: Ajouter un commentaire interne
|
||||
Étant donné que je travaille sur un cas complexe
|
||||
Quand je clique sur "Commenter" (C)
|
||||
Alors une zone de commentaire s'affiche:
|
||||
"""
|
||||
Commentaire interne (visible uniquement par modérateurs)
|
||||
|
||||
[Champ texte riche]
|
||||
|
||||
Mentionner un collègue: @mod_
|
||||
|
||||
[Annuler] [Publier le commentaire]
|
||||
"""
|
||||
Et je peux mentionner un collègue avec @
|
||||
Et le commentaire apparaît dans le fil d'activité
|
||||
Et cela facilite la collaboration
|
||||
|
||||
Scénario: Fil de commentaires sur un signalement
|
||||
Étant donné qu'un signalement a 3 commentaires internes
|
||||
Quand j'affiche le fil de commentaires
|
||||
Alors je vois:
|
||||
"""
|
||||
💬 Commentaires internes (3)
|
||||
|
||||
@mod_alice - Il y a 1h
|
||||
"Passage à 2:30 borderline. Besoin d'un second avis @mod_senior"
|
||||
|
||||
@mod_senior - Il y a 30min
|
||||
"J'ai écouté. C'est clairement discriminatoire. Approuver avec Strike 2."
|
||||
|
||||
@mod_alice - Il y a 5min
|
||||
"OK merci ! Je valide."
|
||||
"""
|
||||
Et je vois l'historique des discussions
|
||||
Et cela améliore la qualité des décisions
|
||||
|
||||
# Logs d'audit
|
||||
|
||||
Scénario: Génération automatique des logs d'audit
|
||||
Étant donné que je valide un signalement
|
||||
Quand l'action est effectuée
|
||||
Alors un log d'audit complet est créé automatiquement:
|
||||
| champ | valeur |
|
||||
| signalement_id | #MOD-2026-00142 |
|
||||
| content_id | content_123456 |
|
||||
| moderator_id | mod_alice |
|
||||
| moderator_role | Junior |
|
||||
| action_taken | Approved - Strike 2 + Suspension 7d |
|
||||
| ia_score | 97% |
|
||||
| ia_category | Haine & violence |
|
||||
| priority | CRITIQUE |
|
||||
| processing_time | 12 minutes 34 secondes |
|
||||
| timestamp | 2026-01-15T14:42:18Z |
|
||||
| commentaires_internes | 2 commentaires |
|
||||
| annotations_audio | 3 annotations aux timestamps 2:15, 3:42, 8:20 |
|
||||
Et le log est conservé pour conformité DSA
|
||||
Et il sera anonymisé après 3 ans (RGPD)
|
||||
|
||||
Scénario: Export des logs d'audit
|
||||
Étant donné que je suis admin modération
|
||||
Quand je veux exporter les logs
|
||||
Alors je peux exporter en:
|
||||
| format | contenu | usage |
|
||||
| CSV | Tableau complet | Analyse Excel |
|
||||
| JSON | Données structurées | Analyse programmatique |
|
||||
| PDF | Rapport formaté | Audit DSA officiel |
|
||||
Et je peux filtrer par date, modérateur, action
|
||||
Et les logs sont conformes aux exigences légales
|
||||
|
||||
# Performance et UX
|
||||
|
||||
Scénario: Performance du player audio
|
||||
Étant donné que j'ouvre la page de détails
|
||||
Quand le player audio se charge
|
||||
Alors la waveform s'affiche en <2 secondes
|
||||
Et la transcription se charge en parallèle
|
||||
Et je peux commencer à écouter immédiatement
|
||||
Et le streaming HLS est fluide sans coupure
|
||||
Et l'UX est professionnelle et rapide
|
||||
|
||||
Scénario: Raccourcis clavier pour actions rapides
|
||||
Étant donné que je suis sur la page de détails
|
||||
Quand j'utilise les raccourcis clavier
|
||||
Alors je peux:
|
||||
| touche | action |
|
||||
| Espace | Play/Pause audio |
|
||||
| ← / → | Reculer/Avancer 5 secondes |
|
||||
| ↑ / ↓ | Augmenter/Diminuer volume |
|
||||
| A | Approuver |
|
||||
| R | Rejeter |
|
||||
| S | Escalader |
|
||||
| C | Commenter |
|
||||
| 1/2/3/4 | Vitesse 0.75x/1x/1.5x/2x |
|
||||
| M | Ajouter marqueur/annotation |
|
||||
| Échap | Retour au dashboard |
|
||||
Et je gagne en productivité
|
||||
|
||||
# Coût infrastructure
|
||||
|
||||
Scénario: Coût des outils modérateur
|
||||
Étant donné que tous les outils sont déployés
|
||||
Quand on évalue le coût
|
||||
Alors le coût est réparti ainsi:
|
||||
| composant | technologie | coût mensuel |
|
||||
| Player Wavesurfer.js | JavaScript (open source)| 0€ |
|
||||
| Transcription Whisper | Self-hosted (CPU/GPU) | 0-200€ |
|
||||
| Analyse NLP | Self-hosted | 0€ (inclus) |
|
||||
| Stockage transcriptions| PostgreSQL | 0€ (inclus) |
|
||||
| Logs audit | PostgreSQL | 0€ (inclus) |
|
||||
| Total | - | 0-200€/mois |
|
||||
Et le coût est largement compensé par la productivité ×3-5
|
||||
@@ -0,0 +1,42 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @copyright @appeal @mvp
|
||||
Fonctionnalité: Procédure d'appel pour droits d'auteur
|
||||
|
||||
En tant que créateur sanctionné
|
||||
Je veux faire appel d'une décision
|
||||
Afin de contester une sanction injuste
|
||||
|
||||
Scénario: Dépôt d'un appel
|
||||
Étant donné un créateur "alice@roadwave.fr" sanctionné
|
||||
Quand il fait appel dans les 15 jours
|
||||
Alors un dossier d'appel est créé
|
||||
Et il doit fournir des preuves (fair use, licence, etc.)
|
||||
Et un événement "COPYRIGHT_APPEAL_FILED" est enregistré
|
||||
|
||||
Scénario: Examen de l'appel par comité
|
||||
Étant donné un appel déposé
|
||||
Quand le comité l'examine (3 modérateurs)
|
||||
Alors une décision est prise dans les 7 jours
|
||||
Et le créateur est notifié du résultat
|
||||
Et un événement "COPYRIGHT_APPEAL_REVIEWED" est enregistré
|
||||
|
||||
Scénario: Appel accepté - Annulation de la sanction
|
||||
Étant donné un appel validé
|
||||
Alors la sanction est annulée
|
||||
Et le contenu est rétabli
|
||||
Et le compteur d'infractions n'est pas incrémenté
|
||||
Et un événement "COPYRIGHT_APPEAL_ACCEPTED" est enregistré
|
||||
|
||||
Scénario: Appel rejeté - Maintien de la sanction
|
||||
Étant donné un appel rejeté
|
||||
Alors la sanction est maintenue
|
||||
Et le créateur ne peut plus faire appel pour ce cas
|
||||
Et un événement "COPYRIGHT_APPEAL_REJECTED" est enregistré
|
||||
|
||||
Scénario: Délai de prescription des infractions
|
||||
Étant donné une infraction datant de > 2 ans
|
||||
Et aucune nouvelle infraction depuis
|
||||
Alors l'infraction est retirée de l'historique
|
||||
Et ne compte plus dans le système de sanctions progressives
|
||||
Et un événement "COPYRIGHT_INFRACTION_EXPIRED" est enregistré
|
||||
@@ -0,0 +1,76 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @audit @governance @mvp
|
||||
Fonctionnalité: Audit trimestriel du système de modération
|
||||
|
||||
En tant que responsable de la plateforme
|
||||
Je veux un audit trimestriel de la modération
|
||||
Afin d'assurer transparence et amélioration continue
|
||||
|
||||
Scénario: Génération automatique du rapport d'audit
|
||||
Étant donné la fin d'un trimestre (31 mars 2026)
|
||||
Quand le système génère le rapport
|
||||
Alors il contient:
|
||||
| Section | Détails |
|
||||
| Statistiques globales | Signalements, taux de traitement|
|
||||
| Performance modérateurs | Temps moyen, précision |
|
||||
| Contenus bloqués | Par catégorie |
|
||||
| Appels et contestations | Taux d'acceptation |
|
||||
| Améliorations proposées | Recommandations |
|
||||
Et un PDF est généré et archivé
|
||||
Et un événement "QUARTERLY_AUDIT_GENERATED" est enregistré
|
||||
|
||||
Scénario: Publication transparente des métriques
|
||||
Étant donné le rapport d'audit trimestriel
|
||||
Quand il est publié
|
||||
Alors une page publique affiche:
|
||||
| Métrique | Q1 2026 | Q4 2025 |
|
||||
| Signalements traités | 15,234 | 12,876 |
|
||||
| Temps moyen de traitement | 8h | 12h |
|
||||
| Taux de précision automatique | 85% | 82% |
|
||||
| Appels acceptés | 18% | 22% |
|
||||
| Comptes bannis | 234 | 198 |
|
||||
Et un événement "AUDIT_PUBLICLY_PUBLISHED" est enregistré
|
||||
|
||||
Scénario: Analyse des tendances sur 4 trimestres
|
||||
Étant donné 4 rapports trimestriels
|
||||
Alors un graphique d'évolution est affiché:
|
||||
| Métrique | Tendance |
|
||||
| Signalements totaux | +12% par tri |
|
||||
| Temps de traitement | -25% |
|
||||
| Taux de faux positifs | -5% |
|
||||
Et des insights sont générés automatiquement
|
||||
Et un événement "AUDIT_TRENDS_ANALYZED" est enregistré
|
||||
|
||||
Scénario: Recommandations d'amélioration
|
||||
Étant donné le rapport d'audit
|
||||
Quand le système analyse les données
|
||||
Alors des recommandations sont proposées:
|
||||
| Recommandation | Priorité |
|
||||
| Recruter 2 modérateurs supplémentaires| Haute |
|
||||
| Améliorer modèle ML de détection | Moyenne |
|
||||
| Revoir processus d'appel | Basse |
|
||||
Et un plan d'action trimestriel est établi
|
||||
Et un événement "AUDIT_RECOMMENDATIONS_GENERATED" est enregistré
|
||||
|
||||
Scénario: Audit externe annuel
|
||||
Étant donné la fin de l'année (31 décembre)
|
||||
Quand un audit externe est commandé
|
||||
Alors un cabinet indépendant analyse:
|
||||
| Aspect | Conformité |
|
||||
| Respect RGPD | Oui |
|
||||
| Transparence des décisions | Oui |
|
||||
| Impartialité de la modération | Oui |
|
||||
| Temps de réponse | Acceptable |
|
||||
Et un certificat de conformité est délivré
|
||||
Et un événement "EXTERNAL_AUDIT_COMPLETED" est enregistré
|
||||
|
||||
Scénario: Métriques d'impact des audits
|
||||
Étant donné 4 audits trimestriels effectués
|
||||
Alors l'impact est mesuré:
|
||||
| Métrique | Amélioration |
|
||||
| Temps de traitement | -30% |
|
||||
| Satisfaction utilisateurs | +15% |
|
||||
| Taux de faux positifs | -40% |
|
||||
| Coûts de modération | -10% |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
76
docs/domains/moderation/features/api/badges-system.feature
Normal file
76
docs/domains/moderation/features/api/badges-system.feature
Normal file
@@ -0,0 +1,76 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @gamification @mvp
|
||||
Fonctionnalité: Système de badges de modération
|
||||
|
||||
En tant qu'utilisateur modérateur
|
||||
Je veux gagner des badges pour ma contribution
|
||||
Afin d'être reconnu et motivé à modérer
|
||||
|
||||
Scénario: Badge Bronze - 10 signalements validés
|
||||
Étant donné un utilisateur "alice@roadwave.fr" qui a 10 signalements validés
|
||||
Quand le 10ème signalement est confirmé
|
||||
Alors le badge "Modérateur Bronze" est débloqué
|
||||
Et affiché sur son profil
|
||||
Et +50 points de réputation
|
||||
Et un événement "BADGE_BRONZE_MODERATOR_UNLOCKED" est enregistré
|
||||
|
||||
Scénario: Badge Argent - 50 signalements validés
|
||||
Étant donné un utilisateur avec 50 signalements validés
|
||||
Alors le badge "Modérateur Argent" est débloqué
|
||||
Et il obtient des privilèges supplémentaires
|
||||
Et +200 points de réputation
|
||||
Et un événement "BADGE_SILVER_MODERATOR_UNLOCKED" est enregistré
|
||||
|
||||
Scénario: Badge Or - 200 signalements validés
|
||||
Étant donné un utilisateur avec 200 signalements validés
|
||||
Alors le badge "Modérateur Or" est débloqué
|
||||
Et il devient "Utilisateur de confiance"
|
||||
Et ses signalements sont traités en priorité
|
||||
Et +500 points de réputation
|
||||
Et un événement "BADGE_GOLD_MODERATOR_UNLOCKED" est enregistré
|
||||
|
||||
Scénario: Badge Diamant - 1000 signalements + 95% de précision
|
||||
Étant donné un utilisateur avec 1000 signalements validés
|
||||
Et un taux de précision > 95%
|
||||
Alors le badge "Modérateur Diamant" est débloqué
|
||||
Et il peut devenir modérateur officiel
|
||||
Et +2000 points de réputation
|
||||
Et un événement "BADGE_DIAMOND_MODERATOR_UNLOCKED" est enregistré
|
||||
|
||||
Scénario: Perte de badge si précision < 70%
|
||||
Étant donné un utilisateur avec badge Silver
|
||||
Quand son taux de précision tombe < 70%
|
||||
Alors le badge est révoqué temporairement
|
||||
Et il doit retrouver 80% de précision pour le récupérer
|
||||
Et un événement "BADGE_REVOKED_LOW_ACCURACY" est enregistré
|
||||
|
||||
Scénario: Badges spéciaux pour expertise
|
||||
Étant donné un utilisateur spécialisé
|
||||
Alors il peut obtenir des badges thématiques:
|
||||
| Badge | Condition |
|
||||
| Expert droits d'auteur | 100 signalements copyright validés|
|
||||
| Expert contenu offensant | 100 signalements haine validés |
|
||||
| Expert spam | 100 signalements spam validés |
|
||||
Et un événement "EXPERT_BADGE_UNLOCKED" est enregistré
|
||||
|
||||
Scénario: Classement des meilleurs modérateurs
|
||||
Étant donné tous les utilisateurs modérateurs
|
||||
Alors un leaderboard est affiché:
|
||||
| Rang | Utilisateur | Signalements | Précision | Badge |
|
||||
| 1 | alice | 1,234 | 98% | Diamant |
|
||||
| 2 | bob | 876 | 96% | Or |
|
||||
| 3 | charlie | 543 | 94% | Or |
|
||||
Et le top 10 reçoit des récompenses mensuelles
|
||||
Et un événement "MODERATOR_LEADERBOARD_VIEWED" est enregistré
|
||||
|
||||
Scénario: Récompenses mensuelles pour top modérateurs
|
||||
Étant donné le top 10 du mois
|
||||
Quand le mois se termine
|
||||
Alors chacun reçoit:
|
||||
| Rang | Récompense |
|
||||
| 1-3 | 6 mois Premium gratuit |
|
||||
| 4-6 | 3 mois Premium gratuit |
|
||||
| 7-10 | 1 mois Premium gratuit |
|
||||
Et un badge "Top modérateur du mois"
|
||||
Et un événement "MONTHLY_MODERATOR_REWARDS_DISTRIBUTED" est enregistré
|
||||
@@ -0,0 +1,84 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @ml @security @mvp
|
||||
Fonctionnalité: Détection de patterns suspects par ML
|
||||
|
||||
En tant que système de sécurité
|
||||
Je veux détecter automatiquement les comportements suspects
|
||||
Afin de prévenir les abus et fraudes
|
||||
|
||||
Scénario: Détection de signalements coordonnés
|
||||
Étant donné 5 utilisateurs qui signalent le même contenu en 10 minutes
|
||||
Et leurs comptes ont été créés la même semaine
|
||||
Quand le système analyse le pattern
|
||||
Alors une alerte "Brigade de signalement" est déclenchée
|
||||
Et les signalements sont mis en quarantaine
|
||||
Et un modérateur vérifie manuellement
|
||||
Et un événement "COORDINATED_REPORTING_DETECTED" est enregistré
|
||||
|
||||
Scénario: Détection de compte bot de signalement
|
||||
Étant donné un compte avec pattern suspect:
|
||||
| Indicateur | Valeur |
|
||||
| Signalements par jour | 50 |
|
||||
| Intervalle régulier | Exactement 120s |
|
||||
| Diversité de contenus | Faible |
|
||||
| Interaction humaine | Aucune |
|
||||
Quand le système ML analyse
|
||||
Alors le compte est identifié comme "Probable bot"
|
||||
Et suspendu automatiquement
|
||||
Et un événement "BOT_ACCOUNT_DETECTED" est enregistré
|
||||
|
||||
Scénario: Détection de vendetta personnelle
|
||||
Étant donné un utilisateur A qui signale systématiquement l'utilisateur B
|
||||
Et 15 signalements en 1 semaine, tous rejetés
|
||||
Quand le système détecte le pattern
|
||||
Alors une alerte "Harcèlement par signalements" est déclenchée
|
||||
Et l'utilisateur A est bloqué de signaler B
|
||||
Et un événement "VENDETTA_PATTERN_DETECTED" est enregistré
|
||||
|
||||
Scénario: Détection d'usage d'IA pour contenu offensant déguisé
|
||||
Étant donné un contenu avec texte subtil généré par IA
|
||||
Quand l'analyse NLP détecte des marqueurs d'IA toxique
|
||||
Alors le contenu est mis en quarantaine
|
||||
Et un modérateur expert vérifie
|
||||
Et un événement "AI_GENERATED_TOXIC_DETECTED" est enregistré
|
||||
|
||||
Scénario: Analyse des métadonnées EXIF suspectes
|
||||
Étant donné une image uploadée avec métadonnées:
|
||||
| Métadonnée | Valeur suspect |
|
||||
| GPS Location | Corée du Nord |
|
||||
| Device Model | Connu pour bots |
|
||||
| Timestamp | Futur (2027) |
|
||||
Quand le système analyse
|
||||
Alors l'image est marquée "Métadonnées suspectes"
|
||||
Et un événement "SUSPICIOUS_METADATA_DETECTED" est enregistré
|
||||
|
||||
Scénario: Score de risque ML combiné
|
||||
Étant donné un contenu analysé par ML
|
||||
Alors un score de risque global est calculé:
|
||||
| Facteur | Poids | Score |
|
||||
| Contenu textuel | 30% | 0.8 |
|
||||
| Métadonnées image | 20% | 0.3 |
|
||||
| Comportement utilisateur | 30% | 0.9 |
|
||||
| Patterns de signalement | 20% | 0.1 |
|
||||
| **Score global** | 100% | **0.65** |
|
||||
Et si score > 0.7, mise en quarantaine automatique
|
||||
Et un événement "ML_RISK_SCORE_CALCULATED" est enregistré
|
||||
|
||||
Scénario: Apprentissage continu du modèle ML
|
||||
Étant donné 10 000 contenus modérés manuellement
|
||||
Quand les décisions humaines sont collectées
|
||||
Alors le modèle ML est réentraîné mensuellement
|
||||
Et la précision s'améliore de 2-3% par itération
|
||||
Et un événement "ML_MODEL_RETRAINED" est enregistré
|
||||
|
||||
Scénario: Métriques de performance de la détection ML
|
||||
Étant donné que 50 000 contenus ont été analysés
|
||||
Alors les indicateurs suivants sont disponibles:
|
||||
| Métrique | Valeur |
|
||||
| Précision de détection | 87% |
|
||||
| Rappel (contenus détectés) | 82% |
|
||||
| Faux positifs | 8% |
|
||||
| Temps moyen d'analyse | 250ms |
|
||||
| Économie de temps modérateurs | 60% |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
@@ -0,0 +1,51 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @anti-abuse @mvp
|
||||
Fonctionnalité: Limites temporelles anti-abus de modération
|
||||
|
||||
En tant que plateforme
|
||||
Je veux limiter les signalements abusifs
|
||||
Afin de prévenir le spam et les abus du système
|
||||
|
||||
Scénario: Limitation à 20 signalements par jour
|
||||
Étant donné un utilisateur "alice@roadwave.fr" qui a fait 20 signalements aujourd'hui
|
||||
Quand il tente un 21ème signalement
|
||||
Alors le signalement est bloqué
|
||||
Et un message s'affiche: "Limite quotidienne atteinte (20 signalements). Réessayez demain."
|
||||
Et un événement "REPORT_DAILY_LIMIT_REACHED" est enregistré
|
||||
|
||||
Scénario: Limite augmentée pour utilisateurs de confiance
|
||||
Étant donné un utilisateur de confiance
|
||||
Alors sa limite quotidienne est de 50 signalements
|
||||
Et un événement "TRUSTED_USER_HIGHER_LIMIT" est enregistré
|
||||
|
||||
Scénario: Cooldown de 5 minutes entre signalements
|
||||
Étant donné un utilisateur qui vient de faire un signalement
|
||||
Quand il tente un nouveau signalement 2 minutes après
|
||||
Alors le signalement est bloqué
|
||||
Et un message affiche: "Attendez 3 minutes avant le prochain signalement"
|
||||
Et un événement "REPORT_COOLDOWN_ACTIVE" est enregistré
|
||||
|
||||
Scénario: Détection de signalements en masse suspects
|
||||
Étant donné un utilisateur qui fait 10 signalements en 10 minutes
|
||||
Quand le système détecte le pattern
|
||||
Alors une alerte modérateur est déclenchée
|
||||
Et l'utilisateur passe en review manuelle
|
||||
Et un événement "MASS_REPORTING_DETECTED" est enregistré
|
||||
|
||||
Scénario: Blocage temporaire pour abus répétés
|
||||
Étant donné un utilisateur avec 10 signalements rejetés en 24h
|
||||
Quand le 10ème est rejeté
|
||||
Alors l'utilisateur est bloqué de la modération pour 7 jours
|
||||
Et un message explique: "Trop de signalements invalides. Blocage temporaire."
|
||||
Et un événement "REPORTING_SUSPENDED_ABUSE" est enregistré
|
||||
|
||||
Scénario: Métriques de détection d'abus
|
||||
Étant donné que 1000 utilisateurs ont tenté d'abuser
|
||||
Alors les indicateurs suivants sont disponibles:
|
||||
| Métrique | Valeur |
|
||||
| Tentatives de spam détectées | 1,234 |
|
||||
| Utilisateurs bloqués | 156 |
|
||||
| Faux positifs | 2% |
|
||||
| Taux de récidive après blocage | 15% |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
@@ -0,0 +1,397 @@
|
||||
# language: fr
|
||||
|
||||
@moderation @community
|
||||
Fonctionnalité: Modération communautaire - Badges et récompenses
|
||||
En tant que plateforme
|
||||
Je veux gamifier les signalements pertinents
|
||||
Afin d'améliorer la qualité des signalements et réduire la charge modérateurs
|
||||
|
||||
# 19. Modération Communautaire - Badges et Récompenses
|
||||
|
||||
Contexte:
|
||||
Étant donné que le système de modération communautaire est actif
|
||||
|
||||
# 19.1 - Système de badges
|
||||
|
||||
Scénario: Trois niveaux de badges disponibles
|
||||
Étant donné que je consulte le système de badges
|
||||
Quand je vois les badges disponibles
|
||||
Alors 3 niveaux de badges existent:
|
||||
| badge | nom | critères | avantages |
|
||||
| 🥉 | Contributeur Bronze | 5 validés + 70% pertinence | Signalements prioritaires (+10 points) |
|
||||
| 🥈 | Contributeur Argent | 20 validés + 80% pertinence | +20 points + Badge visible profil |
|
||||
| 🥇 | Contributeur Or | 50 validés + 90% pertinence | +30 points + Badge + Réduction Premium |
|
||||
Et les badges valorisent la qualité plutôt que la quantité
|
||||
|
||||
Scénario: Règles d'éligibilité aux badges
|
||||
Étant donné que je veux obtenir un badge
|
||||
Quand je consulte les règles d'éligibilité
|
||||
Alors les critères suivants s'appliquent:
|
||||
| règle | valeur |
|
||||
| Minimum signalements envoyés pour éligibilité | 10 |
|
||||
| Signalements "En cours" comptent dans le calcul | non |
|
||||
| Signalements rejetés font baisser le taux | oui |
|
||||
| Période de calcul (glissante) | 6 mois |
|
||||
Et seuls les 6 derniers mois sont pris en compte
|
||||
|
||||
Scénario: Calcul du taux de pertinence
|
||||
Étant donné que j'ai envoyé 20 signalements
|
||||
Et que 16 ont été validés par les modérateurs
|
||||
Et que 4 ont été rejetés
|
||||
Quand le système calcule mon taux de pertinence
|
||||
Alors la formule appliquée est "Signalements validés / Total signalements × 100"
|
||||
Et mon taux est de 80% (16 / 20 × 100)
|
||||
Et ce taux détermine mon éligibilité aux badges
|
||||
|
||||
Scénario: Obtention du badge Bronze
|
||||
Étant donné que j'ai 10 signalements envoyés
|
||||
Et que 7 signalements ont été validés
|
||||
Et que mon taux de pertinence est de 70%
|
||||
Quand le système évalue mon éligibilité
|
||||
Alors j'obtiens le badge 🥉 Contributeur Bronze
|
||||
Et je reçois une notification:
|
||||
"""
|
||||
🎉 Félicitations ! Vous êtes désormais Contributeur Bronze.
|
||||
Merci de rendre RoadWave meilleur !
|
||||
"""
|
||||
Et mes futurs signalements gagnent +10 points de priorité
|
||||
|
||||
Scénario: Obtention du badge Argent
|
||||
Étant donné que j'ai déjà le badge Bronze
|
||||
Et que j'ai 25 signalements envoyés
|
||||
Et que 20 signalements ont été validés
|
||||
Et que mon taux de pertinence est de 80%
|
||||
Et que 30 jours se sont écoulés depuis l'obtention du badge Bronze
|
||||
Quand le système évalue mon éligibilité
|
||||
Alors j'obtiens le badge 🥈 Contributeur Argent
|
||||
Et je reçois une notification:
|
||||
"""
|
||||
🎉 Impressionnant ! Badge Contributeur Argent obtenu.
|
||||
Votre engagement fait la différence !
|
||||
"""
|
||||
Et le badge est visible sur mon profil public
|
||||
Et mes futurs signalements gagnent +20 points de priorité
|
||||
|
||||
Scénario: Obtention du badge Or
|
||||
Étant donné que j'ai déjà le badge Argent
|
||||
Et que j'ai 60 signalements envoyés
|
||||
Et que 54 signalements ont été validés
|
||||
Et que mon taux de pertinence est de 90%
|
||||
Et que 60 jours se sont écoulés depuis l'obtention du badge Argent
|
||||
Quand le système évalue mon éligibilité
|
||||
Alors j'obtiens le badge 🥇 Contributeur Or
|
||||
Et je reçois une notification:
|
||||
"""
|
||||
🎉 Exceptionnel ! Vous êtes Contributeur Or.
|
||||
La communauté vous remercie pour votre aide précieuse !
|
||||
"""
|
||||
Et je bénéficie d'une réduction Premium -50% pendant 3 mois
|
||||
Et mes futurs signalements gagnent +30 points de priorité
|
||||
|
||||
Scénario: Délai minimum entre niveaux de badges
|
||||
Étant donné que j'ai obtenu le badge Bronze il y a 15 jours
|
||||
Et que je remplis les critères pour le badge Argent
|
||||
Quand le système évalue mon éligibilité
|
||||
Alors je ne peux pas encore obtenir le badge Argent
|
||||
Et je dois attendre 15 jours supplémentaires (30 jours minimum)
|
||||
Et cela évite la montée en badge trop rapide (anti-farming)
|
||||
|
||||
# 19.1.3 - Découverte du système
|
||||
|
||||
Scénario: Modal d'information au premier signalement
|
||||
Étant donné que je viens d'envoyer mon tout premier signalement
|
||||
Et que le toast de confirmation standard s'est affiché
|
||||
Quand exactement 2 secondes se sont écoulées
|
||||
Alors une modal d'information s'affiche automatiquement
|
||||
Et la modal explique le système de badges et récompenses
|
||||
Et la modal contient le titre "🎯 Bravo ! Vous contribuez à une communauté plus saine"
|
||||
Et la modal contient le message suivant:
|
||||
"""
|
||||
En signalant ce contenu, vous participez activement à améliorer
|
||||
l'expérience de tous les utilisateurs RoadWave.
|
||||
|
||||
Vos contributions de qualité sont valorisées et récompensées :
|
||||
|
||||
🥉 Bronze : 5 signalements validés
|
||||
→ Signalements prioritaires (+10 points)
|
||||
|
||||
🥈 Argent : 20 signalements validés
|
||||
→ Badge visible + priorité accrue (+20 points)
|
||||
|
||||
🥇 Or : 50 signalements validés
|
||||
→ Réduction Premium -50% pendant 3 mois
|
||||
|
||||
💡 Votre taux de pertinence compte !
|
||||
Formule : Signalements validés ÷ Total × 100
|
||||
|
||||
Continuez à nous aider, chaque signalement pertinent compte ! 🙏
|
||||
"""
|
||||
Et la modal contient un bouton "En savoir plus" qui redirige vers la page dédiée badges
|
||||
Et la modal contient un bouton "J'ai compris" qui ferme la modal
|
||||
Et la modal ne se réaffiche jamais (flag "badge_modal_seen" en base de données)
|
||||
Et le délai de 2 secondes permet de laisser l'utilisateur lire le toast de confirmation d'abord
|
||||
|
||||
# 19.1.4 - Affichage badges et statistiques
|
||||
|
||||
Scénario: Statistiques personnelles visibles
|
||||
Étant donné que j'ai un badge Bronze
|
||||
Quand je consulte "Profil > Mes signalements"
|
||||
Alors je vois mes statistiques de modération:
|
||||
"""
|
||||
📊 Vos statistiques de modération
|
||||
Signalements envoyés : 27
|
||||
Validés : 23 ✅
|
||||
Rejetés : 4 ❌
|
||||
Taux de pertinence : 85%
|
||||
|
||||
Badge actuel : 🥉 Contributeur Bronze
|
||||
Prochain palier : 🥈 Contributeur Argent (17 signalements validés restants)
|
||||
"""
|
||||
Et je vois ma progression vers le prochain badge
|
||||
|
||||
Scénario: Toast après validation de signalement
|
||||
Étant donné que j'ai un badge Bronze (3/5 signalements validés)
|
||||
Et que j'envoie un nouveau signalement
|
||||
Quand le modérateur valide mon signalement
|
||||
Alors je reçois un toast:
|
||||
"""
|
||||
✅ Bravo ! Votre signalement a aidé la communauté.
|
||||
Progression : 4/5 pour badge Bronze 🥉
|
||||
"""
|
||||
Et je vois ma progression vers le badge suivant
|
||||
|
||||
Scénario: Toast après rejet de signalement
|
||||
Étant donné que j'ai un taux de pertinence de 65%
|
||||
Et que j'envoie un nouveau signalement
|
||||
Quand le modérateur rejette mon signalement
|
||||
Alors je reçois un toast:
|
||||
"""
|
||||
❌ Signalement non retenu.
|
||||
Taux de pertinence : 60%.
|
||||
Continuez vos efforts !
|
||||
"""
|
||||
Et je vois l'impact sur mon taux de pertinence
|
||||
|
||||
# 19.2 - Score de fiabilité
|
||||
|
||||
Scénario: Calcul du score de fiabilité
|
||||
Étant donné que j'ai 15 signalements validés
|
||||
Et que j'ai 3 signalements rejetés
|
||||
Et que j'ai le badge Or actif
|
||||
Quand le système calcule mon score de fiabilité
|
||||
Alors la formule appliquée est:
|
||||
"""
|
||||
Score fiabilité = min(100, (Validés × 10 - Rejetés × 5 + Bonus_Or × 20))
|
||||
"""
|
||||
Et mon score est: min(100, (15 × 10 - 3 × 5 + 1 × 20)) = 100 (plafonné)
|
||||
Et ce score est utilisé dans l'algorithme de priorisation
|
||||
|
||||
Scénario: Utilisation du score dans la priorisation
|
||||
Étant donné que j'ai un score de fiabilité de 85/100
|
||||
Et qu'un autre utilisateur a un score de 30/100
|
||||
Quand nous signalons des contenus similaires
|
||||
Alors mon signalement a un meilleur score de priorité
|
||||
Et mon signalement est traité en premier
|
||||
Et la formule de priorité inclut:
|
||||
"""
|
||||
Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_signaleur × 0.1)
|
||||
"""
|
||||
Et la fiabilité est normalisée : 85/100 = 0.85
|
||||
|
||||
# 19.3 - Statut "Utilisateur de confiance"
|
||||
|
||||
Scénario: Obtention automatique du statut de confiance
|
||||
Étant donné que j'obtiens le badge Argent
|
||||
Quand mon statut est mis à jour
|
||||
Alors je deviens automatiquement "Utilisateur de confiance"
|
||||
Et mes signalements sont traités en priorité (même score IA)
|
||||
Et je reçois des notifications sous 12h (au lieu de 24-48h)
|
||||
Et le badge "Utilisateur de confiance" s'affiche sur mon profil
|
||||
|
||||
Scénario: Révocation du statut de confiance
|
||||
Étant donné que je suis "Utilisateur de confiance"
|
||||
Et que je perds mon badge Argent après audit trimestriel
|
||||
Quand mon statut est réévalué
|
||||
Alors le statut "Utilisateur de confiance" est révoqué
|
||||
Et je reviens au statut normal
|
||||
Et aucune sanction supplémentaire n'est appliquée
|
||||
|
||||
# 19.4 - Réduction Premium pour badge Or
|
||||
|
||||
Scénario: Notification de réduction Premium au badge Or
|
||||
Étant donné que j'obtiens le badge Contributeur Or
|
||||
Quand la notification est envoyée
|
||||
Alors je reçois un email + push + in-app:
|
||||
"""
|
||||
🎉 Exceptionnel ! Vous avez obtenu le badge Contributeur Or
|
||||
|
||||
Vous faites partie des meilleurs contributeurs de RoadWave.
|
||||
Grâce à votre engagement et votre vigilance, vous aidez
|
||||
des milliers d'utilisateurs à profiter d'une expérience audio de qualité.
|
||||
|
||||
La communauté vous remercie ! 🙏
|
||||
|
||||
En reconnaissance de votre aide précieuse, vous bénéficiez de :
|
||||
|
||||
✨ 3 mois d'abonnement Premium à -50%
|
||||
→ 2.49€/mois au lieu de 4.99€
|
||||
|
||||
[Profiter de l'offre]
|
||||
|
||||
Cette offre est valable pendant 30 jours.
|
||||
"""
|
||||
Et l'offre est valable pendant 30 jours
|
||||
|
||||
Scénario: Activation de la réduction Premium Or
|
||||
Étant donné que j'ai obtenu le badge Or
|
||||
Et que j'ai reçu l'offre Premium -50%
|
||||
Quand je clique sur "Profiter de l'offre" dans les 30 jours
|
||||
Alors je souscris à Premium à 2.49€/mois
|
||||
Et la réduction est valable pour 3 mois
|
||||
Et après 3 mois, le renouvellement passe à 4.99€/mois
|
||||
Et l'offre n'est pas cumulable avec l'offre annuelle
|
||||
|
||||
Scénario: Expiration de l'offre Premium après 30 jours
|
||||
Étant donné que j'ai obtenu le badge Or il y a 31 jours
|
||||
Et que je n'ai pas activé l'offre Premium -50%
|
||||
Quand j'essaie d'activer l'offre
|
||||
Alors l'offre a expiré
|
||||
Et je vois le message "Votre offre Premium -50% a expiré"
|
||||
Et mon badge Or est conservé (seule l'offre expire)
|
||||
Et je ne peux plus bénéficier de la réduction
|
||||
|
||||
Scénario: Rappels avant expiration de l'offre
|
||||
Étant donné que j'ai obtenu le badge Or
|
||||
Et que je n'ai pas encore activé l'offre Premium
|
||||
Quand il reste 7 jours avant l'expiration
|
||||
Alors je reçois un email + push:
|
||||
"""
|
||||
Il vous reste 7 jours pour profiter de votre réduction Premium -50%
|
||||
"""
|
||||
Et quand il reste 1 jour, je reçois un dernier rappel:
|
||||
"""
|
||||
Dernière chance ! Votre réduction Premium -50% expire demain
|
||||
"""
|
||||
|
||||
Scénario: Perte du badge Or pendant l'abonnement Premium
|
||||
Étant donné que j'ai le badge Or et l'abonnement Premium -50% actif
|
||||
Et que je perds le badge Or après un audit trimestriel
|
||||
Quand mon abonnement arrive à échéance
|
||||
Alors l'abonnement en cours reste actif jusqu'à sa fin normale
|
||||
Mais le renouvellement se fait à prix normal 4.99€/mois
|
||||
Et je ne peux pas réobtenir l'offre -50% même si je récupère le badge Or
|
||||
|
||||
# 19.5 - Anti-abus
|
||||
|
||||
Scénario: Limite de 10 signalements par 24h
|
||||
Étant donné que j'ai déjà envoyé 10 signalements aujourd'hui
|
||||
Quand j'essaie d'envoyer un 11ème signalement
|
||||
Alors le signalement est automatiquement rejeté
|
||||
Et je vois le message:
|
||||
"""
|
||||
Limite quotidienne atteinte (10 signalements/24h).
|
||||
Réessayez demain.
|
||||
"""
|
||||
Et une alerte modérateur automatique est déclenchée
|
||||
|
||||
Scénario: Détection de signalement massif suspect
|
||||
Étant donné que j'ai envoyé 35 signalements cette semaine
|
||||
Quand l'audit automatique hebdomadaire s'exécute
|
||||
Alors mon compte est détecté comme suspect (>30/semaine)
|
||||
Et une enquête manuelle modérateur est déclenchée
|
||||
Et le modérateur peut révoquer mon badge si abus confirmé
|
||||
|
||||
Scénario: Patterns suspects détectés
|
||||
Étant donné que le système analyse mes patterns de signalement
|
||||
Quand des comportements suspects sont identifiés:
|
||||
| pattern | seuil |
|
||||
| Signalement massif | >30/semaine |
|
||||
| Taux de pertinence très faible | <50% |
|
||||
| Tous signalements rejetés sur 7 jours | 100% rejet |
|
||||
| Signalements ciblant toujours même créateur | Harcèlement |
|
||||
Alors une enquête manuelle est déclenchée
|
||||
Et le modérateur examine les signalements en détail
|
||||
|
||||
Scénario: Audit trimestriel automatique des badges
|
||||
Étant donné que le système effectue l'audit trimestriel
|
||||
Quand mon badge est audité
|
||||
Alors le système recalcule mon taux de pertinence sur 6 mois glissants
|
||||
Et vérifie les critères:
|
||||
| badge | taux minimum |
|
||||
| Bronze | 70% |
|
||||
| Argent | 80% |
|
||||
| Or | 90% |
|
||||
Et si mon taux est insuffisant, mon badge est révoqué
|
||||
|
||||
Scénario: Email de prévention 7 jours avant audit
|
||||
Étant donné que l'audit trimestriel arrive dans 7 jours
|
||||
Et que mon taux de pertinence est de 78%
|
||||
Et que j'ai un badge Argent (minimum 80% requis)
|
||||
Quand le système envoie les notifications préventives
|
||||
Alors je reçois un email:
|
||||
"""
|
||||
Votre badge Contributeur Argent sera audité dans 7 jours.
|
||||
Taux de pertinence actuel : 78%
|
||||
Minimum requis : 80%
|
||||
|
||||
Continuez à signaler du contenu pertinent pour conserver votre badge !
|
||||
"""
|
||||
Et je suis informé à l'avance pour améliorer mes signalements
|
||||
|
||||
Scénario: Résultat d'audit - Badge conservé
|
||||
Étant donné que l'audit trimestriel vient d'être effectué
|
||||
Et que mon taux de pertinence est de 85%
|
||||
Et que j'ai un badge Argent (minimum 80% requis)
|
||||
Quand je reçois le résultat
|
||||
Alors je reçois un email: "Badge conservé ✓"
|
||||
Et mon badge reste actif pour 3 mois supplémentaires
|
||||
|
||||
Scénario: Résultat d'audit - Badge révoqué
|
||||
Étant donné que l'audit trimestriel vient d'être effectué
|
||||
Et que mon taux de pertinence est de 75%
|
||||
Et que j'ai un badge Argent (minimum 80% requis)
|
||||
Quand je reçois le résultat
|
||||
Alors je reçois un email: "Badge révoqué ✗"
|
||||
Et mon badge Argent est révoqué immédiatement
|
||||
Mais je peux réobtenir un badge ultérieurement (pas de ban)
|
||||
|
||||
Scénario: Sanctions pour abus détecté - Mineur
|
||||
Étant donné que j'ai envoyé >10 signalements/jour pendant 1 jour
|
||||
Quand l'abus mineur est détecté
|
||||
Alors je reçois un avertissement
|
||||
Et ma limite est réduite à 5 signalements/jour pendant 7 jours
|
||||
Et je reçois une notification explicative
|
||||
|
||||
Scénario: Sanctions pour abus détecté - Modéré
|
||||
Étant donné que j'ai envoyé >30 signalements/semaine
|
||||
Et que mon taux de pertinence est <50%
|
||||
Quand l'abus modéré est confirmé
|
||||
Alors tous mes badges sont révoqués
|
||||
Et je suis interdit de signalement pendant 30 jours
|
||||
Et je reçois une notification de sanction
|
||||
|
||||
Scénario: Sanctions pour abus détecté - Grave
|
||||
Étant donné que j'ai participé à un farming coordonné de signalements
|
||||
Quand l'abus grave est confirmé par modérateur
|
||||
Alors je reçois un ban permanent de la fonctionnalité signalement
|
||||
Et tous mes badges sont révoqués définitivement
|
||||
Et il n'y a pas de recours possible pour farming confirmé
|
||||
|
||||
# ROI et justification
|
||||
|
||||
Scénario: ROI positif de la modération communautaire
|
||||
Étant donné que 10 utilisateurs Or sont actifs
|
||||
Quand on calcule le ROI
|
||||
Alors chaque utilisateur Or économise 5-10h de modération/mois
|
||||
Et cela représente 75-150€ économisés par utilisateur (taux 15€/h)
|
||||
Et le total est de 750-1500€ économisés/mois
|
||||
Et le coût des réductions Premium est maximum 200€/mois (50 utilisateurs Or)
|
||||
Et le ROI est positif dès 2-3 utilisateurs Or actifs
|
||||
|
||||
Scénario: Coût total du système
|
||||
Étant donné que le système de modération communautaire est en place
|
||||
Quand on calcule le coût total
|
||||
Alors en phase MVP, le coût est de 0€
|
||||
Et en phase Post-MVP avec réductions Premium, le coût est de 0-200€/mois
|
||||
Et le système est entièrement automatique (0€ développement continu)
|
||||
Et le ROI est largement positif
|
||||
@@ -0,0 +1,284 @@
|
||||
# language: fr
|
||||
|
||||
@moderation @preventive
|
||||
Fonctionnalité: Modération préventive
|
||||
|
||||
# 14.5 - Modération préventive (rappel)
|
||||
|
||||
Contexte:
|
||||
Étant donné que le système de modération préventive est actif
|
||||
|
||||
# Nouveaux créateurs - Validation manuelle des 3 premiers contenus
|
||||
|
||||
Scénario: Créateur nouvellement inscrit
|
||||
Étant donné que je viens de créer un compte créateur
|
||||
Et que je n'ai jamais publié de contenu
|
||||
Quand j'examine mon statut de créateur
|
||||
Alors mon compte est marqué comme "Nouveau créateur"
|
||||
Et mes 3 premiers contenus devront être validés manuellement
|
||||
Et je suis informé de ce processus lors de l'onboarding
|
||||
|
||||
Scénario: Publication du premier contenu par un nouveau créateur
|
||||
Étant donné que je suis un nouveau créateur
|
||||
Et que je n'ai publié aucun contenu auparavant
|
||||
Quand je publie mon premier contenu
|
||||
Alors le contenu entre en file d'attente de validation manuelle
|
||||
Et le statut du contenu est "En attente de validation"
|
||||
Et le contenu n'est pas diffusé sur la plateforme
|
||||
Et je reçois une notification:
|
||||
"""
|
||||
Votre contenu est en cours de validation.
|
||||
Les premiers contenus sont vérifiés manuellement pour garantir la qualité de la plateforme.
|
||||
Délai: 24-48h (jours ouvrés).
|
||||
"""
|
||||
|
||||
Scénario: Validation manuelle par un modérateur
|
||||
Étant donné que j'ai publié mon premier contenu
|
||||
Et que le contenu est en attente de validation
|
||||
Quand un modérateur examine mon contenu
|
||||
Alors le modérateur utilise la transcription automatique Whisper
|
||||
Et le modérateur vérifie:
|
||||
| critère | conforme |
|
||||
| Respect des règles communauté | oui |
|
||||
| Pas de contenu inapproprié | oui |
|
||||
| Qualité audio acceptable | oui |
|
||||
| Métadonnées cohérentes | oui |
|
||||
| Tags appropriés | oui |
|
||||
Et si tout est conforme, le contenu est validé
|
||||
|
||||
Scénario: Délai de validation de 24-48h jours ouvrés
|
||||
Étant donné que j'ai publié mon premier contenu lundi à 10:00
|
||||
Quand le contenu entre en file de validation
|
||||
Alors le contenu est validé avant mercredi 10:00 (48h jours ouvrés)
|
||||
Et dans la plupart des cas, la validation est effectuée sous 24h
|
||||
Et je reçois une notification dès que le contenu est validé
|
||||
|
||||
Scénario: Notification de validation réussie
|
||||
Étant donné que mon premier contenu a été validé par un modérateur
|
||||
Quand la validation est approuvée
|
||||
Alors je reçois une notification:
|
||||
"""
|
||||
✓ Votre contenu "Mon premier podcast" a été validé!
|
||||
Il est maintenant diffusé sur RoadWave.
|
||||
"""
|
||||
Et le statut du contenu passe à "Publié"
|
||||
Et le contenu devient visible pour tous les utilisateurs
|
||||
Et il entre dans l'algorithme de recommandation
|
||||
|
||||
Scénario: Refus de validation si contenu non conforme
|
||||
Étant donné que mon premier contenu viole les règles de la communauté
|
||||
Quand le modérateur examine le contenu
|
||||
Alors le contenu est refusé
|
||||
Et je reçois une notification détaillée:
|
||||
"""
|
||||
⚠️ Votre contenu "Mon premier podcast" n'a pas été validé.
|
||||
|
||||
Raison: Contenu inapproprié détecté
|
||||
Passage problématique: 3:15-3:45
|
||||
Transcription: "[passage surligné]"
|
||||
|
||||
Que faire?
|
||||
- Corrigez le problème et republiez
|
||||
- Consultez les règles de la communauté
|
||||
- Contactez le support si vous avez des questions
|
||||
"""
|
||||
Et le contenu reste en statut "Refusé"
|
||||
Et je peux modifier et republier
|
||||
|
||||
Scénario: Les 3 premiers contenus sont validés manuellement
|
||||
Étant donné que je suis un nouveau créateur
|
||||
Quand je publie mes contenus
|
||||
Alors les contenus suivants nécessitent une validation manuelle:
|
||||
| contenu | validation manuelle |
|
||||
| 1er | oui |
|
||||
| 2ème | oui |
|
||||
| 3ème | oui |
|
||||
| 4ème | non (auto) |
|
||||
Et après 3 contenus validés, mes futurs contenus sont publiés automatiquement
|
||||
|
||||
Scénario: Passage en mode automatique après 3 validations
|
||||
Étant donné que mes 3 premiers contenus ont été validés avec succès
|
||||
Quand je publie mon 4ème contenu
|
||||
Alors le contenu est publié automatiquement
|
||||
Et aucune validation manuelle n'est requise
|
||||
Et le statut passe directement à "Publié"
|
||||
Et je reçois une notification:
|
||||
"""
|
||||
✓ Votre contenu a été publié automatiquement.
|
||||
Vos 3 premiers contenus ayant été conformes, vos futurs contenus sont publiés instantanément.
|
||||
"""
|
||||
|
||||
# Score de confiance dynamique
|
||||
|
||||
Scénario: Évolution du score de confiance
|
||||
Étant donné que je suis un créateur établi
|
||||
Quand le système évalue mon historique
|
||||
Alors un score de confiance est calculé basé sur:
|
||||
| critère | poids |
|
||||
| Nombre de contenus publiés | 20% |
|
||||
| Strikes reçus | 40% |
|
||||
| Signalements infondés | 20% |
|
||||
| Ancienneté du compte | 10% |
|
||||
| Taux d'engagement positif | 10% |
|
||||
Et le score évolue dynamiquement
|
||||
|
||||
Scénario: Créateur fiable - Publication automatique
|
||||
Étant donné que je suis un créateur
|
||||
Et que j'ai 0 strike depuis 6 mois
|
||||
Et que tous mes contenus précédents ont été conformes
|
||||
Quand mon score de confiance est calculé
|
||||
Alors je suis classé comme "Créateur fiable"
|
||||
Et tous mes nouveaux contenus sont publiés automatiquement
|
||||
Et aucune validation manuelle n'est nécessaire
|
||||
Et je bénéficie d'une publication instantanée
|
||||
|
||||
Scénario: Créateur suspect - Validation manuelle systématique
|
||||
Étant donné que je suis un créateur
|
||||
Et que j'ai reçu 2 strikes récents (< 3 mois)
|
||||
Quand mon score de confiance est recalculé
|
||||
Alors je suis classé comme "Créateur suspect"
|
||||
Et tous mes nouveaux contenus nécessitent une validation manuelle
|
||||
Et chaque contenu est examiné avant publication
|
||||
Et je suis notifié de ce changement de statut:
|
||||
"""
|
||||
En raison de sanctions récentes, vos contenus nécessitent une validation manuelle.
|
||||
Respectez les règles de la communauté pour retrouver la publication automatique.
|
||||
"""
|
||||
|
||||
Scénario: Réhabilitation après période sans incident
|
||||
Étant donné que j'étais un "Créateur suspect"
|
||||
Et que je publie 10 contenus conformes sur 6 mois
|
||||
Et que je ne reçois aucun nouveau strike
|
||||
Quand le système réévalue mon score de confiance
|
||||
Alors je passe en "Créateur fiable"
|
||||
Et la publication automatique est rétablie
|
||||
Et je reçois une notification de réhabilitation:
|
||||
"""
|
||||
✓ Félicitations! Vous êtes de nouveau un créateur fiable.
|
||||
Vos contenus seront publiés automatiquement.
|
||||
"""
|
||||
|
||||
# Publicités - Validation manuelle obligatoire
|
||||
|
||||
Scénario: Toute publicité nécessite validation manuelle
|
||||
Étant donné qu'un annonceur soumet une publicité audio
|
||||
Quand la publicité est créée
|
||||
Alors elle entre automatiquement en file de validation manuelle
|
||||
Et aucune publicité n'est diffusée sans validation préalable
|
||||
Et cela est obligatoire pour des raisons de responsabilité juridique
|
||||
|
||||
Scénario: Validation d'une publicité - Processus complet
|
||||
Étant donné qu'une publicité est en attente de validation
|
||||
Quand un modérateur senior examine la publicité
|
||||
Alors le modérateur vérifie:
|
||||
| critère | conforme |
|
||||
| Transcription automatique Whisper | effectuée|
|
||||
| Contenu conforme aux règles | oui |
|
||||
| Pas de fausse publicité / arnaque | oui |
|
||||
| Respect du ciblage géographique | oui |
|
||||
| Durée conforme (10-60s) | oui |
|
||||
| Volume audio acceptable (pas trop fort)| oui |
|
||||
| Métadonnées correctes | oui |
|
||||
Et si tout est conforme, la publicité est validée
|
||||
|
||||
Scénario: Délai de validation d'une publicité - 24-48h
|
||||
Étant donné qu'un annonceur soumet une publicité lundi à 10:00
|
||||
Quand la publicité entre en file de validation
|
||||
Alors la publicité est validée avant mercredi 10:00 (48h jours ouvrés)
|
||||
Et l'annonceur est notifié dès la validation
|
||||
Et la campagne publicitaire peut alors démarrer
|
||||
|
||||
Scénario: Refus de validation d'une publicité
|
||||
Étant donné qu'une publicité contient des éléments non conformes
|
||||
Quand le modérateur examine la publicité
|
||||
Alors la publicité est refusée
|
||||
Et l'annonceur reçoit une notification détaillée:
|
||||
"""
|
||||
⚠️ Votre publicité n'a pas été validée.
|
||||
|
||||
Raison: Contenu trompeur détecté
|
||||
Passage problématique: 0:15-0:25
|
||||
Transcription: "[promesse irréaliste surlignée]"
|
||||
|
||||
Que faire?
|
||||
- Modifiez votre publicité
|
||||
- Soumettez-la à nouveau pour validation
|
||||
- Consultez les règles publicitaires de RoadWave
|
||||
"""
|
||||
Et l'annonceur peut modifier et resoumettre la publicité
|
||||
Et aucun remboursement n'est effectué pour une publicité refusée
|
||||
|
||||
# Prévention > Réaction
|
||||
|
||||
Scénario: Économie de modération grâce à la prévention
|
||||
Étant donné que la modération préventive est active
|
||||
Quand on analyse l'efficacité du système
|
||||
Alors 80% des contenus inappropriés sont détectés avant publication
|
||||
Et cela réduit le nombre de signalements de 70%
|
||||
Et les ressources de modération sont optimisées
|
||||
Et la qualité de la plateforme est préservée dès le début
|
||||
|
||||
Scénario: Qualité de la plateforme maintenue
|
||||
Étant donné que tous les nouveaux créateurs sont vérifiés
|
||||
Quand on analyse la qualité globale des contenus
|
||||
Alors le taux de contenus inappropriés est <1%
|
||||
Et les utilisateurs font confiance à la plateforme
|
||||
Et la réputation de RoadWave est préservée
|
||||
Et l'expérience utilisateur est optimale
|
||||
|
||||
# Transparence envers les créateurs
|
||||
|
||||
Scénario: Information claire sur le processus de validation
|
||||
Étant donné que je suis un nouveau créateur
|
||||
Quand je consulte la page d'aide "Validation des contenus"
|
||||
Alors j'apprends que:
|
||||
"""
|
||||
Validation des contenus
|
||||
|
||||
Nouveaux créateurs:
|
||||
- Vos 3 premiers contenus sont validés manuellement
|
||||
- Délai: 24-48h (jours ouvrés)
|
||||
- Après 3 contenus conformes: publication automatique
|
||||
|
||||
Créateurs établis:
|
||||
- Publication automatique si historique conforme
|
||||
- Validation manuelle si strikes récents
|
||||
|
||||
Publicités:
|
||||
- Validation manuelle obligatoire pour toutes les publicités
|
||||
- Délai: 24-48h (jours ouvrés)
|
||||
"""
|
||||
Et le processus est clair et transparent
|
||||
|
||||
Scénario: Badge "Créateur vérifié" après validation
|
||||
Étant donné que mes 3 premiers contenus ont été validés avec succès
|
||||
Quand je consulte mon profil créateur
|
||||
Alors un badge discret "✓ Créateur vérifié" s'affiche
|
||||
Et ce badge rassure les auditeurs sur la qualité de mes contenus
|
||||
Et il améliore ma crédibilité sur la plateforme
|
||||
|
||||
# Conformité et justification
|
||||
|
||||
Scénario: Justification de la modération préventive
|
||||
Étant donné que la modération préventive est en place
|
||||
Quand on évalue les bénéfices
|
||||
Alors les avantages suivants sont constatés:
|
||||
| bénéfice |
|
||||
| Prévention meilleure que réaction |
|
||||
| Économie de ressources de modération (×3-5) |
|
||||
| Qualité de la plateforme préservée dès le début |
|
||||
| Confiance des utilisateurs renforcée |
|
||||
| Moins de contenus inappropriés signalés |
|
||||
| Réputation de la plateforme protégée |
|
||||
Et l'investissement dans la prévention est rentable
|
||||
|
||||
Scénario: Coût de la modération préventive
|
||||
Étant donné que 100 nouveaux créateurs publient 3 contenus chacun
|
||||
Et que 50 publicités sont soumises par mois
|
||||
Quand on calcule le coût de modération préventive
|
||||
Alors le coût en temps modérateur est:
|
||||
| type | nombre | temps/contenu | total |
|
||||
| Nouveaux créateurs| 300 | 5 min | 25h |
|
||||
| Publicités | 50 | 10 min | 8.3h |
|
||||
Et le coût total est d'environ 33h de modération/mois
|
||||
Et c'est largement compensé par la réduction des signalements réactifs
|
||||
@@ -0,0 +1,56 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @premium @rewards @mvp
|
||||
Fonctionnalité: Réduction Premium pour badge Or
|
||||
|
||||
En tant qu'utilisateur avec badge Or
|
||||
Je veux obtenir une réduction sur l'abonnement Premium
|
||||
Afin d'être récompensé de ma contribution
|
||||
|
||||
Scénario: Réduction automatique à l'obtention du badge Or
|
||||
Étant donné un utilisateur "alice@roadwave.fr" qui débloque le badge Or
|
||||
Quand il consulte la page Premium
|
||||
Alors une réduction de 20% est automatiquement appliquée
|
||||
Et le prix passe de 4.99€/mois à 3.99€/mois
|
||||
Et un événement "PREMIUM_DISCOUNT_GOLD_APPLIED" est enregistré
|
||||
|
||||
Scénario: Cumul avec autres réductions
|
||||
Étant donné un utilisateur avec badge Or ET statut Trusted
|
||||
Alors les réductions se cumulent:
|
||||
| Réduction | Montant |
|
||||
| Badge Or | -20% |
|
||||
| Utilisateur confiance| -10% |
|
||||
| Total | -30% |
|
||||
Et le prix final: 4.99€ - 30% = 3.49€/mois
|
||||
Et un événement "PREMIUM_DISCOUNTS_STACKED" est enregistré
|
||||
|
||||
Scénario: Badge Diamant - Premium gratuit à vie
|
||||
Étant donné un utilisateur avec badge Diamant
|
||||
Alors l'abonnement Premium est gratuit à vie
|
||||
Et aucun paiement n'est requis
|
||||
Et un badge spécial "Premium Lifetime" s'affiche
|
||||
Et un événement "PREMIUM_LIFETIME_GRANTED" est enregistré
|
||||
|
||||
Scénario: Perte de la réduction si perte du badge
|
||||
Étant donné un utilisateur avec badge Or et réduction active
|
||||
Quand le badge Or est révoqué (précision < 70%)
|
||||
Alors la réduction est supprimée au prochain renouvellement
|
||||
Et l'utilisateur est notifié 7 jours à l'avance
|
||||
Et un événement "PREMIUM_DISCOUNT_REVOKED" est enregistré
|
||||
|
||||
Scénario: Code promo automatique pour badge Or
|
||||
Étant donné un utilisateur "bob@roadwave.fr" avec badge Or
|
||||
Quand il s'abonne à Premium
|
||||
Alors un code promo "GOLD20" est automatiquement appliqué
|
||||
Et visible dans la facture
|
||||
Et un événement "PREMIUM_PROMO_CODE_APPLIED" est enregistré
|
||||
|
||||
Scénario: Statistiques d'impact des réductions
|
||||
Étant donné que 200 utilisateurs ont badge Or
|
||||
Alors les métriques montrent:
|
||||
| Métrique | Valeur |
|
||||
| Utilisateurs avec réduction | 200 |
|
||||
| Taux de conversion Premium (Or) | 45% |
|
||||
| Taux de conversion Premium (standard)| 12% |
|
||||
| Revenus générés malgré réduction | +35% |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
@@ -0,0 +1,42 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @sanctions @mvp
|
||||
Fonctionnalité: Sanctions progressives pour abus de signalement
|
||||
|
||||
En tant que plateforme
|
||||
Je veux sanctionner les abus de signalement progressivement
|
||||
Afin de dissuader le spam et les faux signalements
|
||||
|
||||
Scénario: Premier abus - Avertissement
|
||||
Étant donné un utilisateur avec 3 faux signalements en 24h
|
||||
Quand le 3ème est confirmé comme faux
|
||||
Alors un avertissement est envoyé
|
||||
Et un message explique les règles
|
||||
Et un événement "ABUSE_WARNING_ISSUED" est enregistré
|
||||
|
||||
Scénario: Deuxième abus - Limitation temporaire
|
||||
Étant donné un utilisateur avec 2ème série de faux signalements
|
||||
Alors il est limité à 5 signalements par jour pendant 7 jours
|
||||
Et un événement "ABUSE_LIMITED_REPORTING" est enregistré
|
||||
|
||||
Scénario: Troisième abus - Suspension 30 jours
|
||||
Étant donné un utilisateur avec 3ème série d'abus
|
||||
Alors il perd le droit de signaler pendant 30 jours
|
||||
Et tous ses badges modération sont révoqués
|
||||
Et un événement "ABUSE_SUSPENDED_30D" est enregistré
|
||||
|
||||
Scénario: Quatrième abus - Bannissement définitif
|
||||
Étant donné un utilisateur avec 4ème série d'abus
|
||||
Alors il est définitivement banni de la modération
|
||||
Et ne peut jamais récupérer ce droit
|
||||
Et un événement "ABUSE_PERMANENT_BAN" est enregistré
|
||||
|
||||
Scénario: Métriques de sanctions
|
||||
Étant donné que 500 sanctions ont été appliquées
|
||||
Alors les indicateurs suivants sont disponibles:
|
||||
| Sanction | Nombre | % |
|
||||
| Avertissements | 320 | 64% |
|
||||
| Limitations | 120 | 24% |
|
||||
| Suspensions 30j | 50 | 10% |
|
||||
| Bannissements | 10 | 2% |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
@@ -0,0 +1,43 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @copyright @sanctions @mvp
|
||||
Fonctionnalité: Sanctions progressives pour violations droits d'auteur
|
||||
|
||||
En tant que plateforme
|
||||
Je veux appliquer des sanctions progressives
|
||||
Afin de dissuader les violations répétées
|
||||
|
||||
Scénario: Première infraction - Avertissement
|
||||
Étant donné un créateur "alice@roadwave.fr" première infraction
|
||||
Quand la violation est confirmée
|
||||
Alors un avertissement formel est envoyé
|
||||
Et le contenu est retiré
|
||||
Et aucune sanction sur le compte
|
||||
Et un événement "COPYRIGHT_WARNING_ISSUED" est enregistré
|
||||
|
||||
Scénario: Deuxième infraction - Suspension 7 jours
|
||||
Étant donné un créateur avec 2ème infraction
|
||||
Alors le compte est suspendu 7 jours
|
||||
Et tous les contenus sont masqués temporairement
|
||||
Et un événement "COPYRIGHT_SUSPENSION_7D" est enregistré
|
||||
|
||||
Scénario: Troisième infraction - Suspension 30 jours
|
||||
Étant donné un créateur avec 3ème infraction
|
||||
Alors le compte est suspendu 30 jours
|
||||
Et perte de tous les badges
|
||||
Et un événement "COPYRIGHT_SUSPENSION_30D" est enregistré
|
||||
|
||||
Scénario: Quatrième infraction - Bannissement définitif
|
||||
Étant donné un créateur avec 4ème infraction
|
||||
Alors le compte est définitivement banni
|
||||
Et tous les contenus sont supprimés
|
||||
Et l'email/IP sont blacklistés
|
||||
Et un événement "COPYRIGHT_PERMANENT_BAN" est enregistré
|
||||
|
||||
Scénario: Réhabilitation après bonne conduite
|
||||
Étant donné un créateur suspendu depuis 6 mois
|
||||
Et aucune nouvelle infraction
|
||||
Quand il demande une réhabilitation
|
||||
Alors son historique peut être effacé
|
||||
Et il repart avec un compteur à zéro
|
||||
Et un événement "COPYRIGHT_REHABILITATION_GRANTED" est enregistré
|
||||
@@ -0,0 +1,352 @@
|
||||
# language: fr
|
||||
|
||||
@moderation @sanctions
|
||||
Fonctionnalité: Sanctions et notifications de modération
|
||||
|
||||
# 14.3 - Sanctions
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis un créateur de contenu
|
||||
Et que j'ai publié un contenu
|
||||
|
||||
# 14.3.1 - Notification au créateur (multi-canal)
|
||||
|
||||
Scénario: Notification multi-canal après sanction
|
||||
Étant donné que mon contenu a été modéré
|
||||
Quand la sanction est appliquée
|
||||
Alors je reçois une notification sur 3 canaux:
|
||||
| canal | timing | contenu |
|
||||
| Push | Immédiat | "Votre contenu a été modéré" |
|
||||
| In-app | Au prochain lancement| Popup détaillée avec bouton "Voir détails" |
|
||||
| Email | Dans l'heure | Notification complète avec lien d'appel |
|
||||
Et chaque canal contient un lien vers les détails complets
|
||||
|
||||
Scénario: Notification push immédiate
|
||||
Étant donné que mon contenu vient d'être modéré
|
||||
Quand la sanction est appliquée
|
||||
Alors je reçois une notification push immédiate
|
||||
Et le message est court: "⚠️ Votre contenu a été modéré"
|
||||
Et je peux cliquer pour voir les détails
|
||||
Et la notification utilise Firebase Cloud Messaging (Android) ou APNs (iOS)
|
||||
Et le coût est de 0€
|
||||
|
||||
Scénario: Popup in-app au prochain lancement
|
||||
Étant donné que mon contenu a été modéré
|
||||
Quand j'ouvre l'application
|
||||
Alors une popup détaillée s'affiche automatiquement
|
||||
Et la popup contient:
|
||||
| élément | description |
|
||||
| Titre du contenu | "Mon podcast #42" |
|
||||
| Icône d'avertissement | ⚠️ |
|
||||
| Catégorie violée | 🚫 Haine & violence |
|
||||
| Sanction | Strike 2/4 - Suspension 7 jours |
|
||||
| Bouton "Voir détails" | Redirige vers page détaillée |
|
||||
| Bouton "Compris" | Ferme la popup |
|
||||
Et je ne peux pas fermer la popup sans l'avoir vue
|
||||
|
||||
Scénario: Email de notification complet dans l'heure
|
||||
Étant donné que mon contenu a été modéré à 14:00
|
||||
Quand la sanction est appliquée
|
||||
Alors je reçois un email avant 15:00 (dans l'heure)
|
||||
Et l'objet de l'email est "Modération de votre contenu \"[Titre du contenu]\""
|
||||
Et l'email contient toutes les informations détaillées
|
||||
Et le coût est d'environ 0.001€ par email (Brevo, Resend)
|
||||
|
||||
# 14.3.2 - Détail de la sanction
|
||||
|
||||
Scénario: Email de notification complet et structuré
|
||||
Étant donné que mon contenu "Mon podcast #42" a été modéré
|
||||
Quand je reçois l'email de notification dans l'heure suivant la sanction
|
||||
Alors l'email contient la structure exacte suivante:
|
||||
"""
|
||||
Objet : Modération de votre contenu "Mon podcast #42"
|
||||
|
||||
Bonjour @mon_pseudo,
|
||||
|
||||
Votre contenu "Mon podcast #42" publié le 15/01/2026 a été modéré.
|
||||
|
||||
─────────────────────────────────────
|
||||
📋 DÉTAILS DE LA SANCTION
|
||||
─────────────────────────────────────
|
||||
|
||||
Catégorie violée : 🚫 Haine & violence (Article 3.2 CGU)
|
||||
Raison détaillée : Propos discriminatoires envers un groupe de personnes
|
||||
|
||||
─────────────────────────────────────
|
||||
🔊 PASSAGE PROBLÉMATIQUE
|
||||
─────────────────────────────────────
|
||||
|
||||
Timestamp : 3:42-4:15 (33 secondes)
|
||||
Transcription : "[passage problématique surligné en rouge]"
|
||||
|
||||
─────────────────────────────────────
|
||||
⚠️ SANCTION APPLIQUÉE
|
||||
─────────────────────────────────────
|
||||
|
||||
Strike actuel : 2/4
|
||||
Conséquence : Suspension de votre compte pendant 7 jours
|
||||
Date de fin : 22/01/2026
|
||||
|
||||
Que se passe-t-il ensuite ?
|
||||
• Strike 3 : Suspension 30 jours
|
||||
• Strike 4 : Ban définitif
|
||||
|
||||
─────────────────────────────────────
|
||||
📝 RECOURS
|
||||
─────────────────────────────────────
|
||||
|
||||
Vous pouvez contester cette décision sous 7 jours :
|
||||
[Lien formulaire d'appel]
|
||||
|
||||
Cordialement,
|
||||
L'équipe RoadWave
|
||||
"""
|
||||
Et l'email est envoyé via le service Brevo ou Resend
|
||||
Et le coût d'envoi est d'environ 0.001€ par email
|
||||
Et l'email contient un lien direct vers le formulaire d'appel pré-rempli
|
||||
|
||||
Scénario: Page détaillée de la sanction in-app
|
||||
Étant donné que je clique sur "Voir détails" dans la notification
|
||||
Quand la page détaillée s'affiche
|
||||
Alors je vois les 6 éléments obligatoires:
|
||||
| élément | contenu |
|
||||
| 1. Catégorie violée | 🚫 Haine & violence (Article 3.2 CGU) |
|
||||
| 2. Raison détaillée | Explication claire et non juridique |
|
||||
| 3. Extrait audio | Timestamp exact: 3:42-4:15 |
|
||||
| 4. Transcription | Texte problématique surligné en rouge |
|
||||
| 5. Gravité | Strike actuel + conséquences (Strike 2/4, 7j susp) |
|
||||
| 6. Recours | Lien formulaire d'appel + délai 7j |
|
||||
|
||||
Scénario: Affichage du passage problématique avec timestamp
|
||||
Étant donné que la page détaillée de la sanction est affichée
|
||||
Quand je consulte l'extrait audio concerné
|
||||
Alors le timestamp exact est affiché: "3:42-4:15"
|
||||
Et je peux écouter uniquement cette portion de l'audio
|
||||
Et un player audio intégré permet l'écoute du passage
|
||||
Et la transcription correspondante est affichée en dessous
|
||||
Et les mots/phrases problématiques sont surlignés en rouge
|
||||
|
||||
Scénario: Référence précise aux CGU
|
||||
Étant donné que la sanction fait référence à l'Article 3.2 des CGU
|
||||
Quand je clique sur "Article 3.2"
|
||||
Alors je suis redirigé vers la section correspondante des CGU
|
||||
Et la section "Haine & violence" est mise en évidence
|
||||
Et je peux lire exactement ce qui est interdit
|
||||
Et cela m'aide à comprendre mon erreur
|
||||
|
||||
Scénario: Gravité de la sanction avec système de strikes
|
||||
Étant donné que c'est mon 2ème strike
|
||||
Quand je consulte les détails de la sanction
|
||||
Alors je vois clairement "Strike 2/4"
|
||||
Et les conséquences sont explicitées:
|
||||
"""
|
||||
Strike 2/4 - Suspension 7 jours
|
||||
|
||||
Que se passe-t-il ensuite?
|
||||
- Strike 3: Suspension 30 jours
|
||||
- Strike 4: Ban définitif
|
||||
|
||||
Comment éviter les strikes?
|
||||
- Lire et respecter les règles de la communauté
|
||||
- Réhabilitation: -1 strike tous les 6 mois sans incident
|
||||
"""
|
||||
Et je comprends l'escalade des sanctions
|
||||
|
||||
# 14.3.3 - Processus d'appel
|
||||
|
||||
Scénario: Accès au formulaire d'appel depuis la notification
|
||||
Étant donné que j'ai reçu une notification de modération
|
||||
Quand je clique sur "Contester cette décision"
|
||||
Alors je suis redirigé vers le formulaire d'appel
|
||||
Et le formulaire est pré-rempli avec les informations de la sanction
|
||||
Et je peux commencer à rédiger mon appel
|
||||
|
||||
Scénario: Accès au formulaire d'appel depuis "Mes sanctions"
|
||||
Étant donné que j'ai reçu une sanction il y a 2 jours
|
||||
Quand j'ouvre "Profil créateur > Mes sanctions"
|
||||
Alors je vois la liste de mes sanctions
|
||||
Et chaque sanction a un bouton "Faire appel" (si délai <7j)
|
||||
Et je peux accéder au formulaire d'appel
|
||||
|
||||
Scénario: Structure du formulaire d'appel
|
||||
Étant donné que j'ouvre le formulaire d'appel
|
||||
Quand le formulaire s'affiche
|
||||
Alors je vois les champs suivants:
|
||||
| champ | type | obligatoire | description |
|
||||
| Sanction contestée | Pré-rempli (readonly) | oui | "Strike 2 - Podcast #42" |
|
||||
| Raison de l'appel | Texte (50-1000 car) | oui | Explication courte de la contestation |
|
||||
| Arguments détaillés | Zone texte enrichie | oui | Arguments complets |
|
||||
| Preuves | Upload fichiers | non | Max 5 fichiers, 10 MB total |
|
||||
Et tous les champs obligatoires sont marqués d'un astérisque
|
||||
|
||||
Scénario: Validation du formulaire d'appel
|
||||
Étant donné que je remplis le formulaire d'appel
|
||||
Quand je clique sur "Soumettre l'appel"
|
||||
Alors le système valide les champs obligatoires
|
||||
Et si un champ obligatoire est vide, une erreur s'affiche
|
||||
Et si la raison fait moins de 50 caractères, une erreur s'affiche
|
||||
Et si tout est valide, l'appel est soumis
|
||||
|
||||
Scénario: Confirmation après soumission de l'appel
|
||||
Étant donné que j'ai soumis un appel valide
|
||||
Quand l'appel est enregistré
|
||||
Alors un numéro de ticket unique est généré: "#MOD-2026-00142"
|
||||
Et un email de confirmation est envoyé:
|
||||
"""
|
||||
Votre appel #MOD-2026-00142 a été reçu.
|
||||
Nous l'examinerons sous 72h maximum.
|
||||
Vous serez notifié de la décision par email et in-app.
|
||||
"""
|
||||
Et le statut de l'appel est "En cours d'examen"
|
||||
Et je peux suivre le statut dans "Mes sanctions"
|
||||
|
||||
Scénario: Délai de soumission de 7 jours maximum
|
||||
Étant donné que j'ai reçu une sanction le 2026-01-15
|
||||
Quand j'essaie de faire appel le 2026-01-25 (10 jours plus tard)
|
||||
Alors le formulaire d'appel est désactivé
|
||||
Et un message s'affiche:
|
||||
"""
|
||||
Le délai de 7 jours pour faire appel est dépassé.
|
||||
Cette décision est désormais définitive.
|
||||
"""
|
||||
Et je ne peux plus contester la sanction
|
||||
|
||||
Scénario: Bouton "Faire appel" visible si délai respecté
|
||||
Étant donné que j'ai reçu une sanction il y a 3 jours
|
||||
Quand je consulte "Mes sanctions"
|
||||
Alors le bouton "Faire appel" est actif
|
||||
Et un compteur indique "4 jours restants pour faire appel"
|
||||
Et je peux cliquer pour soumettre un appel
|
||||
|
||||
# 14.3.4 - Délai de réponse pour appel
|
||||
|
||||
Scénario: SLA de 72h garanti pour appel standard
|
||||
Étant donné que j'ai soumis un appel standard le lundi à 10:00
|
||||
Quand l'appel est en cours de traitement
|
||||
Alors un modérateur senior est assigné
|
||||
Et l'appel doit être traité avant jeudi 10:00 (72h - 3 jours ouvrés)
|
||||
Et je reçois une réponse dans ce délai
|
||||
|
||||
Scénario: Appel complexe avec notification intermédiaire
|
||||
Étant donné que j'ai soumis un appel complexe
|
||||
Et que le traitement nécessite plus de 72h
|
||||
Quand 3 jours se sont écoulés
|
||||
Alors je reçois un email de notification intermédiaire:
|
||||
"""
|
||||
Votre appel #MOD-2026-00142 est en cours d'examen approfondi.
|
||||
Nous vous répondrons sous 2 jours maximum.
|
||||
"""
|
||||
Et l'appel est traité sous 5 jours ouvrés au total
|
||||
Et un modérateur senior + admin modération examinent le cas
|
||||
|
||||
Scénario: Appel CRITIQUE traité en 24h
|
||||
Étant donné que j'ai reçu une suspension longue ou un ban
|
||||
Et que je soumets un appel
|
||||
Quand l'appel est classé en priorité CRITIQUE
|
||||
Alors l'admin modération traite l'appel sous 24h
|
||||
Et je reçois une réponse rapide
|
||||
Et le cas est examiné en priorité absolue
|
||||
|
||||
Scénario: Réponse finale détaillée - Appel accepté
|
||||
Étant donné que mon appel est accepté
|
||||
Quand je reçois la réponse finale
|
||||
Alors l'email contient:
|
||||
| élément | contenu |
|
||||
| Décision | Annulation de la sanction |
|
||||
| Justification | Explication de pourquoi l'appel est accepté |
|
||||
| Actions | Strike retiré, suspension annulée, contenu rétabli |
|
||||
| Définitif | "Cette décision est définitive" |
|
||||
Et le strike est retiré de mon compte
|
||||
Et le contenu est rétabli sur la plateforme
|
||||
Et je peux continuer normalement
|
||||
|
||||
Scénario: Réponse finale détaillée - Appel rejeté
|
||||
Étant donné que mon appel est rejeté
|
||||
Quand je reçois la réponse finale
|
||||
Alors l'email contient:
|
||||
| élément | contenu |
|
||||
| Décision | Maintien de la sanction |
|
||||
| Justification | Explication de pourquoi l'appel est rejeté |
|
||||
| Actions | Sanction maintenue, strike conservé |
|
||||
| Définitif | "Cette décision est définitive" |
|
||||
Et la sanction reste active
|
||||
Et je ne peux pas faire de second appel
|
||||
Et je dois respecter la suspension
|
||||
|
||||
Scénario: Réponse finale - Réduction de sanction
|
||||
Étant donné que mon appel est partiellement accepté
|
||||
Quand je reçois la réponse finale
|
||||
Alors la décision est "Réduction de sanction"
|
||||
Et l'email explique:
|
||||
"""
|
||||
Après examen de votre appel, nous reconnaissons des circonstances atténuantes.
|
||||
La sanction est réduite:
|
||||
- Strike 2 → Strike 1
|
||||
- Suspension 7 jours → Suspension 3 jours
|
||||
|
||||
Cette décision est définitive.
|
||||
"""
|
||||
Et le strike est réduit
|
||||
Et la suspension est raccourcie
|
||||
Et je suis notifié de la nouvelle date de fin
|
||||
|
||||
Scénario: Suivi du statut de l'appel in-app
|
||||
Étant donné que j'ai soumis un appel
|
||||
Quand je consulte "Mes sanctions"
|
||||
Alors je vois le statut actuel de l'appel:
|
||||
| statut | badge | couleur |
|
||||
| En cours d'examen | En cours 🔍 | orange |
|
||||
| Appel accepté | Accepté ✓ | vert |
|
||||
| Appel rejeté | Rejeté ✗ | rouge |
|
||||
| Sanction réduite | Partiellement accepté| bleu |
|
||||
Et une notification badge m'alerte quand le statut change
|
||||
|
||||
# Transparence et traçabilité
|
||||
|
||||
Scénario: Historique complet des sanctions visible
|
||||
Étant donné que je suis un créateur
|
||||
Quand j'ouvre "Profil créateur > Mes sanctions"
|
||||
Alors je vois la liste complète de mes sanctions passées:
|
||||
| colonne | description |
|
||||
| Date | 15/01/2026 |
|
||||
| Contenu | "Mon podcast #42" |
|
||||
| Catégorie | 🚫 Haine & violence |
|
||||
| Sanction | Strike 2 - Suspension 7j |
|
||||
| Statut | Active / Terminée / Annulée |
|
||||
| Appel | Aucun / Accepté / Rejeté |
|
||||
Et les sanctions sont triées par date décroissante
|
||||
|
||||
Scénario: Conformité DSA - Transparence obligatoire
|
||||
Étant donné que le système de sanction est en place
|
||||
Quand un audit DSA est effectué
|
||||
Alors chaque sanction contient:
|
||||
| élément DSA | présent |
|
||||
| Référence précise à la règle violée | oui |
|
||||
| Explication claire et compréhensible | oui |
|
||||
| Preuve (extrait + transcription) | oui |
|
||||
| Possibilité de recours (appel) | oui |
|
||||
| Délai de recours clairement indiqué | oui |
|
||||
| Réponse motivée au recours | oui |
|
||||
Et le système est conforme au Digital Services Act
|
||||
|
||||
# Pas de second appel
|
||||
|
||||
Scénario: Décision définitive après premier appel
|
||||
Étant donné que mon premier appel a été rejeté
|
||||
Quand j'essaie de faire un second appel
|
||||
Alors le bouton "Faire appel" est désactivé
|
||||
Et un message s'affiche: "Cette décision est définitive. Aucun second appel n'est possible."
|
||||
Et je ne peux plus contester la sanction
|
||||
Et je dois respecter la décision finale
|
||||
|
||||
# Coût des notifications
|
||||
|
||||
Scénario: Coût des notifications multi-canal
|
||||
Étant donné que 100 sanctions sont appliquées en un mois
|
||||
Quand on calcule le coût des notifications
|
||||
Alors le coût total est d'environ 0.10€:
|
||||
| canal | coût unitaire | coût pour 100 |
|
||||
| Email | 0.001€ | 0.10€ |
|
||||
| Push | 0€ | 0€ |
|
||||
| In-app | 0€ | 0€ |
|
||||
Et le coût est négligeable même à grande échelle
|
||||
@@ -0,0 +1,82 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @scoring @mvp
|
||||
Fonctionnalité: Score de fiabilité et priorisation des signalements
|
||||
|
||||
En tant que système de modération
|
||||
Je veux prioriser les signalements selon la fiabilité du rapporteur
|
||||
Afin d'optimiser le traitement par les modérateurs
|
||||
|
||||
Scénario: Calcul du score de fiabilité
|
||||
Étant donné un utilisateur "alice@roadwave.fr" avec historique:
|
||||
| Signalements totaux | Validés | Rejetés | Taux de précision |
|
||||
| 50 | 48 | 2 | 96% |
|
||||
Alors son score de fiabilité est: 96/100
|
||||
Et un événement "RELIABILITY_SCORE_CALCULATED" est enregistré
|
||||
|
||||
Scénario: Priorisation haute pour utilisateurs fiables
|
||||
Étant donné un utilisateur avec score 95+
|
||||
Quand il fait un signalement
|
||||
Alors le signalement est marqué "Priorité haute"
|
||||
Et traité en < 2 heures
|
||||
Et un événement "HIGH_PRIORITY_REPORT_QUEUED" est enregistré
|
||||
|
||||
Scénario: Priorisation normale pour nouveaux utilisateurs
|
||||
Étant donné un nouvel utilisateur sans historique
|
||||
Quand il fait un signalement
|
||||
Alors le signalement est marqué "Priorité normale"
|
||||
Et traité en < 24 heures
|
||||
Et un événement "NORMAL_PRIORITY_REPORT_QUEUED" est enregistré
|
||||
|
||||
Scénario: Priorisation basse pour utilisateurs peu fiables
|
||||
Étant donné un utilisateur avec score < 60
|
||||
Quand il fait un signalement
|
||||
Alors le signalement est marqué "Priorité basse"
|
||||
Et traité en < 72 heures
|
||||
Et nécessite une vérification renforcée
|
||||
Et un événement "LOW_PRIORITY_REPORT_QUEUED" est enregistré
|
||||
|
||||
Scénario: Augmentation du score après signalements validés
|
||||
Étant donné un utilisateur avec score 70
|
||||
Quand 10 signalements consécutifs sont validés
|
||||
Alors le score passe à 85
|
||||
Et il monte de catégorie (basse → normale)
|
||||
Et un événement "RELIABILITY_SCORE_INCREASED" est enregistré
|
||||
|
||||
Scénario: Diminution du score après faux signalements
|
||||
Étant donné un utilisateur avec score 90
|
||||
Quand 5 signalements consécutifs sont rejetés
|
||||
Alors le score passe à 75
|
||||
Et il redescend de catégorie (haute → normale)
|
||||
Et un avertissement est envoyé
|
||||
Et un événement "RELIABILITY_SCORE_DECREASED" est enregistré
|
||||
|
||||
Scénario: Réinitialisation du score après inactivité
|
||||
Étant donné un utilisateur inactif pendant 6 mois
|
||||
Quand il refait un signalement
|
||||
Alors son score est réinitialisé à 50 (neutre)
|
||||
Et il doit reconstruire sa réputation
|
||||
Et un événement "RELIABILITY_SCORE_RESET" est enregistré
|
||||
|
||||
Scénario: Affichage du score dans le profil
|
||||
Étant donné un utilisateur "bob@roadwave.fr"
|
||||
Quand il consulte son profil
|
||||
Alors il voit:
|
||||
| Métrique | Valeur |
|
||||
| Score de fiabilité | 87/100 |
|
||||
| Signalements validés | 145 |
|
||||
| Taux de précision | 87% |
|
||||
| Catégorie | Haute |
|
||||
Et un graphique d'évolution du score
|
||||
Et un événement "RELIABILITY_SCORE_VIEWED" est enregistré
|
||||
|
||||
Scénario: Métriques de performance de la priorisation
|
||||
Étant donné que 10 000 signalements ont été traités
|
||||
Alors les indicateurs suivants sont disponibles:
|
||||
| Métrique | Valeur |
|
||||
| Temps moyen de traitement (haute) | 1.5h |
|
||||
| Temps moyen de traitement (normale) | 18h |
|
||||
| Temps moyen de traitement (basse) | 48h |
|
||||
| Taux de validation (haute) | 92% |
|
||||
| Taux de validation (basse) | 65% |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
@@ -0,0 +1,53 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @copyright @mvp
|
||||
Fonctionnalité: Signalement musique a posteriori
|
||||
|
||||
En tant qu'ayant-droit ou utilisateur
|
||||
Je veux signaler une utilisation musicale non conforme
|
||||
Afin de faire respecter les droits d'auteur
|
||||
|
||||
Scénario: Signalement par un ayant-droit
|
||||
Étant donné un ayant-droit "Universal Music"
|
||||
Quand il signale un contenu avec sa musique
|
||||
Alors un formulaire DMCA est pré-rempli
|
||||
Et le contenu est immédiatement suspendu (safe harbor)
|
||||
Et le créateur est notifié
|
||||
Et un événement "COPYRIGHT_CLAIM_FILED" est enregistré
|
||||
|
||||
Scénario: Vérification du signalement par modérateur
|
||||
Étant donné un signalement reçu
|
||||
Quand un modérateur l'examine
|
||||
Alors il écoute le contenu
|
||||
Et vérifie si fair use (< 30s)
|
||||
Et prend une décision dans les 48h
|
||||
Et un événement "COPYRIGHT_CLAIM_REVIEWED" est enregistré
|
||||
|
||||
Scénario: Contre-signalement du créateur
|
||||
Étant donné un créateur "alice@roadwave.fr" dont le contenu est suspendu
|
||||
Quand il fait un counter-claim avec preuve
|
||||
Alors le dossier est transmis à l'ayant-droit
|
||||
Et celui-ci a 14 jours pour répondre
|
||||
Et un événement "COPYRIGHT_COUNTER_CLAIM_FILED" est enregistré
|
||||
|
||||
Scénario: Rétablissement du contenu si fair use validé
|
||||
Étant donné un contenu suspendu
|
||||
Quand le modérateur confirme le fair use
|
||||
Alors le contenu est rétabli
|
||||
Et le signalement est rejeté
|
||||
Et le créateur est notifié
|
||||
Et un événement "COPYRIGHT_CLAIM_REJECTED" est enregistré
|
||||
|
||||
Scénario: Sanctions pour abus de signalement
|
||||
Étant donné un ayant-droit qui abuse des signalements
|
||||
Quand 3 signalements consécutifs sont rejetés
|
||||
Alors son compte est suspendu temporairement
|
||||
Et un événement "COPYRIGHT_CLAIMANT_SUSPENDED" est enregistré
|
||||
|
||||
Scénario: Historique des signalements pour un créateur
|
||||
Étant donné un créateur "bob@roadwave.fr"
|
||||
Alors il voit ses signalements:
|
||||
| Date | Ayant-droit | Statut | Issue |
|
||||
| 2026-02-01 | Sony Music | Résolu | Fair use OK|
|
||||
| 2026-01-10 | Warner | Confirmé | Contenu retiré|
|
||||
Et un événement "COPYRIGHT_HISTORY_VIEWED" est enregistré
|
||||
225
docs/domains/moderation/features/api/signalement.feature
Normal file
225
docs/domains/moderation/features/api/signalement.feature
Normal file
@@ -0,0 +1,225 @@
|
||||
# language: fr
|
||||
|
||||
@moderation @reporting
|
||||
Fonctionnalité: Signalement de contenu inapproprié
|
||||
|
||||
# 14.1 - Signalement utilisateur
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis un utilisateur connecté
|
||||
Et que je suis en train d'écouter un contenu
|
||||
|
||||
# 14.1.1 - Catégories de signalement
|
||||
|
||||
Scénario: Affichage du formulaire de signalement
|
||||
Étant donné que j'écoute un contenu inapproprié
|
||||
Quand j'ouvre le menu du contenu
|
||||
Et que je clique sur "Signaler"
|
||||
Alors un formulaire de signalement s'affiche
|
||||
Et le formulaire contient une liste déroulante "Catégorie du problème"
|
||||
Et le formulaire contient un champ texte "Commentaire (optionnel)"
|
||||
Et le formulaire contient un bouton "Envoyer le signalement"
|
||||
|
||||
Scénario: Liste des 7 catégories prédéfinies
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Quand je clique sur la liste déroulante "Catégorie du problème"
|
||||
Alors je vois les 7 catégories suivantes:
|
||||
| icône | catégorie | description |
|
||||
| 🚫 | Haine & violence | Incitation à la haine, discrimination, menaces |
|
||||
| 🔞 | Contenu sexuel | Pornographie, contenu explicite |
|
||||
| ⚖️ | Illégalité | Terrorisme, apologie de crimes |
|
||||
| 🎵 | Droits d'auteur | Musique/contenu protégé non autorisé (voir Section 18) |
|
||||
| 📧 | Spam | Publicité non sollicitée, répétition |
|
||||
| ❌ | Fausse information | Désinformation sur santé, sécurité routière |
|
||||
| 🔧 | Autre | Champ texte obligatoire si sélectionné |
|
||||
Et chaque catégorie a une description claire
|
||||
Et la catégorie "Droits d'auteur" renvoie vers les règles détaillées de détection automatique
|
||||
|
||||
Scénario: Sélection de la catégorie "Haine & violence"
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Quand je sélectionne la catégorie "🚫 Haine & violence"
|
||||
Alors la catégorie est sélectionnée
|
||||
Et la description "Incitation à la haine, discrimination, menaces" s'affiche
|
||||
Et je peux passer au champ commentaire
|
||||
|
||||
Scénario: Catégorie "Autre" nécessite un commentaire obligatoire
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Quand je sélectionne la catégorie "🔧 Autre"
|
||||
Alors le champ "Commentaire" devient obligatoire
|
||||
Et un message s'affiche: "Veuillez décrire le problème (obligatoire)"
|
||||
Et le placeholder change en "Décrivez le problème rencontré"
|
||||
Et je ne peux pas envoyer le signalement sans commentaire
|
||||
|
||||
# 14.1.2 - Commentaire du signaleur
|
||||
|
||||
Scénario: Champ commentaire optionnel avec incitation
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Et que j'ai sélectionné une catégorie autre que "Autre"
|
||||
Quand je consulte le champ "Commentaire"
|
||||
Alors le champ est optionnel (pas d'astérisque rouge)
|
||||
Et le placeholder indique "Décrivez le problème (optionnel mais recommandé)"
|
||||
Et la limite de caractères est de 500
|
||||
Et un compteur affiche "0/500"
|
||||
|
||||
Scénario: Envoi de signalement sans commentaire
|
||||
Étant donné que j'ai sélectionné la catégorie "📧 Spam"
|
||||
Et que je n'ai pas rempli le champ commentaire
|
||||
Quand je clique sur "Envoyer le signalement"
|
||||
Alors le signalement est envoyé avec succès
|
||||
Et aucune erreur de validation ne s'affiche
|
||||
Et le commentaire est enregistré comme vide
|
||||
|
||||
Scénario: Envoi de signalement avec commentaire
|
||||
Étant donné que j'ai sélectionné la catégorie "🚫 Haine & violence"
|
||||
Et que j'ai saisi le commentaire "Le créateur tient des propos discriminatoires à 2:30"
|
||||
Quand je clique sur "Envoyer le signalement"
|
||||
Alors le signalement est envoyé avec succès
|
||||
Et le commentaire est enregistré avec le signalement
|
||||
Et il sera visible par les modérateurs
|
||||
|
||||
Scénario: Limite de 500 caractères pour le commentaire
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Quand je saisis un commentaire de 501 caractères
|
||||
Alors le champ limite automatiquement à 500 caractères
|
||||
Et le compteur affiche "500/500"
|
||||
Et les caractères supplémentaires ne sont pas acceptés
|
||||
|
||||
# 14.1.3 - Confirmation après signalement
|
||||
|
||||
Scénario: Toast de confirmation après signalement
|
||||
Étant donné que j'ai envoyé un signalement
|
||||
Quand le signalement est enregistré
|
||||
Alors un toast notification s'affiche
|
||||
Et le toast contient le message "✓ Signalement envoyé. Nous l'examinerons sous 24-48h."
|
||||
Et le toast s'affiche pendant 5 secondes
|
||||
Et le toast contient un bouton "Voir mes signalements"
|
||||
Et je peux fermer le toast manuellement avec un bouton X
|
||||
|
||||
Scénario: Accès à l'historique des signalements via le toast
|
||||
Étant donné que le toast de confirmation est affiché
|
||||
Quand je clique sur "Voir mes signalements"
|
||||
Alors je suis redirigé vers la page "Mes signalements"
|
||||
Et je vois la liste de tous mes signalements
|
||||
Et le signalement que je viens d'envoyer apparaît en premier
|
||||
|
||||
Scénario: Historique personnel des signalements
|
||||
Étant donné que j'ai envoyé 3 signalements précédemment
|
||||
Quand j'ouvre "Profil > Mes signalements"
|
||||
Alors je vois la liste de mes 3 signalements
|
||||
Et chaque signalement affiche:
|
||||
| information | description |
|
||||
| Titre du contenu | "Podcast #42" |
|
||||
| Créateur | @pseudo_createur |
|
||||
| Catégorie | 🚫 Haine & violence |
|
||||
| Date | 15/01/2026 |
|
||||
| Statut | En cours / Traité / Rejeté |
|
||||
| Mon commentaire | Texte que j'ai saisi |
|
||||
Et les signalements sont triés par date décroissante
|
||||
|
||||
Plan du Scénario: Statuts possibles d'un signalement
|
||||
Étant donné que j'ai envoyé un signalement
|
||||
Quand le statut du signalement est "<statut>"
|
||||
Alors le badge affiché est "<badge>"
|
||||
Et la couleur du badge est "<couleur>"
|
||||
|
||||
Exemples:
|
||||
| statut | badge | couleur |
|
||||
| En cours | En cours | orange |
|
||||
| Traité | Traité ✓ | vert |
|
||||
| Rejeté | Rejeté ✗ | rouge |
|
||||
|
||||
Scénario: Notification in-app si action prise
|
||||
Étant donné que j'ai signalé un contenu il y a 24h
|
||||
Quand le modérateur traite mon signalement
|
||||
Et que le contenu est effectivement retiré
|
||||
Alors je reçois une notification in-app
|
||||
Et la notification indique "Votre signalement a été traité. Le contenu a été retiré."
|
||||
Et le statut de mon signalement passe à "Traité ✓"
|
||||
Et je peux voir les détails de l'action prise
|
||||
|
||||
Scénario: Notification si signalement rejeté
|
||||
Étant donné que j'ai signalé un contenu
|
||||
Quand le modérateur rejette mon signalement
|
||||
Alors je reçois une notification in-app
|
||||
Et la notification indique "Votre signalement a été examiné. Le contenu ne viole pas les règles de la communauté."
|
||||
Et le statut de mon signalement passe à "Rejeté ✗"
|
||||
Et je peux voir la raison du rejet
|
||||
|
||||
# Signalements multiples du même contenu
|
||||
|
||||
Scénario: Un contenu peut être signalé plusieurs fois
|
||||
Étant donné qu'un contenu a déjà été signalé par 5 autres utilisateurs
|
||||
Quand je signale le même contenu
|
||||
Alors mon signalement est enregistré indépendamment
|
||||
Et le compteur de signalements du contenu passe à 6
|
||||
Et mon signalement rejoint la file d'attente de modération
|
||||
Et les signalements cumulés augmentent la priorité de traitement
|
||||
|
||||
Scénario: Limite de signalements par utilisateur
|
||||
Étant donné que j'ai déjà signalé le même contenu il y a 2 jours
|
||||
Quand j'essaie de signaler à nouveau le même contenu
|
||||
Alors un message m'informe "Vous avez déjà signalé ce contenu"
|
||||
Et le formulaire de signalement n'est pas affiché
|
||||
Et je peux consulter le statut de mon signalement précédent
|
||||
|
||||
# Signalements abusifs
|
||||
|
||||
Scénario: Détection de signalements abusifs répétés
|
||||
Étant donné que j'ai envoyé 10 signalements ce mois-ci
|
||||
Et que 8 d'entre eux ont été rejetés comme infondés
|
||||
Quand j'essaie d'envoyer un nouveau signalement
|
||||
Alors mon compte est marqué comme "signaleur suspect"
|
||||
Et un avertissement s'affiche:
|
||||
"""
|
||||
Attention: vos signalements récents ont été majoritairement rejetés.
|
||||
Les signalements abusifs peuvent entraîner des sanctions.
|
||||
"""
|
||||
Et je peux toujours envoyer le signalement
|
||||
Mais mes futurs signalements auront une priorité réduite
|
||||
|
||||
Scénario: Sanction pour signalements abusifs graves
|
||||
Étant donné que j'ai envoyé 20 signalements abusifs en 1 mois
|
||||
Et que tous ont été rejetés comme volontairement faux
|
||||
Quand le modérateur détecte le pattern abusif
|
||||
Alors mon compte reçoit un avertissement formel
|
||||
Et je perds la possibilité de signaler pendant 30 jours
|
||||
Et je reçois un email m'expliquant la sanction
|
||||
|
||||
# Signalement depuis différents points de l'app
|
||||
|
||||
Scénario: Signalement depuis le player audio
|
||||
Étant donné que j'écoute un contenu
|
||||
Quand j'ouvre le menu "⋮" du player
|
||||
Alors je vois l'option "Signaler"
|
||||
Et je peux ouvrir le formulaire de signalement
|
||||
|
||||
Scénario: Signalement depuis la page de détails du contenu
|
||||
Étant donné que je consulte la page de détails d'un contenu
|
||||
Quand je clique sur le bouton "⋮" en haut à droite
|
||||
Alors je vois l'option "Signaler"
|
||||
Et je peux ouvrir le formulaire de signalement
|
||||
|
||||
Scénario: Signalement depuis l'historique d'écoute
|
||||
Étant donné que je consulte mon historique d'écoute
|
||||
Quand je clique sur "⋮" à côté d'un contenu passé
|
||||
Alors je vois l'option "Signaler"
|
||||
Et je peux signaler ce contenu même si je ne l'écoute plus actuellement
|
||||
|
||||
# Anonymat du signaleur
|
||||
|
||||
Scénario: Identité du signaleur anonyme pour le créateur
|
||||
Étant donné que j'ai signalé un contenu
|
||||
Quand le créateur est notifié de la modération
|
||||
Alors mon identité reste anonyme
|
||||
Et le créateur ne peut pas savoir qui a signalé
|
||||
Et seuls les modérateurs ont accès à l'identité du signaleur
|
||||
|
||||
# Coût de la solution
|
||||
|
||||
Scénario: Coût du système de signalement
|
||||
Étant donné que le système de signalement est en place
|
||||
Quand on calcule le coût
|
||||
Alors le coût est de 0€
|
||||
Et le formulaire est développé en interne
|
||||
Et aucun service tiers n'est utilisé
|
||||
Et les notifications in-app sont gratuites
|
||||
@@ -0,0 +1,270 @@
|
||||
# language: fr
|
||||
|
||||
@moderation @processing
|
||||
Fonctionnalité: Traitement des signalements par l'IA et les modérateurs
|
||||
|
||||
# 14.2 - Traitement des signalements
|
||||
|
||||
Contexte:
|
||||
Étant donné que le système de modération est actif
|
||||
|
||||
# 14.2.1 - IA pré-filtre (Whisper + NLP)
|
||||
|
||||
Scénario: Signalement ajouté à la file d'attente asynchrone
|
||||
Étant donné qu'un utilisateur envoie un signalement pour un contenu audio
|
||||
Quand le signalement est reçu
|
||||
Alors le signalement est ajouté à la file d'attente asynchrone
|
||||
Et un worker de traitement est déclenché
|
||||
Et le traitement se fait en arrière-plan sans bloquer l'utilisateur
|
||||
|
||||
Scénario: Transcription automatique avec Whisper large-v3
|
||||
Étant donné qu'un contenu audio signalé dure 5 minutes
|
||||
Quand le worker de traitement démarre
|
||||
Alors le système utilise Whisper large-v3 pour transcrire l'audio
|
||||
Et la transcription est en self-hosted (pas de service cloud)
|
||||
Et le texte transcrit est enregistré en base de données
|
||||
Et le délai de transcription est de 1-3 minutes
|
||||
|
||||
Plan du Scénario: Délai de transcription selon durée audio
|
||||
Étant donné qu'un contenu audio signalé dure <duree> minutes
|
||||
Quand le système transcrit l'audio
|
||||
Alors la transcription prend environ <delai>
|
||||
|
||||
Exemples:
|
||||
| duree | delai |
|
||||
| 2 | 1-3 minutes |
|
||||
| 10 | 3-10 minutes |
|
||||
| 45 | 10-20 minutes |
|
||||
|
||||
Scénario: Analyse automatique du contenu transcrit
|
||||
Étant donné que la transcription audio est terminée
|
||||
Quand le système analyse le texte transcrit
|
||||
Alors les analyses suivantes sont effectuées:
|
||||
| analyse | technologie |
|
||||
| Analyse de sentiment | distilbert-base-uncased |
|
||||
| Détection de haine | facebook/roberta-hate-speech |
|
||||
| Mots-clés interdits | Liste noire FR/EN + regex |
|
||||
Et chaque analyse génère un score de confiance (0-100%)
|
||||
|
||||
Scénario: Génération du score de confiance IA
|
||||
Étant donné que toutes les analyses sont terminées
|
||||
Quand le système calcule le score final
|
||||
Alors un score de confiance IA entre 0-100% est généré
|
||||
Et le score indique la probabilité que le contenu viole les règles
|
||||
Et la catégorie la plus probable est identifiée
|
||||
Et les timestamps des passages problématiques sont extraits
|
||||
|
||||
Scénario: Détection automatique de contenu clairement inapproprié
|
||||
Étant donné qu'un contenu contient des insultes graves et répétées
|
||||
Quand l'IA analyse la transcription
|
||||
Alors le score de confiance IA est >95%
|
||||
Et la catégorie détectée est "Haine & violence"
|
||||
Et les passages problématiques sont identifiés avec timestamps précis:
|
||||
| timestamp | durée | texte problématique | score confiance |
|
||||
| 02:15 | 12s | [insulte discriminatoire] | 97% |
|
||||
| 03:42 | 18s | [propos haineux] | 95% |
|
||||
Et chaque passage problématique a un timestamp de début et de fin
|
||||
Et le signalement est classé en priorité CRITIQUE
|
||||
Et les timestamps sont utilisés pour générer les marqueurs audio dans le dashboard modérateur
|
||||
|
||||
# 14.2.2 - Délais de traitement (SLA)
|
||||
|
||||
Plan du Scénario: SLA selon priorité du signalement
|
||||
Étant donné qu'un signalement a une priorité "<priorite>"
|
||||
Quand le signalement entre en file d'attente
|
||||
Alors le délai de traitement cible est "<delai>"
|
||||
Et le responsable du traitement est "<responsable>"
|
||||
|
||||
Exemples:
|
||||
| priorite | delai | responsable |
|
||||
| CRITIQUE | <2h (24/7) | Modérateur senior (astreinte) |
|
||||
| HAUTE | <24h (jours ouvrés) | Modérateur junior/senior |
|
||||
| MOYENNE | <24h (jours ouvrés) | Modérateur junior |
|
||||
| BASSE | <72h (jours ouvrés) | Modérateur junior |
|
||||
|
||||
Scénario: Traitement automatique pour score IA >95%
|
||||
Étant donné qu'un signalement a un score IA de 97%
|
||||
Et que la catégorie détectée est "Spam" (évidente)
|
||||
Quand le système évalue le signalement
|
||||
Alors une action automatique immédiate est déclenchée
|
||||
Et le contenu est retiré automatiquement
|
||||
Et le créateur est notifié de la modération
|
||||
Et le créateur peut faire appel de la décision
|
||||
Et un modérateur senior vérifie l'action a posteriori
|
||||
|
||||
Scénario: Signalement CRITIQUE traité en moins de 2h
|
||||
Étant donné qu'un signalement de priorité CRITIQUE est reçu à 14:00
|
||||
Et que le contenu concerne une menace de violence
|
||||
Quand le signalement est assigné à un modérateur senior d'astreinte
|
||||
Alors le modérateur est alerté immédiatement (push + SMS)
|
||||
Et le signalement est traité avant 16:00 (2h)
|
||||
Et une décision est prise et appliquée
|
||||
Et les autorités peuvent être contactées si nécessaire
|
||||
|
||||
Scénario: Astreinte modérateur 24/7 pour signalements CRITIQUES
|
||||
Étant donné qu'un signalement CRITIQUE est reçu un dimanche à 03:00
|
||||
Quand le signalement est classé en priorité CRITIQUE
|
||||
Alors le modérateur senior d'astreinte est alerté
|
||||
Et le signalement est traité dans les 2h (avant 05:00)
|
||||
Et le service d'astreinte garantit une disponibilité 24/7
|
||||
|
||||
Scénario: Signalement HAUTE priorité traité en moins de 24h
|
||||
Étant donné qu'un signalement de priorité HAUTE est reçu lundi à 10:00
|
||||
Et que le contenu concerne du harcèlement
|
||||
Quand le signalement entre en file d'attente
|
||||
Alors le signalement est assigné à un modérateur (junior ou senior)
|
||||
Et le signalement est traité avant mardi 10:00 (24h jours ouvrés)
|
||||
Et une décision est prise et appliquée
|
||||
|
||||
Scénario: Signalement BASSE priorité traité en moins de 72h
|
||||
Étant donné qu'un signalement de priorité BASSE est reçu lundi à 10:00
|
||||
Et que le contenu concerne des tags incorrects
|
||||
Quand le signalement entre en file d'attente
|
||||
Alors le signalement est traité avant jeudi 10:00 (72h jours ouvrés)
|
||||
Et un modérateur junior peut traiter ce type de signalement
|
||||
|
||||
# 14.2.3 - Priorisation automatique
|
||||
|
||||
Scénario: Calcul du score de priorité
|
||||
Étant donné qu'un signalement a les caractéristiques suivantes:
|
||||
| caractéristique | valeur |
|
||||
| Score IA | 85% |
|
||||
| Signalements cumulés | 3 |
|
||||
| Fiabilité du signaleur | 75% |
|
||||
Quand le système calcule la priorité
|
||||
Alors la formule appliquée est:
|
||||
"""
|
||||
Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_signaleur × 0.1)
|
||||
"""
|
||||
Et le score de priorité est: (85 × 0.7) + (3 × 0.2) + (75 × 0.1) = 67.5
|
||||
Et le signalement est classé en priorité MOYENNE
|
||||
|
||||
Plan du Scénario: Classification selon score de priorité
|
||||
Étant donné qu'un signalement a un score de priorité de <score>
|
||||
Quand le système classe le signalement
|
||||
Alors la priorité assignée est "<priorite>"
|
||||
Et le signalement entre dans la file "<file>"
|
||||
|
||||
Exemples:
|
||||
| score | priorite | file |
|
||||
| 95 | CRITIQUE | Immédiate |
|
||||
| 82 | HAUTE | Prioritaire |
|
||||
| 55 | MOYENNE | Normale |
|
||||
| 25 | BASSE | Différée |
|
||||
|
||||
Scénario: Boost de priorité avec signalements cumulés
|
||||
Étant donné qu'un contenu a été signalé par 1 utilisateur avec un score IA de 60%
|
||||
Et que le signalement est classé en priorité MOYENNE (score 42)
|
||||
Quand 5 autres utilisateurs signalent le même contenu
|
||||
Alors le nombre de signalements cumulés passe à 6
|
||||
Et le score de priorité augmente significativement
|
||||
Et le signalement peut passer en priorité HAUTE
|
||||
Et le traitement est accéléré
|
||||
|
||||
Scénario: Impact de la fiabilité du signaleur
|
||||
Étant donné qu'un utilisateur de confiance (90% fiabilité) envoie un signalement
|
||||
Et qu'un utilisateur suspect (20% fiabilité) envoie un signalement similaire
|
||||
Quand le système calcule les priorités
|
||||
Alors le signalement de l'utilisateur de confiance a un score plus élevé
|
||||
Et son signalement est traité en priorité
|
||||
Et le signalement de l'utilisateur suspect est traité plus tard
|
||||
|
||||
Scénario: Évolution du score de fiabilité du signaleur
|
||||
Étant donné qu'un utilisateur a envoyé 10 signalements
|
||||
Et que 8 d'entre eux ont été acceptés par les modérateurs
|
||||
Quand le système calcule son score de fiabilité
|
||||
Alors le score est de 80% (8 acceptés / 10 total)
|
||||
Et ses futurs signalements auront plus de poids
|
||||
Et il peut devenir "utilisateur de confiance"
|
||||
|
||||
# File d'attente intelligente
|
||||
|
||||
Scénario: Files d'attente séparées par priorité
|
||||
Étant donné que 50 signalements sont en attente
|
||||
Quand le système organise la file d'attente
|
||||
Alors les signalements sont répartis dans les files suivantes:
|
||||
| file | nombre | priorité |
|
||||
| Immédiate (24/7) | 5 | CRITIQUE |
|
||||
| Prioritaire | 15 | HAUTE |
|
||||
| Normale | 20 | MOYENNE |
|
||||
| Différée | 10 | BASSE |
|
||||
Et les modérateurs traitent en priorité la file Immédiate
|
||||
|
||||
Scénario: Modérateurs assignés selon compétences
|
||||
Étant donné qu'un signalement complexe de harcèlement est reçu
|
||||
Quand le système assigne un modérateur
|
||||
Alors un modérateur senior est prioritairement assigné
|
||||
Et les modérateurs juniors peuvent traiter les cas simples (spam, tags)
|
||||
Et les modérateurs seniors traitent les cas complexes (haine, violence, appels)
|
||||
|
||||
# Technologies opensource
|
||||
|
||||
Scénario: Stack technique 100% opensource
|
||||
Étant donné que le système de modération IA est déployé
|
||||
Quand on analyse les technologies utilisées
|
||||
Alors toutes les technologies sont opensource:
|
||||
| composant | technologie | hébergement |
|
||||
| Transcription | Whisper large-v3 | Self-hosted |
|
||||
| Analyse sentiment | distilbert-base-uncased | Self-hosted |
|
||||
| Détection haine | facebook/roberta-hate-speech | Self-hosted |
|
||||
| Mots-clés interdits | Liste noire FR/EN + regex | PostgreSQL |
|
||||
Et aucune dépendance à Google, AWS, Azure
|
||||
|
||||
# Coût infrastructure
|
||||
|
||||
Plan du Scénario: Coût selon phase du projet
|
||||
Étant donné que RoadWave est en phase "<phase>"
|
||||
Quand on calcule le coût de l'infrastructure IA
|
||||
Alors le coût mensuel est "<cout>"
|
||||
|
||||
Exemples:
|
||||
| phase | cout |
|
||||
| MVP | 0-50€ (CPU) |
|
||||
| Scale | 50-200€ (GPU VPS) |
|
||||
|
||||
Scénario: Processing asynchrone en MVP avec CPU
|
||||
Étant donné que RoadWave est en phase MVP
|
||||
Et que le volume est <1000 signalements/mois
|
||||
Quand le système traite les signalements
|
||||
Alors un serveur CPU standard est suffisant
|
||||
Et le coût est de 0€ (serveur existant)
|
||||
Et le processing asynchrone absorbe les pics de charge
|
||||
Et les délais restent acceptables (1-20 minutes)
|
||||
|
||||
Scénario: Scaling avec GPU pour gros volumes
|
||||
Étant donné que RoadWave reçoit >1000 signalements/jour
|
||||
Quand le système nécessite un scaling
|
||||
Alors un VPS avec GPU est requis
|
||||
Et le coût passe à 50-200€/mois
|
||||
Et les délais de transcription sont divisés par 5-10
|
||||
Et le système peut gérer 10 000+ signalements/mois
|
||||
|
||||
# Logs et audit
|
||||
|
||||
Scénario: Logs d'audit pour chaque traitement
|
||||
Étant donné qu'un signalement est traité
|
||||
Quand une action est prise (rejet, acceptation, sanction)
|
||||
Alors un log d'audit complet est créé:
|
||||
| champ | description |
|
||||
| signalement_id | ID unique du signalement |
|
||||
| content_id | ID du contenu signalé |
|
||||
| ia_score | Score de confiance IA |
|
||||
| ia_category | Catégorie détectée par IA |
|
||||
| priority | CRITIQUE / HAUTE / MOYENNE / BASSE |
|
||||
| moderator_id | ID du modérateur assigné |
|
||||
| action_taken | Retiré / Rejeté / Strike |
|
||||
| processing_time | Durée du traitement |
|
||||
| timestamp | Date et heure de la décision |
|
||||
Et le log est conservé pour conformité DSA
|
||||
Et les logs sont anonymisés après 3 ans (RGPD)
|
||||
|
||||
# Conformité DSA
|
||||
|
||||
Scénario: Traçabilité complète pour conformité DSA
|
||||
Étant donné que le système de modération est actif
|
||||
Quand un audit DSA est effectué
|
||||
Alors toutes les actions de modération sont tracées
|
||||
Et les délais de traitement sont mesurés et respectés
|
||||
Et les décisions sont justifiées et documentées
|
||||
Et la transparence vis-à-vis des utilisateurs est garantie
|
||||
Et le système est conforme au Digital Services Act
|
||||
@@ -0,0 +1,63 @@
|
||||
# language: fr
|
||||
|
||||
@api @moderation @trust @mvp
|
||||
Fonctionnalité: Statut utilisateur de confiance
|
||||
|
||||
En tant qu'utilisateur méritant
|
||||
Je veux obtenir le statut "Utilisateur de confiance"
|
||||
Afin de bénéficier de privilèges et reconnaissance
|
||||
|
||||
Scénario: Critères d'obtention du statut
|
||||
Étant donné un utilisateur "alice@roadwave.fr" qui remplit:
|
||||
| Critère | Requis | Actuel |
|
||||
| Compte actif depuis | 6 mois | 8 mois |
|
||||
| Signalements validés | 100 | 150 |
|
||||
| Taux de précision | 90% | 94% |
|
||||
| Badge modération | Or | Or |
|
||||
| Aucune sanction | Oui | Oui |
|
||||
Quand les critères sont remplis
|
||||
Alors le statut "Utilisateur de confiance" est accordé
|
||||
Et un événement "TRUSTED_USER_STATUS_GRANTED" est enregistré
|
||||
|
||||
Scénario: Privilèges de l'utilisateur de confiance
|
||||
Étant donné un utilisateur de confiance
|
||||
Alors il bénéficie de:
|
||||
| Privilège | Détail |
|
||||
| Signalements traités en priorité | < 1h au lieu de 24h |
|
||||
| Modération de commentaires | Peut masquer spam/haine |
|
||||
| Badge profil "Trusted" | Visible publiquement |
|
||||
| Réduction Premium -20% | Sur abonnement annuel |
|
||||
| Accès beta features | Nouvelles fonctionnalités |
|
||||
Et un événement "TRUSTED_USER_PRIVILEGES_DISPLAYED" est enregistré
|
||||
|
||||
Scénario: Badge "Trusted" visible sur le profil
|
||||
Étant donné un utilisateur de confiance
|
||||
Quand son profil est consulté
|
||||
Alors un badge bleu "✓ Utilisateur de confiance" s'affiche
|
||||
Et une tooltip explique le statut
|
||||
Et un événement "TRUSTED_BADGE_DISPLAYED" est enregistré
|
||||
|
||||
Scénario: Révocation du statut pour inactivité
|
||||
Étant donné un utilisateur de confiance inactif 6 mois
|
||||
Quand le système vérifie les statuts
|
||||
Alors le statut est révoqué automatiquement
|
||||
Et l'utilisateur est notifié
|
||||
Et peut le retrouver en redevenant actif
|
||||
Et un événement "TRUSTED_STATUS_REVOKED_INACTIVITY" est enregistré
|
||||
|
||||
Scénario: Révocation du statut pour baisse de précision
|
||||
Étant donné un utilisateur de confiance
|
||||
Quand son taux de précision passe < 85%
|
||||
Alors le statut est révoqué temporairement
|
||||
Et il doit retrouver 90% pour le récupérer
|
||||
Et un événement "TRUSTED_STATUS_REVOKED_LOW_ACCURACY" est enregistré
|
||||
|
||||
Scénario: Statistiques des utilisateurs de confiance
|
||||
Étant donné que 500 utilisateurs ont le statut
|
||||
Alors les indicateurs suivants sont disponibles:
|
||||
| Métrique | Valeur |
|
||||
| Nombre d'utilisateurs de confiance| 500 |
|
||||
| % de la base utilisateurs | 0.5% |
|
||||
| Temps moyen pour obtenir statut | 8 mois |
|
||||
| Taux de rétention du statut | 92% |
|
||||
Et les métriques sont exportées vers le monitoring
|
||||
391
docs/domains/moderation/features/ui/badges-statistiques.feature
Normal file
391
docs/domains/moderation/features/ui/badges-statistiques.feature
Normal file
@@ -0,0 +1,391 @@
|
||||
# language: fr
|
||||
|
||||
@ui @moderation @badges @gamification
|
||||
Fonctionnalité: Badges et statistiques de modération communautaire (Mobile)
|
||||
En tant qu'utilisateur contributeur
|
||||
Je veux voir mes badges et statistiques de modération
|
||||
Afin d'être motivé à continuer à signaler du contenu pertinent
|
||||
|
||||
# 19.1.4 - Affichage badges et statistiques
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis connecté à l'application mobile
|
||||
Et que j'ai envoyé des signalements
|
||||
|
||||
# Affichage des statistiques personnelles
|
||||
|
||||
Scénario: Accéder aux statistiques de modération
|
||||
Étant donné que je suis dans mon profil
|
||||
Quand je clique sur "Mes signalements"
|
||||
Alors je vois en haut de page une carte "📊 Vos statistiques de modération"
|
||||
Et la carte affiche:
|
||||
| élément | valeur | couleur |
|
||||
| Signalements envoyés | 27 | Bleu |
|
||||
| Validés | 23 ✅ | Vert |
|
||||
| Rejetés | 4 ❌ | Rouge |
|
||||
| Taux de pertinence | 85% | Vert/Orange |
|
||||
| Badge actuel | 🥈 Contributeur Argent | Argent |
|
||||
| Prochain palier | 🥇 Contributeur Or | Or |
|
||||
| Progression vers prochain | 27 signalements restants| Bleu |
|
||||
Et les données sont mises à jour en temps réel
|
||||
|
||||
Scénario: Design de la carte statistiques
|
||||
Étant donné que j'affiche mes statistiques
|
||||
Quand je vérifie le design
|
||||
Alors la carte a un fond dégradé subtil (blanc → gris clair)
|
||||
Et les icônes sont colorées et expressives
|
||||
Et les nombres sont en gras et mis en évidence
|
||||
Et le taux de pertinence a une jauge visuelle (progress bar)
|
||||
Et l'ensemble est visuellement attrayant et motivant
|
||||
|
||||
Plan du Scénario: Couleur du taux de pertinence selon performance
|
||||
Étant donné que mon taux de pertinence est de <taux>%
|
||||
Quand j'affiche mes statistiques
|
||||
Alors la jauge de pertinence est de couleur "<couleur>"
|
||||
Et le message associé est "<message>"
|
||||
|
||||
Exemples:
|
||||
| taux | couleur | message |
|
||||
| 95 | Vert | Excellent ! |
|
||||
| 82 | Vert clair | Très bon |
|
||||
| 72 | Orange | Bon, continuez vos efforts |
|
||||
| 55 | Rouge | Améliorez la qualité de vos signalements |
|
||||
|
||||
# Affichage du badge actuel
|
||||
|
||||
Scénario: Badge Bronze visible
|
||||
Étant donné que j'ai le badge 🥉 Contributeur Bronze
|
||||
Quand j'affiche mon profil public
|
||||
Alors le badge 🥉 s'affiche à côté de mon pseudo
|
||||
Et un tooltip s'affiche au survol/appui long:
|
||||
"""
|
||||
🥉 Contributeur Bronze
|
||||
Signale du contenu inapproprié pour améliorer la communauté
|
||||
"""
|
||||
Et le badge est discret mais visible
|
||||
|
||||
Scénario: Badge Argent visible avec priorité
|
||||
Étant donné que j'ai le badge 🥈 Contributeur Argent
|
||||
Quand j'affiche mon profil
|
||||
Alors le badge 🥈 s'affiche de manière plus proéminente
|
||||
Et le badge est affiché avec une animation subtile (brille légèrement)
|
||||
Et le tooltip indique:
|
||||
"""
|
||||
🥈 Contributeur Argent
|
||||
Utilisateur de confiance - Signalements traités en priorité
|
||||
"""
|
||||
Et le badge inspire confiance aux autres utilisateurs
|
||||
|
||||
Scénario: Badge Or visible avec effet premium
|
||||
Étant donné que j'ai le badge 🥇 Contributeur Or
|
||||
Quand j'affiche mon profil
|
||||
Alors le badge 🥇 s'affiche avec un effet brillant/doré
|
||||
Et une animation subtile attire l'attention
|
||||
Et le tooltip indique:
|
||||
"""
|
||||
🥇 Contributeur Or
|
||||
Top contributeur - Aide précieuse à la communauté
|
||||
"""
|
||||
Et le badge est prestigieux et reconnu
|
||||
|
||||
# Toast après validation/rejet de signalement
|
||||
|
||||
Scénario: Toast après validation avec progression vers badge
|
||||
Étant donné que j'ai 3 signalements validés sur 5 pour le badge Bronze
|
||||
Et que j'envoie un nouveau signalement
|
||||
Quand le modérateur valide mon signalement
|
||||
Alors je reçois un toast:
|
||||
"""
|
||||
✅ Bravo ! Votre signalement a aidé la communauté.
|
||||
Progression : 4/5 pour badge Bronze 🥉
|
||||
"""
|
||||
Et une mini progress bar s'affiche dans le toast (80%)
|
||||
Et le toast s'affiche pendant 6 secondes
|
||||
Et je me sens motivé à continuer
|
||||
|
||||
Scénario: Toast célébration obtention badge Bronze
|
||||
Étant donné que j'ai 4 signalements validés
|
||||
Quand mon 5ème signalement est validé
|
||||
Alors je reçois un toast spécial avec animation:
|
||||
"""
|
||||
🎉 Félicitations !
|
||||
Vous êtes désormais Contributeur Bronze 🥉
|
||||
Merci de rendre RoadWave meilleur !
|
||||
"""
|
||||
Et le toast a une animation de confettis
|
||||
Et un son de célébration est joué (vibration haptique)
|
||||
Et le toast reste affiché 8 secondes
|
||||
Et je peux cliquer pour voir mes nouveaux avantages
|
||||
|
||||
Scénario: Toast célébration obtention badge Argent
|
||||
Étant donné que j'obtiens le badge 🥈 Contributeur Argent
|
||||
Quand la notification est affichée
|
||||
Alors je reçois un toast premium:
|
||||
"""
|
||||
🎉 Impressionnant !
|
||||
Badge Contributeur Argent obtenu 🥈
|
||||
Votre engagement fait la différence !
|
||||
"""
|
||||
Et l'animation est plus spectaculaire (confettis argentés)
|
||||
Et un son de réussite est joué
|
||||
Et le badge est ajouté à mon profil instantanément
|
||||
|
||||
Scénario: Toast célébration obtention badge Or avec offre Premium
|
||||
Étant donné que j'obtiens le badge 🥇 Contributeur Or
|
||||
Quand la notification est affichée
|
||||
Alors je reçois un toast VIP:
|
||||
"""
|
||||
🎉 Exceptionnel !
|
||||
Badge Contributeur Or obtenu 🥇
|
||||
+ Offre Premium -50% pendant 3 mois !
|
||||
|
||||
[Voir l'offre]
|
||||
"""
|
||||
Et l'animation est spectaculaire (confettis dorés)
|
||||
Et un son de victoire est joué
|
||||
Et le toast reste affiché 10 secondes
|
||||
Et je peux cliquer pour accéder à l'offre Premium
|
||||
|
||||
Scénario: Toast après rejet avec encouragement
|
||||
Étant donné que mon taux de pertinence est de 65%
|
||||
Quand un signalement est rejeté
|
||||
Alors je reçois un toast constructif:
|
||||
"""
|
||||
❌ Signalement non retenu.
|
||||
Taux de pertinence : 60%
|
||||
Continuez vos efforts !
|
||||
"""
|
||||
Et le ton est encourageant, pas décourageant
|
||||
Et un lien "Améliorer mes signalements" est affiché
|
||||
Et je peux consulter les bonnes pratiques
|
||||
|
||||
# Progression visuelle vers le prochain badge
|
||||
|
||||
Scénario: Barre de progression vers badge Argent
|
||||
Étant donné que j'ai le badge Bronze
|
||||
Et que j'ai 12 signalements validés (sur 20 requis pour Argent)
|
||||
Quand j'affiche mes statistiques
|
||||
Alors je vois une barre de progression:
|
||||
"""
|
||||
Prochain palier : 🥈 Contributeur Argent
|
||||
[████████░░░░░░░░] 60% (12/20)
|
||||
8 signalements validés restants
|
||||
"""
|
||||
Et la barre est animée progressivement
|
||||
Et je vois clairement combien il me reste à faire
|
||||
|
||||
Scénario: Progression avec délai minimum
|
||||
Étant donné que j'ai obtenu le badge Bronze il y a 15 jours
|
||||
Et que j'ai déjà 20 signalements validés
|
||||
Quand j'affiche ma progression vers Argent
|
||||
Alors je vois un message:
|
||||
"""
|
||||
✓ Critères atteints (20 signalements validés)
|
||||
⏰ Délai minimum : encore 15 jours
|
||||
|
||||
Les badges nécessitent une contribution régulière sur la durée.
|
||||
"""
|
||||
Et je comprends que le délai minimum est anti-farming
|
||||
|
||||
# Page dédiée "En savoir plus" sur les badges
|
||||
|
||||
Scénario: Accéder à la page d'explication des badges
|
||||
Étant donné que je vois mes statistiques
|
||||
Quand je clique sur "En savoir plus" sur les badges
|
||||
Alors une page dédiée s'affiche avec:
|
||||
| section | contenu |
|
||||
| Introduction | Pourquoi nous récompensons les contributeurs |
|
||||
| Les 3 badges | Bronze, Argent, Or avec critères détaillés |
|
||||
| Calcul taux de pertinence | Formule et exemples |
|
||||
| Avantages de chaque badge | Priorisation, visibilité, réduction Premium |
|
||||
| Délais entre badges | 30j Bronze→Argent, 60j Argent→Or |
|
||||
| Règles anti-abus | Limite 10/24h, audit trimestriel |
|
||||
| FAQ | Questions fréquentes |
|
||||
Et la page est bien structurée et facile à lire
|
||||
|
||||
Scénario: Design de la page badges
|
||||
Étant donné que j'affiche la page "En savoir plus"
|
||||
Quand je vérifie le design
|
||||
Alors chaque badge a une illustration attrayante
|
||||
Et les critères sont affichés en tableaux clairs
|
||||
Et des exemples concrets sont fournis
|
||||
Et le ton est motivant et positif
|
||||
Et je peux facilement comprendre le système
|
||||
|
||||
# Affichage sur profil public
|
||||
|
||||
Scénario: Badge visible sur mon profil public
|
||||
Étant donné que j'ai le badge 🥈 Contributeur Argent
|
||||
Quand un autre utilisateur consulte mon profil
|
||||
Alors il voit le badge 🥈 à côté de mon pseudo
|
||||
Et il peut cliquer sur le badge pour voir la description
|
||||
Et cela renforce ma crédibilité
|
||||
Et les autres utilisateurs me font davantage confiance
|
||||
|
||||
Scénario: Badge visible sur mes commentaires/interactions
|
||||
Étant donné que j'ai le badge 🥇 Contributeur Or
|
||||
Quand je laisse un commentaire sur un contenu
|
||||
Alors le badge 🥇 s'affiche à côté de mon pseudo
|
||||
Et cela montre que je suis un membre actif de la communauté
|
||||
Et mes interactions ont plus de poids
|
||||
|
||||
# Notification email pour badges
|
||||
|
||||
Scénario: Email de félicitations pour badge Bronze
|
||||
Étant donné que j'obtiens le badge 🥉 Contributeur Bronze
|
||||
Quand le badge est attribué
|
||||
Alors je reçois un email de félicitations:
|
||||
"""
|
||||
Objet: 🎉 Vous êtes maintenant Contributeur Bronze !
|
||||
|
||||
Bravo [Pseudo] !
|
||||
|
||||
Vous avez obtenu le badge Contributeur Bronze grâce à
|
||||
vos 5 signalements validés et votre taux de pertinence de 72%.
|
||||
|
||||
Vos avantages:
|
||||
- Signalements traités en priorité (+10 points)
|
||||
- Badge visible sur votre profil
|
||||
|
||||
Continuez à nous aider à maintenir une communauté saine ! 🙏
|
||||
|
||||
L'équipe RoadWave
|
||||
"""
|
||||
Et l'email contient un lien vers mes statistiques
|
||||
|
||||
Scénario: Email de félicitations pour badge Or avec offre Premium
|
||||
Étant donné que j'obtiens le badge 🥇 Contributeur Or
|
||||
Quand le badge est attribué
|
||||
Alors je reçois un email VIP:
|
||||
"""
|
||||
Objet: 🎉 Badge Or obtenu ! Offre Premium -50% offerte
|
||||
|
||||
Exceptionnel [Pseudo] !
|
||||
|
||||
Vous faites partie des meilleurs contributeurs de RoadWave.
|
||||
Grâce à vos 50 signalements validés (90% pertinence), vous
|
||||
aidez des milliers d'utilisateurs.
|
||||
|
||||
🎁 En reconnaissance, vous bénéficiez de:
|
||||
✨ 3 mois d'abonnement Premium à -50%
|
||||
→ 2.49€/mois au lieu de 4.99€
|
||||
|
||||
[Profiter de l'offre]
|
||||
|
||||
Cette offre est valable pendant 30 jours.
|
||||
|
||||
Merci de contribuer à rendre RoadWave meilleur ! 🏆
|
||||
|
||||
L'équipe RoadWave
|
||||
"""
|
||||
Et l'email contient un CTA mis en évidence
|
||||
|
||||
# Rappels expiration offre Premium
|
||||
|
||||
Scénario: Rappel J-7 expiration offre Premium
|
||||
Étant donné que j'ai obtenu le badge Or il y a 23 jours
|
||||
Et que je n'ai pas activé l'offre Premium -50%
|
||||
Quand le système envoie les rappels
|
||||
Alors je reçois un email + push:
|
||||
"""
|
||||
⏰ Il vous reste 7 jours !
|
||||
|
||||
Votre offre Premium -50% expire bientôt.
|
||||
Profitez de 3 mois à 2.49€/mois au lieu de 4.99€.
|
||||
|
||||
[Activer maintenant]
|
||||
"""
|
||||
Et le CTA est mis en évidence en orange
|
||||
|
||||
Scénario: Rappel J-1 expiration offre Premium
|
||||
Étant donné que j'ai obtenu le badge Or il y a 29 jours
|
||||
Et que je n'ai pas activé l'offre
|
||||
Quand le dernier rappel est envoyé
|
||||
Alors je reçois un email + push urgent:
|
||||
"""
|
||||
⚠️ Dernière chance !
|
||||
|
||||
Votre offre Premium -50% expire DEMAIN.
|
||||
Ne manquez pas cette opportunité !
|
||||
|
||||
[Activer avant expiration]
|
||||
"""
|
||||
Et le CTA est en rouge pour l'urgence
|
||||
|
||||
# Affichage après expiration offre
|
||||
|
||||
Scénario: Message d'expiration de l'offre Premium
|
||||
Étant donné que l'offre Premium a expiré (31 jours)
|
||||
Quand j'accède à mes statistiques
|
||||
Alors je vois un message:
|
||||
"""
|
||||
Votre offre Premium -50% a expiré.
|
||||
Votre badge Or est conservé.
|
||||
"""
|
||||
Et le message est informatif, sans regret excessif
|
||||
|
||||
# Animation et gamification
|
||||
|
||||
Scénario: Animation lors de la montée de niveau
|
||||
Étant donné que je passe de Bronze à Argent
|
||||
Quand le changement est effectué
|
||||
Alors une animation "level up" s'affiche à l'écran
|
||||
Et mon nouveau badge apparaît avec un effet de brillance
|
||||
Et un son de réussite est joué
|
||||
Et l'UX est gratifiante et mémorable
|
||||
|
||||
Scénario: Confettis pour badge Or
|
||||
Étant donné que j'obtiens le badge Or
|
||||
Quand la notification s'affiche
|
||||
Alors des confettis dorés tombent sur l'écran
|
||||
Et l'animation dure 3 secondes
|
||||
Et le badge Or apparaît avec un effet "shine"
|
||||
Et je me sens valorisé et reconnu
|
||||
|
||||
# Dark mode et accessibilité
|
||||
|
||||
Scénario: Support du dark mode pour les badges
|
||||
Étant donné que j'ai activé le dark mode
|
||||
Quand j'affiche mes statistiques et badges
|
||||
Alors les couleurs s'adaptent:
|
||||
| élément | couleur light | couleur dark |
|
||||
| Badge Bronze | #CD7F32 | #D4A574 |
|
||||
| Badge Argent | #C0C0C0 | #E8E8E8 |
|
||||
| Badge Or | #FFD700 | #FFC700 |
|
||||
| Fond carte stats | Blanc | Gris foncé |
|
||||
| Jauge pertinence verte | #28A745 | #34D058 |
|
||||
| Jauge pertinence orange | #FF8C00 | #FFA500 |
|
||||
Et le contraste reste optimal
|
||||
|
||||
Scénario: Accessibilité lecteur d'écran pour badges
|
||||
Étant donné que j'utilise un lecteur d'écran
|
||||
Quand je navigue dans mes statistiques
|
||||
Alors le lecteur annonce clairement:
|
||||
"""
|
||||
Vos statistiques de modération.
|
||||
Signalements envoyés: 27.
|
||||
Validés: 23.
|
||||
Rejetés: 4.
|
||||
Taux de pertinence: 85%.
|
||||
Badge actuel: Contributeur Argent.
|
||||
Prochain palier: Contributeur Or, 27 signalements validés restants.
|
||||
"""
|
||||
Et tous les éléments visuels ont des équivalents textuels
|
||||
|
||||
# Coût et performance
|
||||
|
||||
Scénario: Performance de l'affichage des statistiques
|
||||
Étant donné que j'affiche mes statistiques
|
||||
Quand je mesure les performances
|
||||
Alors les données se chargent en <300ms
|
||||
Et les animations sont fluides (60 FPS)
|
||||
Et la mémoire utilisée est <50 MB
|
||||
Et l'UX est instantanée
|
||||
|
||||
Scénario: Coût de la fonctionnalité
|
||||
Étant donné que le système de badges est en place
|
||||
Quand on évalue le coût
|
||||
Alors le développement est 100% interne (Flutter)
|
||||
Et les calculs sont effectués côté backend (0€ côté app)
|
||||
Et les notifications sont gratuites (Firebase)
|
||||
Et le coût opérationnel est de 0€ (MVP)
|
||||
@@ -0,0 +1,304 @@
|
||||
# language: fr
|
||||
|
||||
@ui @moderation @historique
|
||||
Fonctionnalité: Historique des signalements utilisateur (Mobile)
|
||||
En tant qu'utilisateur
|
||||
Je veux consulter l'historique de mes signalements
|
||||
Afin de suivre leur traitement et comprendre les décisions prises
|
||||
|
||||
# 14.1.3 - Historique personnel des signalements
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis connecté à l'application mobile
|
||||
Et que j'ai envoyé des signalements précédemment
|
||||
|
||||
# Accès à l'historique
|
||||
|
||||
Scénario: Accéder à l'historique depuis le profil
|
||||
Étant donné que je suis dans mon profil utilisateur
|
||||
Quand je scroll vers le bas
|
||||
Alors je vois une section "📊 Modération"
|
||||
Et je vois l'option "Mes signalements"
|
||||
Et je vois le nombre de signalements en badge: "(12)"
|
||||
Et je peux cliquer pour accéder à l'historique
|
||||
|
||||
Scénario: Accéder à l'historique depuis le toast de confirmation
|
||||
Étant donné que je viens d'envoyer un signalement
|
||||
Et que le toast de confirmation est affiché
|
||||
Quand je clique sur "Voir mes signalements"
|
||||
Alors je suis redirigé vers la page "Mes signalements"
|
||||
Et la page s'affiche en moins de 500ms
|
||||
Et mon dernier signalement est en tête de liste
|
||||
|
||||
# Affichage de la liste des signalements
|
||||
|
||||
Scénario: Affichage de l'historique vide
|
||||
Étant donné que je n'ai jamais envoyé de signalement
|
||||
Quand j'ouvre "Mes signalements"
|
||||
Alors je vois un message:
|
||||
"""
|
||||
Aucun signalement pour le moment
|
||||
|
||||
Vous pouvez signaler un contenu inapproprié
|
||||
depuis le menu de n'importe quel contenu.
|
||||
"""
|
||||
Et je vois une illustration vide sympathique
|
||||
Et un bouton "Découvrir les règles de la communauté"
|
||||
|
||||
Scénario: Liste des signalements avec informations clés
|
||||
Étant donné que j'ai envoyé 5 signalements
|
||||
Quand j'ouvre "Mes signalements"
|
||||
Alors je vois une liste de 5 cartes de signalements
|
||||
Et chaque carte affiche:
|
||||
| information | exemple | position |
|
||||
| Statut badge | "En cours 🔍" (orange) | Haut à droite |
|
||||
| Titre du contenu | "Podcast #42" | Titre |
|
||||
| Créateur | "@pseudo_createur" | Sous-titre |
|
||||
| Catégorie | "🚫 Haine & violence" | Ligne 1 |
|
||||
| Date | "Il y a 2 jours" ou "15/01/2026" | Ligne 2 |
|
||||
| Mon commentaire | "Propos discriminatoires à 2:30" | Ligne 3 (si rempli) |
|
||||
Et les cartes sont triées par date décroissante (plus récent en haut)
|
||||
|
||||
Plan du Scénario: Couleur du badge selon statut
|
||||
Étant donné que j'ai un signalement avec le statut "<statut>"
|
||||
Quand j'affiche l'historique
|
||||
Alors le badge affiché est "<badge>"
|
||||
Et la couleur du badge est "<couleur>"
|
||||
|
||||
Exemples:
|
||||
| statut | badge | couleur |
|
||||
| En cours | En cours 🔍 | Orange |
|
||||
| Traité | Traité ✓ | Vert |
|
||||
| Rejeté | Rejeté ✗ | Rouge |
|
||||
|
||||
Scénario: Affichage de la date relative
|
||||
Étant donné que j'ai envoyé des signalements à différentes dates
|
||||
Quand j'affiche l'historique
|
||||
Alors les dates récentes s'affichent en format relatif:
|
||||
| date signalement | affichage |
|
||||
| Il y a 5 minutes | "À l'instant" |
|
||||
| Il y a 2 heures | "Il y a 2h" |
|
||||
| Il y a 1 jour | "Hier" |
|
||||
| Il y a 3 jours | "Il y a 3j" |
|
||||
| Il y a 10 jours | "15/01/2026" |
|
||||
Et les dates anciennes (>7 jours) sont en format absolu
|
||||
|
||||
# Détails d'un signalement
|
||||
|
||||
Scénario: Consulter les détails d'un signalement
|
||||
Étant donné que j'ai envoyé un signalement il y a 3 jours
|
||||
Quand je clique sur la carte du signalement
|
||||
Alors une page de détails s'affiche
|
||||
Et je vois toutes les informations:
|
||||
| section | contenu |
|
||||
| En-tête | Titre du contenu + lien vers le contenu |
|
||||
| Créateur | Pseudo + lien vers profil créateur |
|
||||
| Ma catégorie | 🚫 Haine & violence |
|
||||
| Mon commentaire | "Propos discriminatoires à 2:30" |
|
||||
| Date d'envoi | "Envoyé le 15/01/2026 à 14:32" |
|
||||
| Statut actuel | "En cours 🔍 - En attente de traitement" |
|
||||
| Délai estimé | "Traitement sous 24-48h" |
|
||||
Et je vois un bouton "Retour à mes signalements"
|
||||
|
||||
Scénario: Lien vers le contenu signalé
|
||||
Étant donné que je consulte les détails d'un signalement
|
||||
Et que le contenu signalé est toujours en ligne
|
||||
Quand je clique sur le titre du contenu
|
||||
Alors je suis redirigé vers la page du contenu
|
||||
Et je peux réécouter le contenu si besoin
|
||||
Et un badge "Signalé par vous" s'affiche discrètement
|
||||
|
||||
Scénario: Contenu supprimé suite au signalement
|
||||
Étant donné que le contenu que j'ai signalé a été supprimé
|
||||
Quand je consulte les détails du signalement
|
||||
Alors le titre du contenu est affiché en gris barré
|
||||
Et un message s'affiche: "Ce contenu a été retiré de la plateforme"
|
||||
Et je ne peux pas accéder au contenu
|
||||
Et le statut est "Traité ✓"
|
||||
|
||||
# Notifications de changement de statut
|
||||
|
||||
Scénario: Notification quand un signalement est traité
|
||||
Étant donné que j'ai signalé un contenu il y a 24h
|
||||
Quand le modérateur traite mon signalement
|
||||
Et que le contenu est retiré
|
||||
Alors je reçois une notification push:
|
||||
"""
|
||||
✓ Votre signalement a été traité
|
||||
Le contenu a été retiré de la plateforme.
|
||||
"""
|
||||
Et je reçois une notification in-app identique
|
||||
Et le statut dans mon historique passe à "Traité ✓"
|
||||
Et un badge (1) apparaît sur l'onglet "Mes signalements"
|
||||
|
||||
Scénario: Notification quand un signalement est rejeté
|
||||
Étant donné que j'ai signalé un contenu
|
||||
Quand le modérateur rejette mon signalement
|
||||
Alors je reçois une notification:
|
||||
"""
|
||||
Votre signalement a été examiné
|
||||
Le contenu ne viole pas les règles de la communauté.
|
||||
"""
|
||||
Et le statut dans mon historique passe à "Rejeté ✗"
|
||||
Et je peux voir la raison du rejet dans les détails
|
||||
|
||||
Scénario: Affichage de la raison du rejet
|
||||
Étant donné que mon signalement a été rejeté
|
||||
Quand je consulte les détails du signalement
|
||||
Alors je vois une section "Raison du rejet":
|
||||
"""
|
||||
Après examen, le contenu ne viole pas nos règles.
|
||||
Le passage mentionné est dans un contexte éducatif.
|
||||
"""
|
||||
Et la raison est claire et compréhensible
|
||||
Et je peux apprendre pour améliorer mes futurs signalements
|
||||
|
||||
# Filtres et recherche
|
||||
|
||||
Scénario: Filtrer les signalements par statut
|
||||
Étant donné que j'ai 20 signalements avec différents statuts
|
||||
Quand j'ouvre l'historique
|
||||
Alors je vois des onglets de filtres:
|
||||
| onglet | nombre |
|
||||
| Tous (20) | 20 |
|
||||
| En cours (8)| 8 |
|
||||
| Traités (9) | 9 |
|
||||
| Rejetés (3) | 3 |
|
||||
Et je peux cliquer sur un onglet pour filtrer
|
||||
Et la liste se met à jour instantanément
|
||||
|
||||
Scénario: Rechercher dans mes signalements
|
||||
Étant donné que j'ai 50 signalements
|
||||
Quand j'ouvre la barre de recherche
|
||||
Et que je tape "podcast"
|
||||
Alors seuls les signalements contenant "podcast" s'affichent:
|
||||
| recherche dans |
|
||||
| Titre du contenu |
|
||||
| Pseudo du créateur |
|
||||
| Mon commentaire |
|
||||
Et les résultats sont mis en évidence
|
||||
Et la recherche est instantanée (pas de délai)
|
||||
|
||||
# Pull-to-refresh
|
||||
|
||||
Scénario: Actualiser la liste des signalements
|
||||
Étant donné que je suis sur la page "Mes signalements"
|
||||
Quand je tire vers le bas (pull-to-refresh)
|
||||
Alors un spinner de chargement s'affiche
|
||||
Et la liste est actualisée depuis le serveur
|
||||
Et les nouveaux statuts sont affichés
|
||||
Et un toast s'affiche: "✓ Mis à jour"
|
||||
|
||||
# Pagination et performance
|
||||
|
||||
Scénario: Chargement progressif des signalements (pagination)
|
||||
Étant donné que j'ai 100 signalements
|
||||
Quand j'ouvre "Mes signalements"
|
||||
Alors seuls les 20 premiers signalements sont chargés
|
||||
Et quand je scroll en bas de liste
|
||||
Alors les 20 suivants sont chargés automatiquement
|
||||
Et un loader discret s'affiche pendant le chargement
|
||||
Et l'UX est fluide sans saccade
|
||||
|
||||
Scénario: Performance de la liste
|
||||
Étant donné que j'ai 100 signalements
|
||||
Quand j'ouvre l'historique
|
||||
Alors le premier affichage prend <500ms
|
||||
Et le scroll est fluide (60 FPS)
|
||||
Et les images/avatars se chargent en lazy loading
|
||||
Et la mémoire utilisée reste <100 MB
|
||||
|
||||
# État vide pour chaque filtre
|
||||
|
||||
Scénario: Aucun signalement "En cours"
|
||||
Étant donné que tous mes signalements ont été traités
|
||||
Quand je clique sur l'onglet "En cours"
|
||||
Alors je vois un message:
|
||||
"""
|
||||
Aucun signalement en cours
|
||||
|
||||
Tous vos signalements ont été traités.
|
||||
"""
|
||||
Et je vois une illustration vide
|
||||
|
||||
Scénario: Aucun signalement "Rejeté"
|
||||
Étant donné que tous mes signalements ont été acceptés
|
||||
Quand je clique sur l'onglet "Rejetés"
|
||||
Alors je vois un message:
|
||||
"""
|
||||
Aucun signalement rejeté
|
||||
|
||||
Tous vos signalements étaient pertinents ! 🎉
|
||||
"""
|
||||
Et je vois un message encourageant
|
||||
|
||||
# Dark mode et accessibilité
|
||||
|
||||
Scénario: Support du dark mode
|
||||
Étant donné que j'ai activé le dark mode
|
||||
Quand j'affiche "Mes signalements"
|
||||
Alors les couleurs s'adaptent:
|
||||
| élément | couleur light | couleur dark |
|
||||
| Fond page | Blanc | Noir (#121212) |
|
||||
| Cartes | Gris clair | Gris foncé |
|
||||
| Texte principal | Noir | Blanc |
|
||||
| Badge "En cours" | Orange (#FF8C00) | Orange (#FFA500) |
|
||||
| Badge "Traité" | Vert (#28A745) | Vert (#34D058) |
|
||||
| Badge "Rejeté" | Rouge (#DC3545) | Rouge (#F85149) |
|
||||
Et le contraste reste suffisant (WCAG AA)
|
||||
|
||||
Scénario: Accessibilité pour lecteur d'écran
|
||||
Étant donné que j'utilise un lecteur d'écran
|
||||
Quand je navigue dans l'historique
|
||||
Alors chaque carte est annoncée clairement:
|
||||
"""
|
||||
Signalement du contenu "Podcast #42" par @pseudo.
|
||||
Catégorie: Haine et violence.
|
||||
Statut: En cours d'examen.
|
||||
Envoyé il y a 2 jours.
|
||||
"""
|
||||
Et je peux naviguer au clavier entre les cartes
|
||||
Et tous les boutons ont des labels descriptifs
|
||||
|
||||
# Gestion d'erreur
|
||||
|
||||
Scénario: Erreur réseau lors du chargement
|
||||
Étant donné que je n'ai pas de connexion internet
|
||||
Quand j'ouvre "Mes signalements"
|
||||
Alors un message d'erreur s'affiche:
|
||||
"""
|
||||
Impossible de charger vos signalements
|
||||
Vérifiez votre connexion internet
|
||||
"""
|
||||
Et un bouton "Réessayer" est affiché
|
||||
Et je peux cliquer pour réessayer
|
||||
|
||||
Scénario: Cache local pour consultation hors ligne
|
||||
Étant donné que j'ai consulté mes signalements hier
|
||||
Et que je n'ai pas de connexion internet aujourd'hui
|
||||
Quand j'ouvre "Mes signalements"
|
||||
Alors les signalements en cache s'affichent
|
||||
Et un message discret indique:
|
||||
"""
|
||||
📡 Mode hors ligne - Données mises en cache
|
||||
"""
|
||||
Et je peux consulter les détails
|
||||
Mais les statuts peuvent ne pas être à jour
|
||||
|
||||
# Coût et conformité
|
||||
|
||||
Scénario: Coût de la fonctionnalité
|
||||
Étant donné que l'historique des signalements est en place
|
||||
Quand on évalue le coût
|
||||
Alors le développement est 100% interne (Flutter)
|
||||
Et aucun service tiers n'est utilisé
|
||||
Et le coût opérationnel est de 0€
|
||||
Et les notifications in-app sont gratuites
|
||||
|
||||
Scénario: Conformité RGPD
|
||||
Étant donné que mes données de signalement sont stockées
|
||||
Quand je supprime mon compte
|
||||
Alors tous mes signalements sont anonymisés
|
||||
Et mes commentaires personnels sont supprimés
|
||||
Et seules les métadonnées nécessaires sont conservées (conformité DSA)
|
||||
Et je suis informé de cette procédure
|
||||
@@ -0,0 +1,58 @@
|
||||
# language: fr
|
||||
|
||||
@ui @moderation @gamification @mvp
|
||||
Fonctionnalité: Modal de découverte des badges
|
||||
|
||||
En tant qu'utilisateur
|
||||
Je veux découvrir les badges disponibles
|
||||
Afin de me motiver à participer à la modération
|
||||
|
||||
Scénario: Première visite - Modal d'introduction
|
||||
Étant donné un nouvel utilisateur "alice@roadwave.fr"
|
||||
Quand il effectue son premier signalement
|
||||
Alors une modal s'affiche expliquant le système:
|
||||
| Section | Contenu |
|
||||
| Titre | Devenez Modérateur RoadWave ! |
|
||||
| Explication | Gagnez des badges en modérant |
|
||||
| Badges disponibles | Bronze, Argent, Or, Diamant |
|
||||
| Récompenses | Points, Premium gratuit, etc. |
|
||||
Et un bouton "J'ai compris"
|
||||
Et un événement "BADGE_DISCOVERY_MODAL_SHOWN" est enregistré
|
||||
|
||||
Scénario: Galerie des badges avec progression
|
||||
Étant donné un utilisateur qui consulte les badges
|
||||
Alors il voit pour chaque badge:
|
||||
| Badge | Progression | Statut |
|
||||
| Bronze | 7/10 | En cours |
|
||||
| Argent | 0/50 | Verrouillé |
|
||||
| Or | 0/200 | Verrouillé |
|
||||
| Diamant | 0/1000 | Verrouillé |
|
||||
Et une barre de progression visuelle
|
||||
Et un événement "BADGE_GALLERY_VIEWED" est enregistré
|
||||
|
||||
Scénario: Notification de déverrouillage de badge
|
||||
Étant donné un utilisateur "bob@roadwave.fr"
|
||||
Quand il atteint 10 signalements validés
|
||||
Alors une animation de célébration s'affiche
|
||||
Et une modal annonce: "🎉 Badge Bronze débloqué !"
|
||||
Et un partage social est proposé
|
||||
Et un événement "BADGE_UNLOCKED_NOTIFICATION" est enregistré
|
||||
|
||||
Scénario: Affichage des badges sur le profil
|
||||
Étant donné un utilisateur avec 3 badges
|
||||
Quand un autre utilisateur visite son profil
|
||||
Alors les badges sont affichés de manière visible:
|
||||
| Badge | Affichage |
|
||||
| Modérateur Or | Grande icône |
|
||||
| Expert copyright | Petite icône |
|
||||
| Top modérateur | Badge spécial |
|
||||
Et un tooltip explique chaque badge au survol
|
||||
Et un événement "PROFILE_BADGES_DISPLAYED" est enregistré
|
||||
|
||||
Scénario: Challenge mensuel de modération
|
||||
Étant donné qu'un nouveau mois commence
|
||||
Alors un challenge est proposé:
|
||||
"Challenge Février : Validez 20 signalements pour gagner 1 mois Premium !"
|
||||
Et une barre de progression individuelle
|
||||
Et un classement en temps réel
|
||||
Et un événement "MONTHLY_CHALLENGE_ANNOUNCED" est enregistré
|
||||
410
docs/domains/moderation/features/ui/sanctions-appel.feature
Normal file
410
docs/domains/moderation/features/ui/sanctions-appel.feature
Normal file
@@ -0,0 +1,410 @@
|
||||
# language: fr
|
||||
|
||||
@ui @moderation @sanctions @appel
|
||||
Fonctionnalité: Interface sanctions et processus d'appel (Mobile)
|
||||
En tant que créateur de contenu
|
||||
Je veux consulter mes sanctions et faire appel si nécessaire
|
||||
Afin de comprendre les décisions et contester si je pense qu'il y a erreur
|
||||
|
||||
# 14.3 - Interface sanctions et appel
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis un créateur de contenu
|
||||
Et que je suis connecté à l'application mobile
|
||||
|
||||
# Notifications multi-canal
|
||||
|
||||
Scénario: Notification push immédiate après sanction
|
||||
Étant donné que mon contenu vient d'être modéré
|
||||
Quand la sanction est appliquée
|
||||
Alors je reçois une notification push immédiate:
|
||||
"""
|
||||
⚠️ Votre contenu a été modéré
|
||||
Appuyez pour voir les détails
|
||||
"""
|
||||
Et la notification est marquée comme importante (son + vibration)
|
||||
Et je peux cliquer pour accéder aux détails
|
||||
Et la notification reste visible jusqu'à ce que je la lise
|
||||
|
||||
Scénario: Popup in-app au prochain lancement
|
||||
Étant donné que mon contenu a été modéré
|
||||
Et que je n'ai pas encore consulté la sanction
|
||||
Quand j'ouvre l'application
|
||||
Alors une popup modale s'affiche automatiquement avant tout:
|
||||
"""
|
||||
⚠️ Attention
|
||||
|
||||
Votre contenu "Mon podcast #42" a été modéré.
|
||||
|
||||
Catégorie violée: 🚫 Haine & violence
|
||||
Sanction: Strike 2/4 - Suspension 7 jours
|
||||
|
||||
[Voir les détails] [Plus tard]
|
||||
"""
|
||||
Et la popup est prioritaire (affichée avant le contenu de l'app)
|
||||
Et je ne peux pas la fermer sans l'avoir lue (pas de bouton X)
|
||||
Et je dois cliquer sur un bouton pour continuer
|
||||
|
||||
Scénario: Design de la popup de sanction
|
||||
Étant donné que la popup de sanction s'affiche
|
||||
Quand je vérifie le design
|
||||
Alors le fond est rouge clair (#FFEBEE) pour signaler la gravité
|
||||
Et l'icône ⚠️ est proéminente
|
||||
Et le texte est clair et concis
|
||||
Et les boutons sont bien visibles:
|
||||
| bouton | style | couleur |
|
||||
| Voir les détails| Primaire (plein) | Rouge |
|
||||
| Plus tard | Secondaire (border)| Gris |
|
||||
Et le design est professionnel et sérieux
|
||||
|
||||
# Page détaillée de la sanction
|
||||
|
||||
Scénario: Affichage de la page détails sanction
|
||||
Étant donné que je clique sur "Voir les détails"
|
||||
Quand la page s'affiche
|
||||
Alors je vois toutes les informations obligatoires:
|
||||
| section | contenu exemple |
|
||||
| En-tête avec icône | ⚠️ Contenu modéré |
|
||||
| Titre du contenu | "Mon podcast #42" |
|
||||
| Date de publication | "Publié le 15/01/2026" |
|
||||
| Catégorie violée | 🚫 Haine & violence (Article 3.2 CGU) |
|
||||
| Raison détaillée | "Propos discriminatoires envers un groupe" |
|
||||
| Passage problématique | "3:42-4:15" (avec player audio) |
|
||||
| Transcription surlignée | "[texte problématique en rouge]" |
|
||||
| Gravité de la sanction | Strike 2/4 - Suspension 7 jours |
|
||||
| Conséquences futures | "Strike 3: 30j / Strike 4: Ban définitif" |
|
||||
| Délai d'appel | "7 jours pour faire appel" |
|
||||
| Bouton Contester | [Contester cette décision] |
|
||||
| Lien CGU | [Voir les règles de la communauté] |
|
||||
Et toutes les sections sont clairement séparées
|
||||
|
||||
Scénario: Player audio du passage problématique
|
||||
Étant donné que je consulte les détails de la sanction
|
||||
Quand je vois la section "Passage problématique"
|
||||
Alors un player audio s'affiche avec le timestamp "3:42-4:15"
|
||||
Et je peux écouter uniquement cette portion de l'audio
|
||||
Et les contrôles sont simples: Play/Pause + volume
|
||||
Et la waveform visualise le passage
|
||||
Et je peux comprendre exactement ce qui pose problème
|
||||
|
||||
Scénario: Transcription avec mise en évidence
|
||||
Étant donné que je consulte la transcription du passage
|
||||
Quand j'affiche la transcription
|
||||
Alors les mots/phrases problématiques sont surlignés en rouge
|
||||
Et le contexte autour est affiché en gris
|
||||
Et je peux voir exactement quels mots ont posé problème:
|
||||
"""
|
||||
[contexte gris]... et c'est pourquoi je pense que
|
||||
[ROUGE: phrase discriminatoire problématique]
|
||||
[contexte gris]... mais c'est mon opinion.
|
||||
"""
|
||||
Et la mise en évidence est claire
|
||||
|
||||
Scénario: Lien vers l'article des CGU
|
||||
Étant donné que la sanction référence "Article 3.2 CGU"
|
||||
Quand je clique sur le lien
|
||||
Alors je suis redirigé vers les CGU
|
||||
Et la section "Article 3.2 - Haine & violence" est mise en évidence
|
||||
Et je peux lire exactement ce qui est interdit
|
||||
Et je comprends mieux ma violation
|
||||
|
||||
# Escalade des sanctions
|
||||
|
||||
Scénario: Affichage de l'escalade des strikes
|
||||
Étant donné que j'ai reçu le Strike 2
|
||||
Quand je consulte la section "Gravité"
|
||||
Alors je vois clairement l'escalade:
|
||||
"""
|
||||
Vous avez reçu le Strike 2/4
|
||||
|
||||
Historique:
|
||||
✓ Strike 1: Avertissement (il y a 3 mois)
|
||||
⚠️ Strike 2: Suspension 7 jours (aujourd'hui)
|
||||
|
||||
Prochaines étapes si récidive:
|
||||
⚠️ Strike 3: Suspension 30 jours
|
||||
❌ Strike 4: Ban définitif
|
||||
|
||||
Réhabilitation:
|
||||
-1 strike tous les 6 mois sans incident
|
||||
"""
|
||||
Et je comprends la progression des sanctions
|
||||
Et je suis motivé à ne pas récidiver
|
||||
|
||||
Scénario: Compteur de suspension visible
|
||||
Étant donné que je suis suspendu pour 7 jours
|
||||
Quand j'ouvre l'application
|
||||
Alors une bannière persistante s'affiche en haut:
|
||||
"""
|
||||
⏸️ Compte suspendu - 5 jours restants
|
||||
"""
|
||||
Et la bannière est visible sur toutes les pages
|
||||
Et je vois le décompte en temps réel
|
||||
Et je ne peux pas publier de nouveau contenu
|
||||
|
||||
# Accès à l'historique des sanctions
|
||||
|
||||
Scénario: Consulter l'historique des sanctions
|
||||
Étant donné que je suis dans mon profil créateur
|
||||
Quand je clique sur "Mes sanctions"
|
||||
Alors je vois la liste de toutes mes sanctions passées:
|
||||
| colonne | contenu exemple |
|
||||
| Date | 15/01/2026 |
|
||||
| Contenu | "Mon podcast #42" |
|
||||
| Catégorie | 🚫 Haine & violence |
|
||||
| Sanction | Strike 2 - Suspension 7j |
|
||||
| Statut | Active / Terminée / Annulée |
|
||||
| Appel | Aucun / En cours / Accepté / Rejeté |
|
||||
| Action | [Faire appel] / [Détails] |
|
||||
Et les sanctions sont triées par date décroissante
|
||||
|
||||
Scénario: Sanctions actives vs terminées
|
||||
Étant donné que j'ai 3 sanctions dans mon historique
|
||||
Quand j'affiche "Mes sanctions"
|
||||
Alors les sanctions actives sont mises en évidence (fond rouge clair)
|
||||
Et les sanctions terminées sont en gris
|
||||
Et les sanctions annulées (après appel) sont en vert clair
|
||||
Et je vois clairement l'état de chaque sanction
|
||||
|
||||
# Formulaire d'appel
|
||||
|
||||
Scénario: Accéder au formulaire d'appel depuis la notification
|
||||
Étant donné que je consulte les détails d'une sanction
|
||||
Et que le délai d'appel n'est pas dépassé (<7 jours)
|
||||
Quand je clique sur "Contester cette décision"
|
||||
Alors le formulaire d'appel s'affiche en plein écran
|
||||
Et le formulaire est pré-rempli avec les informations de la sanction
|
||||
Et je peux commencer à rédiger mon appel
|
||||
|
||||
Scénario: Structure du formulaire d'appel
|
||||
Étant donné que le formulaire d'appel est affiché
|
||||
Quand je vérifie les champs
|
||||
Alors je vois la structure suivante:
|
||||
| champ | type | limite | obligatoire |
|
||||
| Sanction contestée | Texte (readonly) | - | oui |
|
||||
| Raison de l'appel | Texte court | 50-1000 car. | oui |
|
||||
| Arguments détaillés | Zone texte enrichie | 1000-5000 car. | oui |
|
||||
| Preuves | Upload fichiers | 5 max, 10MB tot.| non |
|
||||
| Bouton Annuler | Secondaire | - | - |
|
||||
| Bouton Soumettre | Primaire | - | - |
|
||||
Et tous les champs obligatoires sont marqués d'un astérisque rouge
|
||||
|
||||
Scénario: Validation du formulaire d'appel
|
||||
Étant donné que je remplis le formulaire d'appel
|
||||
Quand je clique sur "Soumettre l'appel"
|
||||
Alors le système valide:
|
||||
| règle | message d'erreur si non respecté |
|
||||
| Raison >50 caractères | "La raison doit faire au moins 50 caractères" |
|
||||
| Arguments >100 caractères | "Développez vos arguments (min 100 car.)" |
|
||||
| Total fichiers <10 MB | "Taille totale des fichiers >10 MB" |
|
||||
| Formats fichiers acceptés (PDF, JPG) | "Format de fichier non accepté" |
|
||||
Et si une erreur existe, le champ est surligné en rouge
|
||||
Et je dois corriger avant de pouvoir soumettre
|
||||
|
||||
Scénario: Upload de preuves
|
||||
Étant donné que je veux joindre des preuves
|
||||
Quand je clique sur "Ajouter des preuves"
|
||||
Alors je peux choisir depuis:
|
||||
| source | types acceptés |
|
||||
| Galerie photos | JPG, PNG |
|
||||
| Fichiers | PDF |
|
||||
| Caméra (nouveau) | JPG |
|
||||
Et je peux uploader jusqu'à 5 fichiers
|
||||
Et la taille totale ne peut pas dépasser 10 MB
|
||||
Et une progress bar s'affiche pendant l'upload
|
||||
|
||||
Scénario: Confirmation après soumission de l'appel
|
||||
Étant donné que j'ai soumis un appel valide
|
||||
Quand l'appel est enregistré
|
||||
Alors une page de confirmation s'affiche:
|
||||
"""
|
||||
✓ Appel envoyé avec succès
|
||||
|
||||
Numéro de ticket: #MOD-2026-00142
|
||||
|
||||
Votre appel sera examiné par un modérateur senior
|
||||
sous 72h maximum (3 jours ouvrés).
|
||||
|
||||
Vous serez notifié de la décision par:
|
||||
- Notification push
|
||||
- Email
|
||||
- Notification in-app
|
||||
|
||||
[Retour à mes sanctions]
|
||||
"""
|
||||
Et je reçois un email de confirmation identique
|
||||
Et le statut dans "Mes sanctions" passe à "Appel en cours 🔍"
|
||||
|
||||
# Délai d'appel et compteur
|
||||
|
||||
Scénario: Compteur de jours restants pour faire appel
|
||||
Étant donné que j'ai reçu une sanction il y a 3 jours
|
||||
Quand je consulte les détails de la sanction
|
||||
Alors je vois un compteur en haut de page:
|
||||
"""
|
||||
⏰ 4 jours restants pour faire appel
|
||||
"""
|
||||
Et le compteur est en orange pour attirer l'attention
|
||||
Et il se met à jour en temps réel (chaque jour)
|
||||
|
||||
Scénario: Délai d'appel dépassé
|
||||
Étant donné que j'ai reçu une sanction il y a 8 jours
|
||||
Quand je consulte les détails de la sanction
|
||||
Alors le bouton "Contester cette décision" est désactivé (grisé)
|
||||
Et un message s'affiche:
|
||||
"""
|
||||
⚠️ Le délai de 7 jours pour faire appel est dépassé.
|
||||
Cette décision est désormais définitive.
|
||||
"""
|
||||
Et je ne peux plus contester la sanction
|
||||
|
||||
# Suivi de l'appel
|
||||
|
||||
Scénario: Statut de l'appel dans l'historique
|
||||
Étant donné que j'ai soumis un appel
|
||||
Quand je consulte "Mes sanctions"
|
||||
Alors je vois le statut de l'appel:
|
||||
| statut appel | badge | couleur |
|
||||
| Aucun appel | - | - |
|
||||
| Appel en cours | En cours 🔍 | Orange |
|
||||
| Appel accepté | Accepté ✓ | Vert |
|
||||
| Appel rejeté | Rejeté ✗ | Rouge |
|
||||
| Sanction réduite | Partiellement accepté 🟡 | Bleu |
|
||||
Et un badge de notification m'alerte si le statut change
|
||||
|
||||
Scénario: Notification quand l'appel est traité - Accepté
|
||||
Étant donné que mon appel a été accepté
|
||||
Quand le modérateur prend la décision
|
||||
Alors je reçois une notification push + in-app:
|
||||
"""
|
||||
✓ Appel accepté
|
||||
|
||||
Votre sanction a été annulée.
|
||||
Le strike a été retiré et votre contenu a été rétabli.
|
||||
|
||||
[Voir les détails]
|
||||
"""
|
||||
Et je reçois un email détaillé avec la justification
|
||||
Et le statut dans mes sanctions passe à "Annulée"
|
||||
|
||||
Scénario: Notification quand l'appel est traité - Rejeté
|
||||
Étant donné que mon appel a été rejeté
|
||||
Quand le modérateur prend la décision
|
||||
Alors je reçois une notification:
|
||||
"""
|
||||
Appel rejeté
|
||||
|
||||
Votre appel a été examiné et la sanction est maintenue.
|
||||
Cette décision est définitive.
|
||||
|
||||
[Voir la justification]
|
||||
"""
|
||||
Et je reçois un email avec la justification détaillée
|
||||
Et le statut reste "Active"
|
||||
Et je ne peux pas faire de second appel
|
||||
|
||||
Scénario: Notification intermédiaire si délai >72h
|
||||
Étant donné que mon appel complexe est en cours depuis 3 jours
|
||||
Quand le délai de 72h est dépassé
|
||||
Alors je reçois une notification intermédiaire:
|
||||
"""
|
||||
Appel #MOD-2026-00142 en cours
|
||||
|
||||
Votre appel nécessite un examen approfondi.
|
||||
Réponse sous 2 jours maximum.
|
||||
|
||||
Merci de votre patience.
|
||||
"""
|
||||
Et je suis rassuré que mon appel n'est pas oublié
|
||||
|
||||
# Page détails de la réponse à l'appel
|
||||
|
||||
Scénario: Détails de la réponse - Appel accepté
|
||||
Étant donné que mon appel a été accepté
|
||||
Quand je consulte les détails de la réponse
|
||||
Alors je vois:
|
||||
"""
|
||||
Décision: Annulation de la sanction ✓
|
||||
|
||||
Justification:
|
||||
Après examen de votre appel, nous reconnaissons que le
|
||||
passage mentionné était dans un contexte éducatif et ne
|
||||
constitue pas une violation des règles de la communauté.
|
||||
|
||||
Actions prises:
|
||||
✓ Strike retiré de votre compte
|
||||
✓ Suspension annulée
|
||||
✓ Contenu rétabli sur la plateforme
|
||||
|
||||
Cette décision est définitive.
|
||||
"""
|
||||
Et je suis satisfait de la transparence
|
||||
|
||||
Scénario: Détails de la réponse - Sanction réduite
|
||||
Étant donné que mon appel a été partiellement accepté
|
||||
Quand je consulte les détails
|
||||
Alors je vois:
|
||||
"""
|
||||
Décision: Réduction de la sanction 🟡
|
||||
|
||||
Justification:
|
||||
Nous reconnaissons des circonstances atténuantes.
|
||||
|
||||
Sanction initiale: Strike 2 - Suspension 7 jours
|
||||
Sanction réduite: Strike 1 - Suspension 3 jours
|
||||
|
||||
Cette décision est définitive.
|
||||
"""
|
||||
Et je vois le compteur de suspension mis à jour (3 jours au lieu de 7)
|
||||
|
||||
# Dark mode et accessibilité
|
||||
|
||||
Scénario: Support du dark mode
|
||||
Étant donné que j'ai activé le dark mode
|
||||
Quand j'affiche la page de sanction
|
||||
Alors les couleurs s'adaptent:
|
||||
| élément | couleur light | couleur dark |
|
||||
| Fond page | Blanc | Noir (#121212) |
|
||||
| Carte sanction | Rouge clair | Rouge foncé |
|
||||
| Texte principal | Noir | Blanc |
|
||||
| Passage problématique | Rouge | Rouge (#FF6B6B) |
|
||||
| Bouton Contester | Rouge (#DC3545) | Rouge (#F85149) |
|
||||
Et le contraste reste suffisant
|
||||
|
||||
Scénario: Accessibilité lecteur d'écran
|
||||
Étant donné que j'utilise un lecteur d'écran
|
||||
Quand je navigue dans la page de sanction
|
||||
Alors chaque section est clairement annoncée:
|
||||
"""
|
||||
Contenu modéré. Attention.
|
||||
Votre contenu "Mon podcast numéro 42" a été modéré.
|
||||
Catégorie violée: Haine et violence, Article 3 point 2.
|
||||
Raison: Propos discriminatoires envers un groupe.
|
||||
Passage problématique: 3 minutes 42 secondes à 4 minutes 15 secondes.
|
||||
Sanction: Strike 2 sur 4. Suspension 7 jours.
|
||||
Bouton: Contester cette décision.
|
||||
"""
|
||||
Et tous les éléments sont accessibles au clavier
|
||||
|
||||
# Coût et conformité
|
||||
|
||||
Scénario: Coût de la fonctionnalité
|
||||
Étant donné que l'interface sanctions et appel est en place
|
||||
Quand on évalue le coût
|
||||
Alors le développement est 100% interne (Flutter)
|
||||
Et aucun service tiers n'est utilisé
|
||||
Et le coût opérationnel est de 0€
|
||||
Et les emails de notification coûtent ~0.001€/email
|
||||
|
||||
Scénario: Conformité DSA - Transparence
|
||||
Étant donné que le système de sanction est en place
|
||||
Quand on vérifie la conformité DSA
|
||||
Alors chaque sanction contient:
|
||||
| élément DSA requis | présent |
|
||||
| Référence précise à la règle violée | ✓ |
|
||||
| Explication claire | ✓ |
|
||||
| Preuve (extrait + transcription) | ✓ |
|
||||
| Possibilité de recours | ✓ |
|
||||
| Délai de recours clairement indiqué | ✓ |
|
||||
| Réponse motivée au recours | ✓ |
|
||||
Et le système est conforme au Digital Services Act
|
||||
291
docs/domains/moderation/features/ui/signalement-ui.feature
Normal file
291
docs/domains/moderation/features/ui/signalement-ui.feature
Normal file
@@ -0,0 +1,291 @@
|
||||
# language: fr
|
||||
|
||||
@ui @moderation @signalement
|
||||
Fonctionnalité: Interface de signalement de contenu (Mobile)
|
||||
En tant qu'utilisateur de l'application mobile
|
||||
Je veux pouvoir signaler un contenu inapproprié facilement
|
||||
Afin de contribuer à améliorer la qualité de la plateforme
|
||||
|
||||
# 14.1 - Interface de signalement utilisateur
|
||||
|
||||
Contexte:
|
||||
Étant donné que je suis connecté à l'application mobile
|
||||
Et que je suis en train d'écouter un contenu
|
||||
|
||||
# Accès au formulaire de signalement
|
||||
|
||||
Scénario: Accéder au signalement depuis le player audio
|
||||
Étant donné que j'écoute un contenu audio
|
||||
Quand j'ouvre le menu "⋮" du player
|
||||
Alors je vois l'option "🚫 Signaler ce contenu"
|
||||
Et l'option est facilement accessible (3ème position)
|
||||
Et l'icône est rouge pour la visibilité
|
||||
|
||||
Scénario: Accéder au signalement depuis la page de détails
|
||||
Étant donné que je consulte la page de détails d'un contenu
|
||||
Quand j'ouvre le menu "⋮" en haut à droite
|
||||
Alors je vois l'option "🚫 Signaler ce contenu"
|
||||
Et je peux ouvrir le formulaire de signalement
|
||||
|
||||
Scénario: Accéder au signalement depuis l'historique d'écoute
|
||||
Étant donné que je consulte mon historique d'écoute
|
||||
Quand je fais un appui long sur un contenu
|
||||
Alors un menu contextuel s'affiche
|
||||
Et je vois l'option "🚫 Signaler"
|
||||
Et je peux signaler le contenu même si je ne l'écoute plus
|
||||
|
||||
# Formulaire de signalement - Design et UX
|
||||
|
||||
Scénario: Affichage du formulaire de signalement
|
||||
Étant donné que je clique sur "Signaler ce contenu"
|
||||
Quand le formulaire s'affiche
|
||||
Alors il apparaît en modal plein écran (iOS) ou bottom sheet (Android)
|
||||
Et le titre est "Signaler ce contenu"
|
||||
Et je vois le nom du contenu et le créateur en haut
|
||||
Et le formulaire contient:
|
||||
| élément | type | obligatoire |
|
||||
| Catégorie du problème | Liste déroulante | oui |
|
||||
| Commentaire | Zone texte | non* |
|
||||
| Bouton Annuler | Secondaire (gris) | - |
|
||||
| Bouton Envoyer | Primaire (rouge) | - |
|
||||
Et le bouton "Envoyer" est désactivé tant qu'aucune catégorie n'est sélectionnée
|
||||
|
||||
Scénario: Design responsive du formulaire
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Quand je vérifie l'adaptation de l'interface
|
||||
Alors sur petit écran (<375px), le texte est réduit mais lisible
|
||||
Et sur grand écran (>414px), le formulaire utilise l'espace disponible
|
||||
Et le clavier ne masque pas le bouton "Envoyer"
|
||||
Et je peux scroller si le contenu dépasse la hauteur de l'écran
|
||||
|
||||
# Liste des catégories avec icônes
|
||||
|
||||
Scénario: Affichage des 7 catégories prédéfinies
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Quand je clique sur "Catégorie du problème"
|
||||
Alors une liste déroulante s'affiche avec 7 options:
|
||||
| icône | catégorie | description visible en sous-titre |
|
||||
| 🚫 | Haine & violence | Incitation à la haine, discrimination |
|
||||
| 🔞 | Contenu sexuel | Pornographie, contenu explicite |
|
||||
| ⚖️ | Illégalité | Terrorisme, apologie de crimes |
|
||||
| 🎵 | Droits d'auteur | Musique/contenu protégé non autorisé |
|
||||
| 📧 | Spam | Publicité non sollicitée, répétition |
|
||||
| ❌ | Fausse information | Désinformation santé, sécurité routière |
|
||||
| 🔧 | Autre | Champ texte obligatoire si sélectionné |
|
||||
Et chaque option affiche l'icône, le titre et la description
|
||||
Et la description est en gris clair pour la hiérarchie visuelle
|
||||
|
||||
Scénario: Sélection d'une catégorie
|
||||
Étant donné que la liste des catégories est affichée
|
||||
Quand je sélectionne "🚫 Haine & violence"
|
||||
Alors la liste se ferme
|
||||
Et le champ "Catégorie du problème" affiche "🚫 Haine & violence"
|
||||
Et le bouton "Envoyer" s'active (devient rouge)
|
||||
Et je peux passer au champ commentaire (optionnel)
|
||||
|
||||
Scénario: Animation visuelle lors de la sélection
|
||||
Étant donné que je suis sur le formulaire de signalement
|
||||
Quand je sélectionne une catégorie
|
||||
Alors une animation de validation subtile s'affiche (✓ vert)
|
||||
Et le champ commentaire s'anime légèrement pour attirer l'attention
|
||||
Et l'UX est fluide et encourageante
|
||||
|
||||
# Catégorie "Autre" avec commentaire obligatoire
|
||||
|
||||
Scénario: Catégorie "Autre" rend le commentaire obligatoire
|
||||
Étant donné que le formulaire de signalement est affiché
|
||||
Quand je sélectionne "🔧 Autre"
|
||||
Alors le champ "Commentaire" affiche un astérisque rouge (*)
|
||||
Et le placeholder change en "Décrivez le problème (obligatoire)"
|
||||
Et une étiquette "Obligatoire" apparaît en rouge
|
||||
Et le bouton "Envoyer" reste désactivé tant que je n'ai pas saisi de commentaire
|
||||
|
||||
Scénario: Validation du commentaire obligatoire pour "Autre"
|
||||
Étant donné que j'ai sélectionné "🔧 Autre"
|
||||
Et que je n'ai pas rempli le champ commentaire
|
||||
Quand je clique sur "Envoyer"
|
||||
Alors un message d'erreur s'affiche sous le champ:
|
||||
"""
|
||||
Veuillez décrire le problème (minimum 10 caractères)
|
||||
"""
|
||||
Et le champ commentaire est mis en évidence en rouge
|
||||
Et le signalement n'est pas envoyé
|
||||
|
||||
# Champ commentaire - UX et validation
|
||||
|
||||
Scénario: Commentaire optionnel avec incitation
|
||||
Étant donné que j'ai sélectionné une catégorie autre que "Autre"
|
||||
Quand je consulte le champ "Commentaire"
|
||||
Alors le placeholder indique "Décrivez le problème (optionnel mais recommandé)"
|
||||
Et aucun astérisque rouge n'est affiché
|
||||
Et un compteur "0/500" s'affiche en bas à droite
|
||||
Et l'incitation encourage à fournir des détails sans obliger
|
||||
|
||||
Scénario: Compteur de caractères en temps réel
|
||||
Étant donné que je suis dans le champ commentaire
|
||||
Quand je tape du texte
|
||||
Alors le compteur se met à jour en temps réel: "42/500"
|
||||
Et quand j'atteins 450 caractères, le compteur passe en orange
|
||||
Et quand j'atteins 490 caractères, le compteur passe en rouge
|
||||
Et à 500 caractères, le clavier bloque la saisie
|
||||
Et un message s'affiche: "Limite atteinte"
|
||||
|
||||
Scénario: Limite stricte de 500 caractères
|
||||
Étant donné que j'ai saisi 500 caractères dans le commentaire
|
||||
Quand j'essaie de taper un caractère supplémentaire
|
||||
Alors le caractère n'est pas accepté
|
||||
Et le clavier vibre légèrement (feedback haptique)
|
||||
Et le compteur reste à "500/500" en rouge
|
||||
|
||||
# Envoi du signalement
|
||||
|
||||
Scénario: Envoi d'un signalement sans commentaire
|
||||
Étant donné que j'ai sélectionné "📧 Spam"
|
||||
Et que je n'ai pas rempli le champ commentaire
|
||||
Quand je clique sur "Envoyer"
|
||||
Alors un loader s'affiche sur le bouton "Envoyer"
|
||||
Et le formulaire se ferme après 1 seconde
|
||||
Et le signalement est envoyé avec succès
|
||||
Et aucune erreur ne s'affiche
|
||||
|
||||
Scénario: Envoi d'un signalement avec commentaire
|
||||
Étant donné que j'ai sélectionné "🚫 Haine & violence"
|
||||
Et que j'ai saisi "Propos discriminatoires à 2:30"
|
||||
Quand je clique sur "Envoyer"
|
||||
Alors un loader s'affiche pendant l'envoi
|
||||
Et le formulaire se ferme
|
||||
Et le signalement est envoyé avec le commentaire
|
||||
Et le commentaire sera visible par les modérateurs
|
||||
|
||||
Scénario: Gestion d'erreur lors de l'envoi
|
||||
Étant donné que j'ai rempli le formulaire de signalement
|
||||
Et que ma connexion réseau est perdue
|
||||
Quand je clique sur "Envoyer"
|
||||
Alors un message d'erreur s'affiche:
|
||||
"""
|
||||
Impossible d'envoyer le signalement.
|
||||
Vérifiez votre connexion internet.
|
||||
"""
|
||||
Et le formulaire reste ouvert avec mes données
|
||||
Et je peux réessayer sans perdre ma saisie
|
||||
|
||||
# Toast de confirmation
|
||||
|
||||
Scénario: Toast de confirmation après envoi réussi
|
||||
Étant donné que j'ai envoyé un signalement
|
||||
Quand le signalement est enregistré avec succès
|
||||
Alors un toast notification s'affiche en bas de l'écran
|
||||
Et le toast contient:
|
||||
| élément | contenu |
|
||||
| Icône | ✓ (vert) |
|
||||
| Message | Signalement envoyé. Examen sous 24-48h. |
|
||||
| Bouton | Voir mes signalements |
|
||||
| Bouton fermer | × (croix en haut à droite) |
|
||||
Et le toast s'affiche pendant 5 secondes
|
||||
Et je peux le fermer manuellement
|
||||
|
||||
Scénario: Animation du toast
|
||||
Étant donné que le signalement est envoyé
|
||||
Quand le toast s'affiche
|
||||
Alors il apparaît avec une animation slide-up depuis le bas
|
||||
Et après 5 secondes, il disparaît avec une animation fade-out
|
||||
Et l'animation est fluide et professionnelle
|
||||
|
||||
Scénario: Redirection vers l'historique depuis le toast
|
||||
Étant donné que le toast de confirmation est affiché
|
||||
Quand je clique sur "Voir mes signalements"
|
||||
Alors le toast se ferme
|
||||
Et je suis redirigé vers "Profil > Mes signalements"
|
||||
Et je vois mon nouveau signalement en tête de liste
|
||||
Et le statut est "En cours 🔍"
|
||||
|
||||
# Modal de découverte au premier signalement
|
||||
|
||||
Scénario: Découverte du système de badges au 1er signalement
|
||||
Étant donné que je viens d'envoyer mon tout premier signalement
|
||||
Et que le toast de confirmation s'est affiché
|
||||
Quand 2 secondes se sont écoulées
|
||||
Alors une modal d'information s'affiche par-dessus
|
||||
Et la modal contient le titre "🎯 Bravo ! Vous contribuez à une communauté plus saine"
|
||||
Et la modal explique le système de badges:
|
||||
"""
|
||||
🥉 Bronze : 5 signalements validés
|
||||
🥈 Argent : 20 signalements validés
|
||||
🥇 Or : 50 signalements validés → -50% Premium 3 mois
|
||||
"""
|
||||
Et la modal contient 2 boutons:
|
||||
| bouton | action |
|
||||
| En savoir plus | Ouvre page dédiée badges |
|
||||
| J'ai compris | Ferme la modal |
|
||||
Et cette modal ne se réaffiche jamais
|
||||
|
||||
Scénario: Modal responsive et accessible
|
||||
Étant donné que la modal de découverte s'affiche
|
||||
Quand je vérifie l'accessibilité
|
||||
Alors la modal est centrée sur l'écran
|
||||
Et le fond est assombri (overlay semi-transparent)
|
||||
Et je ne peux pas interagir avec l'écran en arrière-plan
|
||||
Et je peux fermer en cliquant hors de la modal
|
||||
Et le texte est lisible (contraste WCAG AA)
|
||||
|
||||
# Limite de signalements déjà effectués
|
||||
|
||||
Scénario: Impossible de signaler deux fois le même contenu
|
||||
Étant donné que j'ai déjà signalé ce contenu il y a 3 jours
|
||||
Quand j'ouvre le menu "⋮" du contenu
|
||||
Alors l'option "Signaler" est désactivée (grisée)
|
||||
Et un tooltip s'affiche: "Vous avez déjà signalé ce contenu"
|
||||
Et je peux consulter mon signalement précédent via le tooltip (lien)
|
||||
|
||||
Scénario: Redirection vers le signalement existant
|
||||
Étant donné que j'ai déjà signalé ce contenu
|
||||
Et que l'option "Signaler" est désactivée
|
||||
Quand je clique sur le tooltip "Vous avez déjà signalé ce contenu"
|
||||
Alors je suis redirigé vers "Mes signalements"
|
||||
Et le signalement concerné est mis en évidence
|
||||
Et je vois le statut actuel: "En cours 🔍" / "Traité ✓" / "Rejeté ✗"
|
||||
|
||||
# Accessibilité et dark mode
|
||||
|
||||
Scénario: Support du dark mode
|
||||
Étant donné que j'ai activé le dark mode sur mon téléphone
|
||||
Quand j'ouvre le formulaire de signalement
|
||||
Alors le formulaire s'adapte au dark mode:
|
||||
| élément | couleur dark mode |
|
||||
| Fond de la modal | Gris foncé (#1E1E1E) |
|
||||
| Texte principal | Blanc (#FFFFFF) |
|
||||
| Texte secondaire | Gris clair (#B0B0B0) |
|
||||
| Bordures | Gris moyen (#3E3E3E) |
|
||||
| Bouton Envoyer | Rouge (#FF4444) |
|
||||
Et le contraste reste suffisant (WCAG AA)
|
||||
|
||||
Scénario: Accessibilité pour lecteur d'écran
|
||||
Étant donné que j'utilise un lecteur d'écran (VoiceOver/TalkBack)
|
||||
Quand je navigue dans le formulaire de signalement
|
||||
Alors chaque élément a un label descriptif:
|
||||
| élément | label lecteur d'écran |
|
||||
| Bouton menu | "Menu du contenu" |
|
||||
| Option signaler | "Signaler ce contenu" |
|
||||
| Liste catégories | "Sélectionner une catégorie de problème" |
|
||||
| Champ commentaire | "Commentaire optionnel, 500 caractères maximum" |
|
||||
| Bouton Envoyer | "Envoyer le signalement" |
|
||||
Et je peux naviguer au clavier (tab/shift-tab)
|
||||
Et tous les états (activé/désactivé) sont annoncés
|
||||
|
||||
# Coût et performance
|
||||
|
||||
Scénario: Performance de l'interface
|
||||
Étant donné que j'ouvre le formulaire de signalement
|
||||
Quand je mesure les performances
|
||||
Alors le formulaire s'affiche en <300ms
|
||||
Et l'animation est fluide (60 FPS)
|
||||
Et l'envoi du signalement prend <2 secondes
|
||||
Et l'UX est instantanée et réactive
|
||||
|
||||
Scénario: Coût de développement
|
||||
Étant donné que l'interface de signalement est développée
|
||||
Quand on évalue le coût
|
||||
Alors le développement est 100% interne (Flutter)
|
||||
Et aucun service tiers n'est utilisé
|
||||
Et le coût opérationnel est de 0€
|
||||
Et l'interface est native iOS et Android
|
||||
75
docs/domains/moderation/flows/moderation-signalement.md
Normal file
75
docs/domains/moderation/flows/moderation-signalement.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Flux de modération - Processus de signalement
|
||||
|
||||
📖 Voir [Règles métier - Section 14 : Modération Flows](../rules/moderation-flows.md)
|
||||
|
||||
## Diagramme
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([Utilisateur signale un contenu]) --> Form[Formulaire signalement<br/>7 catégories + commentaire optionnel]
|
||||
Form --> Submit[Envoi signalement]
|
||||
Submit --> Toast[Toast confirmation<br/>Traitement sous 24-48h]
|
||||
|
||||
Submit --> Queue[Ajout file d'attente]
|
||||
Queue --> Transcription[Transcription automatique<br/>Whisper large-v3]
|
||||
Transcription --> AI[Analyse IA<br/>Score confiance 0-100%]
|
||||
|
||||
AI --> Priority{Calcul priorité}
|
||||
Priority -->|Score ≥90| Critical[🔴 CRITIQUE<br/>Traitement <2h]
|
||||
Priority -->|Score 70-89| High[🟠 HAUTE<br/>Traitement <24h]
|
||||
Priority -->|Score 40-69| Medium[🟡 MOYENNE<br/>Traitement <24h]
|
||||
Priority -->|Score <40| Low[⚪ BASSE<br/>Traitement <72h]
|
||||
|
||||
Critical --> AutoAction{Score IA >95%<br/>+ catégorie évidente?}
|
||||
AutoAction -->|Oui| AutoSanction[Action automatique]
|
||||
AutoAction -->|Non| ModReview
|
||||
|
||||
High --> ModReview[Examen modérateur]
|
||||
Medium --> ModReview
|
||||
Low --> ModReview
|
||||
|
||||
ModReview --> Decision{Décision}
|
||||
|
||||
Decision -->|Validé| Sanction[Application sanction<br/>Strike/Suspension/Ban]
|
||||
Decision -->|Rejeté| Reject[Signalement rejeté]
|
||||
|
||||
AutoSanction --> Notify
|
||||
Sanction --> Notify[Notification créateur<br/>Email + Push + In-app]
|
||||
|
||||
Notify --> Creator{Créateur réagit?}
|
||||
Creator -->|Conteste<br/>sous 7 jours| Appeal[Formulaire d'appel<br/>Ticket généré]
|
||||
Creator -->|Accepte ou<br/>pas de réaction| Final1[Sanction définitive]
|
||||
|
||||
Appeal --> SeniorMod[Modérateur senior<br/>Examen sous 72h]
|
||||
SeniorMod --> AppealDecision{Décision appel}
|
||||
|
||||
AppealDecision -->|Accepté| Overturn[Annulation sanction<br/>Strike retiré]
|
||||
AppealDecision -->|Rejeté| Maintain[Maintien sanction]
|
||||
|
||||
Overturn --> Final2[Décision définitive]
|
||||
Maintain --> Final2
|
||||
|
||||
Reject --> NotifyReporter[Notification signaleur<br/>Mise à jour historique]
|
||||
|
||||
Final1 --> End([Fin du processus])
|
||||
Final2 --> End
|
||||
NotifyReporter --> End
|
||||
|
||||
style Critical fill:#ff6b6b,stroke:#c92a2a,color:#fff
|
||||
style High fill:#ff922b,stroke:#d9480f,color:#fff
|
||||
style Medium fill:#ffd43b,stroke:#f59f00,color:#000
|
||||
style Low fill:#e9ecef,stroke:#adb5bd,color:#000
|
||||
style Sanction fill:#fa5252,stroke:#c92a2a,color:#fff
|
||||
style Overturn fill:#51cf66,stroke:#2b8a3e,color:#fff
|
||||
style AutoSanction fill:#ff6b6b,stroke:#c92a2a,color:#fff
|
||||
```
|
||||
|
||||
## Légende
|
||||
|
||||
**Priorités de traitement** :
|
||||
- 🔴 **CRITIQUE** (score ≥90) : <2h - Violence, suicide, danger immédiat
|
||||
- 🟠 **HAUTE** (70-89) : <24h - Haine, harcèlement
|
||||
- 🟡 **MOYENNE** (40-69) : <24h - Spam, contenu inapproprié
|
||||
- ⚪ **BASSE** (<40) : <72h - Qualité audio, tags incorrects
|
||||
|
||||
**Calcul priorité** : `(Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_signaleur × 0.1)`
|
||||
633
docs/domains/moderation/rules/autres-comportements.md
Normal file
633
docs/domains/moderation/rules/autres-comportements.md
Normal file
@@ -0,0 +1,633 @@
|
||||
## 15. Autres comportements
|
||||
|
||||
### 15.1 Partage de contenu
|
||||
|
||||
**Décision** : Système de partage complet avec web player
|
||||
|
||||
#### 15.1.1 Bouton "Partager"
|
||||
|
||||
**Disponibilité** : Partout dans l'application
|
||||
|
||||
**Emplacements** :
|
||||
- Player en lecture (bouton dans contrôles)
|
||||
- Page profil créateur (sur chaque contenu)
|
||||
- Liste de recherche (menu contextuel)
|
||||
- Historique personnel
|
||||
|
||||
**Icône** : ⬆️ (universelle iOS/Android)
|
||||
|
||||
**Menu options** :
|
||||
- Copier le lien
|
||||
- WhatsApp
|
||||
- Email
|
||||
- SMS
|
||||
- Plus... (sheet natif OS)
|
||||
|
||||
**Justification** :
|
||||
- Viralité = croissance organique gratuite
|
||||
- Aucune friction, partage universel
|
||||
|
||||
---
|
||||
|
||||
#### 15.1.2 Comportement du lien partagé
|
||||
|
||||
**Format URL** : `https://roadwave.fr/share/c/[content_id]`
|
||||
|
||||
**Comportement multi-plateforme** :
|
||||
|
||||
```
|
||||
User clique lien partagé
|
||||
↓
|
||||
Page web responsive
|
||||
↓
|
||||
┌─────────────────────────────────┐
|
||||
│ Si app installée │
|
||||
│ → Deep link (ouverture directe) │
|
||||
└─────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────┐
|
||||
│ Si app non installée │
|
||||
│ → Web player + CTA téléchargement│
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Contenu de la page web** :
|
||||
|
||||
```html
|
||||
┌───────────────────────────────────────┐
|
||||
│ RoadWave │
|
||||
├───────────────────────────────────────┤
|
||||
│ [Image cover 16:9] │
|
||||
│ │
|
||||
│ 📻 Titre du contenu │
|
||||
│ Par @créateur · 12 min · 🎧 2.3K │
|
||||
│ │
|
||||
│ 📍 Paris 5e · Ancré │
|
||||
│ 🏷️ #Voyage #Histoire │
|
||||
│ │
|
||||
│ Description : Lorem ipsum... │
|
||||
│ │
|
||||
│ [▶️ Écouter maintenant] │
|
||||
│ (Player HTML5 si contenu public) │
|
||||
│ │
|
||||
│ ────────────────────────────────── │
|
||||
│ │
|
||||
│ 📱 Télécharger l'app RoadWave │
|
||||
│ [App Store] [Google Play] │
|
||||
│ │
|
||||
│ [Voir le profil de @créateur] │
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Métadonnées Open Graph (SEO)** :
|
||||
|
||||
```html
|
||||
<meta property="og:title" content="[Titre contenu] - RoadWave">
|
||||
<meta property="og:description" content="[Description ou extrait]">
|
||||
<meta property="og:image" content="[URL cover image]">
|
||||
<meta property="og:audio" content="[URL audio si public]">
|
||||
<meta property="og:type" content="music.song">
|
||||
<meta property="og:site_name" content="RoadWave">
|
||||
<meta name="twitter:card" content="player">
|
||||
<meta name="twitter:player" content="https://roadwave.fr/player/[content_id]">
|
||||
```
|
||||
|
||||
**Deep linking** :
|
||||
- iOS : Universal Links (configuration `apple-app-site-association`)
|
||||
- Android : App Links (configuration `assetlinks.json`)
|
||||
- URL scheme : `roadwave://content/[content_id]`
|
||||
|
||||
**Justification** :
|
||||
- Meilleure viralité (partage social optimisé)
|
||||
- SEO (contenus indexés Google)
|
||||
- UX optimale (web + app)
|
||||
- Coût : 0€ (backend simple + CDN existant)
|
||||
|
||||
---
|
||||
|
||||
#### 15.1.3 Contenus Premium partagés
|
||||
|
||||
**Décision** : Preview 30 secondes + paywall
|
||||
|
||||
**Comportement** :
|
||||
|
||||
1. User clique lien contenu Premium partagé
|
||||
2. Page web affiche badge "👑 Contenu Premium"
|
||||
3. Player démarre automatiquement
|
||||
4. Après **30 secondes exactement** :
|
||||
- Fade out audio (2 secondes)
|
||||
- Overlay apparaît :
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 👑 Contenu réservé Premium │
|
||||
│ │
|
||||
│ Profitez de ce contenu complet │
|
||||
│ et de milliers d'autres │
|
||||
│ sans publicité │
|
||||
│ │
|
||||
│ [Passer Premium - 4.99€/mois] │
|
||||
│ [Télécharger l'app] │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
5. Utilisateur peut :
|
||||
- S'abonner Premium (redirection web Mangopay)
|
||||
- Télécharger l'app (redirection stores)
|
||||
- Rejouer les 30 premières secondes (illimité)
|
||||
|
||||
**Tracking** :
|
||||
- Métriques créateur : "Partages Premium" + "Conversions Premium"
|
||||
- Créateur touche sa part si conversion (70%)
|
||||
|
||||
**Justification** :
|
||||
- Équilibre viralité / monétisation
|
||||
- 30s = assez pour donner envie, pas assez pour satisfaire
|
||||
- Protège revenus créateurs
|
||||
|
||||
---
|
||||
|
||||
### 15.2 Profil créateur
|
||||
|
||||
**Décision** : Profil public complet et transparent
|
||||
|
||||
#### 15.2.1 Structure de la page profil
|
||||
|
||||
**URL** : `https://roadwave.fr/@[pseudo]`
|
||||
|
||||
**Layout** :
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────┐
|
||||
│ [Photo profil 120×120] │
|
||||
│ @pseudo ✓ │
|
||||
│ [Badge vérifié si applicable] │
|
||||
│ │
|
||||
│ Bio : Lorem ipsum dolor sit amet... │
|
||||
│ (300 caractères max) │
|
||||
│ │
|
||||
│ 🎧 1.2K abonnés │
|
||||
│ 📻 42 contenus │
|
||||
│ ⏱️ 18h de contenu créé │
|
||||
│ 🔊 54K écoutes totales │
|
||||
│ │
|
||||
│ [S'abonner] [Partager profil] [•••] │
|
||||
│ │
|
||||
│ ──────────────────────────────────── │
|
||||
│ │
|
||||
│ Contenus ▼ [Plus récents ▼] │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────┐ │
|
||||
│ │ [Cover] Titre contenu 1 │ │
|
||||
│ │ 12 min · 🎧 2.3K · 📍 Paris │ │
|
||||
│ │ [▶️] │ │
|
||||
│ └──────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────┐ │
|
||||
│ │ [Cover] Titre contenu 2 │ │
|
||||
│ │ 8 min · 🎧 5.1K · 📍 Lyon │ │
|
||||
│ │ [▶️] │ │
|
||||
│ └──────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [Charger plus] │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Informations affichées** :
|
||||
|
||||
| Élément | Visibilité | Détails |
|
||||
|---------|------------|---------|
|
||||
| **Photo + pseudo** | ✅ Public | Identité visuelle |
|
||||
| **Badge vérifié ✓** | ✅ Public (si applicable) | Compte authentique |
|
||||
| **Bio** | ✅ Public | 0-300 caractères, markdown basique (gras, italique, liens) |
|
||||
| **Nombre abonnés** | ✅ Public | Arrondi si >1000 (ex: 1.2K, 54K) |
|
||||
| **Nombre contenus** | ✅ Public | Exact |
|
||||
| **Durée totale créée** | ✅ Public | Arrondi en heures (ex: 18h, 142h) |
|
||||
| **Écoutes totales** | ✅ Public | Arrondi (ex: 54K, 1.2M) |
|
||||
| **Liste abonnés** | ❌ Privé | Protection vie privée (RGPD) |
|
||||
| **Revenus** | ❌ Privé | Confidentialité financière |
|
||||
| **Localisation précise** | ❌ Privé | Sécurité |
|
||||
| **Email** | ❌ Privé | Anti-spam |
|
||||
|
||||
**Tri des contenus** :
|
||||
|
||||
| Option | Comportement |
|
||||
|--------|--------------|
|
||||
| **Plus récents** | Date publication DESC (défaut) |
|
||||
| **Plus populaires** | Écoutes complètes × (1 + (date_publication - now) / 90 jours) |
|
||||
| **Plus anciens** | Date publication ASC |
|
||||
| **Par tag** | Filtre multi-sélection tags |
|
||||
|
||||
**Recherche locale** :
|
||||
- Barre recherche dans profil : "Rechercher dans les contenus de @pseudo"
|
||||
- Recherche full-text sur titres + descriptions
|
||||
|
||||
**Actions menu [•••]** :
|
||||
- Partager profil
|
||||
- Signaler profil (spam, usurpation)
|
||||
- Bloquer créateur (masque tous ses contenus)
|
||||
|
||||
---
|
||||
|
||||
#### 15.2.2 Statistiques publiques
|
||||
|
||||
**Décision** : Stats arrondies et motivantes
|
||||
|
||||
**Affichage public** :
|
||||
|
||||
| Métrique | Format affichage | Exemple |
|
||||
|----------|------------------|---------|
|
||||
| **Abonnés** | Exact si <1000, arrondi sinon | 342 / 1.2K / 54K / 1.2M |
|
||||
| **Écoutes totales** | Arrondi dès 1000 | 842 / 5.4K / 142K / 2.1M |
|
||||
| **Contenus publiés** | Exact | 42 contenus |
|
||||
| **Durée totale** | Arrondi en heures | 18h / 142h de contenu |
|
||||
|
||||
**Métriques PRIVÉES (créateur uniquement)** :
|
||||
|
||||
| Métrique | Disponible dans dashboard créateur |
|
||||
|----------|-------------------------------------|
|
||||
| **Taux complétion moyen** | 78% (écoutes >80% / écoutes totales) |
|
||||
| **Évolution abonnés** | Graphique 30j / 90j / 1 an |
|
||||
| **Écoutes par contenu** | Tableau détaillé |
|
||||
| **Revenus** | Dashboard monétisation dédié |
|
||||
| **Taux conversion Premium** | Partages → conversions |
|
||||
| **Démographie** | Âge / zone géo (agrégée, anonymisée) |
|
||||
|
||||
**Justification** :
|
||||
- Arrondi = évite comparaisons anxiogènes
|
||||
- Preuve sociale pour nouveaux auditeurs (trust)
|
||||
- Gamification douce (motivation créateurs)
|
||||
- Privacy by design
|
||||
|
||||
---
|
||||
|
||||
#### 15.2.3 Badge vérifié
|
||||
|
||||
**Décision** : Badge unique ✓ (vérifié officiel)
|
||||
|
||||
**Critères d'attribution** (au moins UN des critères) :
|
||||
|
||||
1. **KYC monétisation validé** : identité vérifiée via Mangopay KYC
|
||||
2. **Célébrité / Média officiel** : validation manuelle équipe RoadWave
|
||||
3. **Communauté significative** : ≥10K abonnés + compte actif >6 mois
|
||||
|
||||
**Affichage** :
|
||||
- Badge bleu **✓** accolé au pseudo (partout : profil, player, recherche)
|
||||
- Tooltip au survol/appui long : "Compte vérifié"
|
||||
|
||||
**Processus d'obtention** :
|
||||
|
||||
| Type | Processus |
|
||||
|------|-----------|
|
||||
| **Automatique (KYC)** | Badge attribué dès validation documents Mangopay |
|
||||
| **Manuel (célébrité)** | Formulaire demande → équipe vérifie identité → validation 48-72h |
|
||||
| **Automatique (10K)** | Badge attribué automatiquement à 10K abonnés si compte >6 mois |
|
||||
|
||||
**Retrait du badge** :
|
||||
- Suspension monétisation → badge retiré temporairement
|
||||
- Strikes multiples → badge retiré définitivement
|
||||
- Usurpation identité détectée → ban + retrait
|
||||
|
||||
**Justification** :
|
||||
- Combat usurpations d'identité
|
||||
- Trust auditeurs (surtout pour médias/personnalités)
|
||||
- Simplicité (1 seul badge, pas de gamification excessive)
|
||||
- Coût : 0€ (champ boolean `verified` en DB)
|
||||
|
||||
---
|
||||
|
||||
### 15.3 Recherche
|
||||
|
||||
**Décision** : Recherche full-text + géo + filtres avancés
|
||||
|
||||
#### 15.3.1 Recherche par mot-clé
|
||||
|
||||
**Implémentation** : PostgreSQL full-text search (français)
|
||||
|
||||
**Configuration technique** :
|
||||
|
||||
```sql
|
||||
-- Index full-text optimisé français
|
||||
CREATE INDEX idx_content_search ON contents
|
||||
USING GIN(
|
||||
to_tsvector('french',
|
||||
coalesce(title, '') || ' ' ||
|
||||
coalesce(description, '') || ' ' ||
|
||||
coalesce(creator_pseudo, '')
|
||||
)
|
||||
);
|
||||
|
||||
-- Recherche avec ranking
|
||||
SELECT
|
||||
c.*,
|
||||
ts_rank(
|
||||
to_tsvector('french', c.title || ' ' || c.description),
|
||||
plainto_tsquery('french', $search_query)
|
||||
) AS rank
|
||||
FROM contents c
|
||||
WHERE to_tsvector('french', c.title || ' ' || c.description)
|
||||
@@ plainto_tsquery('french', $search_query)
|
||||
ORDER BY rank DESC, listen_count DESC
|
||||
LIMIT 20;
|
||||
```
|
||||
|
||||
**Champs indexés** :
|
||||
- Titre du contenu (poids × 3)
|
||||
- Description (poids × 1)
|
||||
- Pseudo créateur (poids × 2)
|
||||
- Tags (poids × 1.5)
|
||||
|
||||
**Fonctionnalités** :
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Stemming français** | "voyages" trouve "voyage", "voyager", etc. |
|
||||
| **Correction auto** | Suggestion si 0 résultat |
|
||||
| **Recherches populaires** | "Essayez plutôt : balade paris, audio-guide louvre" |
|
||||
| **Historique personnel** | 10 dernières recherches sauvegardées |
|
||||
| **Autocomplete** | Suggestions pendant frappe (top 5) |
|
||||
|
||||
**Coût** : 0€ (PostgreSQL natif)
|
||||
|
||||
**Migration future** :
|
||||
- Si >100K contenus : Meilisearch (typo-tolerance avancée, ~20-50€/mois)
|
||||
- Si >1M contenus : Elasticsearch cluster
|
||||
|
||||
**Justification** :
|
||||
- PostgreSQL full-text = performant jusqu'à 500K contenus
|
||||
- Stemming français natif
|
||||
- 0€, aucune dépendance externe
|
||||
|
||||
---
|
||||
|
||||
#### 15.3.2 Recherche géographique
|
||||
|
||||
**Décision** : Recherche lieu + rayon paramétrable
|
||||
|
||||
**Interface utilisateur** :
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ 🔍 Recherche contenu... │
|
||||
├─────────────────────────────────────┤
|
||||
│ <20><> Lieu │
|
||||
│ [Paris, France ▼] │
|
||||
│ · Autour de moi (GPS actuel) │
|
||||
│ · Entrer une adresse/ville │
|
||||
│ │
|
||||
│ 📏 Rayon de recherche │
|
||||
│ [●─────────────────] 50 km │
|
||||
│ (curseur 5 km → 500 km) │
|
||||
│ │
|
||||
│ 🗺️ [Afficher sur carte] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Géocodage** :
|
||||
|
||||
| Service | Usage | Coût |
|
||||
|---------|-------|------|
|
||||
| **Nominatim (OSM)** | MVP (API publique) | 0€ (rate limit 1 req/s) |
|
||||
| **Nominatim self-hosted** | Scale (Docker) | 20-50€/mois VPS |
|
||||
| **Mapbox Geocoding** | Fallback premium | 0.50€ / 1000 requêtes |
|
||||
|
||||
**Processus de recherche géo** :
|
||||
|
||||
1. User tape "Louvre" ou "Paris"
|
||||
2. Autocomplete via Nominatim → liste suggestions
|
||||
3. User sélectionne → récupération coordonnées (lat, lon)
|
||||
4. Requête PostGIS :
|
||||
|
||||
```sql
|
||||
SELECT c.*,
|
||||
ST_Distance(c.location::geography, ST_Point($lon, $lat)::geography) AS distance
|
||||
FROM contents c
|
||||
WHERE ST_DWithin(
|
||||
c.location::geography,
|
||||
ST_Point($lon, $lat)::geography,
|
||||
$radius_meters
|
||||
)
|
||||
ORDER BY distance ASC;
|
||||
```
|
||||
|
||||
**Affichage résultats** :
|
||||
- Tri par défaut : distance croissante
|
||||
- Indication distance : "À 2.3 km" / "À 15 km" / "À 142 km"
|
||||
- Option carte : markers cliquables (clustering si >50 résultats)
|
||||
|
||||
**Coût** :
|
||||
- MVP : 0€ (Nominatim public)
|
||||
- Scale : 20-50€/mois (Nominatim self-hosted Docker)
|
||||
|
||||
**Justification** :
|
||||
- Essentiel pour tourisme / planification trajet
|
||||
- OpenStreetMap = pas de dépendance Google
|
||||
- PostGIS = performant (index GIST natif)
|
||||
|
||||
---
|
||||
|
||||
#### 15.3.3 Filtres avancés
|
||||
|
||||
**Décision** : 7 catégories de filtres combinables
|
||||
|
||||
**Interface filtres** :
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Filtres [×] │
|
||||
├─────────────────────────────────────┤
|
||||
│ Type de contenu │
|
||||
│ ☐ Contenu court (<5 min) │
|
||||
│ ☐ Podcast (>5 min) │
|
||||
│ ☐ Radio live │
|
||||
│ ☐ Audio-guide │
|
||||
│ │
|
||||
│ Durée │
|
||||
│ ○ Toutes durées │
|
||||
│ ○ <5 min │
|
||||
│ ○ 5-15 min │
|
||||
│ ○ 15-30 min │
|
||||
│ ○ >30 min │
|
||||
│ │
|
||||
│ Classification âge │
|
||||
│ ☐ Tout public │
|
||||
│ ☐ 13+ │
|
||||
│ ☐ 16+ │
|
||||
│ ☐ 18+ │
|
||||
│ │
|
||||
│ Géo-pertinence │
|
||||
│ ☐ Ancré (lieu précis) │
|
||||
│ ☐ Contextuel (zone large) │
|
||||
│ ☐ Neutre (national) │
|
||||
│ │
|
||||
│ Tags (multi-sélection) │
|
||||
│ ☐ Automobile ☐ Voyage │
|
||||
│ ☐ Famille ☐ Histoire │
|
||||
│ ☐ Économie ☐ Sciences │
|
||||
│ ... (liste complète tags) │
|
||||
│ │
|
||||
│ Date de publication │
|
||||
│ ○ Toutes dates │
|
||||
│ ○ Dernières 24h │
|
||||
│ ○ Cette semaine │
|
||||
│ ○ Ce mois │
|
||||
│ ○ Cette année │
|
||||
│ │
|
||||
│ Abonnement │
|
||||
│ ○ Tous les contenus │
|
||||
│ ○ Gratuits uniquement │
|
||||
│ ○ Premium uniquement 👑 │
|
||||
│ │
|
||||
│ ────────────────────────────── │
|
||||
│ [Réinitialiser] [Appliquer] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Options de tri** :
|
||||
|
||||
| Tri | Algorithme |
|
||||
|-----|-----------|
|
||||
| **Pertinence** | Score recherche × (1 + log(listen_count + 1)) |
|
||||
| **Popularité** | Écoutes complètes derniers 30j DESC |
|
||||
| **Récent** | Date publication DESC |
|
||||
| **Proximité** | Distance GPS ASC (si recherche géo active) |
|
||||
| **Durée** | Durée audio ASC ou DESC |
|
||||
|
||||
**Sauvegarde de recherches** :
|
||||
|
||||
- Bouton "💾 Sauvegarder cette recherche"
|
||||
- Nom personnalisable : "Podcasts voyage Paris"
|
||||
- Maximum **5 recherches sauvegardées**
|
||||
- Accès rapide : onglet "Recherches sauvegardées" dans page recherche
|
||||
- Notifications optionnelles : "3 nouveaux contenus dans 'Podcasts voyage Paris'"
|
||||
|
||||
**Performances** :
|
||||
|
||||
```sql
|
||||
-- Index composites pour filtres
|
||||
CREATE INDEX idx_content_filters ON contents (
|
||||
content_type,
|
||||
duration,
|
||||
age_rating,
|
||||
geo_type,
|
||||
published_at
|
||||
);
|
||||
|
||||
-- Index GIN pour tags
|
||||
CREATE INDEX idx_content_tags ON contents USING GIN(tags);
|
||||
```
|
||||
|
||||
**Coût** : 0€ (PostgreSQL + index standards)
|
||||
|
||||
**Justification** :
|
||||
- Filtres essentiels pour découvrabilité
|
||||
- Combinables = puissance maximale
|
||||
- Sauvegarde = gain temps utilisateurs réguliers
|
||||
|
||||
---
|
||||
|
||||
#### 15.3.4 Page de résultats
|
||||
|
||||
**Décision** : Liste avec previews enrichies
|
||||
|
||||
**Layout résultats** :
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 🔍 "voyage paris" │
|
||||
│ 42 résultats · Tri : Pertinence ▼ │
|
||||
│ [Filtres] [Carte] │
|
||||
├─────────────────────────────────────────┤
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ [Cover ] Balade à Paris │ │
|
||||
│ │ [16:9 ] @paris_stories ✓ │ │
|
||||
│ │ [Image ] 12 min · 🎧 2.3K │ │
|
||||
│ │ 📍 Paris 5e · Ancré │ │
|
||||
│ │ 🏷️ #Voyage #Histoire │ │
|
||||
│ │ [▶️ Écouter] [⋮] │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ [Cover ] Secrets Montmartre │ │
|
||||
│ │ [16:9 ] @explore_paris │ │
|
||||
│ │ [Image ] 8 min · 🎧 5.1K │ │
|
||||
│ │ 📍 Paris 18e · Guide │ │
|
||||
│ │ 🏷️ #Voyage #Art │ │
|
||||
│ │ [▶️ Écouter] [⋮] │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [Charger plus] (20 suivants) │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Informations par résultat** :
|
||||
|
||||
| Élément | Affichage |
|
||||
|---------|-----------|
|
||||
| **Cover image** | 16:9, 120×68 px, lazy loading |
|
||||
| **Titre** | Tronqué 2 lignes max |
|
||||
| **Créateur** | @pseudo + badge ✓ si vérifié, cliquable → profil |
|
||||
| **Durée** | Format : "3 min" / "12 min" / "1h 24 min" |
|
||||
| **Écoutes** | Arrondi : "2.3K" / "54K" / "1.2M" |
|
||||
| **Localisation** | Ville + type géo (Ancré/Contextuel/Neutre) |
|
||||
| **Tags** | Maximum 3 premiers tags |
|
||||
| **Badge Premium** | 👑 si contenu premium |
|
||||
| **Distance** | Si recherche géo : "À 2.3 km" |
|
||||
|
||||
**Actions contextuelles [⋮]** :
|
||||
- Partager
|
||||
- Ajouter à une playlist (future feature)
|
||||
- Télécharger (offline)
|
||||
- Signaler
|
||||
|
||||
**Pagination** :
|
||||
- **20 résultats** par page
|
||||
- Infinite scroll (charger automatiquement si scroll >80%)
|
||||
- Bouton "Charger 20 suivants" en bas (fallback si scroll auto désactivé)
|
||||
|
||||
**Vue carte (alternative)** :
|
||||
- Bouton toggle "Liste / Carte"
|
||||
- Map Leaflet (OpenStreetMap)
|
||||
- Markers cliquables → popup avec preview
|
||||
- Clustering si >50 résultats proches
|
||||
|
||||
**Coût** : 0€ (Leaflet open source + OSM tiles gratuit)
|
||||
|
||||
**Justification** :
|
||||
- Équilibre information / compacité
|
||||
- Lazy loading = performances
|
||||
- Infinite scroll = UX moderne
|
||||
|
||||
---
|
||||
|
||||
## Récapitulatif Section 15
|
||||
|
||||
| Point | Décision | Coût | Complexité |
|
||||
|-------|----------|------|------------|
|
||||
| **15.1.1** Bouton partager | Disponible partout (⬆️), menu natif OS | 0€ | Faible |
|
||||
| **15.1.2** Lien partagé | Web player + deep link + Open Graph SEO | 0€ | Moyenne |
|
||||
| **15.1.3** Premium partagé | Preview 30s + paywall overlay | 0€ | Faible |
|
||||
| **15.2.1** Page profil | Profil public complet (stats + bio + contenus + tri) | 0€ | Faible |
|
||||
| **15.2.2** Stats publiques | Arrondies (abonnés, écoutes, durée totale) | 0€ | Faible |
|
||||
| **15.2.3** Badge vérifié | ✓ si KYC/célébrité/>10K abonnés | 0€ | Faible |
|
||||
| **15.3.1** Recherche texte | PostgreSQL full-text french + stemming | 0€ | Moyenne |
|
||||
| **15.3.2** Recherche géo | Lieu + rayon (Nominatim OSM) | 0-50€/mois | Moyenne |
|
||||
| **15.3.3** Filtres | 7 catégories combinables + sauvegarde recherches | 0€ | Moyenne |
|
||||
| **15.3.4** Page résultats | Liste enrichie + vue carte Leaflet + infinite scroll | 0€ | Moyenne |
|
||||
|
||||
**Coût total MVP : 0-50€/mois** (Nominatim self-hosted optionnel)
|
||||
|
||||
---
|
||||
|
||||
## Points d'attention pour Gherkin
|
||||
|
||||
- Tester partage contenu public vs Premium (preview 30s)
|
||||
- Tester deep linking iOS/Android (ouverture app si installée)
|
||||
- Tester Open Graph (aperçu correct sur WhatsApp, Twitter, Facebook)
|
||||
- Tester profil public (stats arrondies, badge vérifié)
|
||||
- Tester recherche full-text français (stemming, accents)
|
||||
- Tester recherche géo + rayon (PostGIS distance)
|
||||
- Tester combinaison filtres multiples (AND logic)
|
||||
- Tester sauvegarde recherches (max 5)
|
||||
- Tester pagination infinite scroll + fallback bouton
|
||||
- Tester vue carte Leaflet (clustering, markers cliquables)
|
||||
430
docs/domains/moderation/rules/moderation-communautaire.md
Normal file
430
docs/domains/moderation/rules/moderation-communautaire.md
Normal file
@@ -0,0 +1,430 @@
|
||||
## 19. Modération Communautaire - Badges et Récompenses
|
||||
|
||||
**Contexte** : Système de gamification pour encourager les utilisateurs à signaler du contenu inapproprié de manière pertinente et qualitative.
|
||||
|
||||
**Objectifs** :
|
||||
- Améliorer la qualité des signalements (réduire les signalements abusifs)
|
||||
- Réduire la charge de travail des modérateurs (priorisation automatique)
|
||||
- Récompenser les contributeurs actifs et fiables
|
||||
|
||||
---
|
||||
|
||||
### 19.1 Système de badges
|
||||
|
||||
**Décision** : 3 niveaux de badges selon l'historique de signalements validés
|
||||
|
||||
#### 19.1.1 Badges et critères
|
||||
|
||||
| Badge | Nom | Critères | Avantages |
|
||||
|-------|-----|----------|-----------|
|
||||
| 🥉 | **Contributeur Bronze** | 5 signalements validés + 70% taux pertinence | Signalements prioritaires (+10 points algorithme) |
|
||||
| 🥈 | **Contributeur Argent** | 20 signalements validés + 80% taux pertinence | Signalements prioritaires (+20 points) + Badge visible profil |
|
||||
| 🥇 | **Contributeur Or** | 50 signalements validés + 90% taux pertinence | Signalements prioritaires (+30 points) + Badge visible + Réduction Premium |
|
||||
|
||||
**Règles d'éligibilité** :
|
||||
- Minimum **10 signalements envoyés** pour être éligible aux badges
|
||||
- Les signalements "En cours" ne comptent pas dans le calcul
|
||||
- Les signalements rejetés font baisser le taux de pertinence
|
||||
|
||||
**Calcul du taux de pertinence** :
|
||||
```
|
||||
Taux de pertinence = (Signalements validés / Total signalements envoyés) × 100
|
||||
```
|
||||
|
||||
**Période de calcul** :
|
||||
- Seuls les **6 derniers mois** comptent (période glissante)
|
||||
- Évite que les utilisateurs se reposent sur leurs lauriers
|
||||
|
||||
**Justification** :
|
||||
- **Simple** : 3 niveaux seulement (pas d'over-engineering)
|
||||
- **Gratuit** : logique backend + affichage frontend
|
||||
- **Efficace** : incite la qualité plutôt que la quantité
|
||||
|
||||
---
|
||||
|
||||
#### 19.1.2 Délai entre obtention badges
|
||||
|
||||
**Décision** : Délai minimum entre niveaux
|
||||
|
||||
| Transition | Délai minimum |
|
||||
|------------|---------------|
|
||||
| **Bronze → Argent** | 30 jours |
|
||||
| **Argent → Or** | 60 jours |
|
||||
|
||||
**Justification** :
|
||||
- Évite la montée en badge trop rapide (anti-farming)
|
||||
- Force une contribution régulière sur la durée
|
||||
- Détecte les patterns suspects (audit modérateur si trop rapide)
|
||||
|
||||
---
|
||||
|
||||
#### 19.1.3 Découverte du système
|
||||
|
||||
**IMPORTANT** : L'utilisateur doit être informé du système de récompenses **dès son premier signalement**.
|
||||
|
||||
**Moment d'affichage** :
|
||||
- Après avoir envoyé le **premier signalement**
|
||||
- Juste après le toast de confirmation standard
|
||||
- **2 secondes de délai** avant affichage de la modal
|
||||
|
||||
**Modal d'information** (affichage unique, ne se réaffiche jamais) :
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 🎯 Bravo ! Vous contribuez à une │
|
||||
│ communauté plus saine │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ En signalant ce contenu, vous participez │
|
||||
│ activement à améliorer l'expérience de │
|
||||
│ tous les utilisateurs RoadWave. │
|
||||
│ │
|
||||
│ Vos contributions de qualité sont │
|
||||
│ valorisées et récompensées : │
|
||||
│ │
|
||||
│ 🥉 Bronze : 5 signalements validés │
|
||||
│ → Signalements prioritaires │
|
||||
│ │
|
||||
│ 🥈 Argent : 20 signalements validés │
|
||||
│ → Badge visible + priorité accrue │
|
||||
│ │
|
||||
│ 🥇 Or : 50 signalements validés │
|
||||
│ → Réduction Premium -50% pendant 3 mois │
|
||||
│ │
|
||||
│ 💡 Votre taux de pertinence compte ! │
|
||||
│ Signalements validés ÷ Total × 100 │
|
||||
│ │
|
||||
│ Continuez à nous aider, chaque │
|
||||
│ signalement pertinent compte ! 🙏 │
|
||||
│ │
|
||||
│ [En savoir plus] [J'ai compris] │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Lien "En savoir plus"** :
|
||||
- Redirection vers page dédiée expliquant :
|
||||
- Calcul détaillé du taux de pertinence
|
||||
- Critères d'obtention pour chaque badge
|
||||
- Avantages détaillés de chaque niveau
|
||||
- Règles anti-abus (limite 10 signalements/24h)
|
||||
- Durée de validité des badges (audit trimestriel)
|
||||
|
||||
**Coût** : **0€** (modal one-time, logique backend simple)
|
||||
|
||||
---
|
||||
|
||||
#### 19.1.4 Affichage badges et statistiques
|
||||
|
||||
**Badge visible** :
|
||||
- **Profil utilisateur** : visible par tous les autres utilisateurs
|
||||
- **Historique signalements** : visible uniquement par l'utilisateur lui-même
|
||||
- **Toast après obtention** :
|
||||
- 🥉 Bronze : "🎉 Félicitations ! Vous êtes désormais Contributeur Bronze. Merci de rendre RoadWave meilleur !"
|
||||
- 🥈 Argent : "🎉 Impressionnant ! Badge Contributeur Argent obtenu. Votre engagement fait la différence !"
|
||||
- 🥇 Or : "🎉 Exceptionnel ! Vous êtes Contributeur Or. La communauté vous remercie pour votre aide précieuse !"
|
||||
|
||||
**Statistiques personnelles** (page Profil > Mes signalements) :
|
||||
```
|
||||
📊 Vos statistiques de modération
|
||||
Signalements envoyés : 27
|
||||
Validés : 23 ✅
|
||||
Rejetés : 4 ❌
|
||||
Taux de pertinence : 85%
|
||||
|
||||
Badge actuel : 🥈 Contributeur Argent
|
||||
Prochain palier : 🥇 Contributeur Or (30 signalements validés restants)
|
||||
```
|
||||
|
||||
**Toast après traitement signalement** :
|
||||
- Si validé : "✅ Bravo ! Votre signalement a aidé la communauté. Progression : 3/5 pour badge Bronze 🥉"
|
||||
- Si rejeté : "❌ Signalement non retenu. Taux de pertinence : 60%. Continuez vos efforts !"
|
||||
|
||||
**Justification** :
|
||||
- **Transparence totale** : l'utilisateur voit sa progression en temps réel
|
||||
- **Motivation** : gamification saine (pas de pression, juste encouragement)
|
||||
- **Gratifiant** : messages positifs valorisant la contribution
|
||||
|
||||
---
|
||||
|
||||
### 19.2 Score de fiabilité
|
||||
|
||||
**Décision** : Score interne utilisé pour prioriser les signalements dans l'algorithme
|
||||
|
||||
#### 19.2.1 Formule
|
||||
|
||||
```
|
||||
Score fiabilité = min(100, (Validés × 10 - Rejetés × 5 + Bonus_Or × 20))
|
||||
```
|
||||
|
||||
**Détails** :
|
||||
- **Validés** : nombre de signalements validés par modérateurs
|
||||
- **Rejetés** : nombre de signalements rejetés
|
||||
- **Bonus_Or** : +20 points si badge Or actif
|
||||
- **Plafond** : maximum 100 points
|
||||
|
||||
**Exemples** :
|
||||
|
||||
| Cas | Validés | Rejetés | Badge | Score |
|
||||
|-----|---------|---------|-------|-------|
|
||||
| Nouvel utilisateur fiable | 10 | 1 | Aucun | 95 |
|
||||
| Utilisateur moyen | 15 | 8 | Bronze | 70 |
|
||||
| Contributeur Or | 50 | 3 | Or | 100 (plafonné) |
|
||||
| Signaleur abusif | 2 | 20 | Aucun | 0 (min 0) |
|
||||
|
||||
---
|
||||
|
||||
#### 19.2.2 Utilisation dans l'algorithme de priorisation
|
||||
|
||||
**Rappel formule Section 14.2.3** :
|
||||
```
|
||||
Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_signaleur × 0.1)
|
||||
```
|
||||
|
||||
**Intégration** :
|
||||
- **Fiabilité_signaleur** = Score fiabilité / 100 (normalisé 0-1)
|
||||
- Les signalements des utilisateurs avec badge Argent/Or passent automatiquement devant les autres (même score IA)
|
||||
|
||||
**Affichage à l'utilisateur** :
|
||||
- **NON affiché** publiquement (risque de gamification abusive)
|
||||
- **Visible** uniquement dans les stats personnelles :
|
||||
```
|
||||
Votre score de fiabilité : 85/100
|
||||
→ Vos signalements sont traités en priorité
|
||||
```
|
||||
|
||||
**Coût** : **0€** (calcul automatique lors du traitement)
|
||||
|
||||
---
|
||||
|
||||
### 19.3 Statut "Utilisateur de confiance"
|
||||
|
||||
**Décision** : Statut automatique pour utilisateurs Badge Argent ou Or
|
||||
|
||||
**Critère** :
|
||||
- Badge **Argent OU Or** actif = automatiquement "Utilisateur de confiance"
|
||||
|
||||
**Avantages** :
|
||||
1. **Priorisation signalements** : traités avant signalements standards (même score IA)
|
||||
2. **Badge visible** : affichage "Utilisateur de confiance" sur profil public
|
||||
3. **Notification différée** : résultats sous 12h (au lieu de 24-48h standards)
|
||||
|
||||
**Révocation** :
|
||||
- Perte badge Argent/Or → perte statut confiance automatique
|
||||
- Retour au statut normal, aucune sanction supplémentaire
|
||||
|
||||
**Coût** : **0€** (simple flag booléen calculé automatiquement)
|
||||
|
||||
---
|
||||
|
||||
### 19.4 Réduction Premium pour badge Or
|
||||
|
||||
**Décision** : Seuls les utilisateurs **Contributeur Or** (top contributeurs) obtiennent une réduction Premium
|
||||
|
||||
#### 19.4.1 Conditions
|
||||
|
||||
| Critère | Valeur |
|
||||
|---------|--------|
|
||||
| **Montant** | **-50% pendant 3 mois** (2.49€/mois au lieu de 4.99€) |
|
||||
| **Éligibilité** | Badge Or actif + pas déjà Premium |
|
||||
| **Durée** | 3 mois à partir de l'activation |
|
||||
| **Renouvellement** | Prix normal (4.99€/mois) après 3 mois |
|
||||
| **Cumul** | Non cumulable avec offre annuelle |
|
||||
| **Délai activation** | 30 jours après obtention badge Or |
|
||||
|
||||
---
|
||||
|
||||
#### 19.4.2 Notification
|
||||
|
||||
**Email + Push + In-app** dès obtention badge Or :
|
||||
|
||||
```
|
||||
🎉 Exceptionnel ! Vous avez obtenu le badge Contributeur Or
|
||||
|
||||
Vous faites partie des meilleurs contributeurs de RoadWave.
|
||||
Grâce à votre engagement et votre vigilance, vous aidez
|
||||
des milliers d'utilisateurs à profiter d'une expérience
|
||||
audio de qualité.
|
||||
|
||||
La communauté vous remercie ! 🙏
|
||||
|
||||
En reconnaissance de votre aide précieuse, vous bénéficiez de :
|
||||
|
||||
✨ 3 mois d'abonnement Premium à -50%
|
||||
→ 2.49€/mois au lieu de 4.99€
|
||||
|
||||
[Profiter de l'offre]
|
||||
|
||||
Cette offre est valable pendant 30 jours.
|
||||
Merci de contribuer à rendre RoadWave meilleur chaque jour !
|
||||
```
|
||||
|
||||
**Rappels** :
|
||||
- Email + Push J-7 : "Il vous reste 7 jours pour profiter de votre réduction Premium -50%"
|
||||
- Email + Push J-1 : "Dernière chance ! Votre réduction Premium -50% expire demain"
|
||||
|
||||
**Si non activée après 30 jours** :
|
||||
- Offre expirée (notification : "Votre offre Premium -50% a expiré")
|
||||
- Badge Or conservé (seule l'offre expire, pas le badge)
|
||||
|
||||
---
|
||||
|
||||
#### 19.4.3 Perte du badge Or
|
||||
|
||||
**Conditions** :
|
||||
- Taux de pertinence descend sous **90%** après audit trimestriel
|
||||
- Signalements abusifs détectés (voir Section 19.5)
|
||||
|
||||
**Conséquences** :
|
||||
- **Badge Or révoqué** immédiatement
|
||||
- **Abonnement Premium en cours** reste actif jusqu'à sa fin normale
|
||||
- **Nouvelle souscription** à prix normal (4.99€/mois)
|
||||
- **Pas de nouvelle offre -50%** même si badge Or réobtenu ultérieurement
|
||||
|
||||
**Justification** :
|
||||
- Maintien qualité badges sur le long terme
|
||||
- Évite abus système
|
||||
|
||||
---
|
||||
|
||||
#### 19.4.4 ROI et justification
|
||||
|
||||
**Coût maximum** : **200€/mois** (si 50 utilisateurs Or simultanés avec réduction active)
|
||||
|
||||
**ROI attendu** :
|
||||
- **1 utilisateur Or** = économie ~5-10h modération/mois = 75-150€ économisés (taux horaire modérateur ~15€/h)
|
||||
- **10 utilisateurs Or actifs** = 750-1500€ économisés > 200€ coût réductions
|
||||
- **ROI positif dès 2-3 utilisateurs Or actifs**
|
||||
|
||||
**Justification** :
|
||||
- **Incitation forte** pour meilleurs contributeurs uniquement
|
||||
- **Conversion** : utilisateurs gratuits très engagés → Premium payant après 3 mois
|
||||
- **Risque limité** : coût max plafonné, largement compensé par économie modération
|
||||
|
||||
---
|
||||
|
||||
### 19.5 Anti-abus
|
||||
|
||||
**CRITIQUE** : Système de protection contre les comportements abusifs
|
||||
|
||||
#### 19.5.1 Limite temporelle
|
||||
|
||||
**Décision** : Maximum 10 signalements / 24h par utilisateur
|
||||
|
||||
**Règles** :
|
||||
- Au-delà de 10 signalements/24h → signalements automatiquement rejetés
|
||||
- Alerte modérateur automatique (enquête manuelle)
|
||||
- Message utilisateur : "Limite quotidienne atteinte (10 signalements/24h). Réessayez demain."
|
||||
|
||||
**Justification** :
|
||||
- Évite signalement massif (farming)
|
||||
- 10/jour = largement suffisant pour usage légitime
|
||||
- Coût : 0€
|
||||
|
||||
---
|
||||
|
||||
#### 19.5.2 Détection patterns suspects
|
||||
|
||||
**Audit automatique hebdomadaire** :
|
||||
|
||||
```sql
|
||||
-- Détection signaleurs suspects
|
||||
SELECT user_id, COUNT(*) as total
|
||||
FROM reports
|
||||
WHERE created_at > NOW() - INTERVAL '7 days'
|
||||
GROUP BY user_id
|
||||
HAVING COUNT(*) > 30
|
||||
```
|
||||
|
||||
**Action** :
|
||||
- Enquête manuelle modérateur
|
||||
- Révocation badge si abus confirmé
|
||||
|
||||
**Patterns détectés** :
|
||||
- Signalement massif (>30/semaine)
|
||||
- Taux de pertinence <50% malgré volume élevé
|
||||
- Signalements tous rejetés sur période 7 jours
|
||||
- Signalements ciblant toujours même créateur (harcèlement)
|
||||
|
||||
---
|
||||
|
||||
#### 19.5.3 Audit trimestriel automatique
|
||||
|
||||
**Décision** : Tous les 3 mois, recalcul badges et révocation si critères non respectés
|
||||
|
||||
**Processus** :
|
||||
1. Recalcul taux pertinence sur période glissante 6 mois
|
||||
2. Vérification critères :
|
||||
- Bronze : minimum 70% pertinence
|
||||
- Argent : minimum 80% pertinence
|
||||
- Or : minimum 90% pertinence
|
||||
3. Révocation badge si taux insuffisant
|
||||
4. Email notification **7 jours avant audit** :
|
||||
```
|
||||
Votre badge Contributeur Argent sera audité dans 7 jours.
|
||||
Taux de pertinence actuel : 78%
|
||||
Minimum requis : 80%
|
||||
|
||||
Continuez à signaler du contenu pertinent pour conserver votre badge !
|
||||
```
|
||||
|
||||
**Après audit** :
|
||||
- Email résultat : "Badge conservé ✓" ou "Badge révoqué ✗"
|
||||
- Possibilité de réobtenir badge ultérieurement (pas de ban)
|
||||
|
||||
**Justification** :
|
||||
- Maintien qualité badges sur le long terme
|
||||
- Évite repos sur lauriers
|
||||
- Coût : 0€ (script automatique)
|
||||
|
||||
---
|
||||
|
||||
#### 19.5.4 Sanctions abus détecté
|
||||
|
||||
| Gravité | Abus détecté | Sanction |
|
||||
|---------|--------------|----------|
|
||||
| **Mineur** | >10 signalements/jour pendant 1 jour | Avertissement + limite 5/jour pendant 7 jours |
|
||||
| **Modéré** | >30 signalements/semaine avec <50% pertinence | Révocation badge + interdiction signalement 30 jours |
|
||||
| **Grave** | Signalements massifs coordonnés (farming) | Ban permanent fonctionnalité signalement + révocation tous badges |
|
||||
|
||||
**Notification sanction** :
|
||||
- Email + Push + In-app
|
||||
- Explication détaillée de l'abus détecté
|
||||
- Durée sanction
|
||||
- **Pas de recours** pour sanctions graves (farming confirmé)
|
||||
|
||||
---
|
||||
|
||||
## Récapitulatif Section 19
|
||||
|
||||
| Point | Décision | Coût |
|
||||
|-------|----------|------|
|
||||
| **Badges (3 niveaux)** | Bronze (5), Argent (20), Or (50) signalements validés | 0€ |
|
||||
| **Modal découverte** | Affichage unique au 1er signalement | 0€ |
|
||||
| **Score fiabilité** | Calcul automatique pour priorisation | 0€ |
|
||||
| **Utilisateurs de confiance** | Statut auto Argent/Or | 0€ |
|
||||
| **Réduction Premium Or** | -50% pendant 3 mois (Post-MVP) | 0-200€/mois |
|
||||
| **Limite temporelle** | Max 10 signalements/24h | 0€ |
|
||||
| **Audit trimestriel** | Révocation si critères non respectés | 0€ |
|
||||
| **Sanctions abus** | Mineur/Modéré/Grave selon pattern | 0€ |
|
||||
|
||||
**Coût total MVP** : **0€**
|
||||
|
||||
**Coût total Post-MVP** : **0-200€/mois** (réductions Premium Or)
|
||||
|
||||
**ROI** : **Positif dès 2-3 utilisateurs Or actifs** (économie modération > coût réductions)
|
||||
|
||||
---
|
||||
|
||||
**Conformité** :
|
||||
- ✅ RGPD : données modération anonymisées après 3 ans
|
||||
- ✅ Transparence : utilisateur informé dès le 1er signalement
|
||||
- ✅ Anti-discrimination : système accessible à tous, basé uniquement sur pertinence
|
||||
|
||||
**Scalabilité** :
|
||||
- 0-100 utilisateurs actifs : système automatique, 0€
|
||||
- 100-1000 utilisateurs actifs : 0-50€/mois (quelques badges Or)
|
||||
- 1000+ utilisateurs actifs : 50-200€/mois (max 50 badges Or simultanés)
|
||||
|
||||
---
|
||||
|
||||
**Prochaine section à clarifier** : Section 20 (si nécessaire) ou validation complète règles métier
|
||||
393
docs/domains/moderation/rules/moderation-flows.md
Normal file
393
docs/domains/moderation/rules/moderation-flows.md
Normal file
@@ -0,0 +1,393 @@
|
||||
## 14. Modération - Flows opérationnels
|
||||
|
||||
### 14.1 Signalement
|
||||
|
||||
**Décision** : Formulaire simple avec 7 catégories prédéfinies
|
||||
|
||||
#### 14.1.1 Catégories de signalement
|
||||
|
||||
Liste déroulante avec 7 options :
|
||||
|
||||
| Catégorie | Description |
|
||||
|-----------|-------------|
|
||||
| 🚫 **Haine & violence** | Incitation à la haine, discrimination, menaces |
|
||||
| 🔞 **Contenu sexuel** | Pornographie, contenu explicite |
|
||||
| ⚖️ **Illégalité** | Terrorisme, apologie de crimes |
|
||||
| 🎵 **Droits d'auteur** | Musique/contenu protégé non autorisé (voir [Section 18](18-detection-contenu-protege.md) pour règles détaillées) |
|
||||
| 📧 **Spam** | Publicité non sollicitée, répétition |
|
||||
| ❌ **Fausse information** | Désinformation sur santé, sécurité routière |
|
||||
| 🔧 **Autre** | Champ texte obligatoire si sélectionné |
|
||||
|
||||
**Justification** :
|
||||
- Équilibre entre simplicité (pas trop de choix) et précision (aide les modérateurs)
|
||||
- Coût : 0€ (liste déroulante standard)
|
||||
|
||||
---
|
||||
|
||||
#### 14.1.2 Commentaire du signaleur
|
||||
|
||||
**Décision** : Optionnel avec incitation
|
||||
|
||||
- Champ texte libre (0-500 caractères)
|
||||
- Placeholder : "Décrivez le problème (optionnel mais recommandé)"
|
||||
- Non bloquant : le signalement peut être envoyé sans commentaire
|
||||
|
||||
**Justification** :
|
||||
- Encourage la qualité des signalements sans créer de friction
|
||||
- Aide les modérateurs à comprendre le contexte
|
||||
- Pas de risque d'abandon du processus
|
||||
|
||||
---
|
||||
|
||||
#### 14.1.3 Confirmation après signalement
|
||||
|
||||
**Décision** : Toast in-app avec lien historique
|
||||
|
||||
**Affichage** :
|
||||
- Toast notification : "✓ Signalement envoyé. Nous l'examinerons sous 24-48h."
|
||||
- Durée affichage : 5 secondes
|
||||
- Bouton optionnel "Voir mes signalements" (accès historique)
|
||||
|
||||
**Historique personnel** :
|
||||
- Liste des signalements envoyés par l'utilisateur
|
||||
- Statut : En cours / Traité / Rejeté
|
||||
- Notification in-app si action prise (contenu retiré, signalement rejeté)
|
||||
|
||||
**Justification** :
|
||||
- Transparence maximale
|
||||
- Coût : 0€ (aucun email automatique)
|
||||
- Bonne UX
|
||||
|
||||
---
|
||||
|
||||
### 14.2 Traitement des signalements
|
||||
|
||||
#### 14.2.1 IA pré-filtre (transcription + analyse)
|
||||
|
||||
**Décision** : OpenAI Whisper open source + NLP
|
||||
|
||||
**Stack technique** :
|
||||
|
||||
| Composant | Technologie | Hébergement |
|
||||
|-----------|-------------|-------------|
|
||||
| **Transcription** | Whisper large-v3 | Self-hosted (CPU MVP, GPU scale) |
|
||||
| **Analyse sentiment** | distilbert-base-uncased | Self-hosted |
|
||||
| **Détection haine** | facebook/roberta-hate-speech | Self-hosted |
|
||||
| **Mots-clés** | Liste noire FR/EN + regex | PostgreSQL |
|
||||
|
||||
**Processus** :
|
||||
1. Signalement reçu → ajout file d'attente asynchrone
|
||||
2. Transcription audio (1-10 minutes selon durée)
|
||||
3. Analyse automatique :
|
||||
- Score de confiance : 0-100%
|
||||
- Catégorie détectée
|
||||
- Timestamps des passages problématiques
|
||||
4. Priorisation automatique selon score
|
||||
|
||||
**Délais** :
|
||||
- Audio <5 min : 1-3 minutes
|
||||
- Audio 5-30 min : 3-10 minutes
|
||||
- Audio >30 min : 10-20 minutes
|
||||
|
||||
**Coût** :
|
||||
- **MVP** : 0€ (CPU standard, processing asynchrone)
|
||||
- **Scale** : 50-200€/mois (GPU VPS si >1000 signalements/jour)
|
||||
|
||||
**Justification** :
|
||||
- 100% open source, pas de dépendance GAFAM
|
||||
- Coût maîtrisé (scaling progressif)
|
||||
- Gain productivité modérateurs ×3-5
|
||||
|
||||
---
|
||||
|
||||
#### 14.2.2 Délais de traitement (SLA)
|
||||
|
||||
**Décision** : SLA progressif selon priorité
|
||||
|
||||
| Priorité | Délai cible | Traitement |
|
||||
|----------|-------------|------------|
|
||||
| **CRITIQUE** | <2h (24/7) | Violence, suicide, mise en danger → Astreinte modérateur senior |
|
||||
| **HAUTE** | <24h (jours ouvrés) | Haine, harcèlement, désinformation → Modérateur junior/senior |
|
||||
| **MOYENNE** | <24h (jours ouvrés) | Spam, contenu inapproprié → Modérateur junior |
|
||||
| **BASSE** | <72h (jours ouvrés) | Qualité audio, tags incorrects → Modérateur junior |
|
||||
|
||||
**Traitement automatique** :
|
||||
- Score IA >95% + catégorie évidente (ex: spam répété) → Action automatique immédiate
|
||||
- Notification créateur + possibilité d'appel
|
||||
|
||||
**Justification** :
|
||||
- Réaliste et conforme DSA (Digital Services Act)
|
||||
- Scalable : priorisation automatique
|
||||
- Ressources humaines optimisées
|
||||
|
||||
---
|
||||
|
||||
#### 14.2.3 Priorisation automatique
|
||||
|
||||
**Décision** : File d'attente intelligente basée sur score IA
|
||||
|
||||
**Calcul de priorité** :
|
||||
|
||||
```
|
||||
Priorité = (Score_IA × 0.7) + (Signalements_cumulés × 0.2) + (Fiabilité_signaleur × 0.1)
|
||||
```
|
||||
|
||||
**Détails** :
|
||||
- **Score_IA** : 0-100% (confiance analyse automatique)
|
||||
- **Signalements_cumulés** : nombre de signalements du même contenu (boost priorité)
|
||||
- **Fiabilité_signaleur** : score utilisateur (historique signalements pertinents)
|
||||
|
||||
**Classification résultante** :
|
||||
- Priorité ≥90 → **CRITIQUE** (traitement immédiat)
|
||||
- Priorité 70-89 → **HAUTE** (file prioritaire)
|
||||
- Priorité 40-69 → **MOYENNE** (file normale)
|
||||
- Priorité <40 → **BASSE** (file différée)
|
||||
|
||||
**Justification** :
|
||||
- Optimise le temps des modérateurs
|
||||
- Traite les cas graves en priorité
|
||||
- Coût : 0€ (algorithme simple)
|
||||
|
||||
---
|
||||
|
||||
### 14.3 Sanctions
|
||||
|
||||
#### 14.3.1 Notification au créateur
|
||||
|
||||
**Décision** : Multi-canal (email + push + in-app)
|
||||
|
||||
**Canaux utilisés** :
|
||||
|
||||
| Canal | Timing | Contenu |
|
||||
|-------|--------|---------|
|
||||
| **Push notification** | Immédiat | Alerte courte : "Votre contenu a été modéré" |
|
||||
| **In-app** | Au prochain lancement | Popup détaillée avec bouton "Voir détails" |
|
||||
| **Email** | Dans l'heure | Notification complète avec lien vers formulaire d'appel |
|
||||
|
||||
**Contenu email** :
|
||||
```
|
||||
Objet : Modération de votre contenu "[Titre du contenu]"
|
||||
|
||||
Bonjour [Pseudo],
|
||||
|
||||
Votre contenu "[Titre]" publié le [Date] a été modéré.
|
||||
|
||||
Catégorie violée : [Catégorie]
|
||||
Raison : [Explication détaillée]
|
||||
Sanction : [Strike X / Suspension X jours / Suppression contenu]
|
||||
|
||||
Extrait audio concerné : [Timestamp]
|
||||
Transcription : "[Passage problématique surligné]"
|
||||
|
||||
Vous pouvez contester cette décision sous 7 jours :
|
||||
[Lien formulaire d'appel]
|
||||
|
||||
L'équipe RoadWave
|
||||
```
|
||||
|
||||
**Coût** :
|
||||
- Email : ~0.001€/notification (Brevo, Resend)
|
||||
- Push : 0€ (APNS / FCM natifs)
|
||||
- In-app : 0€
|
||||
|
||||
**Justification** :
|
||||
- Conformité DSA (transparence obligatoire)
|
||||
- Multi-canal garantit réception
|
||||
- Coût négligeable
|
||||
|
||||
---
|
||||
|
||||
#### 14.3.2 Détail de la sanction
|
||||
|
||||
**Décision** : Notification complète avec preuves
|
||||
|
||||
**Éléments inclus obligatoirement** :
|
||||
|
||||
1. **Catégorie violée** : référence précise CGU (ex: "Article 3.2 - Haine & violence")
|
||||
2. **Raison détaillée** : explication en langage clair (non juridique)
|
||||
3. **Extrait audio** : timestamp exact du passage problématique (ex: "3:42-4:15")
|
||||
4. **Transcription** : texte problématique surligné en rouge
|
||||
5. **Gravité** : Strike actuel + conséquences (ex: "Strike 2/4 - Suspension 7 jours")
|
||||
6. **Recours** : lien direct vers formulaire d'appel + délai (7 jours)
|
||||
|
||||
**Exemple visuel in-app** :
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ ⚠️ Contenu modéré │
|
||||
├─────────────────────────────────────┤
|
||||
│ Titre : "Mon podcast #42" │
|
||||
│ Publié le : 15/01/2026 │
|
||||
│ │
|
||||
│ Catégorie violée : │
|
||||
│ 🚫 Haine & violence (Article 3.2) │
|
||||
│ │
|
||||
│ Passage problématique : 3:42-4:15 │
|
||||
│ "[Transcription surlignée]" │
|
||||
│ │
|
||||
│ Sanction : Strike 2/4 │
|
||||
│ Suspension : 7 jours │
|
||||
│ │
|
||||
│ [Contester cette décision] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Justification** :
|
||||
- Transparence maximale (obligation DSA)
|
||||
- Créateur comprend l'erreur → amélioration future
|
||||
- Réduit les appels non fondés
|
||||
|
||||
---
|
||||
|
||||
#### 14.3.3 Processus d'appel
|
||||
|
||||
**Décision** : Formulaire in-app structuré
|
||||
|
||||
**Accès** :
|
||||
- Bouton "Contester cette décision" dans notification
|
||||
- Section "Mes sanctions" dans profil créateur
|
||||
|
||||
**Formulaire d'appel** :
|
||||
|
||||
| Champ | Type | Obligatoire |
|
||||
|-------|------|-------------|
|
||||
| **Sanction contestée** | Pré-rempli (non modifiable) | ✅ |
|
||||
| **Raison de l'appel** | Texte libre (50-1000 caractères) | ✅ |
|
||||
| **Arguments** | Zone texte enrichie | ✅ |
|
||||
| **Preuves** | Upload fichiers (max 5, 10 MB total) | ❌ |
|
||||
|
||||
**Après soumission** :
|
||||
- Génération numéro de ticket unique (ex: `#MOD-2026-00142`)
|
||||
- Email confirmation : "Votre appel sera traité sous 72h"
|
||||
- Statut visible dans l'app : "En cours d'examen"
|
||||
|
||||
**Délai de soumission** :
|
||||
- Maximum **7 jours** après notification de sanction
|
||||
- Après 7 jours : appel automatiquement refusé
|
||||
|
||||
**Justification** :
|
||||
- Professionnel et traçable
|
||||
- Intégration complète avec système modération
|
||||
- Coût : 0€ (formulaire custom backend)
|
||||
|
||||
---
|
||||
|
||||
#### 14.3.4 Délai de réponse pour appel
|
||||
|
||||
**Décision** : SLA 72h garanti
|
||||
|
||||
**Délais** :
|
||||
|
||||
| Type d'appel | Délai | Responsable |
|
||||
|--------------|-------|-------------|
|
||||
| **Standard** | 72h max (3 jours ouvrés) | Modérateur senior |
|
||||
| **Complexe** | 5 jours ouvrés + notification intermédiaire J+3 | Modérateur senior + Admin modération |
|
||||
| **Critique** | 24h (cas suspension longue/ban) | Admin modération |
|
||||
|
||||
**Notification intermédiaire** (si délai >72h) :
|
||||
- Email J+3 : "Votre appel #MOD-XXX est en cours d'examen approfondi. Réponse sous 2 jours."
|
||||
|
||||
**Réponse finale** :
|
||||
|
||||
Email détaillé avec :
|
||||
1. **Décision** : Maintien / Annulation / Réduction de sanction
|
||||
2. **Justification** : explication de la décision d'appel
|
||||
3. **Actions** : Strike retiré / Suspension annulée / Contenu rétabli (si applicable)
|
||||
4. **Définitif** : mention "Cette décision est définitive" (pas de second appel)
|
||||
|
||||
**Suivi in-app** :
|
||||
- Mise à jour statut : "Appel accepté ✓" ou "Appel rejeté ✗"
|
||||
- Badge notification
|
||||
|
||||
**Justification** :
|
||||
- Équilibre entre rapidité et qualité de traitement
|
||||
- Conforme pratiques industrie (YouTube, TikTok : 5-7 jours)
|
||||
- Ressources humaines réalistes
|
||||
|
||||
---
|
||||
|
||||
### 14.4 Outils modérateurs
|
||||
|
||||
**Stack technique complète** :
|
||||
|
||||
| Outil | Technologie | Fonction |
|
||||
|-------|-------------|----------|
|
||||
| **Dashboard** | React + TanStack Table | Interface modération |
|
||||
| **File signalements** | PostgreSQL + Redis | Priorisation temps réel |
|
||||
| **Player audio** | Wavesurfer.js | Lecture avec waveform + annotations |
|
||||
| **Transcription** | Whisper large-v3 | Conversion audio → texte |
|
||||
| **Historique créateur** | Vue 360° | Contenus, strikes, appels, métriques |
|
||||
| **Actions rapides** | Shortcuts clavier | Approuver (A), Rejeter (R), Escalade (E) |
|
||||
| **Logs audit** | PostgreSQL + export | Traçabilité complète (DSA) |
|
||||
| **Collaboration** | Système de commentaires | Modérateurs peuvent s'entraider sur cas complexes |
|
||||
|
||||
**Fonctionnalités clés** :
|
||||
|
||||
1. **Lecture accélérée** : 0.75x à 2x (gain productivité)
|
||||
2. **Marqueurs temporels** : annotation directe sur waveform
|
||||
3. **Historique créateur** : vue rapide contenus précédents + strikes
|
||||
4. **Statistiques** : signalements traités/jour, temps moyen, précision
|
||||
5. **Fil d'activité** : actions récentes équipe (temps réel)
|
||||
|
||||
**Coût infrastructure** :
|
||||
- MVP : 0-50€/mois (serveur CPU)
|
||||
- Scale : 50-200€/mois (GPU + Redis Cluster)
|
||||
|
||||
---
|
||||
|
||||
### 14.5 Modération préventive (rappel)
|
||||
|
||||
**Nouveaux créateurs** :
|
||||
- Validation manuelle des **3 premiers contenus**
|
||||
- Délai : 24-48h (jours ouvrés)
|
||||
- Transcription automatique pour aide modérateur
|
||||
|
||||
**Score de confiance** :
|
||||
- Évolution dynamique selon historique
|
||||
- Créateur fiable (0 strike depuis 6 mois) → validation automatique
|
||||
- Créateur suspect (strikes récents) → validation manuelle systématique
|
||||
|
||||
**Publicités** :
|
||||
- Validation manuelle obligatoire 24-48h (responsabilité juridique)
|
||||
- Transcription + analyse métadonnées (ciblage, durée, volume)
|
||||
|
||||
**Justification** :
|
||||
- Prévention > réaction (économie modération)
|
||||
- Qualité plateforme préservée dès le début
|
||||
|
||||
---
|
||||
|
||||
## Récapitulatif Section 14
|
||||
|
||||
| Point | Décision | Coût |
|
||||
|-------|----------|------|
|
||||
| **Catégories signalement** | 7 catégories prédéfinies + champ libre | 0€ |
|
||||
| **Commentaire signaleur** | Optionnel avec incitation | 0€ |
|
||||
| **Confirmation** | Toast in-app + historique personnel | 0€ |
|
||||
| **IA pré-filtre** | Whisper (CPU MVP, GPU scale) + NLP open source | 0-200€/mois |
|
||||
| **Délais traitement** | SLA progressif : 2h/24h/72h selon priorité | Dépend équipe |
|
||||
| **Priorisation** | File intelligente basée score IA | 0€ |
|
||||
| **Notification sanction** | Email + push + in-app (multi-canal) | ~0.001€/notif |
|
||||
| **Détail sanction** | Complet : raison + extrait + transcription | 0€ |
|
||||
| **Processus appel** | Formulaire in-app structuré | 0€ |
|
||||
| **Délai appel** | 72h garanti (standard) | Dépend équipe |
|
||||
| **Outils modérateurs** | Dashboard React + Whisper + Wavesurfer.js | 0-200€/mois |
|
||||
|
||||
**Coût total MVP** : **0-200€/mois** (infrastructure IA optionnelle)
|
||||
|
||||
**Conformité** :
|
||||
- ✅ DSA (Digital Services Act) : transparence, traçabilité, délais
|
||||
- ✅ RGPD : données modération anonymisées après 3 ans
|
||||
- ✅ Logs audit : toutes actions tracées (obligation légale plateforme)
|
||||
|
||||
**Scalabilité** :
|
||||
- 0-1000 signalements/mois : équipe 1-2 modérateurs junior + 1 senior
|
||||
- 1000-10K signalements/mois : équipe 5-10 modérateurs + IA GPU
|
||||
- 10K+ signalements/mois : équipe dédiée + IA optimisée + modération communautaire
|
||||
|
||||
---
|
||||
|
||||
**🎯 Modération communautaire** : Voir [Section 19](19-moderation-communautaire.md) pour le système complet de badges, récompenses et priorisation des signalements pertinents.
|
||||
|
||||
---
|
||||
|
||||
**Section suivante** : [Section 19 - Modération Communautaire](19-moderation-communautaire.md)
|
||||
@@ -0,0 +1,59 @@
|
||||
# Processus d'appel de modération
|
||||
|
||||
📖 Voir [Règles métier - Section 14 : Modération Flows](../rules/moderation-flows.md)
|
||||
|
||||
## Diagramme
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor Créateur
|
||||
participant App as Application Mobile
|
||||
participant API as Backend API
|
||||
participant Email as Service Email
|
||||
actor ModSenior as Modérateur Senior
|
||||
|
||||
Note over Créateur,ModSenior: Notification sanction initiale
|
||||
|
||||
API->>Créateur: Email + Push + In-app<br/>(catégorie + raison + extrait)
|
||||
|
||||
Note over Créateur,ModSenior: Soumission appel (J+0 à J+7)
|
||||
|
||||
Créateur->>App: Clique "Contester cette décision"
|
||||
App->>Créateur: Affiche formulaire d'appel
|
||||
|
||||
Créateur->>App: Remplit formulaire + preuves
|
||||
App->>API: POST /appeals
|
||||
|
||||
API->>API: Génère ticket #MOD-2026-XXXXX
|
||||
|
||||
API->>Email: Email confirmation
|
||||
Email->>Créateur: "Appel traité sous 72h"
|
||||
|
||||
Note over Créateur,ModSenior: Examen modérateur senior (J+0 à J+3)
|
||||
|
||||
ModSenior->>API: Consulte appel
|
||||
API-->>ModSenior: Données complètes<br/>(signalement + arguments + historique)
|
||||
|
||||
alt Appel accepté
|
||||
ModSenior->>API: Accepter appel
|
||||
API->>Email: Email créateur
|
||||
Email->>Créateur: "✅ Appel accepté<br/>Strike retiré"
|
||||
else Appel rejeté
|
||||
ModSenior->>API: Rejeter appel
|
||||
API->>Email: Email créateur
|
||||
Email->>Créateur: "❌ Appel rejeté<br/>Décision définitive"
|
||||
end
|
||||
|
||||
opt Cas complexe (J+3)
|
||||
API->>Email: Email intermédiaire
|
||||
Email->>Créateur: "Examen approfondi<br/>Réponse sous 2 jours"
|
||||
end
|
||||
```
|
||||
|
||||
## Légende
|
||||
|
||||
**Phases** :
|
||||
1. **Notification sanction** : Multi-canal (Email + Push + In-app)
|
||||
2. **Soumission appel** : Délai 7 jours max après sanction, formulaire obligatoire (raison + arguments), preuves optionnelles (max 5 fichiers, 10 MB)
|
||||
3. **Examen senior** : 72h standard, 5 jours si complexe avec notification intermédiaire J+3
|
||||
4. **Décision** : Accepté (strike retiré, contenu rétabli) ou Rejeté (définitif, pas de second appel)
|
||||
75
docs/domains/moderation/states/signalement-lifecycle.md
Normal file
75
docs/domains/moderation/states/signalement-lifecycle.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Cycle de vie d'un signalement
|
||||
|
||||
📖 Voir [Règles métier - Section 14 : Modération Flows](../rules/moderation-flows.md)
|
||||
|
||||
## Diagramme
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Reçu: Utilisateur envoie signalement
|
||||
|
||||
Reçu --> EnTranscription: Ajout à la file
|
||||
|
||||
EnTranscription --> EnAnalyseIA: Transcription terminée
|
||||
|
||||
EnAnalyseIA --> EnAttenteModo: Score IA calculé<br/>Priorisé dans la file
|
||||
EnAnalyseIA --> ActionAuto: Score IA >95%<br/>+ Catégorie évidente
|
||||
|
||||
EnAttenteModo --> EnExamen: Modérateur prend en charge
|
||||
|
||||
EnExamen --> Validé: Violation confirmée
|
||||
EnExamen --> Rejeté: Pas de violation
|
||||
|
||||
ActionAuto --> Validé: Sanction automatique
|
||||
|
||||
Validé --> SanctionAppliquée: Notification créateur
|
||||
|
||||
SanctionAppliquée --> EnAppel: Créateur conteste<br/>sous 7 jours
|
||||
SanctionAppliquée --> Clôturé: Pas de contestation<br/>ou délai expiré
|
||||
|
||||
EnAppel --> ExamenAppel: Modérateur senior<br/>examine sous 72h
|
||||
|
||||
ExamenAppel --> AppelAccepté: Sanction annulée
|
||||
ExamenAppel --> AppelRejeté: Sanction maintenue
|
||||
|
||||
AppelAccepté --> Clôturé: Strike retiré<br/>Contenu rétabli
|
||||
AppelRejeté --> Clôturé: Sanction définitive
|
||||
|
||||
Rejeté --> Clôturé: Notification signaleur
|
||||
|
||||
Clôturé --> [*]
|
||||
|
||||
note right of EnAttenteModo
|
||||
File intelligente
|
||||
Tri par priorité:
|
||||
- CRITIQUE (score ≥90)
|
||||
- HAUTE (70-89)
|
||||
- MOYENNE (40-69)
|
||||
- BASSE (<40)
|
||||
end note
|
||||
|
||||
note right of ActionAuto
|
||||
Action immédiate si:
|
||||
- Score IA >95%
|
||||
- Pattern évident
|
||||
- Spam détecté
|
||||
end note
|
||||
|
||||
note right of EnAppel
|
||||
Délai: 7 jours max
|
||||
Ticket unique généré
|
||||
end note
|
||||
```
|
||||
|
||||
## Légende
|
||||
|
||||
**États principaux** :
|
||||
- **Reçu** : Signalement initial (<1s)
|
||||
- **EnTranscription** : Whisper large-v3 (1-20 min)
|
||||
- **EnAnalyseIA** : Score confiance 0-100% (<1 min)
|
||||
- **ActionAuto** : Sanction automatique si score >95%
|
||||
- **EnAttenteModo** : File prioritaire (2h à 72h selon priorité)
|
||||
- **EnExamen** : Modérateur examine (5-20 min)
|
||||
- **SanctionAppliquée** : Notification multi-canal
|
||||
- **EnAppel** : Examen senior (72h max)
|
||||
- **Clôturé** : Archivage 3 ans (RGPD)
|
||||
Reference in New Issue
Block a user