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:
jpgiannetti
2026-02-07 17:15:02 +01:00
parent 78422bb2c0
commit 5e5fcf4714
227 changed files with 1413 additions and 1967 deletions

View File

@@ -0,0 +1,176 @@
# language: fr
@rgpd @anonymization @gps
Fonctionnalité: Anonymisation des données GPS après 24h
# 13.2 - Geohash après 24h (conformité RGPD + CNIL)
Contexte:
Étant donné que je suis un utilisateur avec le GPS activé
Et que j'utilise l'application depuis plusieurs jours
Scénario: Conservation des données GPS précises pendant 24h
Étant donné que j'écoute un contenu à la position GPS 48.8566, 2.3522 (Paris, Tour Eiffel)
Et qu'il est 10:00 le 2025-01-20
Quand l'événement d'écoute est enregistré en base de données
Alors les coordonnées précises 48.8566, 2.3522 sont stockées
Et le champ `anonymized` est à `false`
Et le champ `created_at` contient "2025-01-20 10:00:00"
Et ces données précises servent à la recommandation personnalisée
Scénario: Conversion en geohash après 24h
Étant donné que j'ai écouté un contenu le 2025-01-20 à 10:00 à la position 48.8566, 2.3522
Quand le job quotidien d'anonymisation s'exécute le 2025-01-21 à 02:00
Alors les coordonnées précises sont converties en geohash précision 5
Et le geohash correspond à une zone d'environ 5km²
Et les coordonnées originales 48.8566, 2.3522 sont supprimées définitivement
Et le champ `anonymized` passe à `true`
Et il est impossible de retrouver la position précise d'origine
Scénario: Requête SQL d'anonymisation (PostGIS)
Étant donné que le job quotidien d'anonymisation s'exécute
Quand la requête SQL suivante est exécutée:
"""sql
UPDATE location_history
SET location = ST_SetSRID(ST_GeomFromGeoHash(ST_GeoHash(location::geography, 5)), 4326)::geography,
anonymized = true
WHERE created_at < NOW() - INTERVAL '24 hours' AND anonymized = false;
"""
Alors toutes les positions vieilles de plus de 24h sont anonymisées
Et le processus est automatique et irréversible
Et les données sont conformes RGPD
Scénario: Précision du geohash niveau 5
Étant donné qu'une position GPS est convertie en geohash précision 5
Quand on analyse la zone couverte
Alors la zone fait environ 5km² (4.9km × 4.9km)
Et cette précision est suffisante pour des analytics agrégées
Et cette précision ne permet pas d'identifier un individu (conformité CNIL)
Scénario: Exemple de conversion Paris
Étant donné que ma position précise est 48.8566, 2.3522 (Tour Eiffel)
Quand la conversion en geohash précision 5 est appliquée
Alors le geohash généré est "u09wh"
Et ce geohash couvre une zone de ~5km² autour de la Tour Eiffel
Et toutes les positions dans cette zone partagent le même geohash
Et il est impossible de distinguer deux utilisateurs dans cette zone
# Exception: Historique personnel
Scénario: Conservation de l'historique personnel utilisateur
Étant donné que j'ai écouté des contenus aux positions suivantes:
| date | heure | latitude | longitude | lieu |
| 2025-01-15 | 08:30 | 48.8566 | 2.3522 | Paris |
| 2025-01-16 | 14:00 | 43.6047 | 1.4442 | Toulouse |
| 2025-01-17 | 19:00 | 45.7640 | 4.8357 | Lyon |
Quand j'ouvre mon historique personnel dans "Profil > Mes trajets"
Alors je vois mes trajets avec les positions précises intégrales
Et ces données ne sont pas anonymisées tant que mon compte est actif
Et seul moi peut accéder à ces données
Et elles ne sont pas utilisées pour des analytics globales
Scénario: Anonymisation pour analytics globales uniquement
Étant donné que RoadWave génère des analytics agrégées
Quand l'équipe analyse les zones géographiques populaires
Alors seules les données anonymisées (geohash) sont utilisées
Et les positions précises de l'historique personnel ne sont jamais agrégées
Et les heatmaps de trafic utilisent uniquement les geohash ~5km²
# Job quotidien automatique
Scénario: Planification du job d'anonymisation
Étant donné que le système est en production
Quand on consulte les jobs planifiés (cron)
Alors un job "anonymize_gps_data" est configuré
Et le job s'exécute tous les jours à 02:00 (heure creuse)
Et le job traite toutes les positions vieilles de plus de 24h
Et un log est généré pour traçabilité
Scénario: Exécution du job avec métriques
Étant donné que le job d'anonymisation s'exécute le 2025-01-21 à 02:00
Quand le job se termine
Alors un rapport est généré avec:
| métrique | valeur |
| Nombre de positions traitées | 15420 |
| Nombre de positions anonymisées| 15420 |
| Durée d'exécution | 3.5s |
| Erreurs | 0 |
Et le rapport est loggé dans Sentry/Grafana
Et une alerte est envoyée si le job échoue
Scénario: Performances du job d'anonymisation
Étant donné que 100 000 positions doivent être anonymisées
Quand le job s'exécute
Alors le traitement se fait en moins de 30 secondes
Et la requête PostGIS est optimisée avec index
Et aucun impact sur les performances de l'application en production
# Vraie anonymisation RGPD
Scénario: Impossibilité de réidentification
Étant donné qu'une position a été anonymisée en geohash "u09wh"
Quand un attaquant tente de retrouver la position précise d'origine
Alors il est impossible de déterminer la position exacte
Et des milliers de positions précises correspondent au même geohash
Et il n'y a aucune traçabilité vers la position originale
Et cette anonymisation est irréversible
Scénario: Conformité CNIL - données véritablement anonymisées
Étant donné que les positions sont converties en geohash précision 5
Quand un auditeur CNIL vérifie la conformité
Alors les données sont considérées comme véritablement anonymisées
Et elles ne sont plus considérées comme des données personnelles
Et aucun consentement n'est requis pour leur traitement analytique
Et elles peuvent être conservées indéfiniment
# Analytics agrégées autorisées
Scénario: Heatmap de trafic avec données anonymisées
Étant donné que RoadWave génère une heatmap des zones populaires
Quand on analyse les données utilisées
Alors seules les positions anonymisées (geohash) sont agrégées
Et la heatmap montre des zones de ~5km²
Et aucune position précise n'est révélée
Et cette analyse ne nécessite pas de consentement utilisateur (données anonymes)
Scénario: Statistiques géographiques par département
Étant donné que RoadWave analyse l'utilisation par département
Quand les statistiques sont générées
Alors les données anonymisées sont agrégées par département
Et les résultats montrent: "Paris (75): 12 500 écoutes, Lyon (69): 8 300 écoutes"
Et aucune donnée personnelle n'est révélée
Et les statistiques sont RGPD-compliant
# PostGIS natif - 0
Scénario: Coût de la solution d'anonymisation
Étant donné que PostGIS est utilisé pour l'anonymisation GPS
Quand on calcule le coût de la solution
Alors le coût est de 0 (PostGIS inclus dans PostgreSQL)
Et aucune librairie tierce n'est nécessaire
Et la solution est entièrement maîtrisée (self-hosted)
# Cas limites
Scénario: Anonymisation respecte les positions en cours de session
Étant donné que je suis en train d'écouter du contenu actuellement
Et que certaines de mes positions ont plus de 24h
Quand le job d'anonymisation s'exécute
Alors mes positions de plus de 24h sont anonymisées
Mais ma position actuelle (session en cours) reste précise
Et la recommandation continue de fonctionner normalement
Scénario: Suppression de compte et anonymisation GPS
Étant donné que je demande la suppression de mon compte
Quand le compte est supprimé (après grace period de 30j)
Alors toutes mes positions GPS (précises et anonymisées) sont supprimées
Et mon historique personnel de trajets est supprimé
Et aucune donnée GPS ne subsiste, même anonymisée
Scénario: Export de données avant anonymisation
Étant donné que je demande un export de mes données
Et que certaines de mes positions ont été anonymisées
Quand l'export est généré
Alors les positions précises de mon historique personnel sont incluses
Mais les positions déjà anonymisées (>24h, analytics) apparaissent en geohash
Et l'export précise quelles données ont été anonymisées et pourquoi

View File

