Création de 6 nouvelles features Gherkin + documentation : Features UI mobile (Flutter) : - signalement-ui.feature : interface signalement avec 7 catégories - historique-signalements.feature : suivi personnel des signalements - badges-statistiques.feature : gamification Bronze/Argent/Or - sanctions-appel.feature : notifications et processus d'appel Features Admin dashboard (React) : - dashboard-moderateur.feature : files d'attente et SLA temps réel - outils-moderateur.feature : player Wavesurfer.js, transcription, historique créateur Documentation : - gherkin-moderation-overview.md : mapping complet règles métier, stats, coûts Couverture : - 190 scénarios couvrant 100% sections 14 (moderation-flows) et 19 (badges) - Conformité DSA/RGPD/WCAG testée - Stack : Go/Flutter/React avec Godog/flutter_gherkin/Cucumber.js
462 lines
20 KiB
Gherkin
462 lines
20 KiB
Gherkin
# 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
|