Registre des activités de traitement (art. 30 du RGPD)
MousePlayer — LW IT Solutions Company Lukas Wójcik. Document interne de responsabilité, version 2, 16 octobre 2026 (version 1 sous forme de projet du 10 août 2026). Chaque nouvelle affirmation de cette version a été vérifiée au regard du code, du schéma et de la base de données ; les chiffres portent une date de mesure.
1. Comment lire ce registre
C’est un document interne de responsabilité au titre de l’art. 30 du RGPD. Ce n’est pas une notice de confidentialité, il n’est pas rédigé pour informer les personnes concernées, même s’il est publié, et il n’est pas rédigé pour faire bonne impression. Sa seule fonction est de permettre à une autorité de contrôle — ou à la prochaine personne devant répondre à une question — de voir ce qui est réellement traité, où cela se trouve et combien de temps cela reste.
Trois règles ont gouverné la rédaction. Premièrement : une affirmation n’est faite que lorsque le code, le schéma ou une mesure l’étaye. Lorsqu’une entrée manque, un espace réservé marque la lacune plutôt qu’une phrase plausible. Une lacune honnête résiste à un audit ; une supposition bien formulée, non. Deuxièmement : lorsque le code documente son propre raisonnement, celui-ci est cité avec le fichier et la ligne, pour qu’un lecteur ultérieur puisse le vérifier au lieu de faire confiance à ce document. Troisièmement : la conservation est indiquée deux fois — une fois pour les tables couvertes par la purge quotidienne, une fois pour celles qu’elle ne couvre pas. Un registre qui revendique un délai de suppression valable pour la moitié des tables est pire qu’un registre qui nomme la lacune, car c’est précisément cette lacune qui sera vérifiée.
BASE DE MESURE. Toutes les mesures se rapportent à l’instance de DÉVELOPPEMENT (www.mouseplayer.com, APP_ENV=dev) ; elles ne décrivent pas la production. Les décomptes de lignes, tailles de tables et valeurs de configuration sans date propre proviennent de la séance de mesure du 10 août 2026 et décrivent cet état ; les chiffres plus récents portent leur date (« au 16 octobre 2026 »). Les références aux fichiers et aux lignes sans date reflètent également l’état du 10 août 2026 : les numéros de ligne changent à chaque modification du code ; les fichiers et fonctions nommés font autorité. Chiffres de production : à compléter : les mêmes chiffres mesurés sur l’instance de production, avec la date de mesure
OMIS DÉLIBÉRÉMENT. L’analyse sous-jacente a consigné quatre adresses IP publiques complètes pour prouver que les anciens éléments ne sont pas masqués. Elles ne sont pas reproduites ici. Un registre des activités de traitement circule en interne et auprès des auditeurs ; il ne doit pas devenir lui-même une deuxième copie des données qu’il décrit. Le constat est énoncé ; les valeurs ne le sont pas.
2. L’entité, et pourquoi ce registre comporte deux parties
| Champ | Entrée |
|---|---|
| Entité juridique | LW IT Solutions Company Lukas Wójcik |
| Adresse | al. Tadeusza Kościuszki 80/82 lok. 301, 90-437 Lodz, Poland |
| Identification fiscale | NIP: PL7252266190 |
| Contact | office@mouseplayer.com (aucun numéro de téléphone publié) |
| Produit | MousePlayer — relecture de sessions, cartes de chaleur, analyse comportementale |
| Représentant au titre de l’art. 27 | Sans objet. L’entité est établie dans l’Union (Pologne). |
| Délégué à la protection des données | Aucun désigné. Voir la section 9 pour l’évaluation au titre de l’art. 37. |
MousePlayer occupe deux positions différentes vis-à-vis de deux groupes différents de personnes, et les mélanger produit un registre sans valeur pour les deux. Pour les données des VISITEURS des sites web clients, MousePlayer est sous-traitant et le client est responsable du traitement — l’art. 30(2) s’applique. Pour les données des propres CLIENTS de MousePlayer (comptes, facturation, assistance, journaux d’accès au portail), MousePlayer est responsable du traitement — l’art. 30(1) s’applique.
Ce n’est pas une commodité de rédaction. La distinction est déjà mise en œuvre dans le code et entraîne une conséquence technique différente pour chaque partie : class/Server.class.php:416 indique « REGEL B ... Hier sind wir AUFTRAGSVERARBEITER », et les lignes 421-425 séparent « Regel A (volle Adresse) fuer DIREKTE Zugriffe auf die eigene Anwendung » de la règle B (tronquée) pour les données des visiteurs. L’adresse IP d’un visiteur est tronquée à class/Server.class.php:432-435 ; celle d’un utilisateur client est stockée intégralement. Le système se comporte donc déjà comme si ce registre existait.
- Partie A (section 3) — art. 30(2) : vingt-deux activités de traitement (A.1 à A.22) effectuées pour le compte de responsables du traitement.
- Partie B (section 5) — art. 30(1) : huit activités de traitement (B.1 à B.8) effectuées sous la propre responsabilité de MousePlayer.
- Les sections 6 à 8 sont communes aux deux parties : conservation, prise de décisions automatisée et description générale des mesures techniques et organisationnelles.
- La section 10 énumère les lacunes dont l’existence est démontrée. Un registre est un instrument de travail, pas un certificat.
3. Partie A — art. 30(2) : activités effectuées pour le compte de responsables du traitement
A.0 Parties
| Champ | Entrée |
|---|---|
| Sous-traitant | LW IT Solutions Company Lukas Wójcik, al. Tadeusza Kościuszki 80/82 lok. 301, 90-437 Lodz, Poland. office@mouseplayer.com |
| Responsables du traitement | Les clients qui exploitent les sites web sur lesquels la balise MousePlayer (www/mp.js) est installée. Chaque responsable du traitement est identifié dans le système par projects.channelid ; les coordonnées se trouvent dans users et workspaces, l’appartenance et le rôle dans workspace_users. Mesuré sur l’instance de développement : 7 projets, 4 comptes clients, rôles 4 owner / 1 admin / 1 viewer. |
| Liste faisant autorité des responsables du traitement | Conservée dans le système, sans être dupliquée ici. La liste est générée, pas retranscrite : dans la zone d’administration, sous “Registres des activités de traitement (art. 30)”, un bouton la produit sur demande au format CSV — pour chaque espace de travail, le propriétaire avec nom, e-mail, entreprise, adresse, numéro de TVA, forfait et domaines concernés. Responsable de sa production : Lukas Wójcik, propriétaire ; elle est extraite à chaque réexamen de ce registre, soit chaque année et à chaque modification du traitement. Chaque extraction apparaît dans le journal des modifications (export_controllers). Une liste retranscrite ici constituerait un deuxième endroit pour la même vérité et deviendrait obsolète à chaque nouveau client sans que personne le remarque. (décision du responsable du traitement, 17 août 2026) |
| Représentant du sous-traitant | Sans objet (établi en Pologne). |
| Délégué à la protection des données | Aucun désigné — voir la section 9. |
| Mesures techniques et organisationnelles | La section 8 s’applique à chaque activité de la partie A et n’est pas répétée pour chaque activité. |
A.1 Relecture de sessions — capture des événements comportementaux
| Champ | Entrée |
|---|---|
| Origine des événements | Deux voies. (1) Le navigateur du visiteur via www/mp.js, où la machine à états mpEinw impose techniquement le consentement. mp.js transmet par HTTPS à nginx, où TLS se termine : normalement via le WebSocket à /mp_wss/ ; si le WebSocket ne se connecte jamais, depuis le 11 octobre 2026 par un tunnel HTTP à /mp_wst, auquel s’appliquent les mêmes vérifications du serveur WebSocket (consentement, détection des robots, origine, quota) ; les grands instantanés de pages, depuis le 7 octobre 2026, sous forme de téléversement HTTP à /mp_dom avec un accès signé à durée limitée (conservés dans Redis pendant au plus 120 secondes, puis traités comme un instantané ordinaire). Le point de mesure /mp_wsfail compte uniquement les connexions WebSocket échouées par projet, motif, famille de navigateurs et type d’appareil, sans identifiant de visiteur ; l’adresse IP n’y est que hachée et conservée au plus une heure pour la déduplication. (2) Côté serveur via www/api/capi_ingest.php depuis un système exploité par le client ; cette voie exige une signature (HMAC-SHA256 sur l’horodatage et le corps, fenêtre de cinq minutes) et une déclaration explicite pour chaque transmission attestant l’existence du consentement — sans elle, la requête est rejetée avec 403. MousePlayer ne peut pas vérifier le consentement sur cette voie par des moyens techniques ; le client, en tant que responsable du traitement, le garantit (accord de traitement des données, section 2). La voie peut être activée via site_settings.capi_ingest_aktiv ; elle était désactivée jusqu’au 18 août 2026 et est activée depuis lors. Il existe en outre une préversion d’un SDK d’application native (Android) avec sa propre voie de réception (www/api/native_ingest.php, tables mp_native_apps et mp_native_sessions) ; elle n’existe que sur l’instance de développement et est désactivée (native_preview_enabled = 0 ; au 16 octobre 2026, aucune session stockée). |
| Finalité | Enregistrer le comportement des visiteurs sur les sites web clients — mouvements de souris, clics, défilement, appuis, changements d’onglet — pour que le client puisse relire et analyser la session. |
| Catégories de personnes concernées | Visiteurs des sites web des clients de MousePlayer. |
| Catégories de données à caractère personnel | Coordonnées de déplacement, décalage temporel, position de défilement, hauteur du document ; type d’événement ; dimensions de la zone d’affichage et de l’écran ; identifiants de session et de page vue. Répartition mesurée des événements : move 100934, mutation 66153, scroll 28214, tab_focus 6185, resize 2590, screen_info 2034, pageview 2031, click 1863, input 599, input_mode 425, k 407, tap 401. Dans visitor_sessions en outre : référent, paramètres UTM, identifiant de clic d’un réseau publicitaire avec son type, chemin d’arrivée, canal de trafic, indicateur de navigateur intégré à une application, identifiant du navigateur (agent utilisateur), indicateur de robot avec motif, qualité de session et, depuis le 26 septembre 2026, un score de friction avec motifs (friction_score, friction_gruende). La répartition des événements ci-dessus a été mesurée le 10 août 2026. |
| Lieu de stockage | mouse_events (event_id, pageview_id, event_type, time_offset_ms, x, y, scroll_y, scroll_x, doc_height, target_selector) — 225892 lignes, 322,6 MB, la plus grande table du schéma. session_pageviews (pageview_id, session_id, tab_id, url, viewport_width, viewport_height, start_time, start_time_ms, end_time, page_title). visitor_sessions (session_id, channelid, screen_width, screen_height, start_time, end_time, duration_seconds, is_active, device_type). mouse_events_analytik (id, erfasst_am, pageview_id, channelid, event_type, time_offset_ms, x, y, target_selector) — 11812 lignes : une copie allégée des événements CLICK et de contexte, dans laquelle la couche de clics de la carte de chaleur lit. Elle est nommée séparément parce que sa conservation diffère de celle de mouse_events — ceux-ci passent dans l’archive après 7 jours, la copie reste et porte ainsi la carte des clics sur l’historique entier. Un agrégat quotidien en est construit chaque nuit, mp_hm_klick_tag avec mp_hm_ansicht_tag (depuis le 7 octobre 2026) : par jour, adresse, type d’appareil, classe d’écran, cible et cellule de 8 px, uniquement un nombre, sans session, identifiant de visiteur ni page vue. La carte des clics l’utilise pour les jours dont les sessions n’existent plus. La suppression de sessions ou de personnes individuelles ne l’affecte pas, car aucune ligne ne peut être attribuée à une personne. Depuis octobre 2026, en outre mp_aufnahme_quittung : pour chaque message entrant, un identifiant et un état ; pour un message qui ne peut pas être traité, également son contenu brut et le motif. Les lignes sont supprimées après 7 jours (srv/db_worker.php). Décomptes de lignes de cette entrée sans date : au 10 août 2026. |
| Base juridique (déterminée par le responsable du traitement) | Consentement. Raisonnement dans ai/migrations/018_consent.sql : l’enregistrement est une observation comportementale (considérant 24 du RGPD) et un accès à l’équipement terminal (par. 25 TDDDG) ; il exige un consentement, et l’intérêt légitime ne le justifie pas. Les 7 projets sont tous réglés sur projects.consent_mode='required'. Application côté serveur à class/Server.class.php:977-1004 ; coupe-circuit site_settings.consent_gate_active=1. |
| Catégories de destinataires | (a) Le client concerné — membres de l’espace de travail ayant le rôle owner, admin ou viewer. (b) Tout détenteur d’un lien de partage, SANS connexion : /s/<40-hex-token> est dirigé vers player.php?share=..., table session_shares. (c) En option, le client via REST API v1 avec sa propre clé API, uniquement avec un niveau payant ; au 16 octobre 2026, aucune clé API n’existe. (d) En option, les agents IA du client via le serveur MCP (/mcp) : accès en lecture avec une clé de lecture de l’API REST, à activer séparément pour chaque projet (projects.mcp_active, désactivé par défaut) ; les éléments disponibles sont les projets, chiffres clés, listes de sessions avec lien de relecture, sessions individuelles avec pages vues et événements, pages, signaux de frustration et objectifs — pas l’instantané de page. Au 16 octobre 2026, activé pour aucun projet. (e) Le client sous forme de fichier : export CSV de la liste des sessions et des réponses aux sondages depuis son interface, plafonné (csv_export_max_zeilen) ; chaque export est consigné dans le journal des modifications (csv_export). |
| Transfert vers un pays tiers | Aucun dans le parcours d’enregistrement. Aucun appel sortant n’a été constaté ; la résolution géographique utilise des fichiers MaxMind locaux. Voir la section 4. |
| Conservation | Selon le niveau de forfait, imposée par la purge quotidienne dans srv/db_worker.php (section 6.1) au moyen de la chaîne de suppression mp_sitzungen_loeschen() : free 7 jours, small 30, business 90, enterprise selon le niveau convenu (par défaut 365). Les sessions reconnues comme automatisées (robot) ont leurs propres délais plus courts : leur enregistrement (instantané de page et événements) est vidé une fois que retention_bot_recording_days est écoulé (délai en jours : 1), et la ligne de session avec tout ce qui lui est rattaché est supprimée une fois que retention_bot_session_days est écoulé (délai en jours : 14) ; les deux sont configurables dans la zone d’administration, et 0 désactive le délai distinct, de sorte que le délai du niveau de forfait s’applique. Après 7 jours, les événements passent de mouse_events à des fichiers d’archive comprimés par session (srv/cron_archiv.php) ; ils partagent le délai de leur session, sont supprimés avec elle et font partie de la sauvegarde quotidienne depuis le 6 octobre 2026 (section 4). Si un client supprime un projet, un espace de travail ou son compte, ou qu’une suppression par adresse IP ou par visiteur est déclenchée, depuis le 7 octobre 2026, les données sont d’abord archivées — masquées, sans nouvel enregistrement, restaurables — puis supprimées définitivement après au plus 30 jours (section 6.2, mp_loesch_archiv). |
A.2 Capture du contenu des pages — instantané du DOM et mutations du DOM
| Champ | Entrée |
|---|---|
| Finalité | Enregistrer le contenu des pages pour que la session puisse être relue telle que le visiteur l’a vue. |
| Catégories de personnes concernées | Visiteurs des sites web clients ; et, indirectement, toute personne dont la propre page du client affiche les données — par exemple une confirmation de commande montrant une adresse postale. |
| Catégories de données à caractère personnel | Le HTML complet de la page visitée, y compris texte, URL d’images et métadonnées, tel que rendu par le navigateur, sans scripts et avec le masquage décrit dans A.3. De plus, des fragments HTML sérialisés de chaque modification ultérieure du DOM, stockés dans le champ target_selector des événements de mutation. Depuis le 30 septembre 2026, en outre : le contenu des racines shadow ouvertes des composants web avec leurs feuilles de style (les racines shadow fermées ne sont pas enregistrées) ; les éléments canvas sous forme d’image fixe dans l’instantané et, lorsqu’ils changent, en continu sous forme d’image (au plus une fois par intervalle d’une seconde, avec un plafond par page vue ; pas dans les zones masquées ni pour les éléments canvas contenant des images d’origine différente) ; les iframes de même origine avec leur contenu et, depuis le 2 octobre 2026, les interactions en leur sein (pointeur, clics, saisies, défilement) ; les iframes d’origine différente uniquement sous forme d’espace réservé sans contenu. |
| Lieu de stockage | session_pageviews.payload_blob (longtext), stocké sous forme comprimée depuis le 14 août 2026 (préfixe MPZ1:, gzip, Base64) ; au 16 octobre 2026, toutes les lignes renseignées utilisent ce format. session_pageviews.has_recording est une colonne ordinaire, non générée : le worker la définit lors de l’écriture de l’instantané et la réinitialise lorsqu’il le vide ; de même pour hat_interaktion, hat_scroll et scroll_max_y. mouse_events.target_selector où event_type='mutation', y compris le contenu des racines shadow, canvas et iframes ; après 7 jours, dans les fichiers d’archive (A.1). session_pageviews.html_path existe, mais, au 16 octobre 2026, n’est défini sur aucune ligne. |
| Base juridique (déterminée par le responsable du traitement) | Consentement, comme dans A.1. |
| Catégories de destinataires | Le client, via www/player.php, www/ajax_get_events.php et www/player_theatre.php. Tout détenteur d’un lien de partage. PAS via l’API REST — www/api/v1_session_detail.php:25 consigne l’exclusion délibérée de la charge utile de relecture. |
| Transfert vers un pays tiers | Aucun dans le parcours d’enregistrement. |
| Conservation | Comme dans A.1 : avec la session au moyen de la purge quotidienne et de mp_sitzungen_loeschen() ; pour les sessions reconnues comme des robots, l’instantané est vidé après le délai de A.1 (retention_bot_recording_days, délai en jours : 1). Voir la section 6. |
| Note sur le périmètre du masquage | Le masquage ne s’applique qu’À L’INTÉRIEUR des zones marquées data-mp-mask ou .mp-masked (www/mp.js:3934-3970). Tout le reste du HTML de la page est stocké sans modification. Tout ce que la propre page du client affiche fait donc partie de l’enregistrement, et aucun paramètre de masquage ne l’atteint. |
A.2 est l’activité présentant l’éventail de données le plus large et le moins prévisible de tout le produit. Le masquage contrôle ce que le VISITEUR saisit ; il ne contrôle pas ce que la PAGE du client affiche. Si le site d’un client affiche à l’écran des informations de santé, financières ou d’autres catégories particulières, ce contenu entre dans l’instantané. Traitement de ce cas : autorisé, mais non recommandé. La responsabilité incombe au Client en tant que responsable du traitement ; MousePlayer fournit l’enregistrement et ne juge pas ce que la page affiche. L’utilisation dans les espaces connectés est expressément déconseillée lorsque des données de santé, bancaires ou similaires apparaissent à l’écran : aucun masquage de champs n’y aide, car il agit sur les champs de saisie et non sur ce que la page affiche. (décision du responsable du traitement, 17 août 2026) À reprendre comme règle d’intégration initiale et comme note dans le guide d’installation.
A.3 Capture des saisies de formulaires
| Champ | Entrée |
|---|---|
| Finalité | Enregistrer les saisies de formulaires, caractère par caractère, pour que l’interaction avec un formulaire puisse être relue. |
| Catégories de personnes concernées | Visiteurs des sites web clients. |
| Catégories de données à caractère personnel | Valeurs saisies dans les éléments input, textarea et select — entièrement masquées, partiellement masquées ou en clair selon le niveau de masquage. L’état des cases à cocher et des boutons radio (true/false), qui n’est JAMAIS masqué (www/mp.js:4810-4811). La catégorie de champ déduite par classifyFieldName() (www/mp.js:4657-4674) : email, password, phone, payment, address, name, search, coupon, quantity, other. |
| Lieu de stockage | mouse_events.target_selector où event_type='input', format {"t":"<data-mp-id>","v":"<value>"} — 599 lignes. |
| Base juridique (déterminée par le responsable du traitement) | Consentement, comme dans A.1. |
| Catégories de destinataires | Le client (lecteur) ; tout détenteur d’un lien de partage. |
| Transfert vers un pays tiers | Aucun dans le parcours d’enregistrement. |
| Conservation | Aucun délai propre ; comme dans A.1, avec la session (délai du niveau de forfait, pour les robots les délais de A.1), après 7 jours dans les fichiers d’archive. |
| Garanties en vigueur | Niveau minimal strict pour les mots de passe et les données de paiement quel que soit le niveau (www/mp.js:4831-4837). Masquage complet au niveau 0 (www/mp.js:4818-4819). Les 7 projets sont tous réglés sur projects.smart_masking=0, qui est le paramètre LE PLUS STRICT malgré le libellé. |
| Constat sur les anciennes données | Le 10 août 2026, 173 lignes dans mouse_events contenaient des saisies en clair NON MASQUÉES du 2026-07-21 au 2026-07-27, y compris des noms de personnes ; les lignes à partir de ce jour sont masquées. Au 16 octobre 2026, il ne reste aucune saisie non masquée dans mouse_events (mesuré avec la même requête). Les lignes concernées ont été supprimées le 17 août 2026 (analyse d’impact, R2), soit avant l’introduction des fichiers d’archive le 18 août 2026 ; elles ne peuvent donc pas se trouver dans les fichiers d’archive ni dans la sauvegarde qui les inclut depuis le 6 octobre 2026. Les copies chiffrées de cette époque sur Google Drive ont été supprimées le 6 septembre 2026 ; aucune sauvegarde restante antérieure au 17 août 2026 n’est connue, mais son absence n’a pas été vérifiée en détail. |
A.4 Reconnaissance du visiteur entre les sessions
| Champ | Entrée |
|---|---|
| Finalité | Reconnaître un visiteur entre les sessions et les pages vues. |
| Catégories de personnes concernées | Visiteurs des sites web clients. |
| Catégories de données à caractère personnel | Identifiant de visiteur pseudonyme, généré et conservé dans le localStorage du visiteur sous 'mp_visitor_id' (www/mp.js:5056-5059). Un identifiant en clair défini par le client — identifiant de connexion ou numéro de client — par MousePlayer.setUserId() (www/mp.js:4909-4913, localStorage 'mp_user_id'), et automatiquement depuis le chemin dataLayer 'uid' (www/mp.js:3585-3637). Pseudonyme et nom de navigateur par visiteur, conservés ENTRE projets (UNIQUE sur visitor_id). |
| Lieu de stockage | visitor_sessions.visitor_id (varchar 64), custom_user_id (varchar 128, index propre idx_custom_user_id), nickname_key. visitor_nicknames (visitor_id, nickname_key, browser_name, city, created_at) — 329 lignes ; la colonne city est vide dans les 329. consent_events.visitor_id. |
| Base juridique (déterminée par le responsable du traitement) | Consentement, comme dans A.1. |
| Catégories de destinataires | Le client. Via custom_user_id, la fusion avec les propres dossiers clients du client constitue un usage explicitement prévu. |
| Transfert vers un pays tiers | Aucun dans le parcours d’enregistrement. |
| Conservation | Avec la dernière session du visiteur. mp_sitzungen_loeschen() (srv/db_worker.php) vérifie après chaque suppression s’il reste une session pour ce visiteur et supprime le pseudonyme dans le cas contraire ; le parcours de suppression dans le lecteur fait de même. La purge quotidienne selon le niveau de forfait appelle la même fonction ; un élément orphelin ne peut donc plus apparaître. Il n’existe aucun délai distinct et aucun n’est nécessaire : l’entrée ne survit jamais aux sessions qu’elle nomme. |
A.5 Données de réseau et localisation approximative
| Champ | Entrée |
|---|---|
| Finalité | Déterminer le réseau et la localisation approximative du visiteur, ainsi que la région pour la vérification du consentement. |
| Catégories de personnes concernées | Visiteurs des sites web clients. |
| Catégories de données à caractère personnel | Adresse IP (tronquée dans le parcours d’enregistrement, voir ci-dessous), code pays à deux caractères, ville (déterminée à partir de l’adresse tronquée, et non complète), numéro ASN et nom du fournisseur, code de région. |
| Lieu de stockage | visitor_sessions.ip_address (varchar 45), country, city, asn_number, asn_org, region_code. ip_lifetime_stats (ip_address, first_seen, total_conns, total_msgs, total_traffic, total_uptime_sec) — 446 lignes. |
| Base juridique (déterminée par le responsable du traitement) | Consentement pour l’enregistrement. La détermination du pays est délibérément effectuée côté serveur pour qu’aucun tiers ne soit contacté avant l’existence du consentement (class/Server.class.php:941-944). |
| Catégories de destinataires | Aucun destinataire externe. La résolution géographique utilise des fichiers MaxMind LOCAUX sous cfg/maxmind/ (GeoLite2-City et GeoLite2-ASN ; lus dans class/IP2CityLite.class.php et class/Server.class.php), que srv/geoip_update.sh télécharge régulièrement depuis MaxMind ; aucune donnée de visiteur n’est transmise au cours de ce processus. Les valeurs obtenues sont stockées dans visitor_sessions et visibles pour le client comme le reste de l’enregistrement de session. |
| Transfert vers un pays tiers | Aucun. Aucun appel sortant dans le parcours d’enregistrement. |
| Troncature | Le serveur WebSocket (class/Server.class.php, règle B) remplace le dernier octet IPv4 par 'xxx' et le dernier groupe IPv6 par ':xxxx', immédiatement après avoir déterminé l’adresse de la connexion (derrière nginx à partir de X-Forwarded-For, auquel il ne fait confiance que depuis le pair local), et donc avant tout consommateur. L’adresse complète n’existe que temporairement dans la mémoire du serveur WebSocket, dans des compteurs Redis expirant après quelques secondes et — pour les adresses déclenchant un blocage automatique — pendant la durée du blocage (24 h) dans Redis (mp_autoban:) ; l’instance Redis écrit ses données sur disque pour la persistance (AOF). Au 16 octobre 2026, aucune ligne dans visitor_sessions ou ip_lifetime_stats ne contient d’adresse non tronquée. |
| Conservation et constat sur les anciennes données | 365 jours à compter de first_seen pour ip_lifetime_stats, imposés par l’exécution quotidienne dans srv/db_worker.php ; la valeur se trouve dans site_settings sous retention_ip_stats_days et est configurable dans la zone d’administration. visitor_sessions relève de la purge selon le niveau de forfait. Le constat sur les anciennes données est clôturé : mesuré le 17 août 2026, 267 sur 267 adresses dans ip_lifetime_stats ont été tronquées, ainsi que 881 sur 901 dans visitor_sessions. Les 20 restantes portent 0.0.0.0 et proviennent des données de test de l’analyse de formulaires (s_mptest_form_) — ce ne sont pas des adresses de visiteurs. |
A.6 Enregistrements du consentement
| Champ | Entrée |
|---|---|
| Finalité | Démontrer le consentement et chacune de ses modifications (art. 7(1) du RGPD). |
| Catégories de personnes concernées | Visiteurs des sites web clients. |
| Catégories de données à caractère personnel | État (GRANTED, GRANTED_LATE, withdrawn, region_exempt), source, horodatage ; nom et version de la CMP ; SHA-256 de la chaîne TC — délibérément pas la chaîne elle-même ; signal GPC ; code de région ; version de la configuration du projet. |
| Lieu de stockage | consent_events (id, session_id, channelid, visitor_id, consent_state, consent_source, cmp_name, cmp_version, tcf_hash, gpc_signal, region_code, consent_config_version, occurred_at, created_at) — 120 lignes. visitor_sessions.consent_state, consent_source, consent_ts, cmp_name, cmp_version, tcf_hash, gpc_signal, region_code, consent_config_version, recording_offset_ms. |
| Base juridique | Obligation de démonstration, justifiée dans ai/migrations/018_consent.sql : la charge de prouver un consentement valable incombe au responsable du traitement, et sans journal, rien ne peut être présenté en cas de litige. |
| Catégories de destinataires | Le client. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | 730 jours, comptés à partir de the withdrawal. Le délai et le point de départ se trouvent dans site_settings (consent_evidence_days, consent_evidence_anchor) et sont configurables dans la zone d’administration ; imposés par l’exécution quotidienne dans srv/db_worker.php. Lors de la suppression d’une session, la preuve n’est toujours pas supprimée, mais dépersonnalisée : le fait qu’une décision a été prise doit rester démontrable (art. 5(2)), l’identité de la personne qui l’a prise n’a pas à l’être. Seuls les enregistrements auxquels aucune session ne renvoie encore sont supprimés — tant que l’enregistrement existe, sa preuve doit exister, sinon il se trouverait là sans autorisation. |
| Qualité des données | 671 sessions sur 706 portent consent_source='testdata' avec consent_ts IS NULL, définis par ai/devdata/001_altsitzungen_markieren.sql. Ce ne sont PAS de véritables preuves du consentement. Véritables enregistrements : 27 (api), 5 (gcm), 2 GRANTED_LATE (api), 1 withdrawn (gcm). |
| Suppression lors du retrait | Facultative et désactivée partout : projects.consent_delete_on_withdraw=0 pour les 7 projets, évalué à srv/db_worker.php:1067-1070. Un retrait arrête donc tout nouvel enregistrement, mais ne supprime rien. |
A.7 Événements personnalisés, signaux de frustration et erreurs JavaScript
| Champ | Entrée |
|---|---|
| Finalité | Enregistrer les événements définis par le client, les signaux de frustration et les erreurs JavaScript survenant sur la page du client. |
| Catégories de personnes concernées | Visiteurs des sites web clients. |
| Catégories de données à caractère personnel | Nom d’événement — mesures : dead_click 355, gtm.scrollDepth 290, rage_click 52, text_copied 26, text_selected 26, error_detected 22, consent_status 19, consented_ready 17, consented_update 8, mouse_thrashing 5, add_to_cart 3. Valeurs des paramètres — target 407, tag 386, desc 274, count 57, length 52, snippet 22, message 22, type 19, filename 9, lineno 9, masked_area 4, price 1, currency 1, item_id 1. Deux d’entre eux contiennent plus que leur nom ne le suggère : 'snippet' sur text_copied et text_selected est le texte de la page que le visiteur a sélectionné ou copié ; 'filename' contient des URL complètes et il a été constaté qu’il contenait une adresse moz-extension://, qui est un identifiant d’extension de navigateur propre à l’appareil. |
| Lieu de stockage | session_custom_events (event_id, session_id, pageview_id, event_name, created_at) — 823 lignes. session_custom_event_params (param_id, event_id, param_key, param_string_value, param_int_value, param_float_value) — 1264 lignes. |
| Base juridique (déterminée par le responsable du traitement) | Consentement, comme dans A.1. |
| Catégories de destinataires | Le client. En option, par webhook vers une URL librement choisie par le client — voir la section 4. |
| Transfert vers un pays tiers | Par le webhook, la destination est indéterminée et donc potentiellement un pays tiers. Actuellement inactif : projects.webhook_active=0 et webhook_url NULL pour les 7 projets. |
| Conservation | Avec la session au moyen de la purge quotidienne et de mp_sitzungen_loeschen() (délai du niveau de forfait, pour les robots les délais de A.1) ; session_custom_event_params dépend de session_custom_events par FOREIGN KEY ON DELETE CASCADE. Événements de console, de réseau et Web Vitals dans mouse_events comme dans A.1 ; mp_cwv est supprimé avec sa page vue (nettoyage horaire). |
| Messages de console et requêtes réseau (depuis le 30.09.2026) | Ce que la page écrit dans la console du navigateur (le niveau est défini par l’exploitant, par défaut : erreurs et avertissements) et les requêtes de la page qui échouent ou dépassent un seuil de durée configuré : méthode, adresse, code d’état et durée. Jamais les en-têtes ni le corps d’une requête ou d’une réponse, jamais le contenu des objets journalisés, seulement leur type. Les textes passent par un filtre avant d’être envoyés (adresses e-mail, adresses IP, longues suites de chiffres, jetons d’accès) ; les adresses perdent les valeurs des paramètres portant des noms sensibles. Les requêtes vers MousePlayer lui-même ne sont pas capturées. Stockés comme un événement de souris dans mouse_events (event_type con ou net), avec la même chaîne de conservation et de suppression que l’enregistrement (A.1) ; affichés dans le lecteur à côté de la chronologie. |
| Temps de chargement et de réponse (Web Vitals, depuis le 02.10.2026) | Vitesse de chargement et de réaction de la page pour le visiteur, mesurée dans le navigateur pour chaque page vue : Largest Contentful Paint, Interaction to Next Paint, Cumulative Layout Shift, First Contentful Paint et Time to First Byte. En outre, une brève description du plus grand élément visible et de l’élément de l’interaction la plus lente, comme pour un clic (type, identifiant, texte visible ; dans les zones masquées, uniquement le type). Aucune saisie, aucun contenu de requête. Stockés comme un événement de souris dans mouse_events (event_type cwv) et pour chaque page vue dans mp_cwv, avec la même chaîne de conservation et de suppression que l’enregistrement (A.1) ; affichés dans l’onglet Web Vitals et dans l’en-tête du lecteur. |
A.8 Caractéristiques déduites et chronologies de sessions générées par une machine
| Champ | Entrée |
|---|---|
| Finalité | Déduire des caractéristiques et des comptes rendus textuels générés par une machine pour chaque session — notation du caractère remarquable et de l’attention. |
| Catégories de personnes concernées | Visiteurs des sites web clients. |
| Catégories de données à caractère personnel | Vecteur de caractéristiques : durée, nombre de pages, profondeur de défilement / médiane / inversions, pauses, efficacité du parcours, vitesse de pointe, clics de rage et clics morts, appuis, zoom, source et campagne, temps passé par rôle d’élément (role_dwell_json), comportement des onglets. Évaluations : engagement_score (0-255), session_quality, is_bot. Une chronologie de la session en texte suivi — exemple : 't=0.0 landing / src=(direct) kanal=direct attr=direct mode=unknown motion=unavailable viewport=1699x935 / t=2.0 session ende'. |
| Lieu de stockage | ai_session_features — 4043 lignes (une ligne par session ET builder_version, une session apparaît donc une fois par version). ai_timelines (timeline_id, session_id, channelid, builder_version, input_mode, line_count, char_count, pageviews, duration_s, text en mediumtext, built_at) — 3203 lignes, 5,5 MB. mp_session_ziel (channelid, session_id, goal_id, tag, ziel_fp, gebaut_am) — 628 lignes : quelle session a atteint quel objectif, calculé une fois plutôt qu’à chaque requête. ziel_fp est l’empreinte de la règle d’objectif ; lorsque le responsable du traitement la modifie, la correspondance est reconstruite plutôt que réutilisée silencieusement. mp_hm_tag (channelid, tag, url_md5, url, titel, ansichten, engagiert) et mp_hm_tag_stand (channelid, tag, berechnet_am), depuis le 24 septembre 2026 (migration 148) : pour chaque projet, jour et adresse de page, le nombre de pages vues et de pages vues engagées, à partir desquels la liste des cartes de chaleur des pages est servie. Uniquement des nombres et des adresses — aucun identifiant de visiteur ou de session ; le nombre de visiteurs par adresse est toujours compté à partir des sessions elles-mêmes. |
| Base juridique | Non documentée dans le code. Déduite de l’enregistrement et donc indirectement couverte par le consentement obtenu pour celui-ci. Instruction : elle naît lors de l’inscription du Client et est exécutée dès qu’il installe le script sur son site et que des visiteurs sont enregistrés (déclaration du responsable du traitement, 17 août 2026). La déduction de caractéristiques, de chronologies et de niveaux de valeur fait partie du service commandé. Deux parties sont distinguées. Les niveaux de valeur sont définis par le Client sur son propre projet ; chaque modification est journalisée (log_audit, save_wertregeln). Les résumés rédigés par le modèle de langage dépendaient jusqu’au 17 août 2026 uniquement d’un paramètre global dans la zone d’administration — le Client n’avait aucune influence dessus ; ils ne reposaient donc pas sur son instruction. Depuis la migration 041, projects.ki_texte_aktiv décide en outre, activé par défaut ; le Client peut le désactiver à tout moment dans l’onglet des paramètres, et chaque modification apparaît comme ki_texte_changed dans le journal des modifications. L’interrupteur n’est pas l’instruction, mais le moyen de la limiter : activé par défaut signifie que le Client ne l’a pas activé, mais a simplement omis de le désactiver. |
| Catégories de destinataires | Le client (cfg/project_ai_overview.php). |
| Transfert vers un pays tiers | Aucun. Les phrases générées sont formulées par le modèle de langage sur notre propre matériel à Łódź (section 4) ; rien n’est envoyé à un service d’IA externe. |
| Conservation | Avec la session. ai_session_features et ai_timelines font partie de mp_sitzungen_loeschen() (srv/db_worker.php) depuis le 12 août 2026 et sont donc supprimés aussi bien lors d’une suppression explicite que par la purge quotidienne selon le niveau de forfait. Cette cellule disait auparavant le contraire ; c’était l’état antérieur à ce changement. La notation par visiteur et par jour qui en est déduite (ai_visitor_value) et les textes générés (ai_insights) ont en outre leur propre délai — voir la section 6.2. |
A.9 Collaboration sur la relecture — commentaires et liens de partage
| Champ | Entrée |
|---|---|
| Finalité | Commenter une relecture à un repère temporel et partager une relecture par lien. |
| Catégories de personnes concernées | Utilisateurs clients (les auteurs) et, indirectement, visiteurs enregistrés. |
| Catégories de données à caractère personnel | Texte du commentaire (jusqu’à 2000 caractères), décalage temporel, auteur. Jeton de partage (40 caractères hexadécimaux), créateur, expiration, révocation, nombre d’accès, dernier accès. |
| Lieu de stockage | session_comments (comment_id, channelid, session_id, user_id, time_offset_ms, body, created_at, updated_at) — 12 lignes. session_shares (share_id, channelid, session_id, token, created_by, expires_at, revoked_at, last_seen, view_count, created_at) — 9 lignes. |
| Base juridique | Non documentée dans le code. Instruction : le Client autorise expressément le partage, y compris en dehors de sa propre organisation, et en assume la responsabilité (décision du responsable du traitement, 17 août 2026). L’instruction est documentée par l’acte lui-même : le lien est créé par un membre autorisé de l’espace de travail du Client, et sa création est journalisée (log_audit, action create_share ; révocation sous revoke_share). MousePlayer fournit la fonction ; le choix des destinataires et la licéité de la divulgation incombent au Client. Limitation technique : chaque lien expire — 7 jours par défaut, 90 au maximum — et peut être révoqué à tout moment. |
| Catégories de destinataires | Tout détenteur d’un lien de partage, SANS connexion (www/.htaccess:77). Les jetons inventés, expirés et révoqués renvoient tous la même réponse ; ils ne peuvent donc pas être sondés pour obtenir des informations. |
| Transfert vers un pays tiers | Indéterminé par conception — un lien peut être transmis n’importe où. C’est une propriété de la fonctionnalité, pas un incident. |
| Conservation | Avec la session : session_comments et session_shares font partie de mp_sitzungen_loeschen() depuis le 12 août 2026 et sont supprimés avec la session. Indépendamment de cela, les liens de partage ont leur propre durée de vie maximale : session_shares.expires_at est NOT NULL, mp_share_erstellen() (cfg/lib.php) fixe par défaut 7 jours et plafonne à 90. L’application ne peut pas créer de lien illimité. Une fois un lien expiré ou révoqué, la purge quotidienne supprime sa ligne 90 jours plus tard ; les accès dans share_views sont supprimés avec elle via la clé étrangère (B.6). |
A.10 Vue en direct — observer une session pendant son déroulement
| Champ | Entrée |
|---|---|
| Finalité | Observation en temps réel d’une session en cours : liste en direct des visiteurs présents, mode suivi avec un instantané de page reproduit en miroir, position du pointeur transmise et, depuis le 16 août 2026, état de survol reconstitué (:hover). |
| Catégories de personnes concernées | Visiteurs des sites web des Clients (observés), utilisateurs clients (observateurs). |
| Catégories de données à caractère personnel | Les mêmes catégories que dans A.1 et A.2 — positions du pointeur et de défilement, clics, événements de saisie, instantané de page et ses mutations — mais au moment où elles se produisent. Plus l’identifiant de session, pour que l’observateur suive la bonne session. |
| Lieu de stockage | Non stocké. Le flux passe par le serveur WebSocket (class/Server.class.php) et est transmis au sein du processus aux observateurs connectés. Le jeton d’accès est conservé dans la table de base de données live_tokens (identifiant, projet, identifiant utilisateur, le cas échéant la session suivie, heure de la dernière confirmation). Depuis le 17 septembre 2026, le lecteur d’une session en cours se raccorde également à ce flux avec son propre accès (identifiant avec le préfixe pl_, lié à la session suivie) pour afficher ses événements sans délai. L’enregistrement de la même session est créé indépendamment via A.1 et A.2. |
| Base juridique | Instruction : l’observation est lancée par un membre autorisé de l’espace de travail du Client ; l’accès passe par un jeton à durée limitée dans live_tokens lié à son identifiant utilisateur. L’utilisateur final n’est pas informé séparément au moment de l’observation (décision du responsable du traitement, 17 août 2026). L’information est donnée à l’avance : par le consentement qui précède tout enregistrement et par la politique de confidentialité, qui indique expressément depuis le 17 août 2026 qu’une session en cours peut être suivie en temps réel. Jusqu’alors, elle ne nommait la vue en direct que comme une fonctionnalité dans une liste — la décision reposait donc sur une phrase qui n’existait pas encore. |
| Catégories de destinataires | Le Client, avec une limitation aux membres autorisés de l’espace de travail. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | Le flux lui-même n’est pas stocké. Le serveur WebSocket supprime une ligne dans live_tokens après la fin de la vue, avec un bref délai de grâce pour un rechargement ; un accès qui n’est plus confirmé perd son effet après un court délai et est nettoyé plus tard. |
Cette entrée était absente du registre jusqu’au 17 août 2026. Elle doit être séparée de A.1 et A.2 même si les mêmes données circulent : là, elles sont relues plus tard ; ici, un humain regarde au moment où le visiteur agit. Cette simultanéité est précisément la caractéristique sur laquelle l’art. 35(3) s’appuie pour définir la surveillance systématique, et l’AIPD fonde sa propre nécessité dessus.
A.11 Journal de livraison des intégrations
| Champ | Entrée |
|---|---|
| Finalité | Preuve et dépannage pour les transmissions énumérées sous 4.1. Sans cela, le responsable du traitement ne peut pas savoir si une passerelle fonctionne — un échec serait silencieux de son côté. |
| Catégories de personnes concernées | Visiteurs des sites web clients, dans la mesure où le responsable du traitement leur a attribué un identifiant client. Sans identifiant défini, l’entrée ne contient aucun lien personnel. |
| Catégories de données à caractère personnel | Horodatage, type de passerelle, un identifiant (l’identifiant client fourni par le responsable du traitement via setUserId, le réseau publicitaire ou le nom de l’événement), réussite ou échec, durée en millisecondes, numéro de tentative et texte de réponse ou d'erreur du destinataire. Ce texte peut contenir un identifiant d’enregistrement du système tiers. Aucune donnée comportementale, aucun contenu de page, aucune adresse IP. |
| Lieu de stockage | Redis, clé mp_webhook_log:<channelid>. Les 25 dernières entrées par projet ; les plus anciennes sont retirées via lTrim. Pas dans la base de données, et donc pas dans la sauvegarde quotidienne. |
| Base juridique (déterminée par le responsable du traitement) | Comme dans A.1. L’entrée n’apparaît que si le responsable du traitement a activé une passerelle — elle consigne l’exécution de sa propre instruction. |
| Catégories de destinataires | Le responsable du traitement, via les paramètres du projet (onglet Intégrations). Aucune divulgation ultérieure. |
| Transfert vers un pays tiers | Aucun. L’entrée ne quitte pas notre propre serveur. |
| Conservation | 30 jours. Défini comme délai d’expiration Redis lors de l’écriture ; en outre plafonné à 25 entrées par projet. Il expire de lui-même et ne nécessite aucune exécution d’effacement. Le chiffre se trouve dans site_settings.retention_intlog_days et est réglable dans la zone d’administration. |
A.12 Profils de comportement — regroupement automatisé des visites
| Champ | Entrée |
|---|---|
| Finalité | Regroupement automatisé des VISITES enregistrées selon leur déroulement, afin que le responsable du traitement n’ait pas à examiner les sessions l’une après l’autre, mais voie des groupes — et puisse relire une visite typique par groupe. En parallèle, séquences récurrentes de pages et d’événements au sein de la fenêtre de calcul. |
| Catégories de personnes concernées | Visiteurs des sites web clients. Ce qui est regroupé, ce sont des VISITES, pas des personnes : la même personne avec deux visites peut se retrouver dans deux groupes, et l’interface est formulée ainsi. Aucun profil par PERSONNE n’est calculé — il nécessiterait l’identifiant client fourni par setUserId, et 0 session sur 4226 en porte un (mesuré le 27.08.2026). |
| Catégories de données à caractère personnel | Aucune nouvelle catégorie. Le vecteur de caractéristiques de A.8, restreint aux sept caractéristiques dont le taux de renseignement dépasse 90 % : durée, nombre de pages, score d’attention, pauses, clics de rage, clics morts, changements d’onglet. En sont déduits : le groupe auquel appartient une session et sa distance au centre du groupe. Pour chaque groupe, en outre, l’identifiant de session de la visite la plus typique et de la moins typique, pour que les deux puissent être relues. Pour les séquences : chaîne des motifs de chemins et de noms d’événements, et jusqu’à trois identifiants de session comme exemples. Aucun contenu de page, aucune adresse IP, aucune saisie de formulaire. |
| Lieu de stockage | mp_profile — une ligne par canal et groupe (taille, part, centre, chiffres clés, nom calculé, nom attribué par soi-même, représentant, valeur aberrante) ; 15 lignes. mp_profil_sitzung — session vers groupe et distance ; 4226 lignes. mp_sequenzmuster — chaîne, support, lift, jusqu’à trois exemples ; 115 lignes. Tous trois sont des DÉRIVATIONS : ils peuvent être perdus et recalculés à tout moment et ne contiennent aucune donnée brute qui n’existe pas aussi ailleurs. Depuis le 6 septembre 2026, mp_profil_sitzung contient en outre la clé de personne (person_key, migration 112) : une copie de la clé de A.4 (identifiant client, sinon identifiant de visiteur), que l’exécution des profils met à jour quotidiennement ; la liste des visiteurs récurrents en est calculée. Décomptes de lignes de cette entrée : au 27 août 2026. |
| Base juridique | Comme dans A.8. Déduit de l’enregistrement et donc indirectement couvert par le consentement obtenu pour celui-ci. Instruction : partie du service commandé ; elle naît lors de l’inscription du client et est exécutée dès l'enregistrement de visiteurs. Deux limites méritent d’être nommées. Le regroupement est CALCULÉ, et non généré : le groupe auquel appartient une visite est déterminé par k-means sur les sept caractéristiques dans ai/profile.py, et les noms des groupes proviennent de la position relative du centre, pas d’un texte. Lorsqu’un modèle de langage écrit effectivement une phrase sur un groupe, seules les données chiffrées du GROUPE lui sont remises — pourcentages et moyennes —, jamais un identifiant de session ou de visiteur, et le même garde-fou que dans A.8 rejette tout nombre qui ne figure pas parmi ces données. Il n’existe toutefois aucun interrupteur par projet : profile_aktiv est un paramètre global de l’exploitant, et la sélection des sections d’IA par projet (projects.ki_module) ne couvre pas cet onglet. Consigné comme une lacune dans la section 10. |
| Catégories de destinataires | Le client, via l’onglet Profils de comportement (cfg/project_profiles.php). Aucun transfert à des tiers : l’appartenance à un groupe n’entre dans aucune des passerelles de 4.1. Vérifié par une recherche de profil_key dans cfg/, srv/, www/ et class/ — il n’apparaît que dans le parcours de lecture et dans le lecteur, ni dans www/mp.js ni dans class/Server.class.php, et n’atteint donc jamais non plus le navigateur d'un visiteur. |
| Transferts vers des pays tiers | Aucun. Le calcul s’exécute sur la même machine (ai/profile.py, lancé par srv/ai_worker.php). La phrase facultative par groupe est formulée par le modèle de langage sur l’une de nos propres machines dotées d’une carte graphique dans le même réseau local (voir la section 4), qui ne récupère que les données chiffrées du groupe, par HTTPS. Rien n’est envoyé à un service d’IA externe. |
| Conservation | Avec la session : mp_profil_sitzung fait partie de mp_sitzungen_loeschen(). Au-delà, 180 jours, avec pour point de départ le DÉBUT DE LA SESSION et non le moment du calcul — l’exécution quotidienne actualise celui-ci à chaque passage ; un délai rattaché à ce moment n’expirerait donc jamais et personne ne le remarquerait. Les lignes dont la session n’existe plus sont supprimées sans aucun délai, car tout délai est sans objet pour une ligne qui a disparu. Le chiffre se trouve dans site_settings.retention_profile_days, est réglable dans la zone d’administration et est relevé au moins à la durée de la fenêtre de calcul, pour que la suppression ne retire pas ce que le calcul des profils a écrit le même jour. mp_profile est supprimé dès qu’aucune affectation ne lui reste, lors de la même exécution nocturne — c’est pourquoi cette affirmation vient après les deux précédentes. mp_sequenzmuster est supprimé après 180 jours sans recalcul, et immédiatement lorsque son canal n’a plus aucune session. Ici, le point de départ EST le moment du calcul, à juste titre : contrairement à une affectation, un motif décrit la fenêtre ACTUELLE et est réécrit intégralement par canal à chaque exécution ; un horodatage récent signifie donc réellement „décrit les données d'aujourd’hui“. |
A.13 Nom personnalisé pour un visiteur — attribué par le responsable du traitement
| Champ | Entrée |
|---|---|
| Finalité | Le responsable du traitement donne à un visiteur individuel un nom de son choix afin de le reconnaître dans les listes et les enregistrements. Ce nom remplace le pseudonyme généré de A.4 partout où celui-ci apparaîtrait autrement. Le cas d’usage est la demande d’assistance : „c’est le client qui a appelé“. |
| Catégories de personnes concernées | Visiteurs des sites web clients — précisément, des individus choisis par le responsable du traitement. Contrairement à A.1 à A.12, ce traitement ne survient pas de lui-même lorsque quelqu’un ouvre la page ; il exige une saisie délibérée. Sans cette saisie, il n’existe aucune ligne : le 28.08.2026, 0 visiteur sur 3830 porte un nom personnalisé. |
| Catégories de données à caractère personnel | TEXTE LIBRE de 64 caractères au maximum, plus l’heure et le compte utilisateur de l’attribution. La référence est l’identifiant de visiteur de A.4. Le contenu n’est ni prescrit ni vérifié — il peut s’agir d’un numéro de contrat, d’un pseudonyme ou d’un nom en clair accompagné d’un service. Cela distingue ce traitement de tous les autres de la partie A : là, les données proviennent du visiteur ou sont calculées à partir de son comportement ; ici, le responsable du traitement les saisit. Signalé comme une lacune dans la section 10. |
| Lieu de stockage | visitor_nicknames.custom_label, label_set_at, label_set_by (migration 093) — la même ligne qui porte déjà le pseudonyme généré, une par visiteur, 3830 lignes. Délibérément pas une table propre : le nom remplace exactement le pseudonyme qui y est stocké, dépend de la même clé et est donc supprimé avec lui sans autre intervention. Une table distincte serait un cinquième endroit dans la chaîne de suppression, et un endroit qui peut être oublié. |
| Base juridique | Instruction du responsable du traitement (art. 28(3)(a)), donnée par la saisie elle-même — aucune tâche ni aucun paramètre par défaut ne crée de nom. MousePlayer ne peut pas juger s’il existe une base juridique pour le contenu saisi : le responsable du traitement choisit le texte et connaît le contexte dont il est tiré. L’indication du champ de saisie précise donc la finalité („seule votre équipe voit ce nom“) et pas seulement le champ. |
| Catégories de destinataires | Le client, dans ses propres listes et dans le lecteur. Aucune divulgation à des tiers : le champ n’entre dans aucune des passerelles de 4.1 — vérifié par une recherche de custom_label dans cfg/, srv/, www/ et class/ ; il n’apparaît ni dans www/mp.js ni dans class/Server.class.php et n’atteint donc jamais non plus le navigateur du visiteur. Le lien de partage (B.6) ne le montre délibérément PAS, mais montre le pseudonyme généré à la place : transmettre un lien qui n’exige aucune connexion partage un enregistrement, pas l’identité qui se trouve derrière. La même considération que dans www/selbstauskunft.php. |
| Transferts vers des pays tiers | Aucun. Le champ ne quitte la base de données que pour entrer dans l’interface du client connecté. |
| Conservation | Avec la dernière session du visiteur, comme la ligne dans laquelle il se trouve : mp_sitzungen_loeschen() supprime cette ligne dès qu’il n’existe plus aucune session pour cet identifiant de visiteur — sur les deux voies, la suppression quotidienne et la suppression du compte. Aucun délai calendaire propre, et c’est intentionnel : un délai sur le nom signifierait le supprimer alors que le visiteur est toujours présent et toujours enregistré. Le responsable du traitement peut le retirer à tout moment ; un champ vide le supprime, et le pseudonyme généré s’applique à nouveau. |
A.14 Import depuis Google Analytics 4 — chiffres et sessions du propre compte du responsable du traitement
| Champ | Entrée |
|---|---|
| Finalité | Le responsable du traitement fait récupérer dans MousePlayer les données de son propre compte Google Analytics 4. Deux voies, chacune activée séparément : la Data API ne renvoie que des totaux quotidiens et répond à la question de la couverture — GA4 compte 3 000 sessions pour un jour, MousePlayer en a enregistré 40, et sans ce chiffre de référence, la différence ne peut être ni expliquée ni même remarquée. L’import BigQuery lit l’export brut de la propriété et stocke des sessions GA4 individuelles avec leurs événements, pour rendre visible ce qui s’est passé lors d’une visite que MousePlayer n’a pas pu enregistrer. |
| Catégories de personnes concernées | Visiteurs des sites web clients — les mêmes personnes que dans A.1, observées seulement par un deuxième système de mesure. Ce qui distingue cela de A.1 à A.13 est l’origine : ces données n’ont pas été collectées ici. Elles se trouvent déjà dans le compte Google du responsable du traitement et MousePlayer les récupère. La voie Data API ne concerne en outre aucune personne individuelle ; elle ne renvoie que des totaux quotidiens. |
| Catégories de données à caractère personnel | Pour la voie Data API : aucune — quatre nombres par jour (sessions, utilisateurs, pages vues, sessions engagées) sans aucun lien personnel. Pour la voie BigQuery, par session GA4 : l’identifiant pseudonyme user_pseudo_id, c’est-à-dire l’identifiant client du cookie _ga ; début, fin et durée ; nombre d’événements et de pages vues ; chemin d’arrivée ; catégorie d’appareil et pays ; plus source, support et campagne. En outre, pour chaque nom d’événement, un compteur, le dernier horodatage et, lorsque GA4 en rapporte une, une valeur cumulée. Aucune adresse IP, aucun instantané de page, aucun mouvement de souris — GA4 n’en détient aucun et aucun n’est généré. Une session importée ne peut donc jamais être relue. |
| Lieu de stockage | ga4_daily, ga4_sessions et ga4_events (migration 097) — trois tables SÉPARÉES. Délibérément pas dans visitor_sessions, session_pageviews ni dans session_custom_events. Ce n’est pas une question d’ordre : ces trois tables ne comportent aucune colonne indiquant la provenance d’une ligne, car tout ce qu’elles contiennent a été mesuré ici. Une ligne importée serait impossible à distinguer d’une ligne mesurée, et le sens de chaque chiffre déduit changerait ainsi silencieusement — les profils de comportement de A.12, l’évaluation par visiteur, l’analyse de friction. L’import se trouve donc à côté des données mesurées, comme ai_visitor_value et mp_profile le font déjà. |
| Base juridique | Instruction du responsable du traitement (art. 28(3)(a)), donnée en activant la voie concernée et en fournissant un compte de service dédié. La collecte initiale chez Google relève de la responsabilité du responsable du traitement, pas de MousePlayer : elle a eu lieu avant toute récupération ici et ne peut pas être vérifiée après coup. Une barrière technique existe néanmoins — seules les lignes portant un user_pseudo_id sont importées. Lorsque le consentement est refusé, GA4 envoie des hits sans cookies sous Consent Mode et ceux-ci n’en portent aucun ; ils sont éliminés mécaniquement plutôt que sur la foi d’une assurance. C’est un indice, pas une preuve, et c’est consigné comme tel parmi les lacunes de la section 10. |
| Catégories de destinataires | Aucun nouveau. Cette voie RÉCUPÈRE, elle ne livre pas : aucune donnée de visiteur ne sort de nos locaux. Le destinataire est le client, dans sa propre interface. Google n’apparaît pas ici comme destinataire, mais comme SOURCE — depuis un compte exploité par le responsable du traitement, dont il détermine le contenu. |
| Transfert vers un pays tiers | Aucun transfert de données de visiteurs. La requête est adressée à analyticsdata.googleapis.com et à BigQuery ; ce qui est transmis est l’identifiant d’accès du compte de service et le texte de la requête, pas des données de visiteurs. Les données circulent dans le sens inverse. Le lieu où les données GA4 résident chez Google et les garanties applicables découlent du propre compte du responsable du traitement et relèvent de son contrat avec Google, pas de ce registre. |
| Conservation | 180 jours, avec pour point de départ le jour que la ligne DÉCRIT (ga4_daily.tag, ga4_sessions.start_time) et non le moment de l’import. Celui-ci est reporté à chaque exécution, parce que GA4 complète les données rétroactivement pendant au plus 48 heures et que les mêmes jours sont donc récupérés à nouveau ; un délai rattaché à ce moment n’expirerait jamais. Imposé par l’exécution quotidienne dans srv/db_worker.php, les événements avant leurs sessions. Une demande d’effacement au titre de l’art. 17 les emporte depuis le 01.09.2026, dans la mesure où la ligne peut être attribuée par l’identifiant client ; la suppression selon le niveau de forfait, NON — les données GA4 suivent leur propre calendrier, et un client au niveau gratuit les perdrait sinon après 7 au lieu de 180 jours. Elles sont de toute façon supprimées avec le projet, y compris les lignes qui n’ont jamais appartenu à l’une de nos sessions. Ce que cela n’atteint pas est exposé dans la section 10. |
A.15 Prédiction de sortie et offre qu’elle peut déclencher
| Champ | Entrée |
|---|---|
| Finalité | Estimer, à partir des premières secondes d’une visite, la probabilité que le visiteur parte bientôt sans deuxième page vue. Le responsable du traitement peut rattacher une offre à cette estimation, montrée au visiteur sur SON site web. Contrairement à A.8 à A.14, ce traitement ne s’achève pas par une analyse pour le client, mais agit en retour sur le visiteur — c’est pourquoi il a sa propre entrée plutôt que d’être un sous-point de A.8. De plus, le responsable du traitement peut faire proposer le texte et le design d’une telle offre : un modèle de langage les rédige à partir du contexte de son site web. Une proposition n’est jamais publiée d’elle-même ; elle n’est reprise que partie par partie par le responsable du traitement. |
| Catégories de personnes concernées | Visiteurs des sites web clients, et uniquement lors de la PREMIÈRE page vue d’une session : une page vue ultérieure n’est plus une arrivée et n’est pas notée. Rien de cela ne s’exécute sans consentement — la notation se trouve derrière le même verrou que l’enregistrement. |
| Catégories de données à caractère personnel | Seize caractéristiques mesurées de la visite actuelle, toutes formées dans le navigateur : appareil (mobile oui/non), visiteur récurrent, clic payant, moteur de recherche, réseau social, arrivée sur la page d’accueil, profondeur du chemin de la page d’arrivée, heure nocturne, nombre de mouvements de souris, d’événements de défilement et de clics dans la fenêtre, secondes jusqu’à la première saisie, position de défilement la plus profonde en pourcentage de la page, nombre d’inversions du défilement, perte de focus de l’onglet et absence totale de saisie. Il en résulte UN pourcentage et jusqu’à trois motifs en langage clair. Aucun contenu, aucune coordonnée, aucune valeur de champ. Le marqueur mp_seen_before dans le stockage local du navigateur enregistre que le visiteur est déjà venu ; mp_offer_<date> compte combien de fois une offre lui a été montrée aujourd’hui. La proposition d’offre n’ajoute aucune information sur les visiteurs individuels, mais des informations sur le site web : titre, description, titres de sections et navigation d’au plus dix instantanés de pages, les 40 adresses au maximum ouvertes au moins cinq fois par des visiteurs humains en 30 jours, la part des langues des pages, ainsi que les couleurs, l’arrondi des coins et la police du fond de page et du bouton le plus fréquent, mesurés dans le navigateur. Pour cela, la langue est enregistrée pour chaque page vue (attribut lang de la page). Les adresses et les titres de sections peuvent contenir tout ce que le site web lui-même affiche (voir A.17). |
| Lieu de stockage | Le MODÈLE dans projects.exit_modell (migration 100) — poids, moyennes, écarts, qualité et heure d’entraînement ; il ne contient aucune donnée à caractère personnel, seulement des chiffres sur la population. Le RÉSULTAT par visite comme événement dans session_custom_events : exit_risk avec le pourcentage et les motifs, plus exit_offer_shown, exit_offer_click et exit_offer_dismiss lorsqu’une offre a été montrée. La dernière valeur est en outre conservée temporairement dans l’enregistrement de connexion du serveur WebSocket (Redis, mp_websockets) pour que la vue en direct puisse l’afficher ; elle disparaît avec la connexion. La proposition d’offre est stockée dans projects.exit_offer_vorschlag (migration 114), les mesures de design comme les 60 dernières par canal dans Redis (mp_design:<channel>), la langue de la page dans session_pageviews.lang. Pour la formulation, le contexte passe par ai_ki_queue vers nos propres machines exécutant le modèle de langage (section 4). |
| Base juridique | Instruction du responsable du traitement. L’entraînement s’effectue par projet et uniquement sur ses propres sessions, au moins 200 ; en dessous, aucun modèle n’est créé. Le consentement du visiteur couvre l’enregistrement dont proviennent les caractéristiques — la même base que dans A.8. Le responsable du traitement décide seul si une offre est montrée ; pour cet affichage sur son site web, il est le responsable du traitement, pas nous. |
| Catégories de destinataires | Le client dans son interface. Le pourcentage et les motifs atteignent en outre le NAVIGATEUR DU VISITEUR — ils y sont formés plutôt qu’envoyés — et sont accessibles au propre code du responsable du traitement via MousePlayer.on('exit_risk') et la couche de données. Une offre qui apparaît ensuite est vue par le visiteur lui-même. Une proposition d’offre n’est vue que par le responsable du traitement dans son interface ; elle n’atteint le site web qu’une fois qu’il la reprend. Rien n’est envoyé à des tiers. |
| Transfert vers un pays tiers | Aucun. L’entraînement et la notation s’exécutent sur l’infrastructure à Łódź ou dans le navigateur du visiteur. La proposition d’offre est formulée par le modèle de langage sur notre propre matériel à Łódź (section 4) ; rien n’est envoyé à un service d’IA externe. |
| Conservation | Les événements partagent la conservation de la session à laquelle ils appartiennent (A.7) et sont supprimés avec elle. Le modèle est écrasé à chaque exécution ; il n’existe aucun historique. Les deux marqueurs se trouvent dans le stockage local du visiteur : mp_seen_before sans expiration jusqu’à ce qu’il l’efface ou retire son consentement, mp_offer_<date> uniquement pour le jour courant (mp.js retire les entrées plus anciennes lors de sa prochaine définition). En outre, mp_design_sent dans le stockage de session de l’onglet enregistre que le design a déjà été mesuré. Lors du retrait, mp.js supprime les trois. La proposition d’offre reste jusqu’à son remplacement par une nouvelle ; les mesures de design expirent dans Redis après 30 jours ; la langue de la page partage la conservation de sa page vue. |
A.16 Indicateur de risque de perte des visiteurs récurrents
| Champ | Entrée |
|---|---|
| Finalité | Estimer, à partir des visites antérieures de la même personne, si elle s’éloigne, pour que le responsable du traitement puisse réagir. Contrairement à A.15, cette évaluation ne porte pas sur la visite actuelle, mais sur l’historique. |
| Catégories de personnes concernées | Visiteurs récurrents des sites web clients ayant au moins 2 sessions. Quiconque n’est venu qu’une fois n’a aucune ligne. La clé est la personne au sens de A.4 — l’identifiant client défini par le responsable du traitement, sinon l’identifiant de visiteur. |
| Catégories de données à caractère personnel | Une valeur de risque entre 0 et 1, jusqu’à quatre motifs en langage clair issus d’une liste fixe (engagement en baisse, visites courtes, friction, retard ; un achat au cours des deux dernières visites abaisse la valeur), le nombre de visites et l’heure de la dernière. Aucun contenu, aucune coordonnée. Ce n’est pas un modèle appris, mais quatre observations dénombrables — chacune figure dans la ligne comme motif, pour qu’une valeur n’apparaisse jamais sans motif. |
| Lieu de stockage | ai_churn (migration 100) : channelid, person_key, visitor_id, risiko, gruende, sitzungen, letzte_sitzung, berechnet_am. En outre, un hash Redis par canal, mp_churn:<channel>, expirant après deux jours, dans lequel le serveur WebSocket lit lors de la connexion ; seuls ceux au-dessus du seuil y sont placés. |
| Base juridique | Instruction du responsable du traitement ; les sessions sous-jacentes reposent sur le consentement du visiteur (A.1). Calculé par projet, jamais entre clients. |
| Catégories de destinataires | Le client dans son interface. La valeur est aussi envoyée au NAVIGATEUR DU VISITEUR dès qu’il se connecte et est accessible au propre code du responsable du traitement via MousePlayer.on('churn_risk') ; il peut y rattacher une offre. Ce transfert vers le propre appareil de la personne concernée explique pourquoi cette entrée figure ici plutôt que sous A.8. Rien n’est envoyé à des tiers. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | La ligne est réécrite pour le canal à chaque exécution et est supprimée avec les sessions dont elle provient. L’entrée Redis expire d’elle-même après deux jours. |
A.17 Rapport de synthèse sur un visiteur
| Champ | Entrée |
|---|---|
| Finalité | Rassembler toutes les visites d’UNE personne dans un rapport lisible : d’où elle est venue, ce qui a été payé, où elle a rencontré des difficultés et si un objectif en a résulté. Les constats sont calculés ; un modèle de langage les reformule tout au plus. Un rapport est demandé soit par le client pour un visiteur particulier, soit automatiquement pour au plus 5 visiteurs par projet et par nuit — choisis parmi les visites payantes sans achat. |
| Catégories de personnes concernées | Visiteurs des sites web clients pour lesquels il existe plus d’une visite. La clé est la personne au sens de A.4. |
| Catégories de données à caractère personnel | Au plus quatorze constats calculés sous forme textuelle : nombre de visites et de pages, période, appareils, source avec campagne, achats et objectifs atteints, les trois principaux points de blocage avec leur chemin, la dernière session et les LIBELLÉS des éléments cliqués (jusqu’à cinq, 60 caractères chacun). Plus le texte généré. Les valeurs des champs de formulaire n’en font pas partie — elles ne quittent jamais le navigateur. Les libellés et les chemins proviennent en revanche de ce que le site web du responsable du traitement affiche lui-même et peuvent donc contenir un nom ou une adresse lorsqu’il en affiche ou en inscrit dans l’URL ; consigné comme une lacune dans la section 10. |
| Lieu de stockage | ai_besucher_bericht (migration 100) avec channelid, person_key, lang, les constats, leur empreinte, le texte et le nom du modèle. Pour la formulation, les CONSTATS — pas l’enregistrement — passent par ai_ki_queue vers les machines exécutant le modèle de langage (matériel propre dans le même réseau local, voir la section 4). Chaque rapport consomme un quota (ai_ki_kontingent par espace de travail et par mois, 3 pour le forfait gratuit, sinon 200). |
| Base juridique | Instruction du responsable du traitement ; les sessions sous-jacentes reposent sur le consentement du visiteur (A.1). Le modèle de langage n’est ni entraîné ni modifié ; il ne fait que formuler. |
| Catégories de destinataires | Le client dans son interface. Le visiteur n’en apprend rien — contrairement à A.15 et A.16, rien ici n’agit en retour sur lui. |
| Transfert vers un pays tiers | Aucun. Le modèle de langage s’exécute sur notre propre matériel à Łódź (section 4) ; rien n’est envoyé à un service d’IA externe. |
| Conservation | 180 jours à compter de la demande, imposés par le passage de suivi du processus d’IA. Si la dernière session du visiteur disparaît plus tôt, le rapport est supprimé avec elle. |
A.18 Accès en libre-service du visiteur et demande d’effacement
| Champ | Entrée |
|---|---|
| Finalité | Montrer au visiteur ce qui est stocké à son sujet et lui permettre d’en obtenir l’effacement — assistance au responsable du traitement pour les droits des personnes concernées au titre de l’art. 28(3)(e) du RGPD. Accessible à /my-data, /meine-daten et /moje-dane. |
| Catégories de personnes concernées | Visiteurs des sites web clients, et uniquement ceux qui apportent leur propre identifiant. Le responsable du traitement doit placer le lien ; il est le responsable du traitement pour ses visiteurs, et l’information de l’art. 13 appartient à sa propre politique. |
| Catégories de données à caractère personnel | Sont montrés le nombre, la période et les domaines des sessions — aucun enregistrement. L’identifiant est un jeton au porteur ; quiconque connaît celui d’une autre personne ne devrait pas pouvoir voir le comportement d’un inconnu. Pour la même raison, la réponse reste liée à l’APPAREIL et n’utilise pas mp_person_sql() pour rassembler ce qui appartient à une personne : la jointure divulguerait PLUS, et non moins. Pour la demande d’effacement, nous stockons l’identifiant, l’heure de la demande et l’heure d’exécution. |
| Lieu de stockage | visitor_deletion_requests (visitor_id, requested_at, done_at) — 0 ligne. La page elle-même ne stocke rien ; elle lit. La demande est exécutée par le worker via la même chaîne de suppression que celle déclenchée par le responsable du traitement — un deuxième parcours de suppression serait un deuxième endroit pour la même vérité. |
| Base juridique | Art. 28(3)(e) du RGPD (assistance au responsable du traitement) et son instruction. La forme de l’identifiant est vérifiée (^v_[a-z0-9]{9}_\d{13}$) ; tout autre format est refusé. |
| Catégories de destinataires | Le visiteur lui-même. Rien n’est envoyé au client — il n’apprend l’existence d’une demande d’effacement que parce que les sessions disparaissent. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | La ligne reste pour prouver que l’effacement a eu lieu et quand. Elle ne contient aucune donnée comportementale. Lorsqu’une sauvegarde est restaurée, les demandes consignées sont exécutées à nouveau avant la remise en service du système (clause 24.2 des Conditions d’utilisation). |
A.19 Réexamen de la détection des robots — décisions de l’exploitant comme exemples d’apprentissage
| Champ | Entrée |
|---|---|
| Finalité | Les sessions que la détection par vagues a marquées rétroactivement comme des robots sont vérifiées à nouveau par un mécanisme de surveillance, et les cas douteux sont signalés dans les Urgent Logs. L’exploitant y décide d’un clic : Humain ou Robot. Chaque décision devient un exemple d’apprentissage à partir duquel les poids des sept signaux sont recalculés — uniquement les poids, pas le seuil, et seulement à partir d’un nombre minimal de décisions réglable dans la zone d’administration (bot_revision_lern_min). En dessous, des valeurs fixes s’appliquent. |
| Catégories de personnes concernées | Visiteurs des sites web clients dont la session a été signalée comme cas douteux, et personne ayant décidé (personnel du client ou le nôtre). |
| Catégories de données à caractère personnel | Aucun contenu de visiteur. Sont stockés le canal, l’identifiant de session, la décision, le score, les noms des signaux applicables (par exemple : l’identifiant diverge de la vague, référent présent, adresse d’un réseau privé) et l’identifiant du décideur. Le vecteur de caractéristiques fait partie de l’exemple parce que la session elle-même disparaît après son délai de conservation et que l’apprentissage en a encore besoin. |
| Lieu de stockage | bot_review_labels (migration 140) : une ligne par session ; quiconque change d’avis écrase l’existante. Elle est lue par cfg/bot_revision_lib.php. Sans la table, les mécanismes de surveillance fonctionnent avec des poids fixes. |
| Base juridique | Instruction du responsable du traitement ; A.1 s’applique aux sessions elles-mêmes. La procédure améliore la distinction entre robots et humains et donc l’exactitude de l’analyse (art. 5(1)(d) du RGPD). Aucune décision au sujet du visiteur n’en dépend ; une validation libère une session du marquage, rien de plus. |
| Catégories de destinataires | Aucun hors de l’interface ; les exemples ne sont visibles que par l’exploitant. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | Par défaut : aucune suppression automatique — un exemple est pseudonyme et ne contient aucun contenu de visiteur, et sa valeur croît avec le stock. Le délai peut être fixé en années dans la zone d’administration (retention_bot_labels_years, 0 = illimité) ; à partir de 1, le mécanisme de surveillance d’état (srv/cron_status.php) supprime les lignes après ce nombre d’années. Il ne figure dans aucune chaîne de suppression des sessions : lorsque la session disparaît, l’exemple reste — c’est voulu, mais consigné comme une lacune dans la section 10. |
A.20 Suivi d’éléments — clics sur les éléments marqués des pages
| Champ | Entrée |
|---|---|
| Finalité | Dans l’assistant d’éléments, le responsable du traitement marque les éléments de ses pages — individuellement ou comme groupe d’éléments similaires, par sélecteur CSS — et reçoit les clics, sessions avec un clic, visiteurs et taux de clic pour chaque marquage. Le comptage est rétroactif : srv/element_worker.php attribue les clics déjà enregistrés (A.1, mouse_events_analytik) à l’élément marqué dans l’instantané de leur propre page vue. Un marquage peut aussi être un objectif ou une étape d’entonnoir ; ses occurrences comptent alors comme l’atteinte d’un objectif ou d’une étape. |
| Catégories de personnes concernées | Visiteurs des sites web clients dont les clics ont été enregistrés. |
| Catégories de données à caractère personnel | Un complément à l’enregistrement des clics (A.1), sinon aucune nouvelle collecte : lorsqu’un visiteur clique sur un élément apparu seulement après l’instantané (par exemple un menu ouvert ou une fenêtre contextuelle), mp.js envoie aussi depuis le 27.09.2026 sa structure — balise, classes, quelques attributs (role, type, name, chemin du lien sans requête, data-*), la position parmi les éléments frères de même type et le libellé visible ; dans les zones masquées, uniquement la balise et l’identifiant. Cela est stocké avec les événements de la page vue (A.1) et partage leur conservation. Pour chaque occurrence, sont stockés : identifiants de canal, de session et de page vue, début de la session, type de clic (click ou tap), libellé visible de l’élément touché tiré de l’instantané — masqué exactement comme dans l’enregistrement — et, si le responsable du traitement le choisit, la valeur d’un attribut de cet élément (par exemple data-id) pour la ventilation. Depuis le 27.09.2026, le worker d’éléments conserve une note des clics dont la cible est absente de l’instantané et pour lesquels aucune structure n’a été envoyée (clics plus anciens) : identifiants de canal, de session et de page vue, heure et empreinte du chemin de page et du libellé — le libellé lui-même n’y est pas stocké. À partir des clics résolus, il apprend, pour chaque marquage, quel libellé sur quel chemin de page correspond au marquage (chemin, libellé, deux compteurs, aucun lien avec un visiteur). Lorsque toutes les observations concordent, un clic noté est attribué comme occurrence — marquée comme transférée — ou comme absence d’occurrence. Le marquage lui-même (nom, sélecteur, zone de page) et les compteurs quotidiens de couverture ne portent aucun lien avec un visiteur. |
| Lieu de stockage | mp_element_regeln, mp_element_klicks et mp_element_tag (migration 152), mp_element_offen et mp_element_muster (migration 155). Lus par cfg/element_lib.php. |
| Base juridique | Instruction du responsable du traitement (art. 28(3)(a) du RGPD), donnée par la création d’un marquage ; A.1 s’applique aux clics eux-mêmes. L’évaluation résume des enregistrements existants ; le seul ajout est la structure des cibles de clic créées après l’instantané (ci-dessus), qui décrit la même chose que l’instantané de la page. Aucune décision au sujet du visiteur n’en dépend. |
| Catégories de destinataires | Aucun hors de l’interface tant que le marquage est uniquement évalué. Si le responsable du traitement l’utilise comme objectif ou comme étape d’entonnoir, les objectifs atteints et les abandons d’entonnoir sont envoyés aux transmissions qu’il a activées (4.1) — avec l’identifiant de session, le nom de l’objectif ou de l’entonnoir et le libellé de l’élément cliqué, et uniquement pour les clics dont l’ancienneté ne dépasse pas celle définie dans l’administration (par défaut deux heures). Les occurrences plus anciennes comptent dans l’interface, mais ne sont pas transmises. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | Une occurrence est supprimée avec la session dont elle provient : mp_element_klicks fait partie de la chaîne de suppression (mp_sitzungen_loeschen() dans srv/db_worker.php), et le worker d’éléments retire chaque heure les occurrences dont la page vue n’existe plus — donc aussi après des parcours de suppression hors de cette chaîne, au plus tard dans l’heure. Les clics notés (mp_element_offen) sont supprimés avec leur session par les mêmes voies. Supprimer un marquage supprime ses occurrences, compteurs, notes et motifs ; les motifs ne portent aucun lien avec un visiteur et sont également supprimés lors d’un changement de sélecteur ou après un an sans nouvelle observation. Il n’existe délibérément aucun délai distinct : il serait plus long ou plus court que celui de l’enregistrement, et les deux seraient erronés. |
A.21 Sondages de retour d’information — une question au visiteur, la réponse à côté de l’enregistrement
| Champ | Entrée |
|---|---|
| Finalité | Le responsable du traitement pose aux visiteurs de son site une courte question — probabilité de recommandation de 0 à 10, cinq visages, oui/non ou un choix — et, s’il le souhaite, une question complémentaire sous forme de texte libre. La réponse est rattachée à la visite pour qu’il puisse regarder les enregistrements des visiteurs mécontents. La question, le moment, la part des visiteurs et la langue sont définis par le responsable du traitement. |
| Catégories de personnes concernées | Visiteurs des sites web clients auxquels un sondage a été montré — selon un échantillon défini par le responsable du traitement et au plus une fois par intervalle fixé par lui —, et visiteurs ayant ouvert eux-mêmes un sondage par un bouton au bord de la page ; dans ce cas, l’intervalle ne commence qu’avec une réponse. Seul ce que le visiteur saisit est collecté : quiconque ferme la question ne laisse que le fait qu’elle a été montrée et fermée. |
| Catégories de données à caractère personnel | La note (un nombre ou l’option choisie) avec son sentiment (négatif, neutre, positif), l’heure et l’identifiant du sondage comme événement de la visite (A.7) : survey_shown, survey_answer et survey_dismiss. Pour une question complémentaire, un TEXTE LIBRE de 500 caractères au maximum avec la langue de la page. Avant l’envoi, mp.js retire les adresses e-mail, adresses IP et numéros de téléphone, et le worker le fait une deuxième fois (mp_umfrage_text_filtern()) ; sous le champ, les visiteurs sont priés de s’abstenir de saisir des données à caractère personnel. Dans le navigateur du visiteur, mp_umfrage (localStorage) conserve, pour chaque sondage, le tirage de l’échantillon et l’heure du dernier affichage ; pour le bouton au bord de la page, l’heure de la dernière réponse. |
| Lieu de stockage | La note dans session_custom_events et session_custom_event_params (A.7) ; le texte libre dans mp_umfrage_text (migration 157) — délibérément séparé : c’est la partie la plus sensible d’un sondage et elle n’a pas sa place dans la table lue par les webhooks et les passerelles. Les sondages eux-mêmes, c’est-à-dire uniquement le texte qu’écrit le responsable du traitement, dans projects.survey_json. |
| Base juridique | Instruction du responsable du traitement (art. 28(3)(a) du RGPD), donnée par la création et l’activation d’un sondage. Répondre est facultatif. L’existence d’une base juridique pour la question et la question complémentaire, ainsi que leur mention dans sa notice de confidentialité, relèvent de la responsabilité du responsable du traitement ; le texte pour les clients nomme le sondage comme un point distinct. Aucune décision concernant le visiteur n’en dépend. |
| Catégories de destinataires | Le client, dans la vue des résultats et dans le lecteur. La note est un événement personnalisé et est donc envoyée aux transferts activés par le responsable du traitement pour de tels événements (4.1). Le texte libre n’est envoyé à aucune passerelle : mp_umfrage_text n’est lu que par cfg/umfrage_lib.php. |
| Transfert vers un pays tiers | Aucun — sauf par un transfert activé par le responsable du traitement (4.1), et dans ce cas uniquement la note. |
| Conservation | Avec la session : mp_umfrage_text fait partie de mp_sitzungen_loeschen(), le parcours d’effacement du lecteur, mp_konto_loeschen() et la suppression de projets et d’espaces de travail dans le tableau de bord ; la note est supprimée avec session_custom_events. Il n’existe délibérément aucun délai propre — il serait plus long ou plus court que celui de l’enregistrement, et les deux seraient erronés. La clé mp_umfrage dans le navigateur est supprimée lors du retrait. |
A.22 Recherche de texte affiché — quelles visites avaient un texte donné sur la page
| Champ | Entrée |
|---|---|
| Finalité | Le client trouve les visites dans lesquelles un texte donné figurait sur sa page — au chargement ou affiché plus tard, par exemple un message d’erreur, un avis ou “Épuisé” — pour regarder leurs enregistrements. La recherche se trouve dans User Explorer. |
| Catégories de personnes concernées | Visiteurs des sites web clients dont la visite a été enregistrée (A.2) et n’est pas reconnue comme automatisée. |
| Catégories de données à caractère personnel | Les fragments de texte présents dans l’instantané et les modifications de la page (A.2), un par nœud de texte, plus leur affectation à la page vue. Ce qui est lu a déjà été enregistré : les zones masquées et les saisies de formulaire y sont déjà remplacées et ne sont pas trouvées. Si une page affiche elle-même des données à caractère personnel (une page de confirmation avec nom et adresse), elles sont également ici — comme dans l’enregistrement. |
| Lieu de stockage | mp_text_block (dictionnaire par projet, chaque fragment de texte une fois), mp_text_pv (quelle page vue portait quel fragment) et mp_text_stand (quelle vue a été lue), migration 175. Remplis toutes les dix minutes par srv/textsuche_lauf.php sur notre propre serveur. |
| Base juridique | Instruction du responsable du traitement (art. 28(3)(a) du RGPD) : la recherche donne accès au même enregistrement que celui commandé par le responsable du traitement. Aucune décision au sujet du visiteur n’en dépend. |
| Catégories de destinataires | Le client, comme filtre dans User Explorer. Aucun transfert, aucune passerelle. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | 30 jours à compter du début de la page vue, soit une durée plus courte que celle de l’enregistrement : ensuite, affectation et état sont retirés, un fragment de texte avec sa vue la plus récente. Si la session est supprimée plus tôt (délai de conservation, demande d’effacement, suppression dans le lecteur, suppression du projet ou du compte), l’affectation est supprimée avec elle — directement dans mp_sitzungen_loeschen() et la suppression du projet ; pour tous les autres parcours, au plus tard après dix minutes par l’exécution qui retire les affectations sans page vue. |
4. Partie A — destinataires, sous-traitants ultérieurs et transferts vers des pays tiers
Le parcours d’enregistrement lui-même ne contient aucun appel sortant vers des tiers. Cela a été établi le 10 août 2026 par une recherche dans cfg/, srv/, class/ et www/ (hors vendor et node_modules) de curl_init, curl_exec, file_get_contents avec http, fsockopen et stream_context_create, ainsi que de tous les littéraux https. La résolution géographique utilise des fichiers MaxMind locaux, la feuille de style de l’interface est servie comme fichier précompilé depuis notre propre serveur, et les images de drapeaux proviennent de /img/flags/. Depuis le 23 septembre 2026, les e-mails sont envoyés par SMTP via Namecheap Private Email (mail.privateemail.com, port 465, TLS) avec l’expéditeur office@mouseplayer.com ; la fonction PHP mail() ne serait utilisée que si aucun serveur SMTP n’était configuré, ce qui n’est pas le cas. Limite de cette recherche : les répertoires des fournisseurs (Stripe SDK, Google Cloud SDK, PHPMailer, Symfony) n’ont pas été examinés — c’est là que se trouvent les points de terminaison des services nommés ci-dessous.
| Destinataire | Rôle et éléments transférés | Destination | Garantie | État |
|---|---|---|---|---|
| Stripe | Traitement des paiements pour les comptes CLIENTS. E-mail, nom, adresse de facturation et données de paiement des clients. www/billing_ajax.php:134 définit la clé API ; les lignes 381 et 687 transmettent customer_email ; la ligne 48 définit billing_address_collection='required' ; la ligne 54 customer_update pour l’adresse et le nom ; les lignes 462/527/672 transmettent les métadonnées. Canal de retour www/api/webhook_stripe.php, table stripe_events. Aucune donnée de visiteur. | États-Unis | Accord de traitement des données accepté le 1er août 2026 dans le cadre des conditions acceptées à l’ouverture du compte (déclaration du responsable du traitement). Partie contractante : Stripe Payments Europe, Ltd. ; pour les transferts vers les États-Unis, Stripe, Inc. Module 2 (responsable du traitement vers sous-traitant). Cela découle de la répartition des rôles plutôt que d’une consultation : MousePlayer est le responsable du traitement pour les données de compte et de facturation transmises, Stripe est le sous-traitant pour cette partie. La version acceptée elle-même n’a pas été examinée ; si elle diffère, elle prévaut. | Au 16 octobre 2026, pas en service : les deux emplacements de clés contiennent des clés de test, et aucun paiement réel n’est traité. |
| VIES (Commission européenne) | Vérification d’un numéro d’identification à la TVA fourni par un CLIENT via l’interface REST publique du VAT Information Exchange System (cfg/lib.php). Le code pays et le numéro de TVA sont transmis ; la validité et, lorsqu’ils sont disponibles, le nom et l’adresse de l’entreprise sont renvoyés et stockés avec le compte (B.1). Aucune donnée de visiteur. | UE | Organisme public de l’Union ; pas un sous-traitant, aucun contrat requis. La requête sert à vérifier les informations fiscales du client. | Utilisé dès qu’un client saisit un numéro de TVA. |
| Telegram | Notification d’assistance. Jusqu’au 11 août 2026 cfg/lib.php transmettait le dossier d’assistance ENTIER : état de l’utilisateur avec son identifiant, adresse e-mail, objet, 'IP / Kraj' avec l’adresse IP NON TRONQUÉE, URL source et texte intégral du message. Depuis le 11 août 2026 (commit 02846c2, cfg/lib.php), une chaîne fixe et rien d’autre sort : 'MousePlayer: es liegt eine neue Supportanfrage vor.' Aucune variable, aucun parse_mode, et délibérément aucun numéro de dossier ni aucun lien tiré de la requête. La demande elle-même reste stockée sans modification dans support_requests — les données ne sortent plus, elles ne disparaissent pas. | Hors UE | Jusqu’au 11 août 2026 : aucune — Telegram ne propose aucun accord de traitement des données pour les bots. Depuis le 11 août 2026, aucune n’est requise : la notification ne contient aucune donnée à caractère personnel ; Telegram n’est donc ni sous-traitant ni destinataire. Décision du propriétaire du 11 août 2026 : le canal reste, le message est réduit à un simple signal, l’adresse IP est retirée. Un garde-fou (ai/pruefstand/test_telegram_signal.php) vérifie non pas le résultat, mais la possibilité — quelles variables peuvent atteindre le message tout court ; quatre sont autorisées, 15 attributs sont interdits, et le texte doit être une chaîne entre apostrophes sans interpolation. | ACTIF, mais sans transporter de données à caractère personnel — désamorcé le 11 août 2026. TELEGRAM_BOT_TOKEN et TELEGRAM_CHAT_ID sont toujours définis dans .env ; seul le signal sort. |
| Google reCAPTCHA | Connexion, inscription, formulaire d’assistance, page de facturation. Vérification côté serveur à www/login.php:31-45 et cfg/lib.php:6337 auprès de https://www.google.com/recaptcha/api/siteverify ; côté navigateur à www/billing.php:1290. | États-Unis | reCAPTCHA reste en production. Conditions de traitement des données de Google acceptées le 1er août 2026 (déclaration du responsable du traitement). Partie contractante : Google Ireland Limited ; pour les transferts vers les États-Unis, Google LLC. Sur le système de développement, le service est désactivé (mp_recaptcha_aktiv() renvoie !mp_ist_dev()), en production, il est activé — là, le transfert a lieu à chaque action de connexion, d’inscription, de mot de passe et de facturation. | Inactif sur cette instance uniquement : mp_recaptcha_aktiv() est défini à cfg/config.php:131-133 comme !mp_ist_dev() et APP_ENV=dev. Actif en production. |
| Google BigQuery | Export nocturne vers le PROPRE projet GCP du client. srv/cron_integration_bigquery.php:95-100 sélectionne session_id, channelid, visitor_id, custom_user_id, ip_address, country, referrer, user_agent, screen_width, screen_height, start_time, end_time, duration_seconds, device_type et les charge au format NDJSON dans visitor_sessions_YYYYMMDD. | Région choisie par le client | La destination est le propre projet du client ; celui-ci est donc l’importateur. La clé du compte de service est stockée chiffrée dans projects.bigquery_sa_json (decrypt_sa_key, clé BIGQUERY_SA_AES_KEY issue de .env). | INACTIF. projects.bigquery_active=0 pour les 7 projets, bigquery_project_id NULL partout, et le processus ne s’exécute pas. |
| Webhooks du client | srv/cron_integration_webhook.php:63-80. Corps construit à srv/db_worker.php:1313-1323 : timestamp, event_type, channel_id, session_id, lien direct vers le lecteur 'https://<host>/player?id=...&session=...' et paramètres de l’événement. Formatage spécial pour Slack et Discord (mp_format_webhook_body, cfg/lib.php:5978). | Indéterminée — définie par le client | La destination est choisie par le client et relève donc de la propre responsabilité du responsable du traitement. Oui, la destination est consignée pour chaque Client (décision du responsable du traitement, 17 août 2026). Elle se trouve déjà sur le projet ; ce qui manque est le relevé de QUI l’a définie et quand. Depuis le 17 août 2026 chaque modification de la destination du webhook apparaît dans le journal des modifications (log_audit, action update_integrations, champ webhook_host). Seul l’hôte est consigné, pas l’adresse complète : un chemin de webhook contient souvent un secret — Slack et Discord placent la clé dans l’URL — et un journal des modifications n’est pas le bon endroit pour cela. Pour savoir où les données d’événement quittent nos locaux, l’hôte suffit. | INACTIF. projects.webhook_active=0 et webhook_url NULL pour les 7 projets. Le processus de distribution s’exécute. |
| Meta (Conversions API) | Uniquement si le responsable du traitement active la passerelle et stocke son propre jeton d’accès. Ce qui est transmis est exclusivement constitué des objectifs atteints du projet concerné : nom de l’objectif, horodatage, identifiant d’événement déduit de la session et de l’objectif pour la déduplication, valeur et devise lorsqu’elles sont définies, plus les cookies _fbp et _fbc et la chaîne d’agent utilisateur. Le nom, l’adresse e-mail, le numéro de téléphone et l’adresse IP ne sont pas transmis — MousePlayer ne détient de toute façon qu’une IP tronquée, qui serait sans valeur pour la mise en correspondance. L’envoi n’a lieu que pour les sessions avec consent_state = 'granted' ; sans _fbp/_fbc la transmission est entièrement omise, car elle n’aurait aucun but sans clé de correspondance. Code : mp_capi_meta_ausloesen() et mp_capi_meta_zustellen() dans cfg/lib.php, distribution via srv/cron_integration_webhook.php. | États-Unis | Meta n’est pas un sous-traitant ultérieur de MousePlayer. MousePlayer effectue la transmission sur instruction du responsable du traitement — cette instruction consiste à activer la passerelle et à stocker le jeton. Le destinataire est le propre compte publicitaire du responsable du traitement ; la relation contractuelle avec Meta, y compris les garanties pour le transfert vers les États-Unis, existe entre le responsable du traitement et Meta, pas entre Meta et MousePlayer. Meta traite les données pour ses propres finalités et, dans cette mesure, en tant que responsable du traitement distinct. | Passerelle disponible depuis le 19.08.2026, activée pour aucun projet dans l’état livré. |
| HubSpot / Pipedrive | Uniquement si le responsable du traitement active la passerelle et stocke son propre jeton API. Ce qui est transmis est l’identifiant client défini par le responsable du traitement lui-même (setUserId()), utilisé pour retrouver le contact, suivi d’une note contenant l’URL de relecture de la session. Aucune donnée comportementale, aucun contenu d’enregistrement. Si la recherche ne trouve aucun contact, l’opération s’arrête sans autre transmission. Code : mp_crm_kontakt_suchen() et mp_crm_notiz_anhaengen() dans cfg/lib.php. | États-Unis (HubSpot), UE (Pipedrive) | Comme pour Meta : le destinataire est le propre compte CRM du responsable du traitement, et la relation contractuelle existe entre celui-ci et le fournisseur. MousePlayer transmet sur son instruction. | Passerelle disponible depuis le 19.08.2026, activée pour aucun projet dans l’état livré. |
| Google Cloud Storage (Varsovie) | Copie hors site de la sauvegarde quotidienne. Documentée dans OFFENE_PUNKTE.md, section 3.3 : 'mysqldump --all_databases' et 'tar /var/www/' — chaque base de données et toute l’arborescence web, y compris chaque .env. Attestée localement à 653 MB de base de données et 678 MB de fichiers. Jusqu’au 11 août 2026 la sauvegarde s’exécutait quotidiennement à 02:00 et sortait sans chiffrement. Depuis le 11 août 2026 elle est chiffrée sur notre propre serveur avant son transfert (rclone crypt ; les noms des fichiers et des répertoires sont eux aussi chiffrés), et les deux fichiers de clés se trouvent sur ce même serveur avec le mode 600 — Google ne les possède pas ; l’exécution planifiée a lieu à 03:00 depuis lors. Le dossier de destination précédent, non chiffré, contenant les copies antérieures au 11 août 2026 a été supprimé le 12 août 2026. | Pologne (UE) – bucket de la région europe-central2 (Varsovie), depuis le 5 septembre 2026. Jusqu’alors, la copie était conservée dans un compte Google Drive privé pour lequel aucune région de données ne peut être choisie ; la destination devait être indiquée comme États-Unis / monde entier. | Traitement pour notre compte dans le cadre du Google Cloud Data Processing Addendum, accepté pour le projet Cloud ; partie contractante Google Ireland Limited. Cela supprime l’écart indiqué ici du 17 août 2026 au 5 septembre 2026 : ces conditions ne sont pas disponibles pour un compte Google privé, et les conditions générales d’utilisation n’établissent pas un traitement pour compte au titre de l’art. 28 du RGPD. La copie est toujours chiffrée avant le transfert (rclone crypt, noms des fichiers et des répertoires compris), et seul le responsable du traitement détient les clés — Google voit des blocs sans signification. Cela retire le contenu à Google, pas le rôle. | ACTIF. Jusqu’au 11 août 2026, sans chiffrement et sans vérification à destination — l’exécution utilisait la configuration rclone de root et le script ne journalisait rien. Depuis le 11 août 2026, chiffré ; les exécutions du 11 août 2026 (lancée manuellement) et du 12 août 2026 (planifiée, à 03:00) sont journalisées et ont toutes deux passé une vérification à destination (nombre d’octets du dump de la base de données). Le fonctionnement quotidien est donc attesté, pas seulement la première tentative. L’exploitant a testé le déchiffrement ; il n’existe aucune mesure de notre part à ce sujet. Le dossier de destination précédent, non chiffré, a été supprimé le 12 août 2026. Depuis le 5 septembre 2026, la copie est envoyée à Google Cloud Storage à Varsovie ; les copies auparavant conservées sur le compte Drive ont été supprimées le 6 septembre 2026, après vérification d’une restauration depuis la nouvelle destination. Le type de compte, la région des données et le contrat sont donc réglés. Depuis le 6 octobre 2026, la sauvegarde contient également l’archive des événements d’enregistrement déplacés (/mnt/mouseplayer-dev-archive, A.1) ; localement, cette archive se trouve sur le même disque que le système, et seule la copie chiffrée assure un stockage à un autre endroit. Des tests de restauration depuis la copie ont été effectués les 5/6 septembre 2026 et le 7 octobre 2026 (restauration complète des données). Les sauvegardes quotidiennes sont conservées pendant 7 jours, les hebdomadaires pendant 364 jours. |
| Namecheap | Enregistrement de domaine, DNS faisant autorité, transfert des e-mails entrants ; depuis le 23 septembre 2026, également envoi des e-mails sortants via Namecheap Private Email. Données du domaine ; contenu et expéditeur des e-mails adressés à MousePlayer. Pour les e-mails sortants : nom, adresse e-mail et contenu du message au titulaire du compte ; pour l’avis de connexion, également adresse IP, appareil et localisation approximative. | États-Unis | Data Processing Addendum accepté le 1er août 2026 (déclaration du responsable du traitement) ; il couvre les clauses contractuelles types actuelles. Le courrier entrant passe en permanence par le transfert Namecheap ; aucun autre fournisseur de messagerie n’intervient (décision du responsable du traitement, 17 août 2026). Depuis le 23 septembre 2026, le courrier sortant passe par le service SMTP Namecheap Private Email (TLS) : notifications contractuelles, notifications de compte, avis de connexion et alertes des dispositifs de surveillance. | Utilisé. |
| Let's Encrypt (ISRG) | Émission et renouvellement de certificats TLS. Noms de domaines uniquement. | États-Unis | Autorité de certification publique ; ne traite aucune donnée à caractère personnel pour notre compte. | Utilisé. |
| consented.eu | CMP sur les PROPRES pages de MousePlayer, chargée dans le navigateur du visiteur : cfg/header.php:48 (stub.js) et ligne 50 (cmp.js). Concerne les visiteurs de mouseplayer.com, pas l’enregistrement chez les clients. | Lieu de traitement : le même serveur que MousePlayer (/var/www/html/ConsentedEU sur la même machine, mesuré le 17 août 2026). Base contractuelle : sans objet — consented.eu est exploité par la même entité juridique (déclaration du responsable du traitement). Il n’existe aucun transfert à un tiers. | Sans objet pour la même raison : aucun tiers, donc aucun accord. | Utilisé sur nos propres pages. |
Hébergement : sans objet — exploitation autonome sur notre propre matériel avec la connexion Toya (AS16342, Łódź), aucun transfert à un tiers (décision du responsable du traitement, 17 août 2026) ; si l’exploitation passe à un centre de données ou à un fournisseur cloud, ce paragraphe doit être réécrit. Le matériel propre comprend le serveur exécutant l’application, la base de données et l’enregistrement, ainsi que les machines dotées d’une carte graphique exécutant le modèle de langage — actuellement une, exécutant notre propre IA, auto-hébergée sur notre propre matériel. Tous se trouvent sur le même site, dans le même réseau local, et appartiennent à MousePlayer ; il en va de même de toute machine supplémentaire. Ils récupèrent les constats calculés par HTTPS depuis ai_ki_queue, chaque requête étant signée avec son propre secret, et renvoient le texte formulé. L’enregistrement lui-même ne leur parvient jamais, et rien n’est envoyé à un service d’IA externe (A.8, A.12, A.15, A.17). Lorsqu’une telle machine est arrêtée pour maintenance, les tâches attendent son retour ; entre-temps, l’interface montre la version calculée, et aucune tâche n’est transmise à un autre service.
4.1 Destinataires activés par le responsable du traitement
Le tableau ci-dessus énumère les destinataires engagés par MousePlayer lui-même. À côté d’eux, il existe des passerelles que le responsable du traitement active et pour lesquelles il stocke ses propres identifiants d’accès. Ce ne sont pas des sous-traitants ultérieurs de MousePlayer ; la relation contractuelle avec eux existe entre le responsable du traitement et le destinataire, y compris les garanties pour les pays tiers. Ce qui est nommé, ce sont des catégories plutôt que des fournisseurs — les fournisseurs disponibles au sein d’une catégorie changent avec l’ensemble des fonctionnalités ; la sélection dans les paramètres du projet fait foi. Chaque transmission est déclenchée côté serveur depuis srv/cron_integration_webhook.php ; le résultat est consigné dans le journal de livraison (A.11).
| Catégorie | Ce qui sort | Ce qui le déclenche |
|---|---|---|
| Webhook vers une adresse librement choisie | Nom d’événement, identifiants de canal et de session, URL de relecture, paramètres d’événement. Signés par HMAC-SHA256 sur l’horodatage et le corps. | un événement auquel le responsable du traitement s’est abonné |
| Système de gestion de la relation client (CRM) | L’identifiant client que le responsable du traitement a défini lui-même pour le visiteur, plus l’URL de relecture, rattachés comme note à un contact existant. Si aucun contact n’existe, aucun n’est créé. | fin de session avec un identifiant client défini |
| Assistance et gestion des tickets | Le même élément sous forme de note interne sur le dernier ticket ouvert de l'expéditeur. Si aucun ticket ouvert n’existe, rien ne se passe. | fin de session avec un identifiant client défini |
| Marketing par e-mail et marketing de cycle de vie | Identifiant client, nom d’événement et URL de relecture sous forme d'événement dans le système du responsable du traitement. | fin de session avec un identifiant client défini |
| Réseaux publicitaires (Conversions API) | L’identifiant de clic issu du propre cookie du réseau publicitaire, le nom d'événement, la valeur et la devise. Le nom, l’adresse e-mail, le numéro de téléphone et l’adresse IP ne sont pas transmis. | un objectif atteint lorsqu’un consentement a été donné |
| Stockage d’objets et feuilles de calcul | Identifiant client, horodatage et URL de relecture sous forme d'objet ou de ligne dans le propre stockage du responsable du traitement. | fin de session avec un identifiant client défini |
| Suivi des incidents et des tâches | Titre et description d’un élément portant l’URL de relecture. | un signal de frustration ou une erreur JavaScript |
| Les agents IA du responsable du traitement via le serveur MCP | Lecture seule : projets, chiffres clés, listes de sessions avec lien de relecture, sessions individuelles avec pages vues et événements, pages, signaux de frustration et objectifs — pas l’instantané de page. L’authentification utilise une clé de lecture de l’API REST du responsable du traitement. | une requête de l’agent, uniquement lorsque l’accès est activé pour le projet (projects.mcp_active) et avec un niveau payant |
Transfert vers un pays tiers : indéterminé. Le responsable du traitement choisit la destination et le fournisseur ; la garantie au titre du chapitre V du RGPD lui incombe donc. En aucun cas le contenu des pages enregistrées, la trajectoire de souris ou le texte des formulaires n’est transmis — les passerelles transportent des identifiants et des noms d’événements, pas la relecture.
5. Partie B — art. 30(1) : activités effectuées en tant que responsable du traitement
Responsable du traitement pour tout ce qui figure dans cette partie : LW IT Solutions Company Lukas Wójcik, al. Tadeusza Kościuszki 80/82 lok. 301, 90-437 Lodz, Poland, office@mouseplayer.com. Aucun représentant requis (établi dans l’Union). Aucun délégué à la protection des données désigné — section 9. Mesures techniques et organisationnelles : section 8.
B.1 Comptes clients, espaces de travail et facturation
| Champ | Entrée |
|---|---|
| Finalité | Gérer les propres comptes clients de MousePlayer, l’appartenance aux espaces de travail et la facturation. |
| Catégories de personnes concernées | Utilisateurs clients. Mesures : 4 comptes ; workspace_users 4 owner, 1 admin, 1 viewer. |
| Catégories de données à caractère personnel | E-mail, e-mail normalisé, prénom et nom, type d’activité, type de compte (professionnel ou consommateur, customer_type), langue, thème. Données d’entreprise : nom et adresse de l’entreprise, pays et numéro d’identification à la TVA avec le résultat, l’heure et la source de la vérification, ainsi que le nom et l’adresse selon VIES. Logo de l’entreprise (nom de fichier et heure ; fichier lui-même hors du répertoire web). Empreinte du mot de passe, jetons de vérification et de réinitialisation, expiration de la réinitialisation. Connexion à deux facteurs (TOTP, migration 132) : secret sous forme chiffrée, dernier pas de temps utilisé, heure de configuration et codes de récupération hachés. Interrupteur de notification de connexion (login_alert, B.7). Identifiant d’appareil (device_id), drapeau de suspicion is_suspicious. Dernière adresse IP COMPLÈTE, pays, ville, numéro ASN et organisation ASN. Données de facturation : niveau de forfait, devise, identifiant client Stripe, abonnement Stripe, période de facturation, état, résiliation en fin de période. Heure d’un avertissement d’inactivité. Historique IP par utilisateur. |
| Lieu de stockage | users (user_id, email, normalized_email, device_id, password_hash, first_name, last_name, business_type, customer_type, status, lang, verify_token, reset_token, reset_expires, is_superadmin, is_suspicious, new_email, email_verify_token, last_country, last_city, last_asn_number, last_asn_org, last_ip, created_at, last_login, subscription_tier, stripe_customer_id, stripe_subscription_id, billing_period_end, billing_status, retention_grace_until, retention_grace_days). user_ip_history (user_id, ip_address, asn_number, asn_org, last_seen) — 5 lignes, dont 0 tronquée. workspace_users (workspace_id, user_id, role) ; workspace_invites (token, workspace_id, email, role, invited_by, created_at). Sont en outre nommés dans users depuis cette version : company_name, company_street, company_postcode, company_city, company_country, vat_country, vat_number, vat_valid, vat_checked_at, vat_source, vat_name, vat_address, company_logo, company_logo_at, login_alert, totp_secret, totp_enabled_at, totp_last_step, totp_recovery, theme_mode, cancel_at_period_end, inactive_warned_at, sessions_revoked_at. Décomptes de lignes de cette entrée : au 10 août 2026. |
| Base juridique | Non documentée dans le code. Art. 6(1)(b) pour l’exécution du contrat (compte, espace de travail, facturation) et art. 6(1)(c) pour la conservation légale des factures (décision du responsable du traitement, 17 août 2026). Le délai est indiqué dans la ligne de conservation. |
| Catégories de destinataires | Stripe (facturation, voir la section 4). VIES de la Commission européenne (vérification du numéro de TVA, section 4). Namecheap Private Email comme service d’envoi des e-mails au titulaire du compte : confirmation de compte, réinitialisation du mot de passe, invitations, notification de connexion, avertissement avant suppression pour inactivité, avis de modification des documents contractuels, rapport hebdomadaire, réponses de l’assistance (section 4). Les membres du même espace de travail voient le nom, l’adresse e-mail et le rôle des autres membres ainsi que le type de compte de l’espace de travail, c’est-à-dire celui de son propriétaire (clause 6.6 des Conditions d’utilisation), et le logo de l’entreprise du propriétaire ; une personne invitée voit ce logo via le lien d’invitation tant que celle-ci est ouverte. |
| Transfert vers un pays tiers | Stripe (États-Unis) et Namecheap (États-Unis) ; parties contractantes et garanties dans la section 4. VIES se trouve dans l’Union. |
| Conservation | Effacement intégral à la fin du compte — et il prend fin même sans action du propriétaire. Si le propriétaire déclenche la suppression dans les paramètres du compte, mp_konto_loeschung_ausfuehren() (cfg/lib.php) nettoie, entre autres, user_ip_history, live_tokens, login_sessions, remember_tokens, report_subscriptions, les compteurs du quota d’enregistrement, api_keys, workspace_invites, workspace_users, workspaces et users ; audit_logs, bot_review_labels et les entrées dans mp_loesch_archiv sont dépersonnalisés. Depuis le 7 octobre 2026 (migration 189), ce parcours archive d’abord : le compte est suspendu, les connexions sont révoquées, ses propres espaces de travail et projets sont masqués et ne sont plus enregistrés ; ce qui peut être restauré est conservé dans mp_loesch_archiv. Après 30 jours – ou immédiatement si le propriétaire le choisit – le db_worker efface définitivement par la chaîne nommée ci-dessus, puis compte s’il reste quelque chose. Un compte définitivement effacé ne laisse ni identifiant ni nom dans l’archive. Si le propriétaire reste inactif, l’exécution quotidienne avertit après 24 mois sans connexion et supprime 30 jours plus tard par la même chaîne. Le délai court à compter de la dernière connexion, ou de l’inscription pour un compte jamais utilisé. La suppression ne suit jamais qu’un avertissement qui a été remis ; si l’envoi échoue, le délai ne commence jamais. Les deux valeurs se trouvent dans site_settings et sont configurables dans la zone d’administration. Les factures et les pièces comptables associées sont conservées pendant cinq ans, comptés à partir de la fin de l’année civile au cours de laquelle est tombée l’échéance de paiement de l’impôt (déclaration du responsable du traitement, 17 août 2026 : "5 lat, licząc od końca roku kalendarzowego, w którym upłynął termin płatności podatku"). Les données des factures sont donc exemptées de la suppression du compte ; les autres champs du compte sont supprimés avec celui-ci. Depuis le 16 octobre 2026 seuls les comptes au niveau gratuit sont avertis et supprimés pour inactivité : leur propre niveau est free et ils ne sont membres d’aucun espace de travail dont le propriétaire est à un niveau payant. Cette suppression n’archive pas au préalable, mais supprime directement par la chaîne nommée ci-dessus. Le logo de l’entreprise est supprimé avec le compte, comme dernière étape de la suppression. |
| Logo de l’entreprise (depuis le 7 octobre 2026) | Le client peut téléverser un logo dans les paramètres (PNG, JPEG, WebP). Ce qui est stocké n’est pas le fichier livré, mais une image redessinée sur le serveur, hors du répertoire web (daten/firmenlogos/, migration 184). Il est visible par le compte lui-même, le superadministrateur, les membres des espaces de travail appartenant au compte et les personnes invitées via le lien d’invitation tant que celle-ci est ouverte ; toutes les autres requêtes reçoivent la même réponse que pour un logo absent. |
| Export du compte (art. 15(3), art. 20 du RGPD) | Après avoir saisi son mot de passe, le titulaire du compte peut télécharger dans les paramètres une archive ZIP contenant les données de son compte au format JSON et le logo de l’entreprise. Les tables sont déterminées à partir du schéma (colonnes qui renvoient au compte) ; les secrets comme l’empreinte du mot de passe, les jetons et le secret TOTP sont exclus. Les tentatives échouées sont comptées dans le journal des modifications et bloquent l’export après cinq tentatives en 15 minutes. L’archive n’est créée que comme fichier temporaire pour sa remise. |
| Autres données de compte (au 16 octobre 2026) | legal_acceptances : acceptation des documents contractuels (y compris l’information sur la rétractation et la demande de démarrage immédiat) et avis de modification remis, chacun avec compte, adresse IP complète, identifiant du navigateur, langue, sommes de contrôle des versions et origine de l’entrée ; l’acceptation la plus récente (pas les avis) d’un compte existant est conservée aussi longtemps que le compte existe, pour pouvoir montrer quelle version un client actuel a acceptée (depuis le 16 octobre 2026) ; les acceptations plus anciennes, les avis et les lignes des comptes supprimés sont supprimés 730 jours après l’acceptation ou l’avis concerné (qualification de la base juridique de conservation après la fin du compte en attente auprès du responsable du traitement). report_subscriptions : abonnement au rapport hebdomadaire avec jeton de désabonnement et dernier envoi ; supprimé avec le compte. workspace_transfers : transfert d’un espace de travail vers une adresse e-mail avec jeton et expiration ; supprimé avec l’espace de travail. mp_dashboards : propres tableaux de bord d’un compte par projet ; supprimés avec le compte ou le projet. SSO Enterprise (sso_providers, sso_identities, sso_requests, sso_assertions, sso_policies, migrations 187 et 188) : configuration chiffrée du fournisseur d’identité choisi par le propriétaire de l’espace de travail, par compte uniquement une empreinte de l’identifiant chez le fournisseur, requêtes de connexion valables cinq minutes ; le serveur appelle les points de terminaison de ce fournisseur, le destinataire étant celui choisi par le client. Au 16 octobre 2026, aucun espace de travail n’a de fournisseur configuré. Quota d’enregistrement (mp_aufnahme_monat, mp_aufnahme_sitzung, migration 178) : compteurs par propriétaire et par mois, par session uniquement une empreinte du projet et de l’identifiant de session ; une exécution quotidienne supprime les empreintes des mois passés, les compteurs sont supprimés avec le compte. |
B.2 Journaux d’accès, de sécurité et d’audit du portail
| Champ | Entrée |
|---|---|
| Finalité | Journalisation des accès, de la sécurité et des modifications du propre portail de MousePlayer. |
| Catégories de personnes concernées | Visiteurs et utilisateurs de mouseplayer.com et de www.mouseplayer.com. |
| Catégories de données à caractère personnel | Adresse IP COMPLÈTE, agent utilisateur, chemin complet de la requête, pays, ville, type d’appareil, système d’exploitation, navigateur, ASN. Événements de sécurité avec IP partiellement tronquée : WSS_CONNECT 1261, url_excluded 71, consent_blocked 24. Journal des modifications : utilisateur, espace de travail, action, cible, détails en JSON, IP. |
| Lieu de stockage | mouseplayer_logs (log_id, ip_address, user_agent, page_url, created_at, country_code, asn_number, asn_org, city, device_type, os_name, browser_name) — le 10 août 2026, 36409 lignes, 8,5 MB, sans valeurs IP tronquées. Depuis le 17 août 2026, log_mouseplayer_traffic() (cfg/lib.php) ne place qu’une ligne brute par requête dans la file Redis queue:traffic_logs ; la résolution GeoIP et ASN, la classification du navigateur et de l’appareil et l’écriture — y compris users.last_ip et les champs de localisation du compte — sont effectuées par le db_worker. L’adresse est déterminée par getBestClientIP() ; les en-têtes ne sont considérés comme fiables que lorsque la connexion provient du nginx en amont. security_access_logs (id, ip_address, user_agent, event_type, details, created_at) — le 10 août 2026, 1354 lignes, dont 350 tronquées. audit_logs (log_id, user_id, workspace_id, action, target_id, details, ip_address, created_at) — le 10 août 2026, 666 lignes, non tronquées. banned_ips (ip_address, scope, reason, banned_at, expires_at). |
| Base juridique | Non documentée dans le code. Le seul raisonnement consigné est le commentaire à class/Server.class.php:421-425, qui distingue la règle A (adresse complète, pour l’accès DIRECT à notre propre application) de la règle B (tronquée, pour les données des visiteurs). Cela explique le choix de conception, mais ne constitue pas une base juridique. Art. 6(1)(f). Finalité : défense contre les abus et responsabilité (confirmé par le responsable du traitement, 17 août 2026). Mise en balance : sans journaux, il n’est possible ni de détecter une attaque ni d’établir plus tard qui a effectué une modification. Aucun moyen moins intrusif ne permet d’obtenir la même chose — un journal anonymisé perd précisément l’attribution en cause. L’ingérence est bornée par les délais (72 heures pour le journal de sécurité, 60 jours pour le journal d’accès, 60 jours pour le journal des modifications) et par le fait que les journaux ne concernent que l’accès à l’application elle-même, pas les visiteurs enregistrés. Les personnes touchées sont des utilisateurs clients qui utilisent délibérément le service et s’attendent à ce que leurs actions administratives soient journalisées. |
| Catégories de destinataires | MousePlayer lui-même. audit_logs est en outre visible par le superadministrateur (www/admin.php). |
| Transfert vers un pays tiers | Aucun. |
| Conservation | mouseplayer_logs : 60 jours. security_access_logs : 72 heures. banned_ips : à l’expiration de expires_at ; les entrées définies manuellement sans expiration restent jusqu’à leur levée par l’exploitant. audit_logs : 60 jours, nouveau depuis le 17 août 2026. user_ip_history : 90 jours à compter de la dernière observation d’une adresse, nouveau depuis le 24 septembre 2026 ; au plus tard avec le compte. Toutes les valeurs se trouvent dans site_settings et sont configurables dans la zone d’administration. Le fait que le journal des modifications survive au journal de sécurité est délibéré : le journal d’accès indique qui était présent, celui des modifications qui a changé quelque chose. Ce dernier est le relevé de responsabilité au titre de l’art. 5(2) et doit survivre à un litige qui n’apparaît que des mois plus tard. |
B.3 Demandes d’assistance
| Champ | Entrée |
|---|---|
| Finalité | Recevoir et traiter les demandes d’assistance. Depuis le 30 septembre 2026, cela inclut la traduction d’un message et la préparation d’un projet de réponse par un modèle de langage sur notre propre matériel ; une personne examine chaque projet et l’envoie. |
| Catégories de personnes concernées | Personnes formulant une demande, connectées ou non. |
| Catégories de données à caractère personnel | Adresse e-mail, objet, texte libre du message. Adresse IP COMPLÈTE — REMOTE_ADDR, remplacée par HTTP_X_FORWARDED_FOR, sans troncature. Agent utilisateur, URL source. Le champ d’un code pays est lu dans l’en-tête HTTP_CF_IPCOUNTRY ; aucun Cloudflare n’étant placé en amont, il contient toujours la valeur de repli XX ou rien. |
| Lieu de stockage | support_requests (id, user_id, channelid, email, reason, message, status, ip_address, user_agent, source_url, country_code, created_at). Depuis le 30 septembre 2026, également mp_support_ki : une ligne par tâche (traduction, projet, traduction de notre propre projet) avec le texte préparé pour le modèle, le résultat, le nom du modèle et la durée ; liée à la demande par une clé étrangère. |
| Base juridique | Art. 6(1)(b) lorsque le demandeur est un client et que la demande concerne l’exécution du contrat ; sinon, art. 6(1)(f). L’adresse IP complète repose sur la même base : elle sert à défendre le canal d’assistance contre les abus. Les envois massifs ou répétés, les menaces et les autres préjudices ne peuvent être ni détectés ni arrêtés sans elle, et une adresse tronquée ne permet pas cette distinction. Décision du responsable du traitement, 17 août 2026. |
| Catégories de destinataires | Jusqu’au 11 août 2026 : Telegram. cfg/lib.php envoyait l’état de l’utilisateur, l’adresse e-mail, l’objet, l’adresse IP NON TRONQUÉE avec le pays, l’URL source et le texte intégral du message à api.telegram.org. Depuis le 11 août 2026 : aucun. Tout ce qui parvient à api.telegram.org est la chaîne fixe 'MousePlayer: es liegt eine neue Supportanfrage vor.', sans aucune variable ; Telegram ne reçoit donc aucune donnée à caractère personnel et n’est pas un destinataire. La demande elle-même reste inchangée dans support_requests. Modèle de langage (depuis le 30 septembre 2026) : aucun. Il s’exécute sur nos propres machines dotées d’une carte graphique, dans le même réseau local et sur le même site que le serveur ; elles récupèrent la tâche par HTTPS, chaque requête étant signée avec son propre secret. Elles reçoivent le texte du message, l’objet, le fait que le demandeur possède ou non un compte et le chemin de la page source – les adresses e-mail et les suites de six chiffres ou plus sont remplacées au préalable (mp_supki_saeubern() dans cfg/support_ki_lib.php), dans notre propre projet de réponse uniquement les adresses e-mail. Pas l’adresse IP, pas l’adresse e-mail du demandeur. Aucun service d’IA externe, même en solution de repli. |
| Transfert vers un pays tiers | Jusqu’au 11 août 2026 : Telegram, hors UE ; aucun accord de traitement des données n’est disponible pour les bots — voir la section 4. Depuis le 11 août 2026 : aucun. La notification à api.telegram.org ne contient plus de données à caractère personnel ; aucun transfert vers un pays tiers n’a donc lieu. Le canal continue d’exister comme simple signal — voir la section 4. |
| Décision automatisée | Aucune. Le modèle ne propose que du texte ; rien n’est envoyé automatiquement – une personne lit le projet, le modifie au besoin et l’envoie. Pas une décision au sens de l’art. 22 du RGPD. |
| Conservation | 730 jours, imposés par l’exécution quotidienne dans srv/db_worker.php ; la valeur se trouve dans site_settings sous retention_evidence_days et est configurable dans la zone d’administration. Lors de la suppression du compte, la demande reste, mais perd son lien avec le compte (user_id devient NULL) ; la politique de confidentialité l’indique expressément. Les lignes dans mp_support_ki sont supprimées avec leur demande (ON DELETE CASCADE, migration 168), sur chaque parcours de suppression. |
B.4 Acceptation par le client des règles régionales d’enregistrement
| Champ | Entrée |
|---|---|
| Finalité | Prouver l’acceptation par le client des règles régionales d’enregistrement — une déclaration contractuelle. |
| Catégories de personnes concernées | Utilisateurs clients. |
| Catégories de données à caractère personnel | Identifiant utilisateur, e-mail, régions, version du texte, somme de contrôle du texte, langue. Adresse IP COMPLÈTE et agent utilisateur — délibérément, et la raison est consignée dans ai/migrations/018_consent.sql : c’est l’acceptation d’un contrat par un partenaire commercial, pas des données de visiteurs. |
| Lieu de stockage | consent_region_acceptances (id, channelid, workspace_id, user_id, user_email, regions, text_version, text_checksum, text_lang, ip_address, user_agent, accepted_at) — 0 ligne. |
| Base juridique | Preuve d’une déclaration contractuelle, comme justifié dans l’en-tête de la migration. |
| Catégories de destinataires | MousePlayer lui-même. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | 730 jours à compter de l’acceptation — le même délai que pour les autres enregistrements de consentement aux conditions (support_requests, legal_acceptances ; pour legal_acceptances l’acceptation la plus récente d’un compte existant est conservée au-delà, voir B.1), parce qu’ils répondent à la même question : qui a accepté quoi, et quand. La valeur se trouve dans site_settings sous retention_evidence_days ; imposé par l’exécution quotidienne dans srv/db_worker.php. |
B.5 Visiteurs de notre propre site web
| Champ | Entrée |
|---|---|
| Finalité | Exploitation de mouseplayer.com lui-même : dialogue de consentement, défense contre les accès automatisés, démonstration sur la page d’accueil et journaux du serveur web. |
| Catégories de personnes concernées | Visiteurs de mouseplayer.com. |
| Catégories de données à caractère personnel | Adresse IP — non tronquée dans les journaux serveur —, heure, adresse demandée, code d’état, identification du navigateur. Pour la démonstration, en outre, positions du pointeur et des clics, identifiant de session attribué aléatoirement et pays déduit de l’adresse. Pour reCAPTCHA, l’adresse plus les caractéristiques de l’appareil et du comportement. |
| Lieu de stockage | Journaux d’accès de nginx (/var/log/nginx/) et d’Apache, tous deux avec l’adresse complète, logrotate quotidien avec 14 rotations. Depuis le 16 août 2026, nginx est la première couche à voir une adresse de visiteur ; Apache se trouve derrière sur le bouclage et la reçoit par le protocole PROXY ou X-Forwarded-For. Les données de démonstration ne sont pas stockées, seulement transmises sur le moment. |
| Base juridique | Démonstration : consentement, art. 6(1)(a) — son verrou est en place depuis le 17 août 2026. reCAPTCHA et journaux serveur : intérêt légitime, art. 6(1)(f). Art. 6(1)(f). Finalité : défense contre les abus et responsabilité (confirmé par le responsable du traitement, 17 août 2026). reCAPTCHA : sans protection contre les accès automatisés, les pages de connexion, d’inscription, du formulaire d’assistance et de facturation sont exposées aux attaques. Le moyen moins intrusif — une simple limitation du débit — est en outre en place depuis le 17 août 2026, mais ne remplace pas entièrement la notation. Journaux serveur : l’adresse non tronquée est nécessaire pour attribuer des accès répétés ou massifs au même expéditeur ; une adresse tronquée ne permet pas cette distinction. L’ingérence est bornée par le délai de 14 jours et par le fait que les journaux ne sont pas combinés à d’autres données. |
| Catégories de destinataires | Google Ireland Limited (reCAPTCHA) et consented.eu (dialogue de consentement). Pour la démonstration, également les autres visiteurs qui ont la page d’accueil ouverte au même moment — ils voient le pointeur et le pays, pas l’adresse. |
| Transfert vers un pays tiers | États-Unis via reCAPTCHA ; pour la base et la date d’acceptation, voir la section 4. |
| Conservation | Journaux serveur : 14 jours. La démonstration ne stocke rien. |
Cette entrée manquait jusqu’au 17 août 2026, bien que la section 4 nommât déjà le dialogue de consentement et reCAPTCHA comme destinataires — le traitement correspondant n’apparaissait nulle part. La politique de confidentialité publique a été étendue le même jour pour couvrir le même sujet (sa section 10) ; les deux textes doivent être lus l’un en regard de l’autre.
B.6 Accès à un lien de partage
| Champ | Entrée |
|---|---|
| Finalité | Prouver à quelle fréquence et depuis où un lien de partage a été utilisé. Un tel lien ouvre un enregistrement complet sans connexion ; sans ce journal, il n’est pas possible d’établir après coup combien de fois il a été utilisé ni s’il a quitté le cercle prévu. |
| Catégories de personnes concernées | Personnes qui ouvrent un lien de partage — généralement le personnel du Client ou les destinataires qu’il a choisis. Pas les visiteurs enregistrés ; ce sont des personnes différentes. |
| Catégories de données à caractère personnel | Adresse IP de la personne qui accède (non tronquée), identification du navigateur, heure, identifiant du lien. |
| Lieu de stockage | share_views (migration 043), lié à session_shares par une clé étrangère avec ON DELETE CASCADE. |
| Base juridique | Art. 6(1)(f). Finalité : défense contre les abus — un lien sans connexion est précisément le type d’adresse qui est retransmis. Mise en balance : il n’existe aucun moyen moins intrusif : une adresse tronquée ne permet pas de savoir si deux accès proviennent du même endroit et, sans elle, une retransmission ne peut être ni détectée ni prouvée. L’ingérence est étroitement bornée — elle ne touche pas la personne enregistrée, mais celle qui accède, et la ligne disparaît avec le lien. Les personnes touchées ouvrent un lien vers l’enregistrement d’autrui et doivent s’attendre à ce que cet accès soit journalisé. (décision du responsable du traitement, 17 août 2026) |
| Catégories de destinataires | Aucun. Le journal ne quitte pas notre propre base de données. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | Avec le lien. Lorsqu’il expire ou est révoqué, le journal est supprimé avec lui par la clé étrangère. Un lien vit au plus 90 jours, 7 par défaut — l’application ne peut pas en créer de plus long. |
Le fait que la ligne disparaisse avec le lien n’est pas ici une commodité, mais la moitié de la base juridique : un journal qui survit au lien n’a plus de finalité pour le justifier.
B.7 Connexions actives et leur révocation
| Champ | Entrée |
|---|---|
| Finalité | Montrer au titulaire du compte où son compte est connecté et lui permettre de fermer la connexion d’un seul appareil ou celles de tous les autres. Sans cette liste, une connexion détournée ne peut être ni repérée ni interrompue : jusqu’au 28 août 2026, un changement de mot de passe n’invalidait que les cookies “rester connecté”, tandis que les sessions en cours subsistaient comme fichiers — mesuré entre 24 et 54 minutes. |
| Catégories de personnes concernées | Titulaires et membres d’un compte client. Pas les visiteurs enregistrés ; ce sont deux personnes différentes. |
| Catégories de données à caractère personnel | Adresse IP (non tronquée), agent utilisateur et, déduits de celui-ci, navigateur, système d’exploitation et type d’appareil, localisation approximative (ville et pays) issue de l’adresse, heure de connexion et de la dernière activité. L’identifiant de session lui-même n’est pas stocké, seulement son empreinte SHA-256. À côté, une empreinte d’appareil — une empreinte du navigateur, du système d’exploitation, du type d’appareil et de la plage d’adresses (/24 ou /48, jamais l’adresse complète), qui permet de reconnaître un appareil déjà connu. |
| Lieu de stockage | login_sessions (migration 094), lié par remember_selector à remember_tokens (migration 037). |
| Base juridique | Art. 6(1)(b) lu conjointement avec l’art. 32. Finalité : sécurité du compte — ce traitement est la mesure technique, et non un sous-produit de celle-ci. Mise en balance : il n’existe aucun moyen moins intrusif. Une adresse tronquée échoue précisément à répondre à la question pour laquelle la liste existe (“était-ce moi ?”), et sans navigateur ni localisation, une ligne ne peut être distinguée d’une autre. Les données apparaissent de toute façon à chaque connexion ; la nouveauté est seulement qu’elles deviennent visibles et révocables. Elles ne sont visibles que par le titulaire du compte. |
| Catégories de destinataires | Aucun. La liste ne quitte pas notre propre base de données. |
| Transfert vers un pays tiers | Aucun. |
| Conservation | 90 jours à compter de la dernière activité, et effacement intégral à la fin du compte. Le point de départ est la dernière activité plutôt que la création : un appareil connecté depuis des mois mais utilisé hier correspond à une connexion actuelle et appartient à la liste. |
Depuis le 28 août 2026, les mêmes données produisent en outre un avis au titulaire du compte lorsque son compte est ouvert depuis un appareil jamais apparu auparavant. Il est adressé à la propre adresse enregistrée de la personne concernée et à personne d’autre ; il n’ajoute aucun destinataire au sens de l’art. 4(9). Chaque compte peut le désactiver dans les paramètres sans perdre la liste elle-même — par défaut, il est activé, car un avis de sécurité qu’il faut d’abord activer n’atteint précisément pas ceux qui en ont besoin. L’empreinte repose délibérément sur la plage d’adresses plutôt que sur l’adresse complète : un foyer reçoit une IP différente lors de sa reconnexion nocturne, et avec l’adresse complète, un avis arriverait chaque matin — le signal serait sans valeur, et l’avis avec lui.
Deux décisions doivent ici être expliquées. Ce qui est stocké est l’empreinte de l’identifiant de session, jamais l’identifiant lui-même : sinon, un dump de la base de données livrerait des cookies de session valables, et un dump tombé entre de mauvaises mains est précisément le cas contre lequel cette table est construite. Et une ligne révoquée n’est pas supprimée, mais marquée comme révoquée — une ligne supprimée serait une session inconnue pour la vérification exécutée à chaque requête, et une session inconnue peut être écrite à nouveau. La révocation se serait annulée d’elle-même.
B.8 Alertes opérationnelles et e-mails retenus (urgent_logs)
| Champ | Entrée |
|---|---|
| Finalité | Alertes opérationnelles pour le superadministrateur : défauts détectés par les mécanismes de surveillance dans srv/cron_status.php, cas douteux de la vérification des robots (A.19), au choix du superadministrateur les anomalies d’un projet à la place d’un e-mail, et e-mails sortants retenus par une liste de blocage. Le blocage empêche l’envoi d’e-mails aux propres adresses figurant dans la liste ou aux domaines de test et d’exemple réservés ; l’e-mail retenu est stocké ici pour qu’il reste possible de retracer ce qui aurait été envoyé. |
| Catégories de personnes concernées | Utilisateurs clients et autres destinataires d’un e-mail retenu ; indirectement, visiteurs dont l’identifiant de session apparaît dans une alerte de vérification des robots. |
| Catégories de données à caractère personnel | Source, objet, texte d’alerte, heures de création, de dernière répétition, de résolution et d’envoi d’e-mail. Pour un e-mail retenu, adresse du destinataire et texte intégral de l’e-mail en clair — selon son type, par exemple nom et adresse e-mail et, pour une notification de connexion, également adresse IP, appareil et localisation approximative. |
| Lieu de stockage | urgent_logs (id, quelle, betreff, meldung, erstellt_am, zuletzt_am, erledigt_am, mail_status, mail_am, stoerung_beendet_am). |
| Base juridique | Art. 6(1)(f). Finalité : sécurité opérationnelle et traçabilité de l’envoi d’e-mails. Les alertes ne sont accessibles qu’au superadministrateur et sont supprimées dans un délai défini après leur résolution. |
| Catégories de destinataires | Le superadministrateur. Les alertes de défaut sont en outre envoyées par e-mail à l’adresse d’alarme de l’exploitant (via Namecheap Private Email, section 4) ; un e-mail retenu n’est envoyé à personne. |
| Transfert vers un pays tiers | Aucun ; pour l’envoi à l’adresse d’alarme, voir Namecheap dans la section 4. |
| Conservation | Une ligne reste jusqu’à sa résolution — par le mécanisme de surveillance une fois le défaut disparu, ou manuellement ; un e-mail retenu n’est jamais résolu automatiquement. Le mécanisme de surveillance d’état supprime les lignes résolues 180 jours après la résolution (site_settings.retention_urgent_days, configurable dans la zone d’administration, au moins 7 jours). |
6. Conservation — ce que couvre la purge quotidienne, et ce qu’elle ne couvre pas
Il existe une suppression automatique et, depuis le 17 août 2026, elle couvre toutes les tables contenant des données à caractère personnel, soit par un délai propre, soit par la chaîne de suppression des sessions. Son cœur se trouve dans srv/db_worker.php dans le bloc marqué DAILY DATA PRUNING et s’exécute au sein du processus worker permanent une fois par jour calendaire (contrôlé par $lastPurgeDate). Les délais des sessions de robots (chaque heure), la suppression définitive des entrées archivées (toutes les 30 secondes) et les demandes de suppression de l’accès à ses propres informations en libre-service ont leurs propres cycles dans le même processus. Depuis le 7 octobre 2026, les tâches planifiées s’exécutent depuis /etc/cron.d/mouseplayer via srv/cron_run.sh avec un verrou par tâche, dont le déplacement des événements vers l’archive (chaque heure) et la maintenance de l’index textuel (toutes les dix minutes) ; l’agrégat quotidien de la carte des clics est construit chaque nuit.
Preuve d’exécution (au 16 octobre 2026) : le journal du worker consigne chaque jour l’exécution quotidienne, pour la dernière fois le 16 octobre 2026 à 00:00:11, achevée dix secondes plus tard, ainsi que le délai horaire des sessions de robots avec des sessions et des lignes supprimées (par exemple à 10:00:18 le même jour, 478 sessions avec 3294 lignes). Jusqu’à ce jour, le délai du niveau de forfait n’avait rien à supprimer : les projets ayant des sessions plus anciennes sont au niveau enterprise (365 jours), et les sessions les plus anciennes du niveau gratuit sont plus récentes que son délai. L’échec ou l’absence d’une exécution planifiée est vérifié par le mécanisme de surveillance cron dans srv/cron_status.php, qui le signale dans les Urgent Logs (B.8) et par e-mail.
6.1 Couvert par la purge quotidienne
| Table | Déclencheur et délai | Preuve |
|---|---|---|
| mouseplayer_logs | Plus ancien que 60 jours (site_settings.log_retention_days) | srv/db_worker.php, DAILY DATA PRUNING |
| security_access_logs | Plus ancien que 72 heures (site_settings.security_log_retention_hours) | srv/db_worker.php, DAILY DATA PRUNING |
| banned_ips | expires_at est dans le passé ; les entrées sans expires_at restent jusqu’à leur levée par l’exploitant | srv/db_worker.php, DAILY DATA PRUNING |
| visitor_sessions et tout ce qui lui est rattaché (mouse_events, session_pageviews, session_custom_events avec paramètres et autres tables de la chaîne de suppression) | Par session, une fois le délai du niveau de forfait expiré : free 7 jours, small 30, business 90, enterprise IFNULL(enterprise_custom_tiers.retention_days, 365). Cas particulier free + is_suspicious = 24 heures. Délai de grâce après rétrogradation via GREATEST(...) avec users.retention_grace_until et retention_grace_days. Suppression via mp_sitzungen_loeschen(). | srv/db_worker.php, DAILY DATA PRUNING |
| payload_blob et mouse_events des sessions de robots | L’enregistrement d’une session reconnue comme un robot est vidé une fois le délai écoulé (site_settings.retention_bot_recording_days, délai en jours : 1 ; 0 le désactive) | srv/db_worker.php, chaque heure |
| visitor_sessions des sessions de robots avec tout ce qui leur est rattaché | 14 jours après le début de la session (site_settings.retention_bot_session_days, au moins 8 ; 0 = aucun délai distinct) | srv/db_worker.php, chaque heure, mp_sitzungen_loeschen() |
| mouse_events → fichiers d’archive | déplacés vers des fichiers d’archive comprimés par session après 7 jours ; les fichiers sont supprimés avec leur session | srv/cron_archiv.php (chaque heure), mp_sitzungen_loeschen() |
6.2 Ce qui est en outre couvert depuis le 17 août 2026
Cette section énumérait auparavant treize tables sans aucun délai. C’est réglé. Cinq tables font partie de la chaîne de suppression commune mp_sitzungen_loeschen() depuis le 12 août 2026, six autres ont reçu leur propre délai le 17 août 2026, et deux ne figuraient pas du tout dans la liste : la notation par visiteur et par jour et les textes qui en sont générés.
Les chiffres du tableau ci-dessous ne sont pas des retranscriptions. Ils sont lus dans site_settings lorsque cette page est servie — dans la même ligne que celle lue par la purge — et sont configurables dans la zone d’administration. Un nombre retranscrit serait un deuxième endroit pour la même vérité, et les deux finiraient par diverger.
| Table | Délai | Ce qui l’impose |
|---|---|---|
| ai_session_features | avec la session | mp_sitzungen_loeschen() |
| ai_timelines | avec la session | mp_sitzungen_loeschen() |
| session_comments | avec la session | mp_sitzungen_loeschen() |
| session_shares | avec la session ; le lien lui-même expire après au plus 90 jours, 7 par défaut ; la ligne d’un lien expiré ou révoqué est supprimée 90 jours plus tard, et les accès dans share_views sont supprimés avec elle | mp_sitzungen_loeschen(), mp_share_erstellen(), exécution quotidienne |
| visitor_nicknames | avec la dernière session du visiteur — depuis le 28.08.2026, cela couvre aussi le nom attribué par le responsable du traitement (A.13), qui se trouve dans la même ligne | mp_sitzungen_loeschen() |
| ai_visitor_value | 60 jours à compter du jour noté ; pour Enterprise, la conservation du niveau de forfait. En outre, avec le visiteur dès qu’il ne lui reste plus aucune session | exécution quotidienne, mp_sitzungen_loeschen() |
| ai_insights (scope “visitor”) | de même | exécution quotidienne, mp_sitzungen_loeschen() |
| consent_events | 730 jours à compter de the withdrawal — jamais tant qu’une session y renvoie encore | exécution quotidienne |
| ip_lifetime_stats | 365 jours à compter de first_seen | exécution quotidienne |
| audit_logs | 60 jours | exécution quotidienne |
| support_requests | 730 jours | exécution quotidienne |
| consent_region_acceptances | 730 jours | exécution quotidienne |
| legal_acceptances | 730 jours après l’acceptation ou l’avis ; l’acceptation la plus récente d’un compte existant est conservée aussi longtemps que le compte existe (depuis le 16 octobre 2026) | exécution quotidienne |
| user_ip_history | 90 jours à compter de la dernière observation de l’adresse ; au plus tard avec le compte | exécution quotidienne |
| users (avec last_ip), workspace_users, workspace_invites | avec le compte ; en l’absence de connexion après 24 mois plus un délai d’avertissement de 30 jours | mp_konto_loeschung_ausfuehren(), exécution quotidienne |
| heatmap_page_stats | sans objet — la table a été supprimée le 18 août 2026 (migration 045) | — |
| mp_profil_sitzung | 180 jours à compter du DÉBUT de la session, au moins la fenêtre de calcul ; sans aucun délai dès que la session elle-même a disparu | exécution quotidienne, mp_sitzungen_loeschen() |
| mp_profile, mp_sequenzmuster | mp_profile dès qu’aucune affectation ne lui reste ; mp_sequenzmuster après 180 jours sans recalcul, et immédiatement lorsque son canal n’a plus aucune session | exécution quotidienne |
| ga4_daily, ga4_sessions, ga4_events | 180 jours à compter du jour décrit, respectivement du début de la session GA4 — pas à compter du moment de l’import (A.14) | exécution quotidienne |
| mp_hm_tag, mp_hm_tag_stand | aucun délai propre : un jour stocké est recalculé à partir des sessions encore existantes au plus tard 7 jours après son dernier calcul, à la prochaine ouverture de la liste ; les jours antérieurs à la plus ancienne session restante du projet sont retirés à cette occasion ; tout est supprimé avec le projet (A.8) | à l’ouverture de la liste des cartes de chaleur ; mp_konto_loeschen() |
| mp_umfrage_text | avec la session (A.21) — délibérément aucun délai propre | mp_sitzungen_loeschen(), le parcours d’effacement du lecteur, mp_konto_loeschen() |
| mp_loesch_archiv, mp_loesch_archiv_sitzung | comptes, espaces de travail, projets archivés et visiteurs ou adresses IP archivés (effacement RGPD) : au plus 30 jours, puis effacement définitif. Il reste un enregistrement sans nom – pour les visiteurs et adresses IP, un HMAC de l’identifiant permettant de répéter l’effacement après restauration d’une sauvegarde ; pour les comptes, aucun identifiant – qui est retiré après 730 jours | db_worker, toutes les 30 secondes |
| mp_hm_klick_tag, mp_hm_ansicht_tag | 730 jours à compter du jour décrit par la ligne ; immédiatement avec le projet. Aucune suppression par personne : les lignes ne portent aucun lien personnel (A.1) | srv/hm_aggregat_lauf.php, mp_konto_loeschen() |
| mouse_events_analytik | avec la page vue – depuis le 7 octobre 2026, également sur chaque parcours supprimant des sessions individuelles ; auparavant uniquement avec le projet entier (A.8) | mp_sitzungen_loeschen(), le parcours d’effacement du lecteur, mp_konto_loeschen() |
| login_sessions | 90 jours à compter de la dernière activité ; intégralement avec le compte (B.7) | exécution quotidienne, suppression du compte |
| share_views | avec le lien de partage, via la clé étrangère avec ON DELETE CASCADE (B.6) | clé étrangère |
| ai_churn | réécrit par projet à chaque exécution ; supprimé avec les sessions dont la ligne est déduite (A.16) | srv/ai_worker.php |
| ai_besucher_bericht | 180 jours à compter de la demande ; plus tôt avec la dernière session du visiteur (A.17) | exécution de suivi dans srv/ai_worker.php |
| mp_cwv, mp_element_klicks, mp_element_offen | avec la session ou la page vue ; les lignes dont la page vue manque sont retirées chaque heure (A.7, A.20) | mp_sitzungen_loeschen(), srv/cwv_nachtragen.php, srv/element_worker.php |
| mp_text_block, mp_text_pv, mp_text_stand | 30 jours à compter du début de la page vue ; plus tôt avec la session (A.22) | srv/textsuche_lauf.php, mp_sitzungen_loeschen() |
| bot_review_labels | par défaut : aucune suppression automatique ; configurable en années (retention_bot_labels_years) (A.19) | srv/cron_status.php |
| urgent_logs | 180 jours après la résolution (site_settings.retention_urgent_days) (B.8) | srv/cron_status.php |
| mp_aufnahme_quittung | 7 jours (A.1) | srv/db_worker.php |
| mp_native_apps, mp_native_sessions | jusqu’à l’expiration du délai fixé par session ou jusqu’à révocation ; la préversion est désactivée et n’existe que sur l’instance de développement (A.1) | cfg/native_store.php |
Deux points ont été mesurés plutôt que présumés. Premièrement, l’exécution quotidienne s’exécute réellement. Ce document a indiqué à un moment qu’elle ne l’avait jamais fait ; l’exécution du 17 août 2026 à 17:37:09 est consignée dans le journal du worker. Elle n’a rien supprimé ce jour-là parce que les deux projets contenant des sessions sont au niveau Enterprise et que la session la plus ancienne avait 27 jours — c’est l’état prévu, pas une panne. Deuxièmement, le délai de la notation dérivée a pour point de départ le jour décrit par la ligne, et non le moment de son calcul. Après mesure, 167 lignes portaient 28 jours décrits distincts, mais seulement 6 moments de calcul distincts, le plus récent quelques minutes auparavant : le précalcul recalcule, et chaque recalcul aurait réinitialisé un délai qui lui aurait été rattaché. Il n’aurait jamais expiré et personne ne l’aurait remarqué.
6.3 Constats sur la chaîne de suppression (au 16 octobre 2026)
- LA CHAÎNE FONCTIONNE EN EXPLOITATION. Le 10 août 2026, elle n’avait jamais été exécutée ; c’est pourquoi elle était décrite ici comme non testée. Depuis le 17 septembre 2026, le délai des sessions de robots supprime chaque heure via la même chaîne de suppression
mp_sitzungen_loeschen()que celle également utilisée par le délai du niveau de forfait et par les demandes de suppression ; le 16 octobre 2026, par exemple, 401 et 478 sessions par exécution. Le délai du niveau de forfait lui-même n’avait rien à supprimer jusqu’à ce jour (section 6). - PROJETS SUPPRIMÉS. La sélection du délai du niveau de forfait joint toujours visitor_sessions par INNER JOIN au projet, à l’espace de travail et au propriétaire, et ne voit pas les sessions sans projet. Dans le processus normal, une telle session ne se crée toutefois plus : depuis le 7 octobre 2026, un projet est d’abord archivé puis, lors de la suppression définitive, retiré avec toutes ses sessions par la suppression du canal (
mp_kanaele_loeschen()). Au 16 octobre 2026, aucune session n’est sans projet. - ÉLÉMENTS ORPHELINS. Tout ce qui est dérivé d’une session fait partie de la chaîne de suppression ou a son propre délai (section 6.2). Les pages vues dont la session manque — par exemple après une interruption au milieu d’une suppression — sont comptées une fois par jour par le mécanisme de surveillance d’état et retirées automatiquement avec leurs événements dès qu’elles ont plus de dix minutes.
- LA PURGE DÉPEND DU FONCTIONNEMENT DU WORKER. Un worker arrêté arrête aussi la suppression. Depuis le 19 août 2026, les mécanismes de surveillance signalent les pannes par e-mail ; depuis le 23 septembre 2026, ces e-mails sortent effectivement par SMTP et, depuis le 2 octobre 2026, une machine distincte nous appartenant, dans le même réseau local, vérifie chaque minute depuis l’extérieur que la base de données, Redis, le serveur WebSocket, les processus permanents et la file d’attente sont en ordre. Il reste à noter que ActiveState=active ne prouve pas que le worker est vivant ; la liste des processus est fiable.
Parcours manuels de suppression, pour être complet : le lecteur (delete_session et delete_visitor, limités au channelid, rôles owner et admin) et mp_sitzungen_loeschen() dans srv/db_worker.php. Un retrait ne supprime que lorsque projects.consent_delete_on_withdraw est défini ; au 16 octobre 2026, la valeur n’est définie pour aucun projet. Il n’existe aucun ON DELETE CASCADE en aval de visitor_sessions : la chaîne s’exécute manuellement sur toutes les tables dépendantes, et le point délicat est mouse_events, car les événements dépendent de pageview_id plutôt que de session_id ; depuis le 7 octobre 2026, elle emporte aussi la copie des clics mouse_events_analytik avec elle.
Hors de la base de données : les journaux d’accès de nginx et d’Apache contiennent des adresses IP complètes et sont conservés sur 14 rotations quotidiennes (logrotate). Redis de l’instance de développement n’écoute que sur 127.0.0.1 (port 6381), son accès est restreint et il écrit ses données sur disque pour la persistance (AOF et instantanés RDB) ; les files contiennent l’IP tronquée, l’URL complète et la charge utile DOM jusqu’à leur récupération par le worker, et mp_autoban: conserve l’adresse complète d’un expéditeur bloqué pendant la durée du blocage (24 h). Les fichiers d’archive des événements déplacés se trouvent sous /mnt/mouseplayer-dev-archive sur le même disque que le système et sont inclus dans la sauvegarde depuis le 6 octobre 2026.
7. Prise de décisions automatisée, profilage et notation
La notation et la classification ont lieu. Aucune décision produisant des effets juridiques concernant un VISITEUR, ou l’affectant de manière similaire de façon significative, n’a été constatée — aucune décision de crédit, de tarification ou d’accès, et aucune divulgation des évaluations à quiconque autre que le client. Au vu des éléments constatés, l’art. 22 n’est pas applicable aux visiteurs. Trois conséquences automatisées existent, et deux méritent un examen plus attentif que celui habituellement donné par un registre. La troisième a été ajoutée le 2 septembre 2026 et est la seule qui agit en retour sur le VISITEUR : la prédiction de sortie (A.15) ou l’indicateur de risque de perte (A.16) peut conduire à une surimpression sur le site web du responsable du traitement. Elle n’apparaît que s’il l’active, son contenu est le sien et elle peut être fermée. Il n’en découle aucun effet juridique ni aucune incidence similaire significative au sens de l’art. 22(1) du RGPD — c’est une invitation, pas une décision sur le prix, l’accès ou la solvabilité. Cela appartient néanmoins au registre, car une évaluation quitte ici pour la première fois le panneau client.
| Mécanisme | Ce qu’il fait | Où |
|---|---|---|
| Score d’engagement | Un petit entier construit à partir de points de profondeur (durée, nombre de pages, profondeur de défilement) et de caractère remarquable (clics de rage et clics morts, retours en arrière, onglets parallèles). Les robots et les sessions triviales ont un score de 0. Stocké dans ai_session_features.engagement_score (TINYINT UNSIGNED), index idx_engagement. Effet : ordre de la liste de recommandations dans le panneau client. | ai/features.py:33-70 ; cfg/project_ai_overview.php:126-136 et 150 ; cfg/project_live_users.php:190 |
| Qualité de session | Distingue les sessions où il ne s’est presque rien passé. | visitor_sessions.session_quality ; srv/db_worker.php:706-780 et 1103-1140 |
| Classification des robots | Définit visitor_sessions.is_bot et bot_reason (varchar 32), index idx_is_bot. Noter que la vérification des robots dans mp.js s’exécute AVANT le verrou du consentement. | srv/db_worker.php:963-1000 |
| Détection de frustration dans le navigateur | Génère rage_click, dead_click et mouse_thrashing. Mesures : dead_click 355, rage_click 52, mouse_thrashing 5. Sur rage_click, le script transmet en outre un indicateur aux widgets de discussion tiers présents dans le navigateur du VISITEUR — Intercom('update', {'mouseplayer_rage_click':'DETECTED_NOW'}) et LiveChatWidget.call('set_session_variables', ...). C’est une divulgation ultérieure automatisée d’un jugement comportemental à un système tiers sur la page du client. | www/mp.js:5786 et 5793-5794 |
| Journal textuel de session | Prose générée par une machine sur le déroulement de la session, produite par ai/build.py. Depuis le 12 août 2026, srv/ai_worker.php invoque lui-même la construction (avec répertoire de travail et PYTHONPATH) ; au 16 octobre 2026, elle s’exécute, et la chronologie la plus récente date du même jour. Les messages d’erreur dans ai_build.log proviennent de l’invocation antérieure supprimée depuis et ont été écrits pour la dernière fois le 18 août 2026. | ai/build.py ; srv/ai_worker.php ; ai_timelines |
| is_suspicious à l’inscription | Défini automatiquement lors de l’inscription, en utilisant notamment device_id et l’e-mail normalisé. Conséquence : pour le niveau gratuit, le délai de conservation est ramené à 24 heures. | www/register.php:159-191 ; srv/db_worker.php:824 |
| Blocage automatique | Plus de 15 connexions en 10 secondes, plus de 15 connexions simultanées depuis une IP, plus de 50 messages par seconde et des messages trop grands (sauf un grand instantané de page) ou illisibles entraînent un blocage de 24 h dans le serveur WebSocket (site_settings.autoban_stunden, 1 à 168), conservé dans Redis (mp_autoban:) et journalisé sans l’adresse complète. Devant le serveur web, fail2ban bloque une adresse pendant une heure si elle atteint la limitation de débit nginx plus de 100 fois en une minute (jail mp-nginx-429). Selon le code au 16 octobre 2026, les entrées dans banned_ips ne sont désormais définies que par l’exploitant ; les anciennes entrées automatiques expiraient après 7 jours. | class/Server.class.php (autoBanIp) ; /etc/fail2ban/jail.d/mp-nginx-429.conf ; /etc/nginx/conf.d/mouseplayer.conf |
| Profils de comportement — regroupement des visites (A.12) | k-means sur sept caractéristiques par session attribue chaque visite pouvant être regardée à l’un d’au plus huit groupes et le nomme à partir de la position relative du centre du groupe. Les sessions triviales et celles reconnues comme des robots sont séparées au préalable par une règle et ne sont pas du tout regroupées par clustering. Effet : un AFFICHAGE — un onglet, une pastille de filtre et une file de lecture. Aucune décision n’en dépend. | ai/profile.py ; cfg/project_profiles.php ; mp_profil_sitzung |
| Score de friction et anomalies | Pour chaque session, une valeur de 0 à 100 déduite de signaux pondérés de frustration et d’erreur avec leurs motifs (depuis le 26 septembre 2026) ; elle trie et filtre les listes et peut déclencher un webhook auquel le client s’est abonné lorsqu’un seuil est atteint. Une fois par jour, le jour précédent de chaque projet est comparé aux semaines précédentes (sessions, taux d’objectifs, part avec friction ou erreurs JavaScript, Web Vitals) et une anomalie est signalée — des décomptes sur le projet, pas une évaluation de visiteurs individuels. Aucune décision concernant le visiteur n’en dépend. | cfg/reibung_lib.php ; cfg/anomalie_lib.php ; visitor_sessions.friction_score ; mp_anomalie |
Le blocage automatique est le seul mécanisme ici qui refuse l’accès à un service sans intervention humaine, et il peut toucher un utilisateur client, pas seulement un visiteur. Ce registre ne tranche pas la question de savoir si cela atteint le seuil de l’art. 22(1). Évalué le 17 août 2026, mis à jour le 16 octobre 2026 : le blocage du serveur WebSocket expire de lui-même après 24 h, celui de fail2ban après une heure ; l’ancien blocage automatique dans banned_ips expirait après 7 jours. Une opposition passe par le formulaire d’assistance ou par office@mouseplayer.com et est traitée par un humain ; l’exploitant peut lever un blocage de manière anticipée. La procédure a donc un effet limité, un examen humain sur demande et une voie nommée pour y accéder — les caractéristiques dont dépend l’art. 22. La qualification elle-même reste une question juridique ; ce qui a été décidé, c’est la garantie, et non l’interprétation. (Décision du responsable du traitement, 17 août 2026)
Le regroupement de A.12 est du profilage au sens de l’art. 4(4) du RGPD : les données comportementales sont évaluées automatiquement pour apprécier des aspects du comportement. L’art. 22(1) exige davantage — une DÉCISION produisant des effets juridiques ou affectant de manière similaire la personne de façon significative. Aucune n’a été constatée, après vérification selon trois axes. L’appartenance au groupe est écrite par ai/profile.py et lue sur exactement quatre parcours : les fonctions de lecture dans cfg/lib.php, l’onglet cfg/project_profiles.php, le lecteur www/player.php et le générateur de phrases cfg/ki_lib.php — et nulle part ailleurs. Elle n’entre dans aucune des passerelles de 4.1 : une recherche de profil_key dans cfg/, srv/, www/ et class/ ne renvoie ni www/mp.js ni class/Server.class.php, et n’atteint donc pas non plus le navigateur d'un visiteur. Et elle ne change ni le délai de conservation ni l’enregistrement ni rien de ce que le visiteur rencontre sur le site d'un client. Ce qui est regroupé, en outre, ce sont des VISITES et non des personnes : un profil par personne supposerait l’identifiant client de setUserId, et 0 session sur 4226 en porte un. Il reste les art. 13(1)(c) et 30 — l’obligation d’information et cette entrée. Les deux sont satisfaits. La qualification elle-même reste une question de droit ; ce qui est établi est l’état mesuré des faits, pas son interprétation. (Évalué le 27.08.2026.)
8. Mesures techniques et organisationnelles (art. 32) — description générale
Cette section est la description générale exigée par l’art. 30(1)(g) et 30(2)(d). Chaque mesure ci-dessous a été vérifiée dans le code ou la configuration ; le fichier et la ligne sont donnés pour que le lecteur puisse vérifier plutôt que faire confiance. Les lacunes à la fin de cette section sont tout aussi vérifiées et sont énoncées en même temps, car une description des TOM qui ne liste que ce qui existe est une publicité.
| Domaine | Mesure en vigueur | Preuve |
|---|---|---|
| Chiffrement du transport | Les connexions provenant d’internet sont chiffrées par TLS : TLS se termine dans nginx (192.168.20.2:443), et toute requête HTTP est redirigée vers HTTPS. Le serveur WebSocket n’écoute que sur 127.0.0.1:8081 sans TLS propre et n’est accessible que par nginx (chemin /mp_wss/) ; de même, le tunnel HTTP /mp_wst, le téléversement de grands instantanés de pages /mp_dom et le point de mesure /mp_wsfail fonctionnent par HTTPS. Au sein de notre propre réseau local sur le même site, les connexions à la base de données et à Redis fonctionnent sans chiffrement (voir 8.1). | /etc/nginx/conf.d/mouseplayer.conf ; srv/server.php (MP_WSS_BIND, MP_WSS_TLS) ; www/.htaccess |
| Minimisation des données à la collecte — IP | L’adresse IP du visiteur est tronquée immédiatement après sa détermination et donc avant tout consommateur (dernier octet IPv4, dernier groupe IPv6). Le 10 août 2026, 236 anciennes lignes contenaient encore des adresses complètes ; au 16 octobre 2026, aucune ligne dans visitor_sessions ou ip_lifetime_stats ne contient d’adresse non tronquée. | class/Server.class.php (règle B) |
| Minimisation des données à la capture — saisies de formulaire | Masquage avec un niveau minimal strict : au niveau 0, chaque caractère est remplacé ; quel que soit le niveau, les mots de passe et les données de paiement sont toujours remplacés (catégories password et payment, types password/email/tel/hidden, motifs de classe et de nom card|cc|cvv|cvc|password|credit|social|pesel|nip). Les 7 projets utilisent tous smart_masking=0. | www/mp.js:4818-4853 |
| Minimisation des données à la capture — DOM | Dans data-mp-mask ou .mp-masked, chaque caractère autre qu’un espace blanc est remplacé par '*' et tous les attributs hors MASK_KEEP_ATTRS sont définis sur '[FILTERED]'. S’applique aussi aux mutations en cours. | www/mp.js:3934-3970 et 4732-4768 |
| Minimisation des données à la capture — noms de champs | Le nom ou l’id brut d’un champ de saisie n’est pas transmis ; seule la catégorie classifiée est envoyée, car dans de nombreuses boutiques, le nom brut est suffisamment descriptif pour identifier la personne. | www/mp.js:4653-4674 |
| Application du consentement | Liste d’exclusion de chemins évaluée AVANT le verrou du consentement, avec correspondance sur le chemin plutôt que sur l’URL complète (71 connexions bloquées). Application côté serveur comme deuxième filet : seuls GRANTED, GRANTED_LATE ou une exemption régionale explicite passent ; WITHDRAWN, pays inconnu et toute situation peu claire conduisent à close(1008) (24 connexions bloquées). Coupe-circuit site_settings.consent_gate_active=1. | class/Server.class.php:963-975 et 977-1004 |
| Minimisation de la preuve du consentement | La chaîne TC n’est pas stockée en clair ; seul son SHA-256 est conservé. | visitor_sessions.tcf_hash CHAR(64) ; ai/migrations/018_consent.sql |
| Sécurité de l’application | Jetons CSRF issus de random_bytes(32), comparés avec hash_equals(). Cookie de session avec httponly=true, samesite='Lax' et secure conditionné à HTTPS. Mots de passe stockés comme empreintes et vérifiés avec password_verify(). Requêtes préparées sur l’ensemble des parcours d’écriture audités. Limitation du débit des connexions. | cfg/lib.php:118-132 et 110-112 ; www/login.php:60 et 28 |
| Prévention des abus | Blocage automatique et limite de connexions dans le WebSocket (compteur Redis avec expiration de 10 s ; 15 connexions simultanées par IP ; blocage de 24 h dans Redis, tronqué dans le journal). Limitation du débit et plafonds de connexions par adresse dans nginx pour les pages et les négociations WebSocket. fail2ban avec le jail mp-nginx-429 : quiconque est rejeté plus de 100 fois en une minute est bloqué pour HTTP et HTTPS pendant une heure. | class/Server.class.php ; /etc/nginx/conf.d/mouseplayer.conf ; /etc/fail2ban/jail.d/mp-nginx-429.conf |
| Contrôle des accès | Modèle de rôles par espace de travail (owner / admin / viewer). La suppression dans le lecteur est limitée à owner et admin, et chaque suppression est en outre limitée au channelid — décrit dans le code comme la véritable frontière de sécurité. | workspace_users.role ; www/player.php:267 et 275-282 |
| Journalisation des modifications | log_audit() consigne utilisateur, espace de travail, action, cible, détails et IP. 666 entrées, dont create_share, revoke_share, delete_comment, player_delete_*, firewall_auto_ban (24) et superadmin_*. | cfg/lib.php:2878-2890 |
| Liens de partage | channelid et session_id proviennent exclusivement du jeton ; la chaîne de requête restante est REMPLACÉE plutôt qu’ignorée ; user_role reste NULL pour que la suppression et le repartage disparaissent côté serveur, pas seulement dans l’interface ; les trois points de terminaison sont limités à la session du jeton ; les jetons inventés, expirés et révoqués renvoient la même réponse. | www/share.php ; www/.htaccess:77 |
| Surface de l’API | La charge utile complète de relecture ne fait délibérément pas partie de l’API publique. | www/api/v1_session_detail.php:25 |
| Gestion des clés | La clé du compte de service Google est stockée chiffrée dans projects.bigquery_sa_json et déchiffrée par decrypt_sa_key() avec BIGQUERY_SA_AES_KEY issue de .env ; l’interface nomme AES-256. | srv/cron_integration_bigquery.php:57 ; cfg/lib.php:993 |
| Secrets hors du système de gestion des versions | Confirmé sur l’index actuel : .gitignore liste .env, et git ls-files ne trouve que .env.example. | git ls-files |
| Exposition réseau | Seuls les ports 80 et 443 via nginx sont accessibles depuis internet ; il n’existe aucune redirection de port pour la base de données ou Redis. Redis de l’instance de développement n’est lié qu’à 127.0.0.1 (port 6381) ; une instance Redis plus ancienne et partagée (port 6379) écoute en outre sur le réseau local. MariaDB écoute sur 127.0.0.1 et sur le réseau local. L’accès à la base de données et à Redis est restreint et n’est possible que depuis notre propre réseau local. Une restriction d’accès supplémentaire se trouve devant www.mouseplayer.com. | ss -ltn ; configuration Redis ; www/.htaccess |
8.1 Mesures dont l’absence est démontrée
- Aucun chiffrement au repos. innodb_encrypt_tables, innodb_encrypt_log et innodb_encrypt_temporary_tables sont tous sur OFF, et il n’existe aucun volume chiffré (lsblk montre sda1 sans crypt).
- Aucun TLS sur les connexions à la base de données. have_ssl=YES, mais ssl_cert, ssl_key et ssl_ca sont vides. MariaDB écoute sur 127.0.0.1 et sur le réseau local (192.168.20.2:3306) ; les connexions depuis le réseau local fonctionnent donc sans chiffrement. Leur accès est restreint et elles ne sont pas accessibles depuis internet (aucune redirection de port).
- Aucun chiffrement du transport pour Redis. Les connexions à Redis fonctionnent sans chiffrement par l’interface locale ou sur le réseau local ; l’accès aux deux instances est restreint. L’instance de développement écrit ses données sur disque pour la persistance (AOF), y compris les files d’attente avec IP tronquée, URL complète et charge utile DOM et, pendant la durée du blocage (24 h), l’adresse complète des expéditeurs bloqués.
- AUCUN JOURNAL INDIQUANT QUI A CONSULTÉ QUEL ENREGISTREMENT. audit_logs n’enregistre que les actions d’écriture ; un appel à player.php, ajax_get_events.php ou player_theatre.php n’est pas du tout journalisé. Il est donc impossible de répondre après coup à la question de savoir qui a regardé une session donnée.
- Les journaux d’accès Apache contiennent des adresses IP complètes, conservées pendant 14 jours.
- Les fichiers d’archive des événements d’enregistrement déplacés se trouvent sur le même disque que le système et la base de données. Une panne de ce disque touche les deux ; seule la copie chiffrée de la sauvegarde, qui contient l’archive depuis le 6 octobre 2026, fournit un stockage à un autre endroit.
- Toutes les limites contre la surcharge — nginx, fail2ban et le blocage du serveur WebSocket — comptent par adresse. Rien placé devant la machine n’aide contre une attaque distribuée depuis de nombreuses adresses : aucun CDN ni service de filtrage n’est placé en amont.
- Sécurité physique : l’accès est détenu uniquement par le responsable du traitement. La pièce est fermée à clé et sous vidéosurveillance ; aucune autre personne — y compris propriétaires des locaux ou services de nettoyage — n’y a accès (déclaration du responsable du traitement, 17 août 2026). L’adresse précise n’est délibérément pas indiquée ici.
- Surveillance et reprise : depuis le 19 août 2026, les mécanismes de surveillance dans
srv/cron_status.phpsignalent les défauts, le faible espace disque, les sauvegardes manquantes et les exécutions planifiées échouées dans les Urgent Logs (B.8) et par e-mail ; depuis le 23 septembre 2026, ces e-mails sortent effectivement par SMTP. Depuis le 2 octobre 2026, une machine distincte nous appartenant, dans le même réseau local, vérifie chaque minute la base de données, Redis, le serveur WebSocket, les processus permanents et la file d’attente via un point de terminaison de santé (www/health.php) et signale une panne ; elle ne peut pas voir une défaillance de la connexion internet elle-même. Objectif de délai de reprise : au plus 24 heures. Des tests de restauration depuis la copie hors site ont été effectués les 5/6 septembre 2026 et le 7 octobre 2026 (restauration complète des données) ; ils sont prévus mensuellement (déclaration du responsable du traitement, 17 août 2026). Le disque de sauvegarde USB se trouve dans la même pièce que le serveur — un seul événement à cet endroit touche donc les deux ; seule la copie chiffrée fournit un stockage hors site. Les deux fichiers de clés sont conservés imprimés dans un coffre-fort auquel seul le responsable du traitement a accès et survivent ainsi à la perte de la machine.
9. Délégué à la protection des données — évaluation au titre de l’art. 37 du RGPD
RÉSULTAT : aucune obligation de désigner un délégué à la protection des données n’est démontrée au regard des chiffres disponibles aujourd’hui — mais l’évaluation dépend d’une seule variable, cette variable ne va que dans un sens, et jusqu’au 19 août 2026, rien ne la surveillait. Elle est désormais mesurée quotidiennement (voir la conséquence 2). La réponse est « pas encore », pas « non ».
L’art. 37(1) exige une désignation dans trois cas. Le cas (a), une autorité ou un organisme public, ne s’applique pas. Le cas (c), des activités de base consistant en un traitement à grande échelle de catégories particulières au titre de l’art. 9 ou de données relatives aux condamnations pénales au titre de l’art. 10, n’est pas rempli : aucune donnée de catégorie particulière n’est traitée intentionnellement. Le sujet ne s’arrête pas là — comme noté dans A.2, l’instantané du DOM stocke tout ce que la page du client affiche ; des données de catégories particulières peuvent donc entrer fortuitement dans un enregistrement sur un site de santé ou de finance. Une capture fortuite n’est pas une activité de base consistant en un tel traitement ; le cas (c) n’est donc pas déclenché ; mais l’exposition est réelle et appartient à l’intégration initiale des clients plutôt que d’être écartée par la rédaction ici.
Le cas (b) est celui qui compte, et il comporte deux branches. La première — des activités de base consistant en un traitement qui exige un SUIVI RÉGULIER ET SYSTÉMATIQUE des personnes concernées — est remplie sans discussion. La relecture de sessions est une observation continue et automatisée du comportement individuel ; elle n’est pas accessoire à l’activité, elle EST l’activité. Tout lecteur de ce registre tenté de contester la première branche devrait s’arrêter : elle est remplie, et la contester gaspille la crédibilité nécessaire pour la seconde.
La seconde branche est la GRANDE ÉCHELLE, et c’est là que la réponse est actuellement négative. Les lignes directrices du groupe de travail Article 29 pondèrent quatre facteurs : le nombre de personnes concernées, le volume et l’éventail des données, la durée ou la permanence du traitement et l’étendue géographique. Mesuré le 10 août 2026 : 706 sessions de visiteurs, 329 enregistrements de visiteurs distincts, 7 projets, 4 comptes clients. Quant au nombre de personnes concernées, c’est très loin de la grande échelle — et il s’agit en outre de chiffres de l’instance de développement. Au 16 octobre 2026 : 3514 identifiants de visiteurs distincts classés comme humains au cours des 30 derniers jours sur tous les projets, toujours bien en dessous du seuil de la conséquence 2.
Deux des quatre facteurs pointent néanmoins dans l’autre sens, et le registre devrait le dire plutôt que de s’appuyer sur le facteur confortable. L’ÉVENTAIL des données par personne est exceptionnellement large : HTML complet des pages avec tout ce qu’elles affichent, saisies de formulaires au niveau de chaque frappe, comportement de déplacement et de clic, notation comportementale dérivée et récit de la session en prose. La DURÉE est longue : selon le niveau de forfait, les enregistrements restent jusqu’à 365 jours et dans la sauvegarde jusqu’à 364 jours au-delà, même si des délais de suppression existent et sont appliqués pour toutes les tables depuis août 2026 (section 6). Seul l’effectif maintient l’évaluation sous le seuil, et l’effectif est précisément la quantité que MousePlayer ne contrôle pas : il est déterminé par le trafic reçu par le site web de chaque client. Un seul client de commerce électronique de taille moyenne pourrait à lui seul faire franchir la limite au produit, sans qu’aucune décision ne soit prise ici.
- Conséquence 1 — consigner l’évaluation avec sa date. L’art. 5(2) fait de la responsabilité l’obligation ; une évaluation négative jamais consignée est impossible à distinguer d’une évaluation jamais effectuée.
- Conséquence 2 — définir le déclencheur qui la rouvre. Le déclencheur raisonnable est le nombre de visiteurs suivis par mois sur l’ensemble des clients, plus un réexamen à chaque nouveau client de taille significative. Seuil et fréquence : l’évaluation de l’art. 37 est répétée dès que plus de 100000 utilisateurs finaux par mois sont observés sur l’ensemble des Clients, et en tout état de cause chaque année. Responsable : Lukas Wójcik, propriétaire. (décision du responsable du traitement, 17 août 2026) Mis en œuvre le 19 août 2026 : le nombre d’utilisateurs finaux distincts observés au cours des 30 derniers jours est compté une fois par jour par le processus de surveillance et comparé à ce seuil, ainsi qu’à la date de la dernière évaluation consignée ; tout dépassement envoie un avertissement par e-mail. Le seuil et la date sont des paramètres, lus dans la même ligne que celle citée par cette phrase ; le document et la mesure ne peuvent donc pas diverger. Un déclencheur que personne ne mesure est une note, pas un contrôle – c’était la lacune décrite par ce paragraphe, qui ne la décrit plus.
- Conséquence 3 — vérifier le droit national. L’art. 37(4) permet au droit de l’Union ou des États membres d’exiger une désignation dans d’autres cas. à compléter : confirmation d’un conseil juridique polonais quant à savoir si le droit polonais exige un délégué à la protection des données dans d’autres cas au-delà de l’art. 37(1)
- Conséquence 4 — la désignation volontaire reste possible. Si un délégué à la protection des données est désigné volontairement, les art. 37 à 39 s’appliquent intégralement, y compris la publication et la notification des coordonnées. C’est une décision, pas un choix par défaut.
- Conséquence 5 — distincte mais voisine : une analyse d’impact relative à la protection des données au titre de l’art. 35 est très probablement requise de chaque CLIENT en tant que responsable du traitement, compte tenu de la surveillance systématique combinée à l’évaluation et à la notation. En tant que sous-traitant, MousePlayer doit apporter son assistance au titre de l’art. 28(3)(f). Il existe une analyse d’impact au niveau du produit — c’est celle publiée sous “Analyse d’impact relative à la protection des données”. Une copie distincte n’est pas remise aux Clients (décision du responsable du traitement, 17 août 2026). L’assistance au titre de l’art. 28(3)(f) est fournie sur demande et repose sur les documents publiquement disponibles : ce registre, l’analyse d’impact publiée, les mesures techniques et organisationnelles et la liste des sous-traitants ultérieurs.
10. Lacunes connues
Tout ce qui suit est démontré, pas soupçonné. Cette section existe parce qu’un registre des activités de traitement est un instrument de travail : le but est de pouvoir voir les points ouverts, pas de présenter une feuille sans défaut. Les éléments sont classés selon la mauvaise impression qu’ils feraient dans un audit, pas selon la difficulté à les corriger.
| Lacune | Ce qui est démontré | Pourquoi cela compte |
|---|---|---|
| Adresses IP complètes dans les journaux de notre propre application | Au 16 octobre 2026, les anciennes données dans visitor_sessions et ip_lifetime_stats sont tronquées (le 10 août 2026, respectivement 236 et 291 lignes non tronquées). mouseplayer_logs, audit_logs, user_ip_history, login_sessions, share_views et support_requests (partie B), ainsi que les journaux d’accès de nginx et d’Apache, restent délibérément non tronqués | Pour la partie B, l’adresse complète est justifiée (B.2 à B.7) et limitée par des délais. Elle est néanmoins listée ici parce que ces tables entrent dans chaque sauvegarde. |
| Anciennes données avec saisies de formulaires en clair | Le 10 août 2026, 173 lignes dans mouse_events avec event_type='input' contenaient des valeurs non masquées du 2026-07-21 au 2026-07-27, y compris des noms de personnes. Les lignes ont été supprimées le 17 août 2026, avant l’introduction des fichiers d’archive le 18 août 2026 ; au 16 octobre 2026, aucune d’elles ne se trouve dans mouse_events | Les lignes actuelles sont masquées, le contrôle fonctionne donc. Les anciennes valeurs ne peuvent pas se trouver dans l’archive ni dans la sauvegarde d’aujourd’hui ; aucune sauvegarde antérieure au 17 août 2026 n’est connue, mais son absence n’a pas été vérifiée en détail. |
| Les liens de partage contournent entièrement la connexion | /s/<40-hex-token> mène directement à player.php?share=<token> ; le jeton constitue toute la barrière | Le lien peut être transmis à n’importe qui ; la catégorie des destinataires pour A.1, A.2, A.3 et A.9 est donc en fait ouverte. Cela est limité par la durée de vie maximale (7 jours par défaut, au plus 90), la révocation à tout moment et le journal d’accès (B.6). |
| Aucun journal indiquant qui a consulté un enregistrement | audit_logs n’enregistre que les actions d’écriture ; les appels à player.php, ajax_get_events.php et player_theatre.php ne sont pas journalisés | Après un incident, il est impossible d’établir qui a regardé quelle session. C’est la mesure unique dont l’absence est la plus difficile à expliquer à une autorité de contrôle. |
| Le serveur entier est copié hors site chaque jour | srv/backup-crypt.sh sauvegarde chaque jour toutes les bases de données et toute l’arborescence web avec chaque .env, et, depuis le 6 octobre 2026, également l’archive des événements d’enregistrement ; la copie est chiffrée sur notre propre serveur avant le transfert (rclone crypt) et, depuis le 5 septembre 2026, stockée dans un bucket Google Cloud Storage à Varsovie, couvert par les conditions de traitement des données Google Cloud (section 4) | Ce qui quitte les locaux chaque jour n’est pas seulement une copie des enregistrements de sessions, mais le serveur complet, avec les secrets de production de plusieurs systèmes. Le chiffrement retire le contenu à Google, pas le périmètre. Si les deux fichiers de clés sont perdus, la sauvegarde est irrécupérable ; ils sont donc également conservés imprimés dans le coffre-fort (section 8.1). |
| L’arrivée de la sauvegarde est surveillée | Non prouvée jusqu’au 11 août 2026. Depuis lors, l’exécution écrit un journal et vérifie à destination ; depuis le 19 août 2026, un mécanisme de surveillance compare la dernière exécution réussie à une échéance et signale une exécution manquante dans les Urgent Logs et par e-mail | La lacune de cette ligne est clôturée. Elle reste listée pour qu’il soit possible de retracer que la sauvegarde s’exécutait sans preuve jusqu’au 11 août 2026. |
| Anciens scripts de sauvegarde | Les anciens scripts de sauvegarde ont été supprimés le 16 octobre 2026. Aucun des deux n’était encore exécuté ; depuis le 11 août 2026, la sauvegarde quotidienne passe par srv/backup-crypt.sh | La lacune de cette ligne est clôturée. Elle reste listée pour qu’il soit possible de retracer que, jusqu’au 11 août 2026, quiconque obtenait le compte SSH pi avait les droits root à 02:00. |
| Aucun chiffrement au repos, aucun TLS sur les connexions à la base de données et à Redis | innodb_encrypt_* tous sur OFF, aucun volume chiffré ; ssl_cert/ssl_key/ssl_ca vides, MariaDB également accessible sur le réseau local ; accès Redis restreint, mais sans chiffrement et avec persistance sur disque (AOF) | Les enregistrements — y compris la charge utile DOM dans la file Redis et les fichiers d’archive — sont lisibles par quiconque dispose d’un accès au système de fichiers ; sur le réseau local, les connexions à la base de données fonctionnent en clair. Aucun de ces parcours n’est accessible depuis internet. |
| Certains enregistrements du consentement sont des données de test | Le 10 août 2026, 671 sessions sur 706 portaient consent_source='testdata' avec consent_ts IS NULL, définis par ai/devdata/001_altsitzungen_markieren.sql ; au 16 octobre 2026, il existe encore 566 sessions de ce type | Pour ces sessions, le journal du consentement ne peut pas servir de preuve. C’est un artefact du système de développement, mais la même requête en production nécessiterait la même vérification. |
| Le retrait ne supprime rien | Au 16 octobre 2026, projects.consent_delete_on_withdraw n’est défini pour aucun projet (évalué dans la branche consent_withdrawn de srv/db_worker.php) | Le retrait arrête tout nouvel enregistrement — comme l’exige l’art. 7(3) —, mais un client qui suppose qu’il supprime aussi l’enregistrement antérieur se trompe. Cette distinction doit être indiquée dans la documentation destinée aux clients. |
| Tout ici est mesuré sur l’instance de développement | APP_ENV=dev ; le projet de test mpconsenttest01 et les fixtures s_mptest_ sont inclus dans les décomptes | La structure de ce registre se transpose à la production ; pas les nombres. La production doit être mesurée avant que l’on s’appuie sur ce registre à l’extérieur. |
| La recherche d’appels sortants n’était pas exhaustive | cfg/, srv/, class/ et www/ ont été examinés pour curl_init, curl_exec, file_get_contents avec http, fsockopen, stream_context_create et tous les littéraux https ; les répertoires des fournisseurs n’ont pas été examinés | Les arborescences des fournisseurs contiennent les points de terminaison de Stripe, Google Cloud, PHPMailer et Symfony. Ces services sont nommés dans la section 4, mais l’affirmation 'aucun autre appel sortant n’existe' est bornée par la recherche. |
| Aucun interrupteur par projet pour les profils de comportement | profile_aktiv est un paramètre global de l’exploitant. mp_ki_module_katalog() dans cfg/lib.php liste neuf sections d’IA sélectionnables, et aucune ne correspond aux profils ; projects.ki_module ne couvre donc pas cet onglet ; l’entrée de navigation dans www/project.php est inconditionnelle. Mesuré le 27.08.2026. | Un client qui ne veut pas qu'on regroupe les visites de ses visiteurs ne peut pas le désactiver. Il contrôle l’enregistrement ; pas la déduction qui en est faite. Toute autre section dérivée peut être désélectionnée par projet — celle-ci est l’exception. La lacune de conservation qui figurait ici jusqu’au 27.08.2026 est clôturée : mp_profile et mp_sequenzmuster ont désormais leurs propres délais, voir 6.2. |
| Une demande d’effacement n’atteint les sessions GA4 importées que si la passerelle d’analyse est activée | Depuis le 01.09.2026, mp_sitzungen_loeschen() emporte ga4_sessions et ga4_events lors d’une demande au titre de l’art. 17, liés par ga4_sessions.user_pseudo_id = visitor_sessions.custom_user_id et limités au canal. Ce lien n’existe que lorsque le client a activé la passerelle d’analyse GA4 — c’est elle qui y écrit l’identifiant client du cookie _ga. S’il remplit à la place custom_user_id par setUserId() avec son propre identifiant, il n’existe aucun parcours d’un visiteur vers sa ligne importée. Le cas figure comme test propre (test_ga4_import.php, section J) pour qu’il ne soit pas oublié. | Pour ces clients, la ligne importée reste après une demande d’effacement jusqu’à son retrait par le délai de A.14. Elle est pseudonyme et non attribuable par nous — ce qui est précisément la raison pour laquelle elle ne peut pas être supprimée de manière ciblée. Un parcours de suppression via la propriété GA4 elle-même relève du responsable du traitement qui l’exploite. |
| Le consentement pour les lignes importées ne peut être prouvé, seulement déduit | Ce qui est importé est ce qui porte un user_pseudo_id ; les hits sans cookies sous consentement refusé n’en portent aucun et sont éliminés (A.14). Pour ces lignes, il n’existe aucun relevé comparable à consent_events — GA4 ne fournit dans l’export aucun attribut de consentement qui pourrait être stocké ici. | Pour ses propres enregistrements, MousePlayer peut montrer pour chaque session sur quoi ils reposent ; pour une session importée, il ne le peut pas. La barrière est mécanique et fonctionne, mais elle prouve uniquement qu’un cookie a été déposé — pas ce à quoi le visiteur a consenti. Cela relève du responsable du traitement, qui gouverne la collecte chez Google. |
| Le nom personnalisé du visiteur est un texte libre non contrôlé | A.13, depuis le 28.08.2026. mp_besucher_label_setzen() tronque à 64 caractères, supprime les sauts de ligne et vérifie que le visiteur appartient au projet — rien ne vérifie le CONTENU, et aucune spécification ne précise le type qu’il devrait avoir. | Le responsable du traitement peut y écrire des catégories particulières au titre de l’art. 9 („M. X, fauteuil roulant“) sans barrière ni avertissement. La conformité relève de sa responsabilité, pas de celle du sous-traitant — mais un sous-traitant qui propose un champ de texte libre et n’en dit rien a créé cette possibilité. Une vérification technique n’est pas possible : une machine ne peut pas distinguer un nom d’une donnée de santé. Ce qui serait possible est une note auprès du champ. |
| Exemples de suivi des robots sans délai de suppression | Un vecteur de caractéristiques pseudonyme par session ayant fait l’objet d’une décision (bot_review_labels, A.19) reste après la session aussi longtemps qu’aucun délai n’est défini. La valeur par défaut de retention_bot_labels_years est 0 (illimité) ; l’exploitant peut la fixer en années. | Ce n’est pas du contenu de visiteur, mais ces exemples portent l’identifiant de session. Fixer ou non un délai est une décision de l’exploitant. |
| Le texte libre d’un sondage n’est filtré que grossièrement | A.21, depuis le 27.09.2026. mp_umfrage_text_filtern() remplace les adresses e-mail, adresses IP et numéros de téléphone dans le navigateur, puis à nouveau dans le worker. Il ne reconnaît ni les noms, ni les adresses postales, ni les numéros de client, ni les informations de santé. | Un visiteur peut écrire n’importe quoi dans la question complémentaire, y compris des catégories particulières au titre de l’art. 9. La note sous le champ lui demande de ne pas le faire ; ce n’est pas un verrou. Comme pour le propre nom de visiteur attribué par le responsable du traitement (A.13), il n’est pas possible de classifier le contenu de manière fiable par machine. |
11. Maintenance de ce registre
Les art. 30(1) et 30(2) exigent que le registre soit tenu par écrit et mis à la disposition de l’autorité de contrôle sur demande. Cela rend nécessaires deux choses qui ne se trouvent pas dans le document lui-même : une personne qui en est responsable et un intervalle auquel il est vérifié au regard du système plutôt qu’au regard de sa propre version précédente.
- Responsable et intervalle de réexamen : responsable : Lukas Wójcik, propriétaire. Réexaminé chaque année et à chaque modification du traitement. Les versions datées sont conservées dans le système de gestion des versions sous
ai/cms/. (décision du responsable du traitement, 17 août 2026) - Événements imposant une mise à jour indépendamment de l’intervalle : un nouveau sous-traitant ultérieur ou un changement de destination ; une nouvelle table contenant des données à caractère personnel ; une modification de la chaîne de suppression
mp_sitzungen_loeschen()ou de la purge quotidienne dans srv/db_worker.php ; activation de l’export BigQuery ou de webhooks pour un client quelconque ; modification du comportement de masquage par défaut ; premier client dont le site affiche des données de catégories particulières. - Méthode : chaque chiffre de ce registre provient d’une mesure au regard du code, du schéma ou de la base de données à une date indiquée. Un réexamen qui ne fait que relire le texte n’a rien réexaminé — les nombres doivent être mesurés à nouveau, et les espaces réservés doivent soit être remplis, soit être expressément maintenus avec une raison.
- Ce registre ne remplace ni la liste des sous-traitants ultérieurs, ni le document sur les mesures techniques et organisationnelles, ni l’accord de traitement des données, ni la notice de confidentialité. Lorsque ces documents et ce registre se contredisent, l’écart est un constat, pas une question de mise en forme.