@@ -0,0 +1,256 @@
# language: fr
@rgpd @administrative @dpo
Fonctionnalité: Conformité administrative RGPD (Registre, Breach, DPO)
# 13.8 - Registre des traitements (Article 30 RGPD)
@registre-traitements
Scénario: Registre des traitements en Markdown versionné Git
Étant donné que RoadWave doit tenir un registre des traitements
Quand on consulte la documentation
Alors un fichier `docs/rgpd/registre-traitements.md` existe
Et le fichier est versionné dans Git
Et l'historique des modifications est traçable via Git
Et chaque traitement est documenté dans une section dédiée
Scénario: Contenu obligatoire pour chaque traitement
Étant donné que le registre des traitements contient le traitement "Géolocalisation utilisateurs"
Quand on lit la section correspondante
Alors les informations suivantes sont présentes:
| information obligatoire | exemple |
| Nom du traitement | Géolocalisation utilisateurs |
| Finalité | Recommandation de contenu géolocalisé |
| Catégories de données | Coordonnées GPS, historique de position |
| Base légale | Consentement (Article 6.1.a RGPD) |
| Durée de conservation | 24h (précis), puis geohash anonymisé |
| Destinataires | Aucun tiers |
| Transferts hors UE | Aucun |
| Mesures de sécurité | TLS 1.3, anonymisation après 24h |
Plan du Scénario: Traitements documentés dans le registre
Étant donné que le registre des traitements est complet
Quand on liste tous les traitements
Alors le traitement "<traitement>" est documenté avec la base légale "<base_legale>"
Exemples:
| traitement | base_legale |
| Géolocalisation utilisateurs | Consentement |
| Historique d'écoute | Intérêt légitime |
| Création de contenu | Exécution du contrat |
| Analytics (Matomo) | Consentement |
| Paiements (Mangopay) | Exécution du contrat |
| Modération contenus | Intérêt légitime |
| Notifications push | Consentement |
Scénario: Review trimestrielle du registre
Étant donné que le registre des traitements existe
Quand on consulte l'historique Git
Alors une mise à jour est effectuée au moins tous les 3 mois
Et chaque mise à jour a un commit avec message explicite
Et un tag Git marque chaque review trimestrielle
Et les modifications sont traçables (auteur, date, changements)
Scénario: Mise à jour immédiate si nouveau traitement
Étant donné qu'une nouvelle fonctionnalité nécessite un traitement de données
Quand la fonctionnalité est développée
Alors le registre est mis à jour AVANT le déploiement en production
Et le nouveau traitement est documenté complètement
Et un commit Git enregistre l'ajout
Et le DPO valide la conformité RGPD du nouveau traitement
Scénario: Migration future vers interface admin PostgreSQL
Étant donné que RoadWave dépasse 100 000 utilisateurs
Quand la complexité du registre augmente
Alors une interface admin PostgreSQL est développée
Et le registre Markdown est migré vers la base de données
Et l'historique Git est conservé pour audit
Et l'interface permet une gestion plus efficace des traitements
# 13.9 - Notification violations de données (Breach)
@breach-notification
Scénario: Détection automatique d'événements critiques
Étant donné que le système de monitoring est actif
Quand un événement critique se produit
Alors une alerte est envoyée selon le type d'événement:
| événement | outil | alerte |
| Erreur backend critique | Sentry | Discord/Slack immédiat |
| Pic requêtes anormal | Grafana | Email équipe |
| Accès non autorisé DB | PostgreSQL logs | SMS fondateur |
| Authentification suspecte | Zitadel alerts | Email équipe |
Et les alertes permettent une réaction rapide
Scénario: Runbook de procédure breach disponible
Étant donné qu'une violation de données potentielle est détectée
Quand l'équipe consulte la documentation
Alors un runbook `docs/rgpd/procedure-breach.md` existe
Et le runbook contient une checklist 72h CNIL
Et chaque étape est clairement documentée
Et les contacts d'urgence sont listés
Scénario: Checklist 72h en cas de breach
Étant donné qu'une violation de données est confirmée
Quand l'équipe suit la procédure breach
Alors les étapes suivantes sont exécutées dans les délais:
| délai | étape |
| H+0 | Détection et confinement immédiat |
| H+24 | Évaluation gravité (données concernées, users impactés) |
| H+48 | Notification CNIL si risque pour utilisateurs |
| H+72 | Notification utilisateurs si risque élevé |
Et chaque étape est documentée pour audit
Scénario: Évaluation de la gravité du breach
Étant donné qu'une violation de données est détectée
Quand l'équipe évalue la gravité
Alors les critères suivants sont analysés:
| critère | exemple |
| Type de données concernées | Emails, mots de passe, GPS, etc. |
| Nombre d'utilisateurs impactés | 10, 100, 10000, etc. |
| Mesures de sécurité existantes | Chiffrement, hachage, anonymisation |
| Risque pour les droits et libertés | Faible, modéré, élevé |
Et si le risque est élevé, la CNIL est notifiée sous 72h
Scénario: Notification CNIL dans les 72h
Étant donné qu'un breach avec risque élevé est confirmé à 10:00 le 2025-01-20
Quand la gravité est évaluée comme nécessitant une notification
Alors la CNIL est notifiée avant 10:00 le 2025-01-23 (72h)
Et la notification contient:
| information |
| Nature de la violation |
| Données concernées |
| Nombre d'utilisateurs impactés |
| Conséquences probables |
| Mesures prises |
| Mesures de remédiation |
Et un email pré-rédigé (template) est utilisé pour gagner du temps
Scénario: Notification des utilisateurs si risque élevé
Étant donné qu'un breach impacte 5000 utilisateurs
Et que le risque est élevé (mots de passe non chiffrés exposés)
Quand la CNIL est notifiée
Alors les utilisateurs impactés sont notifiés dans les 72h
Et l'email contient:
"""
Objet: Alerte sécurité - Action requise
Bonjour,
Nous vous informons qu'une violation de données a affecté votre compte RoadWave.
Données concernées: [liste]
Date de l'incident: [date]
Actions prises: [mesures]
Action requise: Changez immédiatement votre mot de passe.
Pour toute question: security@roadwave.fr
"""
Et un lien de réinitialisation de mot de passe est inclus
Scénario: Aucune notification si risque faible
Étant donné qu'un breach mineur est détecté (logs techniques exposés, aucune donnée personnelle)
Quand l'équipe évalue la gravité
Alors le risque est jugé faible
Et aucune notification CNIL n'est requise (Article 33.1 RGPD)
Et aucune notification utilisateur n'est envoyée
Et un log interne est créé pour traçabilité
Scénario: Monitoring proactif pour éviter découverte tardive
Étant donné que Sentry et Grafana sont configurés
Quand un comportement anormal est détecté
Alors une alerte est envoyée en temps réel
Et l'équipe peut réagir avant qu'un breach majeur ne se produise
Et les logs sont analysés quotidiennement pour détecter des anomalies
Et cette approche proactive limite les risques de découverte tardive
# 13.10 - DPO (Délégué à la Protection des Données)
@dpo
Scénario: Fondateur = DPO temporaire (MVP)
Étant donné que RoadWave est en phase MVP
Et que l'entreprise a moins de 250 employés
Quand on vérifie l'obligation légale d'avoir un DPO
Alors le DPO n'est pas obligatoire selon le RGPD Article 37
Et le fondateur assume temporairement le rôle de DPO
Et le fondateur suit la formation CNIL gratuite (4h)
Scénario: Formation CNIL du DPO temporaire
Étant donné que le fondateur est DPO temporaire
Quand on vérifie sa formation
Alors le fondateur a suivi la formation CNIL en ligne (4h)
Et le fondateur a obtenu la certification "Atelier RGPD" (gratuit)
Et le certificat est conservé pour audit
Et la formation couvre:
| sujet |
| Principes fondamentaux du RGPD |
| Droits des personnes |
| Sécurité des données |
| Violations de données (breach) |
| Registre des traitements |
Scénario: Contact DPO publié et accessible
Étant donné que je consulte les mentions légales de RoadWave
Quand je cherche le contact du DPO
Alors l'email "dpo@roadwave.fr" est clairement affiché
Et cet email est également dans les CGU
Et le délai de réponse garanti est de 1 mois maximum (RGPD Article 12.3)
Et une adresse postale est également fournie
Scénario: Demande d'exercice de droits RGPD au DPO
Étant donné que je veux exercer mon droit d'accès à mes données
Quand j'envoie un email à dpo@roadwave.fr
Alors je reçois un accusé de réception dans les 48h
Et ma demande est traitée dans un délai maximum de 1 mois
Et si le délai dépasse 1 mois, je suis informé de la prolongation (max 2 mois supplémentaires)
Et la réponse est complète et conforme au RGPD
Scénario: Types de demandes gérées par le DPO
Étant donné que je contacte le DPO
Quand j'envoie une demande
Alors le DPO peut traiter les demandes suivantes:
| type de demande |
| Droit d'accès (Article 15) |
| Droit de rectification (Article 16) |
| Droit à l'effacement (Article 17) |
| Droit à la portabilité (Article 20) |
| Droit d'opposition (Article 21) |
| Plainte RGPD |
| Question sur le traitement des données |
Et chaque demande reçoit une réponse personnalisée
Scénario: Migration vers DPO externe si croissance
Étant donné que RoadWave dépasse 100 000 utilisateurs
Quand la charge de travail DPO augmente
Alors un DPO externe mutualisé est engagé
Et le coût est d'environ 200/mois
Et le DPO externe a les certifications CNIL requises
Et un contrat de sous-traitance RGPD est signé
Scénario: Recrutement DPO interne si >10 employés
Étant donné que RoadWave a plus de 10 employés
Quand l'entreprise se structure
Alors un DPO interne peut être recruté
Et le DPO interne a une certification CNIL (AFCDP ou équivalent)
Et le DPO est indépendant et ne peut être licencié pour ses fonctions
Et le DPO a un accès direct à la direction
# Coût total conformité RGPD
Scénario: Récapitulatif des coûts RGPD
Étant donné que toutes les mesures RGPD sont en place
Quand on calcule le coût total mensuel
Alors le récapitulatif est le suivant:
| mesure | implémentation | coût |
| Consentement | Tarteaucitron.js + PostgreSQL | 0 |
| Anonymisation GPS | Geohash PostGIS (24h) | 0 |
| Export données | JSON+HTML+ZIP asynchrone | 0 |
| Suppression compte | Grace period 30j + anonymisation | 0 |
| Mode dégradé | GeoIP IP2Location + GPS optionnel | 0 |
| Conservation | Purge auto 5 ans inactivité | 0 |
| Analytics | Matomo self-hosted | ~5/mois |
| Registre traitements | Markdown Git | 0 |
| Breach detection | Sentry + Grafana + runbook | 0 (< 5K events) |
| DPO | Fondateur formé CNIL | 0 |
Et le coût total est d'environ 5/mois
Et cette conformité est 100% opensource et maîtrisée

