# 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