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:
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
|
||||
Reference in New Issue
Block a user