View File

@@ -0,0 +1,186 @@
# language: fr
@rgpd @consent
Fonctionnalité: Gestion du consentement RGPD
Contexte:
Étant donné que je suis un nouvel utilisateur
Et que j'accède à l'application pour la première fois
# 13.1 - Gestion du consentement avec Tarteaucitron.js + PostgreSQL
Scénario: Affichage du banner de consentement au premier lancement web
Étant donné que j'accède à l'application web pour la première fois
Quand la page se charge
Alors un banner RGPD Tarteaucitron.js s'affiche
Et le banner est en français
Et le banner propose les options suivantes:
| option | description |
| Tout accepter | Active tous les consentements |
| Tout refuser | Refuse tous les consentements optionnels |
| Personnaliser | Ouvre le panneau de personnalisation |
Et le banner est customisé aux couleurs de RoadWave
Scénario: Granularité des consentements
Étant donné que le banner RGPD est affiché
Quand je clique sur "Personnaliser"
Alors je vois les catégories de consentements suivantes:
| catégorie | type | requis |
| Fonctionnel | Nécessaire | oui |
| Analytique | Optionnel | non |
| Marketing | Optionnel | non |
Et chaque catégorie a une description claire de son usage
Et je peux accepter ou refuser chaque catégorie individuellement
Scénario: Consentement géolocalisation précise - obligatoire
Étant donné que je suis sur l'application mobile
Et que l'onboarding est terminé
Quand l'application a besoin d'accéder à ma position précise
Alors un écran de demande de consentement s'affiche
Et le message explique clairement l'usage:
"""
RoadWave utilise votre position GPS pour vous proposer du contenu audio géolocalisé pertinent.
Vos données sont anonymisées après 24h.
"""
Et je peux accepter ou refuser
Et si je refuse, l'application bascule en mode dégradé (GeoIP uniquement)
Scénario: Double consentement GPS - banner app + permission OS
Étant donné que je veux activer la géolocalisation précise
Quand j'accepte le consentement dans l'application
Alors l'application demande également la permission au système d'exploitation
Et sur iOS, la popup système s'affiche: "Autoriser RoadWave à accéder à votre position ?"
Et sur Android, la popup système s'affiche avec les options "Toujours autoriser / Autoriser seulement pendant l'utilisation / Refuser"
Et les deux consentements (app + OS) doivent être acceptés pour activer le GPS précis
# Historique des consentements - PostgreSQL backend
Scénario: Enregistrement du consentement en base de données
Étant donné que j'ai accepté les consentements suivants:
| type | accepté |
| Fonctionnel | oui |
| Analytique | oui |
| Marketing | non |
| GPS précis | oui |
Quand je valide mes choix
Alors un enregistrement est créé dans la table `user_consents`
Et l'enregistrement contient les champs suivants:
| champ | valeur |
| user_id | [mon ID utilisateur] |
| consent_type | fonctionnel / analytique / gps |
| version | 1 |
| accepted | true / false |
| timestamp | [date et heure exacte] |
Et chaque type de consentement a un enregistrement séparé
Scénario: Versioning des consentements
Étant donné que j'ai accepté le consentement "Analytique" version 1 le 2025-01-01
Et que les CGU sont mises à jour le 2025-06-01
Quand je me connecte après la mise à jour
Alors un nouveau consentement version 2 m'est demandé
Et mon ancien consentement version 1 reste dans l'historique
Et je dois accepter la nouvelle version pour continuer à utiliser les analytics
Scénario: Historique complet conservé pour preuve légale
Étant donné que j'ai modifié mes consentements plusieurs fois:
| date | consent_type | accepted | version |
| 2025-01-01 | Analytique | oui | 1 |
| 2025-03-15 | Analytique | non | 1 |
| 2025-06-01 | Analytique | oui | 2 |
Quand un auditeur CNIL consulte mon historique de consentements
Alors tous les enregistrements sont conservés
Et l'historique prouve que chaque consentement a été donné librement
Et les timestamps permettent de prouver la conformité à tout moment
# Consentements requis vs optionnels
Scénario: Consentement analytique - optionnel
Étant donné que je refuse le consentement "Analytique"
Quand j'utilise l'application
Alors aucun cookie Matomo `_pk_id` n'est déposé
Et aucune donnée d'usage n'est envoyée à Matomo
Et l'application fonctionne normalement sans analytics
Scénario: Consentement notifications push - optionnel
Étant donné que je refuse le consentement "Notifications push"
Quand un créateur que je suis publie un nouveau contenu
Alors je ne reçois pas de notification push
Mais je peux voir le nouveau contenu dans l'application
Et l'application fonctionne normalement
Scénario: Consentement GPS précis - requis pour fonctionnalités géo
Étant donné que je refuse le consentement "GPS précis"
Quand j'utilise l'application
Alors je peux accéder aux contenus nationaux
Mais les contenus géolocalisés précis (Ancré, Contextuel) ne sont pas disponibles
Et les audio-guides nécessitent l'activation du GPS
Et un banner permanent me rappelle que l'activation du GPS améliore l'expérience
# Modification des consentements
Scénario: Révocation d'un consentement depuis les paramètres
Étant donné que j'ai accepté le consentement "Analytique"
Et que j'utilise l'application depuis 3 mois
Quand j'ouvre "Paramètres > Confidentialité > Gérer mes consentements"
Alors je vois la liste de tous mes consentements actuels
Et je peux révoquer le consentement "Analytique"
Quand je révoque le consentement
Alors un nouvel enregistrement est créé avec `accepted = false`
Et le cookie Matomo est supprimé immédiatement
Et les analytics sont désactivées à partir de ce moment
Scénario: Acceptation d'un consentement précédemment refusé
Étant donné que j'avais refusé le consentement "GPS précis"
Quand j'ouvre "Paramètres > Confidentialité > Gérer mes consentements"
Et que je clique sur "Activer la géolocalisation précise"
Alors un nouvel enregistrement est créé avec `accepted = true`
Et la permission OS est demandée si ce n'est pas déjà fait
Et l'application bascule en mode géolocalisation précise
Et les contenus géolocalisés deviennent disponibles immédiatement
# Preuves légales pour contrôle CNIL
Scénario: Export de l'historique des consentements pour audit
Étant donné qu'un contrôle CNIL est en cours
Quand l'équipe RoadWave exporte l'historique des consentements
Alors l'export contient pour chaque utilisateur:
| champ | description |
| user_id | ID anonymisé |
| consent_type | Type de consentement |
| version | Version des CGU/consentement |
| accepted | Accepté ou refusé |
| timestamp | Date et heure exacte |
| ip_address | IP (anonymisée) au moment du consentement |
| user_agent | Navigateur/app utilisé |
Et l'export est au format CSV pour analyse
Et les données prouvent la conformité RGPD
Scénario: Conformité recommandations CNIL
Étant donné que le système de consentement est implémenté
Quand un auditeur CNIL vérifie la conformité
Alors le système respecte les critères suivants:
| critère CNIL | respecté |
| Consentement libre | oui |
| Consentement spécifique (granulaire) | oui |
| Consentement éclairé (information claire) | oui |
| Consentement univoque (action positive) | oui |
| Révocable à tout moment | oui |
| Preuve du consentement conservée | oui |
# Opensource et self-hosted
Scénario: Tarteaucitron.js self-hosted
Étant donné que l'application web utilise Tarteaucitron.js
Quand je consulte les sources JavaScript chargées
Alors le script Tarteaucitron.js est hébergé sur les serveurs RoadWave
Et aucun script tiers (CDN externe) n'est chargé
Et le code source de Tarteaucitron.js est vérifiable
Et aucune donnée n'est envoyée à un tiers lors de l'affichage du banner
Scénario: Coût de la solution - 0€
Étant donné que Tarteaucitron.js est opensource
Et que PostgreSQL est utilisé pour le backend
Quand on calcule le coût de la solution de consentement
Alors le coût est de 0
Et la solution est entièrement maîtrisée (self-hosted)
Et aucune dépendance à un service SaaS tiers

View File

