Files
roadwave/features/api/moderation/sanctions-notifications.feature
jpgiannetti 37c62206ad feat(bdd): réorganiser features en catégories api/ui/e2e et créer ADR-024
Résolution des incohérences #10, #11, et #12 de l'analyse d'architecture.

## Phase 1 : Réorganisation Features BDD (Point #10 - RÉSOLU)

- Créer structure features/{api,ui,e2e}
- Déplacer 83 features en 3 catégories via git mv (historique préservé)
  - features/api/ : 53 features (tests API backend)
  - features/ui/ : 22 features (tests UI mobile)
  - features/e2e/ : 8 features (tests end-to-end)

Domaines déplacés :
- API : authentication, recommendation, rgpd-compliance, content-creation,
  moderation, monetisation, premium, radio-live, publicites
- UI : audio-guides, navigation, interest-gauges, mode-offline,
  partage, profil, recherche
- E2E : abonnements, error-handling

## Phase 2 : Mise à jour Documentation

### ADR-007 - Tests BDD
- Ajouter section "Convention de Catégorisation des Features"
- Documenter règles api/ui/e2e avec exemples concrets
- Spécifier step definitions (backend Go, mobile Dart)

### ADR-024 - Stratégie CI/CD Monorepo (NOUVEAU)
- Créer ADR dédié pour stratégie CI/CD avec path filters
- Architecture workflows séparés (backend.yml, mobile.yml, shared.yml)
- Configuration path filters détaillée avec exemples YAML
- Matrice de déclenchement et optimisations (~70% gain temps CI)
- Plan d'implémentation (~2h, reporté jusqu'au développement)

### ADR-016 - Organisation Monorepo
- Simplifier en retirant section CI/CD détaillée
- Ajouter référence vers ADR-024 pour stratégie CI/CD

### INCONSISTENCIES-ANALYSIS.md
- Point #10 (Tests BDD synchronisés) :  RÉSOLU
  - Catégorisation features implémentée
  - ADR-007 mis à jour avec convention complète
- Point #11 (70/30 Split paiements) :  ANNULÉ (faux problème)
  - ADR-009 et Règle 18 parfaitement cohérents
  - Documentation exhaustive existante (formule, SQL, comparaisons)
- Point #12 (Monorepo path filters) : ⏸️ DOCUMENTÉ
  - Architecture CI/CD complète dans ADR-024
  - Implémentation reportée (projet en phase documentation)
- Métriques mises à jour :
  - MODERATE : 6/9 traités (4 résolus + 1 annulé + 1 documenté)
  - ADR à jour : 100% (19/19 avec ADR-024)

## Phase 3 : Validation

- Structure features validée (api/ui/e2e, aucun répertoire restant)
- Historique Git préservé (git mv, renommages détectés)
- 83 features total (API: 53, UI: 22, E2E: 8)

Closes: Point #10 (résolu), Point #11 (annulé), Point #12 (documenté)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 11:31:41 +01:00

328 lines
15 KiB
Gherkin
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
Alors l'email contient la structure 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é.
Catégorie violée : 🚫 Haine & violence (Article 3.2 CGU)
Raison : Propos discriminatoires envers un groupe de personnes
Extrait audio concerné : 3:42-4:15
Transcription : "[passage problématique surligné en rouge]"
Sanction : Strike 2/4
Conséquence : Suspension de votre compte pendant 7 jours
Vous pouvez contester cette décision sous 7 jours :
[Lien formulaire d'appel]
L'équipe RoadWave
"""
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