@@ -0,0 +1,245 @@
# language: fr
@rgpd @data-retention
Fonctionnalité: Durée de conservation des données et purge automatique
# 13.6 - 5 ans inactivité purge automatique (principe de minimisation RGPD)
Contexte:
Étant donné que le système de purge automatique est actif
# Règles de conservation
Scénario: Auditeur inactif depuis 5 ans - suppression automatique
Étant donné que je suis un auditeur (sans contenu créé)
Et que je ne me suis pas connecté depuis le 2020-01-01
Et que la date actuelle est 2025-01-02 (>5 ans)
Quand le job de purge automatique s'exécute
Alors mon compte est automatiquement supprimé
Et toutes mes données personnelles sont effacées
Et aucune trace ne subsiste dans la base de données
Scénario: Créateur avec contenus actifs - conservation indéfinie
Étant donné que je suis un créateur
Et que j'ai créé 10 contenus qui reçoivent encore des écoutes
Et que je ne me suis pas connecté depuis 6 ans
Quand le job de purge automatique s'exécute
Alors mon compte n'est pas supprimé
Et mes données personnelles sont conservées tant que mes contenus sont écoutés
Et mes contenus continuent d'être diffusés normalement
Scénario: Créateur inactif sans écoutes - suppression automatique
Étant donné que je suis un créateur
Et que j'ai créé 5 contenus
Et que je ne me suis pas connecté depuis 5 ans (depuis 2020-01-01)
Et que mes contenus n'ont reçu aucune écoute depuis 2 ans (depuis 2023-01-01)
Et que la date actuelle est 2025-01-02
Quand le job de purge automatique s'exécute
Alors mon compte est automatiquement supprimé
Et mes contenus sont anonymisés (créateur = "Utilisateur supprimé")
Et les fichiers audio restent disponibles mais anonymisés
# Notifications avant suppression
Scénario: Notifications par email avant purge
Étant donné que je suis inactif depuis 4 ans et 9 mois
Quand le système détecte que je suis éligible à la purge dans 90 jours
Alors je reçois un email avec le sujet "Votre compte RoadWave sera supprimé dans 90 jours"
Et l'email contient:
"""
Bonjour,
Votre compte RoadWave n'a pas été utilisé depuis plus de 4 ans.
Conformément à notre politique de conservation des données, votre compte sera automatiquement supprimé dans 90 jours si vous ne vous connectez pas.
Pour conserver votre compte, il suffit de vous connecter avant le [date limite].
Date de dernière connexion: [date]
Date de suppression prévue: [date + 90j]
Si vous ne souhaitez pas conserver ce compte, aucune action n'est requise.
"""
Et un lien de connexion est inclus dans l'email
Scénario: Rappels à 90j, 30j et 7j avant suppression
Étant donné que je suis éligible à la purge automatique
Quand les délais s'écoulent
Alors je reçois les emails suivants:
| délai | sujet email |
| 90 jours | Votre compte sera supprimé dans 90 jours |
| 30 jours | Rappel: Votre compte sera supprimé dans 30 jours |
| 7 jours | Dernière alerte: suppression dans 7 jours |
Et chaque email contient un lien de connexion pour réactiver le compte
Et les notifications push sont également envoyées si activées
Scénario: Connexion annule la suppression programmée
Étant donné que je suis éligible à la purge dans 15 jours
Et que j'ai reçu plusieurs emails d'avertissement
Quand je me connecte à mon compte
Alors la suppression programmée est annulée immédiatement
Et le compteur d'inactivité est remis à zéro
Et je reçois un email de confirmation: "Votre compte a été réactivé"
Et je peux continuer à utiliser l'application normalement
# Job de purge automatique
Scénario: Exécution quotidienne du job de purge
Étant donné que le système est en production
Quand on consulte les jobs planifiés
Alors un job "purge_inactive_accounts" est configuré
Et le job s'exécute tous les jours à 03:00 (heure creuse)
Et le job identifie les comptes éligibles à la purge
Et le job traite les suppressions automatiques
Scénario: Critères d'éligibilité à la purge
Étant donné que le job de purge s'exécute
Quand le système identifie les comptes éligibles
Alors les critères suivants sont appliqués:
| type_compte | critères |
| Auditeur uniquement | 5 ans sans connexion |
| Créateur avec contenus actifs| Jamais (tant qu'écoutes) |
| Créateur inactif | 5 ans sans connexion + 2 ans sans écoute |
Et seuls les comptes remplissant tous les critères sont supprimés
Scénario: Métriques du job de purge
Étant donné que le job de purge s'exécute le 2025-01-15
Quand le job se termine
Alors un rapport est généré avec:
| métrique | exemple |
| Comptes analysés | 150 000 |
| Comptes éligibles à la purge | 350 |
| Auditeurs supprimés | 300 |
| Créateurs inactifs supprimés | 50 |
| Créateurs conservés (actifs) | 0 |
| Erreurs | 0 |
| Durée d'exécution | 45s |
Et le rapport est loggé pour audit
# Contenus conservés après purge
Scénario: Contenus de comptes purgés conservés anonymement
Étant donné que mon compte créateur est purgé automatiquement
Quand la suppression est effective
Alors mes contenus créés sont conservés indéfiniment
Et les contenus sont anonymisés (créateur = "Utilisateur supprimé")
Et les fichiers audio restent sur le CDN
Et les statistiques d'écoute sont préservées
Et les utilisateurs peuvent toujours écouter mes contenus
# Exception: créateurs avec écoutes régulières
Scénario: Créateur inactif mais contenus populaires - pas de purge
Étant donné que je suis un créateur inactif depuis 6 ans
Mais que mes contenus reçoivent 500+ écoutes par mois
Quand le job de purge s'exécute
Alors mon compte n'est pas supprimé
Et je continue de recevoir les emails d'avertissement tous les 6 mois
Et mes contenus continuent d'être diffusés
Et je peux me reconnecter à tout moment
# Définition de "écoute" pour les créateurs
Scénario: Qu'est-ce qu'une "écoute" pour le calcul d'inactivité
Étant donné que je suis un créateur
Quand le système calcule si mes contenus sont "actifs"
Alors une "écoute" est comptabilisée si:
| condition | comptabilisée |
| Écoute complète (>80%) | oui |
| Écoute partielle (>30%) | oui |
| Skip rapide (<30%) | non |
| Écoute par un bot (détecté) | non |
Et au moins 1 écoute valide dans les 2 dernières années maintient le compte actif
# Principe de minimisation RGPD
Scénario: Conformité principe de minimisation
Étant donné que le système de purge automatique est en place
Quand un auditeur RGPD vérifie la conformité
Alors le système respecte le principe de minimisation:
| principe | respecté |
| Conservation limitée dans le temps | oui |
| Suppression automatique après inactivité | oui |
| Délai raisonnable (5 ans) | oui |
| Notifications préalables | oui |
| Exception justifiée (contenus actifs) | oui |
Et le délai de 5 ans est conforme aux standards de l'industrie
# Reset du compteur d'inactivité
Scénario: Actions qui réinitialisent le compteur d'inactivité
Étant donné que je suis inactif depuis 4 ans
Quand j'effectue l'une des actions suivantes:
| action |
| Connexion à l'application |
| Publication d'un nouveau contenu |
| Like d'un contenu |
| Abonnement à un créateur |
| Modification de mon profil |
Alors le compteur d'inactivité est remis à zéro
Et la suppression programmée est annulée
Et je ne suis plus éligible à la purge pour 5 ans
# Logs d'audit
Scénario: Traçabilité des suppressions automatiques
Étant donné qu'un compte est supprimé automatiquement
Quand la suppression est effective
Alors un log d'audit est créé avec:
| champ | valeur |
| user_id | [ID anonymisé] |
| account_type | auditeur / créateur |
| last_login | 2020-01-15T10:00:00Z |
| last_content_listen | 2023-06-01T14:30:00Z |
| purge_date | 2025-01-15T03:00:00Z |
| notifications_sent | 3 (90j, 30j, 7j) |
| reason | 5_years_inactivity |
Et le log est conservé 5 ans pour audit RGPD
Et l'user_id est pseudonymisé pour anonymat
# Cas particuliers
Scénario: Compte Premium inactif - pas de privilège spécial
Étant donné que je suis un utilisateur Premium
Et que je suis inactif depuis 5 ans
Quand le job de purge s'exécute
Alors mon compte est supprimé comme un compte gratuit
Et l'abonnement Premium ne prolonge pas la durée de conservation
Et aucun remboursement n'est effectué (compte inactif depuis 5 ans)
Scénario: Compte avec signalements de modération - purge différée
Étant donné que je suis éligible à la purge
Mais que j'ai des signalements de modération en cours
Quand le job de purge s'exécute
Alors ma purge est différée de 90 jours
Et les signalements sont traités en priorité
Et si les signalements aboutissent à un ban, le compte est supprimé immédiatement
Et si les signalements sont infondés, la purge automatique reprend son cours
# Durée de 5 ans - justification
Scénario: Pourquoi 5 ans d'inactivité
Étant donné que le délai de purge est fixé à 5 ans
Quand on justifie ce choix
Alors les raisons suivantes sont avancées:
| justification |
| Standard de l'industrie (Google, Facebook: 2-3 ans) |
| Équilibre raisonnable entre minimisation et utilité |
| Conforme aux recommandations CNIL |
| Laisse une marge de réactivation pour utilisateurs |
| Exception pour créateurs = intérêt légitime communauté |
# Communication transparente
Scénario: Politique de conservation visible dans les CGU
Étant donné que je consulte les CGU de RoadWave
Quand je lis la section "Conservation des données"
Alors la politique de purge automatique est clairement expliquée:
"""
Conservation des données:
- Comptes auditeurs: suppression automatique après 5 ans d'inactivité
- Comptes créateurs: suppression après 5 ans d'inactivité + 2 ans sans écoute de leurs contenus
- Exception: créateurs dont les contenus sont encore écoutés régulièrement
- Notifications: 90j, 30j et 7j avant suppression
- Contenus créés: conservés de manière anonyme après suppression du compte
"""
Et les utilisateurs sont informés dès l'inscription

View File

@@ -0,0 +1,227 @@
# language: fr
@rgpd @cookies @analytics
Fonctionnalité: Cookies et analytics avec Matomo self-hosted
# 13.7 - Matomo self-hosted, zéro cookie tiers (souveraineté données)
Contexte:
Étant donné que je suis un utilisateur de l'application web RoadWave
# Liste des cookies utilisés
Scénario: Cookies strictement nécessaires - pas de consentement requis
Étant donné que j'accède à l'application web
Quand je me connecte
Alors les cookies techniques suivants sont déposés:
| cookie | type | durée | finalité | consentement |
| session | Technique | 30j | Authentification | Non requis |
| refresh_token | Technique | 30j | Session persistante | Non requis |
Et ces cookies sont essentiels au fonctionnement de l'application
Et ils sont exemptés de consentement selon l'article 82 de la loi Informatique et Libertés
Scénario: Cookie analytique Matomo - consentement requis
Étant donné que j'ai accepté le consentement "Analytique"
Quand je navigue sur l'application web
Alors le cookie `_pk_id` est déposé
Et la durée de conservation est de 13 mois
Et ce cookie sert à Matomo pour analytics
Et mon IP est automatiquement anonymisée (2 derniers octets)
Scénario: Refus du consentement analytique - pas de cookie Matomo
Étant donné que j'ai refusé le consentement "Analytique"
Quand je navigue sur l'application web
Alors aucun cookie `_pk_id` n'est déposé
Et aucune donnée d'usage n'est collectée
Et l'application fonctionne normalement sans analytics
# Matomo self-hosted
Scénario: Matomo hébergé sur les serveurs RoadWave
Étant donné que RoadWave utilise Matomo pour les analytics
Quand on analyse l'infrastructure
Alors Matomo est installé sur les serveurs RoadWave (Docker)
Et aucune donnée n'est envoyée à un service tiers
Et toutes les données restent dans l'UE
Et l'accès à Matomo est restreint à l'équipe RoadWave
Scénario: IP anonymisées automatiquement
Étant donné que Matomo collecte des données d'usage
Quand une requête est enregistrée
Alors l'adresse IP est automatiquement anonymisée
Et les 2 derniers octets sont remplacés par des zéros
Et une IP 192.168.1.100 devient 192.168.0.0
Et cette anonymisation est irréversible
Et elle est conforme aux recommandations CNIL
Scénario: Configuration Matomo conforme RGPD
Étant donné que Matomo est configuré pour RoadWave
Quand on vérifie les paramètres
Alors les configurations suivantes sont activées:
| paramètre | valeur |
| Anonymisation IP (2 octets) | activé |
| Respect Do Not Track | activé |
| Suppression auto anciens logs (25 mois)| activé |
| Géolocalisation IP désactivée | activé |
| User ID anonymisé | activé |
Et la configuration est RGPD-compliant
# Trackers interdits
Scénario: Aucun tracker tiers utilisé
Étant donné que j'accède à l'application web
Quand j'inspecte les requêtes réseau avec les DevTools
Alors aucune requête n'est envoyée vers les domaines suivants:
| domaine tiers interdit |
| google-analytics.com |
| facebook.com (Pixel) |
| hotjar.com |
| mixpanel.com |
| segment.io |
| amplitude.com |
Et toutes les requêtes analytics vont uniquement vers matomo.roadwave.fr
Scénario: Conformité zéro cookie tiers
Étant donné que j'analyse les cookies déposés sur roadwave.fr
Quand je consulte la liste des cookies
Alors tous les cookies sont first-party (domaine roadwave.fr)
Et aucun cookie tiers (third-party) n'est présent
Et cette politique respecte les recommandations CNIL 2020
# Alternative: Plausible (si besoin)
Scénario: Alternative Plausible SaaS (EU-hosted)
Étant donné que RoadWave pourrait utiliser Plausible au lieu de Matomo
Quand on compare les deux solutions
Alors Plausible a les caractéristiques suivantes:
| caractéristique | valeur |
| Hébergement | UE (Allemagne) |
| Conformité RGPD | Natif (pas de cookie) |
| Coût | 9/mois (50K pageviews) |
| IP anonymisées | Automatique |
| Consentement requis | Non (selon CNIL 2020) |
Mais Matomo self-hosted reste le choix prioritaire (0, contrôle total)
# Souveraineté des données
Scénario: Aucun transfert de données hors UE
Étant donné que Matomo est self-hosted
Quand on analyse les flux de données
Alors aucune donnée d'analytics n'est transférée hors de l'UE
Et les serveurs sont localisés en France
Et aucun transfert vers les US (pas de Privacy Shield / DPF requis)
Et la souveraineté des données est garantie
# Coût de la solution
Scénario: Matomo self-hosted - coût estimé
Étant donné que Matomo est hébergé sur l'infrastructure RoadWave
Quand on calcule le coût mensuel
Alors le coût est d'environ 5/mois:
| composant | coût |
| Serveur supplémentaire | 0 (mutualisé) |
| Base de données MySQL | 0 (mutualisé) |
| Stockage logs (25 mois) | ~5/mois |
| License Matomo | 0 (opensource) |
Et ce coût est marginal comparé à un SaaS tiers (9-50/mois)
# Respect Do Not Track
Scénario: Respect du signal Do Not Track (DNT)
Étant donné que mon navigateur envoie le header "DNT: 1"
Quand j'accède à l'application web
Alors Matomo détecte le signal DNT
Et aucune donnée d'usage n'est collectée
Et aucun cookie `_pk_id` n'est déposé
Et l'application fonctionne normalement
Et un message discret s'affiche: "Vos préférences de confidentialité sont respectées (DNT activé)"
# Suppression automatique des anciens logs
Scénario: Logs Matomo supprimés après 25 mois
Étant donné que Matomo collecte des données d'usage
Quand les logs atteignent 25 mois d'ancienneté
Alors un job automatique supprime les anciens logs
Et seules les données agrégées (rapports) sont conservées
Et les données brutes (logs) sont supprimées définitivement
Et cette politique respecte le principe de minimisation RGPD
# Métriques collectées par Matomo
Scénario: Données collectées par Matomo
Étant donné que j'ai accepté le consentement "Analytique"
Quand je navigue sur l'application web
Alors Matomo collecte les données suivantes:
| donnée collectée | anonymisée |
| Pages visitées | non |
| Durée de visite | non |
| Navigateur / OS | non |
| Résolution écran | non |
| Provenance (referrer) | non |
| IP (2 derniers octets) | oui |
| User ID (hashé) | oui |
Et aucune donnée personnelle identifiable n'est collectée
Scénario: User ID hashé pour analytics
Étant donné que je suis connecté à l'application
Et que j'ai accepté le consentement "Analytique"
Quand Matomo enregistre mes actions
Alors mon user_id est hashé (SHA-256)
Et le hash est 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
Et il est impossible de retrouver mon user_id original depuis ce hash
Et ce processus garantit l'anonymat
# Conformité CNIL 2020
Scénario: Conformité recommandations CNIL sur les cookies
Étant donné que RoadWave utilise Matomo self-hosted
Quand un auditeur CNIL vérifie la conformité
Alors le système respecte les recommandations CNIL 2020:
| recommandation CNIL | respecté |
| Consentement requis pour cookies analytics | oui |
| IP anonymisées | oui |
| Pas de transfert hors UE | oui |
| Durée conservation limitée (25 mois) | oui |
| Respect Do Not Track | oui |
| Transparence (liste cookies dans CGU) | oui |
# Tarteaucitron.js - gestion du consentement
Scénario: Intégration Tarteaucitron.js pour gérer Matomo
Étant donné que Tarteaucitron.js gère les consentements
Quand je personnalise mes consentements
Alors je vois l'option "Analytique (Matomo)"
Et une description est affichée:
"""
Matomo nous aide à comprendre comment vous utilisez l'application pour l'améliorer.
Vos données restent anonymes et ne sont jamais partagées avec des tiers.
"""
Et je peux activer ou désactiver Matomo indépendamment
Et si je désactive, le cookie `_pk_id` est supprimé immédiatement
# Application mobile - analytics
Scénario: Analytics sur application mobile
Étant donné que j'utilise l'application mobile
Quand j'accepte le consentement "Analytique"
Alors l'app utilise le SDK Matomo Mobile
Et les données sont envoyées à la même instance Matomo self-hosted
Et les mêmes règles d'anonymisation s'appliquent
Et aucun SDK tiers (Google Analytics, Firebase) n'est utilisé
Scénario: Refus analytics sur mobile
Étant donné que j'ai refusé le consentement "Analytique" sur mobile
Quand j'utilise l'application
Alors aucune donnée d'usage n'est collectée
Et le SDK Matomo est désactivé
Et l'application fonctionne normalement sans différence d'UX
# Opensource et auditabilité
Scénario: Matomo opensource et auditable
Étant donné que Matomo est opensource
Quand on consulte le code source
Alors le code est disponible publiquement sur GitHub
Et le code peut être audité par des experts indépendants
Et aucune backdoor ou collecte cachée n'est possible
Et cette transparence renforce la confiance utilisateur

View File

@@ -0,0 +1,224 @@
# language: fr
@rgpd @geoip @degraded-mode
Fonctionnalité: Mode dégradé avec GeoIP (sans GPS précis)
# 13.5 - GeoIP par défaut, GPS optionnel (progressive disclosure)
Contexte:
Étant donné que je suis un nouvel utilisateur
Et que je lance l'application pour la première fois
# Niveaux de précision
Plan du Scénario: Trois niveaux de géolocalisation disponibles
Étant donné que j'utilise le niveau de géolocalisation "<niveau>"
Quand le système détermine ma position
Alors la technologie utilisée est "<technologie>"
Et les contenus accessibles sont "<contenus>"
Et le consentement RGPD est "<consentement>"
Exemples:
| niveau | technologie | contenus | consentement |
| Pays | Aucune géoloc | Contenus nationaux uniquement | Non requis |
| Ville | GeoIP (IP2Location) | Contenus régionaux/ville | Non requis |
| Précis | GPS | Tous contenus (hyperlocaux inclus) | Requis |
# Démarrage avec GeoIP automatique
Scénario: GeoIP activé par défaut au premier lancement
Étant donné que je lance l'application pour la première fois
Et que je n'ai pas encore accepté le GPS précis
Quand l'application démarre
Alors le système utilise automatiquement GeoIP basé sur mon adresse IP
Et ma position est détectée au niveau ville: "Paris, France"
Et aucun consentement n'est requis (GeoIP ne collecte pas de données personnelles)
Et je peux accéder aux contenus régionaux et de ville
Scénario: Détection de ville avec IP2Location Lite
Étant donné que mon adresse IP est 93.184.216.34
Quand le système utilise GeoIP IP2Location Lite
Alors ma ville est détectée: "Paris"
Et ma région est détectée: "Île-de-France"
Et mon pays est détecté: "France"
Et la précision est d'environ 80% au niveau ville
Et aucune coordonnée GPS précise n'est révélée
# Banner in-app pour upgrade vers GPS
Scénario: Banner d'invitation à activer le GPS
Étant donné que j'utilise l'application en mode GeoIP
Quand je suis sur l'écran principal
Alors un banner discret s'affiche en haut:
"""
Activez la géolocalisation pour découvrir du contenu près de chez vous
[Activer]
"""
Et le banner n'est pas intrusif (pas de popup modale)
Et je peux le fermer temporairement avec un bouton X
Et le banner réapparaît tous les 7 jours si je ne l'active pas
Scénario: Upgrade volontaire vers GPS depuis le banner
Étant donné que le banner d'invitation au GPS est affiché
Quand je clique sur "Activer"
Alors un écran de consentement GPS s'affiche
Et l'écran explique les avantages:
"""
En activant la géolocalisation précise, vous pouvez:
- Découvrir du contenu hyperlocal près de vous
- Accéder aux audio-guides géolocalisés
- Recevoir des notifications quand vous passez près de points d'intérêt
"""
Et je peux accepter ou refuser
Et si j'accepte, la permission OS est demandée
# Contenus accessibles selon le niveau
Scénario: Contenus disponibles en mode Pays (aucune géoloc)
Étant donné que je n'autorise aucune géolocalisation
Quand le système recherche du contenu à me proposer
Alors seuls les contenus "National" sont disponibles
Et les contenus géolocalisés (Ancré, Contextuel) ne sont pas proposés
Et je vois un message: "Activez la géolocalisation pour plus de contenu local"
Scénario: Contenus disponibles en mode Ville (GeoIP)
Étant donné que j'utilise le mode GeoIP et que je suis détecté à Paris
Quand le système recherche du contenu à me proposer
Alors les contenus suivants sont disponibles:
| type_contenu | disponible |
| National | oui |
| Région Île-de-France | oui |
| Ville Paris | oui |
| Hyperlocal (GPS) | non |
| Audio-guides | non |
Et je reçois des recommandations pertinentes pour Paris
Scénario: Tous contenus disponibles en mode Précis (GPS)
Étant donné que j'ai activé la géolocalisation précise
Quand le système recherche du contenu à me proposer
Alors tous les types de contenus sont disponibles:
| type_contenu | disponible |
| National | oui |
| Régional | oui |
| Ville | oui |
| Hyperlocal (Ancré) | oui |
| Contextuel | oui |
| Audio-guides | oui |
# Pas de consentement requis pour GeoIP
Scénario: GeoIP ne nécessite pas de consentement RGPD
Étant donné que j'utilise le mode GeoIP
Quand un auditeur CNIL vérifie la conformité
Alors GeoIP n'est pas considéré comme une donnée personnelle
Et l'adresse IP n'est pas conservée après détection de la ville
Et seule la ville est stockée (non identifiant)
Et aucun consentement n'est requis conformément au RGPD
# Implémentation IP2Location Lite
Scénario: Base de données IP2Location self-hosted
Étant donné que RoadWave utilise IP2Location Lite
Quand on analyse l'infrastructure
Alors la base de données IP2Location est hébergée sur les serveurs RoadWave
Et aucune requête n'est envoyée à un service tiers
Et la base de données est mise à jour automatiquement chaque mois
Et le coût est de 0 (IP2Location Lite est gratuit)
Scénario: Mise à jour mensuelle de la base GeoIP
Étant donné que IP2Location publie des mises à jour mensuelles
Quand le 1er du mois arrive
Alors un job automatique télécharge la nouvelle base IP2Location Lite
Et la base est mise à jour sans interruption de service
Et un log est créé pour traçabilité
Et si la mise à jour échoue, une alerte est envoyée
# Progressive disclosure - UX dégradée acceptable
Scénario: UX acceptable en mode GeoIP
Étant donné que j'utilise le mode GeoIP à Paris
Quand je parcours l'application
Alors je peux écouter du contenu pertinent pour Paris et l'Île-de-France
Et l'expérience est satisfaisante même sans GPS précis
Et je ne suis pas bloqué dans l'utilisation de l'application
Et je peux choisir d'activer le GPS quand je le souhaite
Scénario: Incitation progressive à activer le GPS
Étant donné que j'utilise le mode GeoIP depuis 2 semaines
Et que je n'ai pas activé le GPS
Quand je consulte un audio-guide dans les résultats de recherche
Alors un message s'affiche:
"""
Cet audio-guide nécessite la géolocalisation précise pour fonctionner.
[Activer le GPS] [Plus tard]
"""
Et si je clique "Plus tard", je peux continuer à utiliser l'app normalement
Et l'incitation reste douce et non intrusive
# Passage d'un mode à l'autre
Scénario: Upgrade GeoIP vers GPS
Étant donné que j'utilise le mode GeoIP
Quand j'active la géolocalisation précise
Alors le système bascule immédiatement en mode GPS
Et les contenus hyperlocaux deviennent disponibles
Et mon feed se rafraîchit avec du contenu plus précis
Et un toast de confirmation s'affiche: "Géolocalisation activée"
Scénario: Downgrade GPS vers GeoIP
Étant donné que j'utilise le mode GPS précis
Quand je désactive la géolocalisation dans les paramètres OS
Alors le système bascule automatiquement en mode GeoIP
Et les contenus hyperlocaux ne sont plus proposés
Et un banner s'affiche: "Géolocalisation désactivée. Seul le contenu régional est disponible."
Et l'application continue de fonctionner normalement
# Détection automatique du mode
Scénario: Détection automatique au démarrage de l'app
Étant donné que j'ouvre l'application
Quand l'app vérifie les permissions de géolocalisation
Alors le système détecte automatiquement le mode disponible:
| permission GPS | consentement app | mode activé |
| Refusée | Non demandé | Pays |
| Refusée | Accepté | GeoIP |
| Accordée | Accepté | GPS précis |
Et le mode est appliqué sans interaction utilisateur
# Précision GeoIP ~80%
Scénario: Précision acceptable pour la plupart des cas
Étant donné que j'habite à Lyon
Et que mon IP est une IP résidentielle standard
Quand le système utilise GeoIP pour me localiser
Alors la ville détectée est "Lyon" (correct à 80%)
Et dans 20% des cas, la ville peut être légèrement erronée (banlieue proche)
Et cette précision est suffisante pour proposer du contenu régional pertinent
Scénario: GeoIP avec VPN ou proxy
Étant donné que j'utilise un VPN avec une IP sortante à Paris
Mais que je suis physiquement à Lyon
Quand le système utilise GeoIP
Alors la ville détectée est "Paris" (IP du VPN)
Et les contenus proposés sont pour Paris
Et je peux activer le GPS précis pour corriger la localisation
# Conformité RGPD
Scénario: Pas de donnée personnelle collectée avec GeoIP
Étant donné que j'utilise le mode GeoIP
Quand le système détermine ma ville via mon IP
Alors l'adresse IP n'est pas conservée après détection
Et seule la ville "Paris" est stockée en base de données
Et la ville seule n'est pas une donnée personnelle (RGPD)
Et aucun consentement n'est donc requis
# Coût de la solution: 0€
Scénario: Solution GeoIP gratuite et self-hosted
Étant donné que RoadWave utilise IP2Location Lite
Quand on calcule le coût de la solution
Alors le coût est de 0
Et la solution est opensource
Et la base de données est hébergée sur les serveurs RoadWave
Et aucun coût SaaS tiers

View File

@@ -0,0 +1,282 @@
# language: fr
@rgpd @data-portability
Fonctionnalité: Portabilité des données (Article 20 RGPD)
# 13.3 - Export JSON + HTML + ZIP, génération asynchrone
Contexte:
Étant donné que je suis un utilisateur connecté
Et que j'ai utilisé l'application depuis 6 mois
Scénario: Demande d'export depuis les paramètres
Étant donné que je suis dans "Paramètres > Confidentialité"
Quand je clique sur "Exporter mes données"
Alors une page d'information s'affiche expliquant:
"""
Vous allez recevoir une archive contenant toutes vos données personnelles:
- Profil et informations de compte
- Historique d'écoute complet
- Contenus audio que vous avez créés
- Abonnements et likes
- Centres d'intérêt
- Historique des consentements
L'export sera généré sous 48h maximum et vous recevrez un email avec un lien de téléchargement valide 7 jours.
"""
Et un bouton "Confirmer l'export" est disponible
Scénario: Confirmation et démarrage de l'export
Étant donné que je clique sur "Confirmer l'export"
Quand la demande est validée
Alors un message de confirmation s'affiche:
"""
Votre demande d'export a été prise en compte. Vous recevrez un email sous 48h avec un lien de téléchargement.
"""
Et un worker background démarre la génération de l'export
Et le statut de l'export est "En cours de génération"
Et je peux voir le statut dans "Paramètres > Confidentialité > Mes exports"
# Structure de l'export
Scénario: Contenu de l'archive ZIP
Étant donné que mon export est généré
Quand je télécharge et ouvre l'archive
Alors l'archive a la structure suivante:
"""
export-roadwave-[user_id]-[date].zip
export.json # Machine-readable (JSON complet)
index.html # Human-readable (stylé, navigation)
audio/
content-123.opus # Mes contenus créés
content-456.opus
...
README.txt # Instructions et informations
"""
Et tous les fichiers sont inclus
Scénario: Contenu du fichier export.json
Étant donné que j'ouvre le fichier export.json
Quand j'analyse le contenu
Alors le JSON contient les sections suivantes:
| section | description |
| profile | Email, pseudo, date inscription, bio |
| listening_history | Historique complet d'écoute |
| created_contents | Métadonnées des contenus créés |
| subscriptions | Liste des créateurs suivis |
| likes | Liste des contenus likés |
| interest_gauges | Valeurs des jauges d'intérêt |
| consent_history | Historique des consentements |
| premium_subscription | Informations abonnement Premium |
Et le JSON est formaté de manière lisible (indentation)
Et toutes les dates sont au format ISO 8601
Scénario: Contenu du fichier index.html
Étant donné que j'ouvre le fichier index.html dans un navigateur
Quand la page se charge
Alors je vois un site web stylé avec navigation
Et les sections suivantes sont affichées:
| section | contenu |
| Mon profil | Email, pseudo, date inscription, statistiques |
| Historique d'écoute | Liste paginée avec dates, titres, durées |
| Mes contenus | Liste avec lectures audio intégrées |
| Mes abonnements | Grille des créateurs suivis |
| Mes likes | Liste des contenus likés avec liens |
| Centres d'intérêt | Graphiques des jauges |
| Consentements | Historique des acceptations/refus |
Et la navigation est intuitive (menu latéral)
Et le design est responsive (mobile/desktop)
Scénario: Fichiers audio inclus dans l'export
Étant donné que j'ai créé 5 contenus audio
Quand mon export est généré
Alors le dossier `audio/` contient mes 5 fichiers
Et les fichiers sont au format Opus original
Et chaque fichier est nommé: `content-[id].opus`
Et les fichiers audio correspondent aux métadonnées dans export.json
Scénario: Fichier README.txt explicatif
Étant donné que j'ouvre le fichier README.txt
Quand je lis le contenu
Alors le fichier explique:
"""
Bienvenue dans votre export de données RoadWave.
Contenu de l'archive:
- export.json: Toutes vos données au format JSON (machine-readable)
- index.html: Visualisation web de vos données (ouvrir dans un navigateur)
- audio/: Vos contenus audio créés au format Opus
Cet export a été généré le [date] et contient toutes vos données personnelles conformément à l'article 20 du RGPD.
Pour toute question: dpo@roadwave.fr
"""
# Données exportées en détail
Plan du Scénario: Données de profil exportées
Étant donné que mon export est généré
Quand j'ouvre export.json et lis la section "profile"
Alors je trouve les données suivantes:
| champ | exemple |
| email | user@example.com |
| pseudo | @roadwave_user |
| date_inscription | 2025-01-15T10:30:00Z |
| bio | Passionné d'automobile... |
| avatar_url | https://cdn.roadwave.fr/... |
| compte_verifie | false |
| premium | true |
Scénario: Historique d'écoute exporté
Étant donné que j'ai écouté 150 contenus depuis 6 mois
Quand mon export est généré
Alors la section "listening_history" contient 150 entrées
Et chaque entrée contient:
| champ | exemple |
| content_id | C123 |
| content_title | Histoire de la Tour Eiffel |
| creator_name | @historien_paris |
| listened_at | 2025-01-20T15:30:00Z |
| duration_listened | 180 (secondes) |
| completion_rate | 0.85 (85%) |
| location | [geohash ou coords précises]|
Et les contenus sont triés par date décroissante
Scénario: Centres d'intérêt exportés
Étant donné que mes jauges d'intérêt sont:
| catégorie | valeur |
| Automobile | 78% |
| Voyage | 65% |
| Musique | 52% |
| Politique | 30% |
Quand mon export est généré
Alors la section "interest_gauges" contient ces valeurs
Et chaque jauge indique la date de dernière modification
Scénario: Historique des consentements exporté
Étant donné que j'ai modifié mes consentements plusieurs fois
Quand mon export est généré
Alors la section "consent_history" contient:
| date | consent_type | accepted | version |
| 2025-01-15T10:00 | Fonctionnel | oui | 1 |
| 2025-01-15T10:00 | Analytique | oui | 1 |
| 2025-01-15T10:00 | Marketing | non | 1 |
| 2025-03-20T14:30 | Analytique | non | 1 |
Et l'historique complet est visible
# Génération asynchrone
Scénario: Génération asynchrone pour éviter timeout
Étant donné que j'ai beaucoup de données (500 contenus créés, 10 000 écoutes)
Quand je demande un export
Alors la génération se fait en arrière-plan via un worker
Et la page web ne timeout pas
Et je peux continuer à utiliser l'application pendant la génération
Et je reçois un email quand l'export est prêt
Scénario: Délai de génération conforme RGPD
Étant donné que je demande un export le 2025-01-20 à 10:00
Quand le worker génère l'export
Alors l'export est disponible maximum 48h plus tard (avant le 2025-01-22 à 10:00)
Et la plupart des exports sont prêts en moins de 6h
Et le délai respecte l'article 20 du RGPD
Scénario: Email de notification avec lien de téléchargement
Étant donné que mon export est terminé
Quand le worker finalise la génération
Alors je reçois un email avec le sujet "Votre export de données RoadWave est prêt"
Et l'email contient:
"""
Bonjour,
Votre export de données est prêt. Vous pouvez le télécharger via le lien ci-dessous:
[Télécharger mon export] (lien sécurisé, expire dans 7 jours)
Taille de l'archive: 45 MB
Contenu: Profil, historique, contenus audio, abonnements, likes, centres d'intérêt
Pour toute question: dpo@roadwave.fr
"""
Et le lien de téléchargement est sécurisé (token unique)
Scénario: Lien de téléchargement expire après 7 jours
Étant donné que mon export a été généré le 2025-01-20
Et que je reçois le lien de téléchargement
Quand j'essaie d'accéder au lien le 2025-01-28 (8 jours plus tard)
Alors le lien est expiré
Et je reçois un message "Ce lien a expiré. Veuillez demander un nouvel export."
Et je peux demander un nouvel export si nécessaire
# Limite anti-abus
Scénario: Limite de 1 export par mois
Étant donné que j'ai demandé un export le 2025-01-15
Quand j'essaie de demander un nouvel export le 2025-01-20
Alors je reçois un message d'erreur:
"""
Vous avez déjà demandé un export ce mois-ci. Vous pourrez demander un nouvel export à partir du 2025-02-15.
"""
Et le bouton "Confirmer l'export" est désactivé
Et la date du prochain export possible est affichée
Scénario: Nouvel export possible après 1 mois
Étant donné que j'ai demandé un export le 2025-01-15
Quand la date atteint le 2025-02-15
Alors je peux demander un nouvel export
Et le bouton "Confirmer l'export" est actif
Et aucune limite ne s'applique
# Sécurité
Scénario: Lien de téléchargement sécurisé avec token unique
Étant donné que mon export est prêt
Quand je reçois le lien de téléchargement
Alors le lien contient un token unique et non devinable
Et le format du lien est: `https://roadwave.fr/exports/download/[token_unique]`
Et le token est valide uniquement pour mon compte
Et le token expire après 7 jours ou après 3 téléchargements
Scénario: Vérification de l'authentification avant téléchargement
Étant donné que je reçois le lien d'export
Quand je clique sur le lien
Alors le système vérifie que je suis connecté
Et si je ne suis pas connecté, je suis redirigé vers la page de connexion
Et après connexion, le téléchargement démarre automatiquement
Et seul le propriétaire du compte peut télécharger l'export
# Conformité RGPD Article 20
Scénario: Conformité portabilité des données
Étant donné que mon export est généré
Quand un auditeur RGPD vérifie la conformité
Alors l'export respecte les exigences de l'article 20:
| exigence RGPD | respecté |
| Format structuré (JSON) | oui |
| Format couramment utilisé | oui |
| Format lisible par machine | oui |
| Format interopérable | oui |
| Délai raisonnable (48h max) | oui |
| Exhaustivité des données | oui |
| Gratuité pour l'utilisateur | oui |
Scénario: Gratuité de l'export
Étant donné que je demande un export de mes données
Quand l'export est généré et téléchargé
Alors aucun coût n'est facturé
Et l'export est entièrement gratuit
Et aucune inscription Premium n'est requise
Et le droit à la portabilité est accessible à tous les utilisateurs
# Statut de l'export visible
Scénario: Suivi du statut de génération
Étant donné que j'ai demandé un export
Quand j'ouvre "Paramètres > Confidentialité > Mes exports"
Alors je vois le statut actuel:
| statut | description |
| En cours de génération| Worker en train de générer l'archive |
| Prêt au téléchargement| Lien de téléchargement disponible |
| Expiré | Lien expiré (>7j), nouvel export requis |
Et la date de demande est affichée
Et la taille estimée de l'archive est visible

View File

@@ -0,0 +1,254 @@
# language: fr
@rgpd @account-deletion
Fonctionnalité: Suppression du compte utilisateur (Article 17 RGPD - Droit à l'effacement)
# 13.4 - Grace period 30j + anonymisation contenus
Contexte:
Étant donné que je suis un utilisateur connecté
Et que j'ai utilisé l'application depuis plusieurs mois
Scénario: Demande de suppression depuis les paramètres
Étant donné que je suis dans "Paramètres > Compte"
Quand je clique sur "Supprimer mon compte"
Alors une page d'avertissement s'affiche avec le message:
"""
Attention: La suppression de votre compte est définitive.
Que se passe-t-il lors de la suppression?
- Votre compte sera désactivé immédiatement (connexion impossible)
- Vos données personnelles seront supprimées dans 30 jours
- Vos contenus créés resteront disponibles de manière anonyme
- Vous pouvez annuler la suppression dans les 30 jours
Voulez-vous vraiment continuer?
"""
Et deux boutons sont disponibles: "Annuler" et "Confirmer la suppression"
Scénario: Confirmation de suppression avec mot de passe
Étant donné que je clique sur "Confirmer la suppression"
Quand un formulaire de confirmation s'affiche
Alors je dois entrer mon mot de passe pour confirmer
Et je dois cocher "Je comprends que cette action est définitive"
Et un captcha peut être requis pour éviter les suppressions automatisées
Quand je valide le formulaire
Alors la suppression est initiée
# Désactivation immédiate
Scénario: Compte désactivé immédiatement après confirmation
Étant donné que j'ai confirmé la suppression de mon compte
Quand la demande est traitée
Alors mon compte est désactivé immédiatement
Et je suis déconnecté de toutes mes sessions
Et je ne peux plus me reconnecter
Et si j'essaie de me connecter, je reçois le message:
"""
Votre compte est en cours de suppression. Si vous souhaitez annuler, cliquez sur le lien reçu par email.
"""
Scénario: Contenus cachés pendant le grace period
Étant donné que mon compte est en cours de suppression
Quand un autre utilisateur recherche mes contenus
Alors mes contenus ne sont plus diffusés dans l'application
Et mes contenus n'apparaissent plus dans les recherches
Et mes contenus ne sont plus recommandés
Mais mes contenus ne sont pas encore supprimés définitivement
# Email de confirmation avec lien d'annulation
Scénario: Email de confirmation envoyé immédiatement
Étant donné que j'ai confirmé la suppression de mon compte
Quand la demande est traitée
Alors je reçois un email avec le sujet "Confirmation de suppression de votre compte RoadWave"
Et l'email contient:
"""
Bonjour,
Votre compte RoadWave est en cours de suppression. Vos données seront définitivement supprimées le [date + 30j].
Si vous changez d'avis, vous pouvez annuler la suppression en cliquant sur le lien ci-dessous (valide 30 jours):
[Annuler la suppression]
Que se passe-t-il ensuite?
- Votre compte est désactivé immédiatement
- Vos contenus sont masqués de l'application
- Vos données seront supprimées dans 30 jours
- Vous pouvez annuler à tout moment pendant ces 30 jours
Pour toute question: dpo@roadwave.fr
"""
Et le lien d'annulation est valide 30 jours
# Grace period de 30 jours
Scénario: Annulation de la suppression dans les 30 jours
Étant donné que j'ai demandé la suppression de mon compte le 2025-01-20
Et que je reçois l'email de confirmation
Quand je clique sur le lien "Annuler la suppression" le 2025-02-05 (16 jours plus tard)
Alors mon compte est réactivé immédiatement
Et je peux me reconnecter normalement
Et mes contenus redeviennent visibles dans l'application
Et toutes mes données sont restaurées
Et je reçois un email de confirmation: "Votre compte a été réactivé"
Scénario: Lien d'annulation expire après 30 jours
Étant donné que j'ai demandé la suppression de mon compte le 2025-01-20
Quand j'essaie de cliquer sur le lien d'annulation le 2025-02-25 (36 jours plus tard)
Alors le lien est expiré
Et je reçois un message "Ce lien a expiré. Votre compte a été définitivement supprimé."
Et la suppression effective a déjà eu lieu
# Suppression effective après 30 jours
Scénario: Suppression effective sans annulation
Étant donné que j'ai demandé la suppression de mon compte le 2025-01-20
Et que je n'ai pas cliqué sur le lien d'annulation
Quand la date atteint le 2025-02-19 (30 jours plus tard)
Alors un job automatique exécute la suppression définitive
Et toutes mes données personnelles sont supprimées
# Données supprimées
Scénario: Liste des données supprimées définitivement
Étant donné que la suppression effective est exécutée
Quand le job de suppression se termine
Alors les données suivantes sont supprimées:
| données | supprimé |
| Compte utilisateur (email, mdp) | oui |
| Profil (pseudo, bio, avatar) | oui |
| Historique d'écoute | oui |
| Historique GPS | oui |
| Centres d'intérêt (jauges) | oui |
| Sessions et tokens | oui |
| Likes et abonnements | oui |
| Notifications non lues | oui |
| Historique consentements | oui |
| Données de paiement | oui |
Et ces suppressions sont irréversibles
# Contenus conservés anonymement
Scénario: Anonymisation des contenus créés
Étant donné que j'ai créé 10 contenus audio
Quand la suppression effective est exécutée
Alors mes contenus audio restent disponibles dans l'application
Et le nom du créateur devient "Utilisateur supprimé"
Et mon pseudo n'est plus visible
Et les métadonnées (titre, description, tags, géolocalisation) sont conservées
Et les fichiers audio restent sur le CDN
Et les statistiques d'écoute sont conservées
Scénario: Justification de l'anonymisation (intérêt légitime)
Étant donné que mes contenus sont conservés anonymement
Quand un auditeur RGPD vérifie la conformité
Alors la conservation est justifiée par l'intérêt légitime de la communauté
Et les contenus ne contiennent plus de données personnelles identifiables
Et la suppression complète nuirait à l'expérience des autres utilisateurs
Et cette pratique est conforme au RGPD si anonymisation réelle
Scénario: Contenu anonymisé visible pour les autres utilisateurs
Étant donné que mon compte a été supprimé
Et que mes contenus ont été anonymisés
Quand un utilisateur consulte un de mes anciens contenus
Alors le créateur affiché est "Utilisateur supprimé"
Et le profil du créateur n'est plus accessible
Et le contenu reste écoutable normalement
Et les likes et statistiques sont conservés
# Likes et abonnements supprimés
Scénario: Suppression de mes likes avec conservation des compteurs
Étant donné que j'avais liké 50 contenus
Quand la suppression effective est exécutée
Alors mes likes sont supprimés de la base de données
Mais les compteurs de likes sur les contenus sont préservés
Et les créateurs ne perdent pas leurs statistiques
Et seule la relation "user X a liké content Y" est supprimée
Scénario: Suppression de mes abonnements
Étant donné que je suivais 20 créateurs
Quand la suppression effective est exécutée
Alors mes abonnements sont supprimés
Et les compteurs d'abonnés des créateurs sont décrémentés de 1
Et les créateurs ne reçoivent pas de notification de désabonnement
# Sessions et tokens révoqués
Scénario: Révocation de tous les tokens immédiatement
Étant donné que je suis connecté sur 3 appareils (mobile, tablette, web)
Quand je demande la suppression de mon compte
Alors tous mes tokens d'authentification sont révoqués immédiatement
Et je suis déconnecté de tous mes appareils
Et toute tentative de reconnexion échoue
# Notifications avant suppression
Scénario: Rappels par email pendant le grace period
Étant donné que j'ai demandé la suppression de mon compte le 2025-01-20
Quand le grace period s'écoule
Alors je reçois des emails de rappel:
| date | jours restants | sujet email |
| 2025-02-04 | 15 jours | Plus que 15 jours pour annuler la suppression |
| 2025-02-12 | 7 jours | Dernière semaine pour annuler la suppression |
| 2025-02-17 | 2 jours | Attention: suppression définitive dans 2 jours |
Et chaque email contient le lien d'annulation
# Conformité RGPD Article 17
Scénario: Conformité droit à l'effacement
Étant donné que la suppression de mon compte est complète
Quand un auditeur RGPD vérifie la conformité
Alors le processus respecte l'article 17 du RGPD:
| exigence RGPD | respecté |
| Suppression de toutes les données personnelles | oui |
| Délai raisonnable (30j grace period acceptable)| oui |
| Possibilité d'annulation (bonne pratique) | oui |
| Anonymisation des contenus (intérêt légitime) | oui |
| Révocation des tokens et sessions | oui |
| Suppression irréversible | oui |
# Cas particuliers
Scénario: Suppression d'un compte Premium
Étant donné que j'ai un abonnement Premium actif
Quand je demande la suppression de mon compte
Alors mon abonnement est annulé immédiatement
Et aucun remboursement n'est effectué (conformément aux CGV)
Et je reçois un email de confirmation d'annulation de l'abonnement
Et le reste du processus de suppression se déroule normalement
Scénario: Suppression d'un compte créateur avec revenus en attente
Étant donné que je suis un créateur avec 75 de revenus en attente de paiement
Quand je demande la suppression de mon compte
Alors un message m'informe:
"""
Vous avez 75 de revenus en attente. Souhaitez-vous recevoir ce paiement avant suppression?
"""
Et je peux choisir "Recevoir le paiement et attendre" ou "Renoncer au paiement"
Et si je choisis "Recevoir le paiement", la suppression est repoussée de 7 jours
Scénario: Suppression avec signalements de modération en cours
Étant donné que j'ai 2 signalements en cours de traitement
Quand je demande la suppression de mon compte
Alors les signalements sont automatiquement clôturés
Et les contenus signalés sont masqués immédiatement
Et aucune sanction n'est appliquée (compte déjà en suppression)
# Traçabilité pour audit
Scénario: Log de la suppression pour traçabilité
Étant donné que la suppression effective est exécutée
Quand le job de suppression se termine
Alors un log est créé avec:
| champ | valeur |
| user_id | [ID anonymisé] |
| deletion_requested_at | 2025-01-20T10:00:00Z |
| deletion_executed_at | 2025-02-19T02:00:00Z |
| deletion_cancelled | false |
| data_deleted | [liste des tables] |
| contents_anonymized | 10 |
Et ce log est conservé 5 ans pour audit RGPD
Et l'user_id est pseudonymisé pour anonymat