Registro de actividades de tratamiento (art. 30 del RGPD)
MousePlayer — LW IT Solutions Company Lukas Wójcik. Documento interno de responsabilidad proactiva, versión 2, 16/10/2026 (versión 1 como borrador del 10/08/2026). Cada nueva afirmación de esta versión se ha contrastado con el código, el esquema y la base de datos; las cifras llevan una fecha de medición.
1. Cómo leer este registro
Este es un documento interno de responsabilidad proactiva conforme al art. 30 del RGPD. No es un aviso de privacidad ni está redactado para informar a los interesados, aunque se publique, y tampoco para dar buena imagen. Su única función es permitir que una autoridad de control —o la siguiente persona que tenga que responder a una pregunta— vea qué se trata realmente, dónde está y cuánto tiempo permanece.
Tres reglas rigieron la redacción. Primera: solo se formula una afirmación cuando la respaldan el código, el esquema o una medición. Si falta una entrada, un marcador señala la carencia en lugar de una frase que suene verosímil. Una carencia reconocida resiste una auditoría; una suposición bien redactada, no. Segunda: cuando el código documenta su propio razonamiento, se cita con archivo y línea para que un lector posterior pueda verificarlo en lugar de confiar en este documento. Tercera: la conservación se indica dos veces: una para las tablas que abarca la purga diaria y otra para las que no. Un registro que afirma un plazo de eliminación que se cumple para la mitad de las tablas es peor que uno que señala la carencia, porque eso es precisamente lo que se comprueba.
BASE DE MEDICIÓN. Todas las mediciones se refieren a la instancia de DESARROLLO (www.mouseplayer.com, APP_ENV=dev); no describen producción. Los recuentos de filas, tamaños de tablas y valores de configuración sin fecha propia proceden de la sesión de medición del 10/08/2026 y describen ese estado; las cifras más recientes llevan su fecha ("a 16/10/2026"). Las referencias a archivos y líneas sin fecha también reflejan el estado del 10/08/2026: los números de línea cambian con cada modificación del código; son los archivos y las funciones mencionados los que hacen fe. Cifras de producción: pendiente de completar: las mismas cifras medidas en la instancia de producción, con la fecha de medición
OMITIDO DELIBERADAMENTE. El análisis subyacente recogió cuatro direcciones IP públicas completas como prueba de que los datos heredados no están enmascarados. No se reproducen aquí. Un registro de actividades de tratamiento circula internamente y entre auditores; no debe convertirse él mismo en una segunda copia de los datos que describe. Se indica el hallazgo, no los valores.
2. La entidad y por qué este registro tiene dos partes
| Campo | Entrada |
|---|---|
| Entidad jurídica | LW IT Solutions Company Lukas Wójcik |
| Dirección | al. Tadeusza Kościuszki 80/82 lok. 301, 90-437 Lodz, Poland |
| Identificación fiscal | NIP: PL7252266190 |
| Contacto | office@mouseplayer.com (sin número de teléfono publicado) |
| Producto | MousePlayer — grabación de sesiones, mapas de calor, análisis del comportamiento |
| Representante conforme al art. 27 | No es aplicable. La entidad está establecida en la Unión (Polonia). |
| Delegado de protección de datos | No se ha designado ninguno. Véase el apartado 9 para la evaluación conforme al art. 37. |
MousePlayer ocupa dos posiciones distintas frente a dos grupos de personas distintos, y mezclarlas produce un registro que no sirve para ninguno. Respecto de los datos de los VISITANTES de los sitios web de clientes, MousePlayer es el encargado del tratamiento y el cliente es el responsable: se aplica el art. 30(2). Respecto de los datos de los propios CLIENTES de MousePlayer (cuentas, facturación, soporte, registros de acceso al portal), MousePlayer es el responsable del tratamiento: se aplica el art. 30(1).
No es una comodidad de redacción. La distinción ya está implementada en el código y tiene una consecuencia técnica diferente para cada parte: class/Server.class.php:416 declara "REGEL B ... Hier sind wir AUFTRAGSVERARBEITER", y las líneas 421-425 separan "Regel A (volle Adresse) fuer DIREKTE Zugriffe auf die eigene Anwendung" de la regla B (truncada) para los datos de visitantes. La dirección IP de un visitante se trunca en class/Server.class.php:432-435; la dirección IP de un usuario cliente se almacena completa. Por tanto, el sistema ya se comporta como si existiera este registro.
- Parte A (apartado 3) — Art. 30(2): veintidós actividades de tratamiento (A.1 a A.22) realizadas por cuenta de responsables del tratamiento.
- Parte B (apartado 5) — Art. 30(1): ocho actividades de tratamiento (B.1 a B.8) realizadas bajo la propia responsabilidad de MousePlayer.
- Los apartados 6 a 8 son comunes a ambas partes: conservación, toma de decisiones automatizada y descripción general de las medidas técnicas y organizativas.
- El apartado 10 enumera las carencias cuya existencia está demostrada. Un registro es un instrumento de trabajo, no un certificado.
3. Parte A — Art. 30(2): actividades realizadas por cuenta de responsables del tratamiento
A.0 Partes
| Campo | Entrada |
|---|---|
| Encargado del tratamiento | LW IT Solutions Company Lukas Wójcik, al. Tadeusza Kościuszki 80/82 lok. 301, 90-437 Lodz, Poland. office@mouseplayer.com |
| Responsables del tratamiento | Los clientes que operan los sitios web en los que está instalada la etiqueta de MousePlayer (www/mp.js). Cada responsable se identifica en el sistema mediante projects.channelid; los datos de contacto se conservan en users y workspaces, y la pertenencia y el rol, en workspace_users. Medido en la instancia de desarrollo: 7 proyectos, 4 cuentas de clientes, roles de 4 propietarios / 1 administrador / 1 lector. |
| Lista de responsables del tratamiento que hace fe | Se mantiene en el sistema, sin duplicarla aquí. La lista se genera, no se transcribe: en el área de administración, bajo “Registro de actividades de tratamiento (art. 30)”, un botón la produce como CSV a petición: por cada espacio de trabajo, el propietario con nombre, correo electrónico, empresa, dirección, NIF-IVA, plan y dominios correspondientes. Responsable de producirla: Lukas Wójcik, propietario; se obtiene en cada revisión de este registro, es decir, anualmente y con cada cambio del tratamiento. Cada obtención aparece en el registro de cambios (export_controllers). Una lista transcrita aquí sería un segundo lugar para la misma información y quedaría obsoleta con cada nuevo cliente sin que nadie lo advirtiera. (decisión del responsable del tratamiento, 17/08/2026) |
| Representante del encargado del tratamiento | No es aplicable (establecido en Polonia). |
| Delegado de protección de datos | No se ha designado ninguno: véase el apartado 9. |
| Medidas técnicas y organizativas | El apartado 8 se aplica a todas las actividades de la Parte A y no se repite en cada una. |
A.1 Grabación de sesiones — captura de eventos de comportamiento
| Campo | Entrada |
|---|---|
| Origen de los eventos | Dos vías. (1) El navegador del visitante mediante www/mp.js, donde la máquina de estados mpEinw impone técnicamente el consentimiento. mp.js transmite mediante HTTPS a nginx, donde termina TLS: normalmente mediante el WebSocket en /mp_wss/; si el WebSocket no llega a conectarse, desde el 11/10/2026 mediante un túnel HTTP en /mp_wst, al que se aplican las mismas comprobaciones del servidor WebSocket (consentimiento, detección de bots, origen, cuota); las capturas grandes de páginas, desde el 07/10/2026, como subida HTTP en /mp_dom con acceso firmado y de duración limitada (se mantiene en Redis durante un máximo de 120 segundos y después se procesa como una captura ordinaria). El punto de medición /mp_wsfail solo cuenta las conexiones WebSocket fallidas por proyecto, motivo, familia de navegador y tipo de dispositivo, sin ID de visitante; allí la dirección IP solo se convierte en hash y se conserva durante un máximo de una hora para eliminar duplicados. (2) Del lado del servidor mediante www/api/capi_ingest.php, desde un sistema operado por el cliente; esta vía exige una firma (HMAC-SHA256 sobre la marca de tiempo y el cuerpo, con una ventana de cinco minutos) y una declaración explícita de que existe consentimiento en cada transmisión; sin ella se rechaza la solicitud con 403. MousePlayer no puede verificar técnicamente el consentimiento en esa vía; el cliente, como responsable del tratamiento, lo garantiza (DPA, apartado 2). La vía puede activarse o desactivarse mediante site_settings.capi_ingest_aktiv; estuvo desactivada hasta el 18/08/2026 y está activada desde entonces. Además, existe una versión preliminar de un SDK de aplicación nativa (Android) con su propia vía de recepción (www/api/native_ingest.php, tablas mp_native_apps y mp_native_sessions); solo existe en la instancia de desarrollo y está desactivada (native_preview_enabled = 0; a 16/10/2026, ninguna sesión almacenada). |
| Finalidad | Grabar el comportamiento de los visitantes de sitios web de clientes —movimientos del ratón, clics, scroll, toques, cambios de pestaña— para que el cliente pueda reproducir y analizar la sesión. |
| Categorías de interesados | Visitantes de los sitios web de los clientes de MousePlayer. |
| Categorías de datos personales | Coordenadas de movimiento, desfase temporal, posición de scroll, altura del documento; tipo de evento; dimensiones del área visible y de la pantalla; identificadores de sesión y de vista de página. Distribución de eventos medida: 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. En visitor_sessions además: referrer, parámetros UTM, ID de clic de una red publicitaria con su tipo, ruta de entrada, canal de tráfico, indicador de navegador integrado en una aplicación, identificador del navegador (agente de usuario), indicador de bot con motivo, calidad de la sesión y, desde el 26/09/2026, una puntuación de fricción con motivos (friction_score, friction_gruende). La distribución de eventos anterior se midió el 10/08/2026. |
| Dónde se almacena | mouse_events (event_id, pageview_id, event_type, time_offset_ms, x, y, scroll_y, scroll_x, doc_height, target_selector) — 225892 filas, 322,6 MB, la tabla más grande del esquema. 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 filas: una copia reducida de los eventos CLICK y de contexto, que sirve de fuente a la capa de clics del mapa de calor. Se menciona por separado porque su conservación difiere de la de mouse_events —estos pasan al archivo tras 7 días, la copia permanece y, por tanto, mantiene el mapa de clics a lo largo de todo el historial. Cada noche se construye a partir de ella un agregado diario, mp_hm_klick_tag con mp_hm_ansicht_tag (desde el 07/10/2026): por día, dirección, tipo de dispositivo, clase de pantalla, objetivo y celda de 8 px, solo un recuento, sin sesión, ID de visitante ni vista de página. El mapa de clics lo utiliza para los días cuyas sesiones ya no existen. La eliminación de sesiones o personas individuales no lo modifica, porque ninguna fila puede atribuirse a una persona. Desde octubre de 2026, además, mp_aufnahme_quittung: por mensaje entrante, un identificador y un estado; para un mensaje que no puede procesarse, también su contenido sin procesar y el motivo. Las filas se eliminan tras 7 días (srv/db_worker.php). Recuentos de filas de esta entrada sin fecha: a 10/08/2026. |
| Base jurídica (determinada por el responsable del tratamiento) | Consentimiento. Razonado en ai/migrations/018_consent.sql: la grabación es observación del comportamiento (considerando 24 del RGPD) y acceso al equipo terminal (apdo. 25 TDDDG); exige consentimiento y el interés legítimo no la ampara. Los 7 proyectos están configurados con projects.consent_mode='required'. Aplicación del lado del servidor en class/Server.class.php:977-1004; interruptor de desactivación site_settings.consent_gate_active=1. |
| Categorías de destinatarios | (a) El cliente correspondiente: miembros del espacio de trabajo con rol de propietario, administrador o lector. (b) Cualquier persona que tenga un enlace para compartir, SIN iniciar sesión: /s/<40-hex-token> se dirige a player.php?share=..., tabla session_shares. (c) Opcionalmente, el cliente mediante REST API v1 con su propia clave de API, solo con un plan de pago; a 16/10/2026 no existe ninguna clave de API. (d) Opcionalmente, los agentes de IA del cliente mediante el servidor MCP (/mcp): acceso de lectura con una clave de lectura de la API REST, que debe habilitarse por separado para cada proyecto (projects.mcp_active, desactivado por defecto); están disponibles proyectos, cifras clave, listas de sesiones con enlace a la reproducción, sesiones individuales con vistas de página y eventos, páginas, señales de frustración y objetivos, pero no la captura de página. A 16/10/2026 no está habilitado para ningún proyecto. (e) El cliente como archivo: exportación CSV de la lista de sesiones y de las respuestas a encuestas desde su interfaz, con límite (csv_export_max_zeilen); cada exportación se registra en el registro de cambios (csv_export). |
| Transferencia a terceros países | Ninguna en la vía de grabación. No se encontró ninguna llamada de salida; la geolocalización se resuelve con archivos locales de MaxMind. Véase el apartado 4. |
| Conservación | Depende del plan; la aplica la purga diaria en srv/db_worker.php (apartado 6.1) mediante la cadena de eliminación mp_sitzungen_loeschen(): Gratis 7 días, Small 30, Business 90, Enterprise según el plan acordado (por defecto, 365). Las sesiones reconocidas como automatizadas (bot) tienen plazos propios más cortos: su grabación (captura de página y eventos) se vacía una vez transcurrido retention_bot_recording_days (plazo en días: 1), y la fila de sesión con todo lo asociado se elimina una vez transcurrido retention_bot_session_days (plazo en días: 14); ambos son configurables en el área de administración, y 0 desactiva el plazo separado, por lo que se aplica el plazo del plan. Tras 7 días, los eventos pasan de mouse_events a archivos comprimidos por sesión (srv/cron_archiv.php); comparten el plazo de su sesión, se eliminan con ella y, desde el 06/10/2026, forman parte de la copia diaria de seguridad (apartado 4). Si un cliente elimina un proyecto, un espacio de trabajo o su cuenta, o se solicita una eliminación por dirección IP o visitante, desde el 07/10/2026 los datos se archivan primero —ocultos, sin nuevas grabaciones y restaurables— y se eliminan definitivamente tras un máximo de 30 días (apartado 6.2, mp_loesch_archiv). |
A.2 Captura del contenido de páginas — captura del DOM y cambios del DOM
| Campo | Entrada |
|---|---|
| Finalidad | Grabar el contenido de la página para que la sesión pueda reproducirse tal como la vio el visitante. |
| Categorías de interesados | Visitantes de sitios web de clientes e, indirectamente, toda persona cuyos datos muestre la propia página del cliente; por ejemplo, una confirmación de pedido con una dirección postal. |
| Categorías de datos personales | El HTML completo de la página visitada, incluidos texto, URL de imágenes y metadatos, tal como lo muestra el navegador, sin scripts y con el enmascaramiento descrito en A.3. Además, fragmentos HTML serializados de cada cambio posterior del DOM, almacenados en el campo target_selector de los eventos mutation. Desde el 30/09/2026, además: el contenido de raíces shadow abiertas de componentes web junto con sus hojas de estilo (las raíces shadow cerradas no se graban); elementos canvas como imagen fija en la captura y, cuando cambian, de forma continua como imagen (como máximo una vez por intervalo de un segundo, con límite por vista de página; no en zonas enmascaradas ni para elementos canvas que contengan imágenes de otro origen); iframes del mismo origen con su contenido y, desde el 02/10/2026, la interacción dentro de ellos (puntero, clics, entradas, scroll); iframes de otro origen solo como marcador sin contenido. |
| Dónde se almacena | session_pageviews.payload_blob (longtext), almacenado comprimido desde el 14/08/2026 (prefijo MPZ1:, gzip, Base64); a 16/10/2026, todas las filas con contenido utilizan este formato. session_pageviews.has_recording es una columna ordinaria, no generada: el trabajador la establece al escribir la captura y la restablece al vaciarla; lo mismo ocurre con hat_interaktion, hat_scroll y scroll_max_y. mouse_events.target_selector donde event_type='mutation', incluido el contenido de raíces shadow, canvas e iframes; tras 7 días, en los archivos (A.1). session_pageviews.html_path existe, pero a 16/10/2026 no está establecido en ninguna fila. |
| Base jurídica (determinada por el responsable del tratamiento) | Consentimiento, como en A.1. |
| Categorías de destinatarios | El cliente, mediante www/player.php, www/ajax_get_events.php y www/player_theatre.php. Cualquier persona que tenga un enlace para compartir. NO mediante la API REST: www/api/v1_session_detail.php:25 documenta la exclusión deliberada de la carga útil de la reproducción. |
| Transferencia a terceros países | Ninguna en la vía de grabación. |
| Conservación | Como A.1: con la sesión mediante la purga diaria y mp_sitzungen_loeschen(); para sesiones reconocidas como bots, la captura se vacía tras el plazo de A.1 (retention_bot_recording_days, plazo en días: 1). Véase el apartado 6. |
| Nota sobre el alcance del enmascaramiento | El enmascaramiento solo se aplica DENTRO de regiones marcadas con data-mp-mask o .mp-masked (www/mp.js:3934-3970). Todo el resto del HTML de la página se almacena sin cambios. Por tanto, todo lo que muestra la propia página del cliente está dentro de la grabación y ninguna configuración de enmascaramiento lo alcanza. |
A.2 es la actividad con la variedad de datos más amplia y menos predecible de todo el producto. El enmascaramiento controla lo que escribe el VISITANTE; no controla lo que muestra la PÁGINA del cliente. Si el sitio de un cliente muestra en pantalla información de salud, financiera o de otras categorías especiales, ese contenido entra en la captura. Tratamiento de esta cuestión: permitido, pero no recomendado. La responsabilidad corresponde al Cliente como responsable del tratamiento; MousePlayer proporciona la grabación y no juzga lo que muestra la página. Se desaconsejan expresamente las zonas con sesión iniciada en las que aparezcan en pantalla datos de salud, bancarios o similares: ningún enmascaramiento de campos ayuda allí, porque actúa sobre campos de entrada y no sobre lo que muestra la página. (decisión del responsable del tratamiento, 17/08/2026) Debe incorporarse como regla de incorporación de clientes y como nota en la guía de instalación.
A.3 Captura de entradas de formularios
| Campo | Entrada |
|---|---|
| Finalidad | Grabar las entradas de formularios, carácter por carácter, para poder reproducir la interacción con un formulario. |
| Categorías de interesados | Visitantes de los sitios web de los clientes. |
| Categorías de datos personales | Valores de entrada de elementos input, textarea y select: totalmente enmascarados, parcialmente enmascarados o en claro, según el nivel de enmascaramiento. El estado de casillas de verificación y botones de opción (true/false), que NUNCA se enmascara (www/mp.js:4810-4811). La categoría del campo derivada mediante classifyFieldName() (www/mp.js:4657-4674): email, password, phone, payment, address, name, search, coupon, quantity, other. |
| Dónde se almacena | mouse_events.target_selector donde event_type='input', formato {"t":"<data-mp-id>","v":"<value>"} — 599 filas. |
| Base jurídica (determinada por el responsable del tratamiento) | Consentimiento, como en A.1. |
| Categorías de destinatarios | El cliente (reproductor); cualquier persona que tenga un enlace para compartir. |
| Transferencia a terceros países | Ninguna en la vía de grabación. |
| Conservación | Sin plazo propio; como A.1, con la sesión (plazo del plan; para bots, los plazos de A.1), tras 7 días en los archivos. |
| Garantías vigentes | Protección mínima incondicional de contraseñas y datos de pago, con independencia del nivel (www/mp.js:4831-4837). Enmascaramiento completo en el nivel 0 (www/mp.js:4818-4819). Los 7 proyectos están configurados con projects.smart_masking=0, que es la configuración MÁS ESTRICTA pese a su descripción. |
| Hallazgo en datos heredados | El 10/08/2026, 173 filas de mouse_events contenían entradas en claro SIN ENMASCARAR del 21/07/2026 al 27/07/2026, incluidos nombres de personas; las filas de ese día en adelante están enmascaradas. A 16/10/2026 no queda ninguna entrada sin enmascarar en mouse_events (medido con la misma consulta). Las filas afectadas se eliminaron el 17/08/2026 (evaluación de impacto, R2), es decir, antes de introducir los archivos el 18/08/2026; por tanto, no pueden estar en los archivos ni en la copia de seguridad que los incluye desde el 06/10/2026. Las copias cifradas de aquel momento en Google Drive se eliminaron el 06/09/2026; no se conoce ninguna copia de seguridad restante anterior al 17/08/2026, pero no se ha verificado en detalle su ausencia. |
A.4 Reconocimiento del visitante entre sesiones
| Campo | Entrada |
|---|---|
| Finalidad | Reconocer a un visitante entre sesiones y vistas de página. |
| Categorías de interesados | Visitantes de los sitios web de los clientes. |
| Categorías de datos personales | Identificador seudónimo del visitante, generado y conservado en el localStorage del visitante como 'mp_visitor_id' (www/mp.js:5056-5059). Un identificador en claro establecido por el cliente —ID de inicio de sesión o número de cliente— mediante MousePlayer.setUserId() (www/mp.js:4909-4913, localStorage 'mp_user_id') y automáticamente desde la ruta 'uid' de dataLayer (www/mp.js:3585-3637). Apodo y nombre del navegador por visitante, conservados ENTRE proyectos (UNIQUE sobre visitor_id). |
| Dónde se almacena | visitor_sessions.visitor_id (varchar 64), custom_user_id (varchar 128, índice propio idx_custom_user_id), nickname_key. visitor_nicknames (visitor_id, nickname_key, browser_name, city, created_at) — 329 filas; la columna city está vacía en las 329. consent_events.visitor_id. |
| Base jurídica (determinada por el responsable del tratamiento) | Consentimiento, como en A.1. |
| Categorías de destinatarios | El cliente. Mediante custom_user_id, la combinación con los registros de los propios clientes del cliente es un uso expresamente previsto. |
| Transferencia a terceros países | Ninguna en la vía de grabación. |
| Conservación | Con la última sesión del visitante. mp_sitzungen_loeschen() (srv/db_worker.php) comprueba después de cada eliminación si queda alguna sesión de ese visitante y, si no, retira el apodo; la vía de eliminación del reproductor hace lo mismo. La purga diaria del plan llama a la misma función, por lo que ya no pueden generarse registros huérfanos. No existe un plazo separado ni es necesario: la entrada nunca sobrevive a las sesiones que identifica. |
A.5 Datos de red y ubicación aproximada
| Campo | Entrada |
|---|---|
| Finalidad | Determinar la red y la ubicación aproximada del visitante y determinar la región para comprobar el consentimiento. |
| Categorías de interesados | Visitantes de los sitios web de los clientes. |
| Categorías de datos personales | Dirección IP (truncada en la vía de grabación, véase más abajo), código de país de dos caracteres, ciudad (determinada a partir de la dirección truncada, no de la completa), número de ASN y nombre del proveedor, código de región. |
| Dónde se almacena | 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 filas. |
| Base jurídica (determinada por el responsable del tratamiento) | Consentimiento para la grabación. El país se determina deliberadamente del lado del servidor para no contactar con terceros antes de que exista consentimiento (class/Server.class.php:941-944). |
| Categorías de destinatarios | Ningún destinatario externo. La geolocalización se resuelve con archivos LOCALES de MaxMind bajo cfg/maxmind/ (GeoLite2-City y GeoLite2-ASN; leídos en class/IP2CityLite.class.php y class/Server.class.php), que srv/geoip_update.sh descarga periódicamente de MaxMind; no se transmite ningún dato de visitantes en el proceso. Los valores resueltos se almacenan en visitor_sessions y son visibles para el cliente como el resto del registro de la sesión. |
| Transferencia a terceros países | Ninguna. Ninguna llamada de salida en la vía de grabación. |
| Truncamiento | El servidor WebSocket (class/Server.class.php, regla B) sustituye el último octeto IPv4 por 'xxx' y el último grupo IPv6 por ':xxxx' inmediatamente después de determinar la dirección de la conexión (detrás de nginx, a partir de X-Forwarded-For, que solo se considera de confianza si procede del par local) y, por tanto, antes de que la utilice ningún componente. La dirección completa solo existe transitoriamente en la memoria del servidor WebSocket, en contadores de Redis que caducan tras unos segundos y —para direcciones que desencadenan un bloqueo automático— durante la duración del bloqueo (24 h) en Redis (mp_autoban:); la instancia de Redis escribe sus datos en disco para persistencia (AOF). A 16/10/2026, ninguna fila de visitor_sessions o ip_lifetime_stats contiene una dirección sin truncar. |
| Conservación y hallazgo en datos heredados | 365 días desde first_seen para ip_lifetime_stats, aplicado por la ejecución diaria en srv/db_worker.php; el valor está en site_settings bajo retention_ip_stats_days y es configurable en el área de administración. visitor_sessions está sujeto a la purga del plan. El hallazgo en datos heredados está cerrado: medido el 17/08/2026, 267 de 267 direcciones de ip_lifetime_stats se truncaron, y 881 de 901 de visitor_sessions. Las 20 restantes contienen 0.0.0.0 y proceden de los datos de prueba del análisis de formularios (s_mptest_form_): no son direcciones de visitantes. |
A.6 Registros de consentimiento
| Campo | Entrada |
|---|---|
| Finalidad | Demostrar el consentimiento y todos sus cambios (art. 7(1) del RGPD). |
| Categorías de interesados | Visitantes de los sitios web de los clientes. |
| Categorías de datos personales | Estado (GRANTED, GRANTED_LATE, withdrawn, region_exempt), origen, marca de tiempo; nombre y versión de la CMP; SHA-256 de la cadena TC, deliberadamente no la propia cadena; señal GPC; código de región; versión de la configuración del proyecto. |
| Dónde se almacena | 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 filas. 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 jurídica | Obligación de demostración, razonada en ai/migrations/018_consent.sql: corresponde al responsable del tratamiento probar un consentimiento válido y, sin registro, no hay nada que mostrar en una controversia. |
| Categorías de destinatarios | El cliente. |
| Transferencia a terceros países | Ninguna. |
| Conservación | 730 días, contados desde the withdrawal. Tanto el plazo como el punto de partida están en site_settings (consent_evidence_days, consent_evidence_anchor) y son configurables en el área de administración; los aplica la ejecución diaria en srv/db_worker.php. Al eliminar la sesión, las pruebas tampoco se eliminan, sino que se despersonalizan: debe poder seguir demostrándose que se tomó una decisión (art. 5(2)), pero no quién la tomó. Solo se eliminan registros a los que ya no se refiere ninguna sesión: mientras exista la grabación, debe existir su prueba, o la grabación quedaría sin autorización. |
| Calidad de los datos | 671 de 706 sesiones llevan consent_source='testdata' con consent_ts IS NULL, establecido por ai/devdata/001_altsitzungen_markieren.sql. NO son pruebas auténticas de consentimiento. Registros auténticos: 27 (api), 5 (gcm), 2 GRANTED_LATE (api), 1 withdrawn (gcm). |
| Eliminación al retirar el consentimiento | Opcional y desactivada en todas partes: projects.consent_delete_on_withdraw=0 para los 7 proyectos, evaluado en srv/db_worker.php:1067-1070. Por tanto, una retirada detiene nuevas grabaciones, pero no elimina nada. |
A.7 Eventos personalizados, señales de frustración y errores de JavaScript
| Campo | Entrada |
|---|---|
| Finalidad | Grabar eventos definidos por el cliente, señales de frustración y errores de JavaScript que se producen en la página del cliente. |
| Categorías de interesados | Visitantes de los sitios web de los clientes. |
| Categorías de datos personales | Nombre del evento, medido: 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. Valores de parámetros: 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. Dos contienen más de lo que sugiere su nombre: 'snippet' en text_copied y text_selected es el texto de la página que el visitante seleccionó o copió; 'filename' contiene URL completas y se encontró una dirección moz-extension://, que es un identificador de extensión de navegador específico del dispositivo. |
| Dónde se almacena | session_custom_events (event_id, session_id, pageview_id, event_name, created_at) — 823 filas. session_custom_event_params (param_id, event_id, param_key, param_string_value, param_int_value, param_float_value) — 1264 filas. |
| Base jurídica (determinada por el responsable del tratamiento) | Consentimiento, como en A.1. |
| Categorías de destinatarios | El cliente. Opcionalmente, por webhook a una URL elegida libremente por el cliente: véase el apartado 4. |
| Transferencia a terceros países | Mediante el webhook, el destino no está determinado y, por tanto, puede ser un tercer país. Actualmente inactivo: projects.webhook_active=0 y webhook_url NULL para los 7 proyectos. |
| Conservación | Con la sesión mediante la purga diaria y mp_sitzungen_loeschen() (plazo del plan; para bots, los plazos de A.1); session_custom_event_params depende de session_custom_events mediante FOREIGN KEY ON DELETE CASCADE. Los eventos de consola, red y Web Vitals de mouse_events como A.1; mp_cwv se elimina con su vista de página (limpieza cada hora). |
| Mensajes de consola y solicitudes de red (desde el 30/09/2026) | Lo que la página escribe en la consola del navegador (el operador establece el nivel; por defecto, errores y advertencias) y las solicitudes de la página que fallan o tardan más de un umbral configurado: método, dirección, código de estado y duración. Nunca las cabeceras ni el cuerpo de una solicitud o respuesta; nunca el contenido de objetos registrados, solo su tipo. Los textos pasan un filtro antes de enviarse (direcciones de correo electrónico, direcciones IP, secuencias largas de dígitos, tokens de acceso); en las direcciones se retiran los valores de parámetros con nombres sensibles. No se capturan las solicitudes al propio MousePlayer. Se almacena como un evento de ratón en mouse_events (event_type con o net), con la misma conservación y cadena de eliminación que la grabación (A.1); se muestra en el reproductor junto a la línea de tiempo. |
| Tiempos de carga y respuesta (Web Vitals, desde el 02/10/2026) | La rapidez con que la página carga y responde para el visitante, medida en el navegador por vista de página: Largest Contentful Paint, Interaction to Next Paint, Cumulative Layout Shift, First Contentful Paint y Time to First Byte. Además, una descripción breve del elemento visible más grande y del elemento de la interacción más lenta, como para un clic (tipo, identificador, texto visible; en zonas enmascaradas, solo el tipo). Sin entradas ni contenido de solicitudes. Se almacena como un evento de ratón en mouse_events (event_type cwv) y por vista de página en mp_cwv, con la misma conservación y cadena de eliminación que la grabación (A.1); se muestra en la pestaña Web Vitals y en la cabecera del reproductor. |
A.8 Características derivadas y líneas de tiempo de sesiones generadas por una máquina
| Campo | Entrada |
|---|---|
| Finalidad | Derivar características por sesión y registros textuales generados por una máquina: puntuación del carácter llamativo y de la atención. |
| Categorías de interesados | Visitantes de los sitios web de los clientes. |
| Categorías de datos personales | Vector de características: duración, número de páginas, profundidad / mediana / inversiones del scroll, pausas, eficiencia del recorrido, velocidad máxima, clics de rabia y clics muertos, toques, zoom, origen y campaña, tiempo de permanencia por rol de elemento (role_dwell_json), comportamiento de pestañas. Evaluaciones: engagement_score (0-255), session_quality, is_bot. Una línea de tiempo de la sesión en texto continuo; muestra: 't=0.0 landing / src=(direct) kanal=direct attr=direct mode=unknown motion=unavailable viewport=1699x935 / t=2.0 session ende'. |
| Dónde se almacena | ai_session_features — 4043 filas (una fila por sesión Y builder_version, de modo que una sesión aparece una vez por versión). ai_timelines (timeline_id, session_id, channelid, builder_version, input_mode, line_count, char_count, pageviews, duration_s, text como mediumtext, built_at) — 3203 filas, 5,5 MB. mp_session_ziel (channelid, session_id, goal_id, tag, ziel_fp, gebaut_am) — 628 filas: qué sesión alcanzó qué objetivo, calculado una vez en lugar de en cada solicitud. ziel_fp es la huella de la regla del objetivo; si el responsable del tratamiento la cambia, se reconstruye la asignación en lugar de reutilizarla silenciosamente. mp_hm_tag (channelid, tag, url_md5, url, titel, ansichten, engagiert) y mp_hm_tag_stand (channelid, tag, berechnet_am), desde el 24/09/2026 (migración 148): por cada proyecto, día y dirección de página, el número de vistas de página y de vistas de página con interacción, que sirve de fuente a la lista de mapas de calor de páginas. Solo recuentos y direcciones, sin identificador de visitante ni de sesión; el número de visitantes por dirección se sigue contando a partir de las propias sesiones. |
| Base jurídica | No documentada en el código. Derivada de la grabación y, por tanto, cubierta indirectamente por el consentimiento obtenido para ella. Instrucción: surge con el registro del Cliente y se ejecuta en cuanto instala el script en su sitio y se graba a los visitantes (declaración del responsable del tratamiento, 17/08/2026). La derivación de características, líneas de tiempo y niveles de valor forma parte del servicio encargado. Se distinguen dos partes. Los niveles de valor los establece el Cliente en su propio proyecto; cada cambio se registra (log_audit, save_wertregeln). Los resúmenes escritos por el modelo de lenguaje dependían hasta el 17/08/2026 exclusivamente de una configuración global del área de administración; el Cliente no podía influir en ella, por lo que no se basaban en sus instrucciones. Desde la migración 041, projects.ki_texte_aktiv decide adicionalmente y está activado por defecto; el Cliente puede desactivarlo en cualquier momento en la pestaña de configuración y cada cambio aparece como ki_texte_changed en el registro de cambios. El interruptor no es la instrucción, sino el medio para limitarla: que esté activado por defecto significa que el Cliente no lo activó, sino que simplemente no lo desactivó. |
| Categorías de destinatarios | El cliente (cfg/project_ai_overview.php). |
| Transferencia a terceros países | Ninguna. El modelo de lenguaje formula las frases generadas en nuestro propio hardware de Łódź (apartado 4); no se envía nada a un servicio externo de IA. |
| Conservación | Con la sesión. ai_session_features y ai_timelines forman parte de mp_sitzungen_loeschen() (srv/db_worker.php) desde el 12/08/2026 y, por tanto, se retiran tanto en la eliminación explícita como mediante la purga diaria del plan. Antes esta celda decía lo contrario; ese era el estado anterior al cambio. Las puntuaciones por visitante y día derivadas de ellos (ai_visitor_value) y los textos generados (ai_insights) tienen además un plazo propio: véase el apartado 6.2. |
A.9 Colaboración sobre la reproducción — comentarios y enlaces para compartir
| Campo | Entrada |
|---|---|
| Finalidad | Comentar una reproducción en una marca temporal y compartir una reproducción mediante un enlace. |
| Categorías de interesados | Usuarios clientes (los autores) e, indirectamente, los visitantes grabados. |
| Categorías de datos personales | Texto del comentario (hasta 2000 caracteres), desfase temporal, autor. Token para compartir (40 caracteres hexadecimales), creador, caducidad, revocación, número de accesos, último acceso. |
| Dónde se almacena | session_comments (comment_id, channelid, session_id, user_id, time_offset_ms, body, created_at, updated_at) — 12 filas. session_shares (share_id, channelid, session_id, token, created_by, expires_at, revoked_at, last_seen, view_count, created_at) — 9 filas. |
| Base jurídica | No documentada en el código. Instrucción: el Cliente permite expresamente compartir, incluso fuera de su propia organización, y asume la responsabilidad por ello (decisión del responsable del tratamiento, 17/08/2026). La instrucción se documenta mediante el propio acto: el enlace lo crea un miembro autorizado del espacio de trabajo del Cliente y su creación se registra (log_audit, acción create_share; revocación como revoke_share). MousePlayer proporciona la función; la elección de destinatarios y la licitud de la comunicación corresponden al Cliente. Limitación técnica: cada enlace caduca —7 días por defecto y 90 como máximo— y puede revocarse en cualquier momento. |
| Categorías de destinatarios | Cualquier persona que tenga un enlace para compartir, SIN iniciar sesión (www/.htaccess:77). Los tokens inventados, caducados y revocados devuelven la misma respuesta, de modo que no se puede obtener información sondeando tokens. |
| Transferencia a terceros países | Indeterminada por diseño: un enlace puede reenviarse a cualquier lugar. Es una propiedad de la función, no un incidente. |
| Conservación | Con la sesión: session_comments y session_shares forman parte de mp_sitzungen_loeschen() desde el 12/08/2026 y se eliminan con la sesión. Independientemente de ello, los enlaces para compartir tienen una duración máxima propia: session_shares.expires_at es NOT NULL, mp_share_erstellen() (cfg/lib.php) tiene un valor por defecto de 7 días y un máximo de 90. La aplicación no puede crear un enlace ilimitado. Una vez que un enlace ha caducado o se ha revocado, la purga diaria elimina su fila 90 días después; los accesos de share_views se eliminan con ella mediante la clave foránea (B.6). |
A.10 Vista en vivo — observar una sesión mientras sucede
| Campo | Entrada |
|---|---|
| Finalidad | Observación de una sesión en curso en tiempo real: lista en vivo de visitantes presentes, modo seguimiento con una captura reflejada de la página, posición transmitida del puntero y, desde el 16/08/2026, un estado de paso del puntero reconstruido (:hover). |
| Categorías de interesados | Visitantes de sitios web de Clientes (observados), usuarios Clientes (observadores). |
| Categorías de datos personales | Las mismas categorías que A.1 y A.2 —posiciones del puntero y del scroll, clics, eventos de entrada, captura de página y sus cambios—, pero en el momento en que se generan. Además, el identificador de la sesión para que el observador siga la sesión correcta. |
| Dónde se almacena | No se almacena. El flujo pasa por el servidor WebSocket (class/Server.class.php) y se transmite, dentro del proceso, a los observadores conectados. El token de acceso se conserva en la tabla de base de datos live_tokens (identificador, proyecto, ID de usuario, en su caso la sesión seguida, hora de la última confirmación). Desde el 17/09/2026, el reproductor de una sesión en curso también se conecta a este flujo con su propio acceso (identificador con el prefijo pl_, vinculado a la sesión seguida) para mostrar sus eventos sin demora. La grabación de la misma sesión se crea de forma independiente mediante A.1 y A.2. |
| Base jurídica | Instrucción: la observación la inicia un miembro autorizado del espacio de trabajo del Cliente; el acceso se realiza mediante un token de duración limitada en live_tokens vinculado a su ID de usuario. No se notifica por separado al usuario final en el momento de la observación (decisión del responsable del tratamiento, 17/08/2026). Se informa de antemano: mediante el consentimiento previo a cualquier grabación y mediante la política de privacidad, que desde el 17/08/2026 indica expresamente que una sesión en curso puede seguirse en tiempo real. Hasta entonces solo mencionaba la vista en vivo como función en una lista; por tanto, la decisión se basaba en una frase que aún no existía. |
| Categorías de destinatarios | El Cliente, limitado a los miembros autorizados del espacio de trabajo. |
| Transferencia a terceros países | Ninguna. |
| Conservación | El propio flujo no se almacena. El servidor WebSocket retira una fila de live_tokens cuando termina la vista, con un breve período de gracia para una recarga; un acceso que deja de confirmarse pierde su efecto al poco tiempo y se limpia después. |
Esta entrada no figuraba en el registro hasta el 17/08/2026. Debe mantenerse separada de A.1 y A.2 aunque circulen los mismos datos: allí se reproducen después; aquí una persona observa en el momento en que actúa el visitante. Esa simultaneidad es precisamente la característica a la que se refiere el art. 35(3) al definir la observación sistemática, y la EIPD basa en ella su propia necesidad.
A.11 Registro de entregas de integraciones
| Campo | Entrada |
|---|---|
| Finalidad | Prueba y resolución de problemas de las transmisiones enumeradas en 4.1. Sin él, el responsable no puede saber si un puente funciona: un fallo sería silencioso de su lado. |
| Categorías de interesados | Visitantes de sitios web de clientes, en la medida en que el responsable les haya asignado un ID de cliente. Sin un ID asignado, la entrada no contiene ninguna referencia personal. |
| Categorías de datos personales | Marca de tiempo, tipo de puente, un identificador (el ID de cliente que el responsable proporcionó mediante setUserId, la red publicitaria o el nombre del evento), éxito o fallo, duración en milisegundos, número de intento y respuesta o texto de error del destinatario. Ese texto puede contener un ID de registro del sistema de terceros. Ningún dato de comportamiento, contenido de página ni dirección IP. |
| Dónde se almacena | Redis, clave mp_webhook_log:<channelid>. Las últimas 25 entradas por proyecto; las anteriores se descartan mediante lTrim. No en la base de datos y, por tanto, tampoco en la copia diaria de seguridad. |
| Base jurídica (determinada por el responsable del tratamiento) | Como A.1. La entrada solo se crea si el responsable ha activado un puente: es el registro de la ejecución de su propia instrucción. |
| Categorías de destinatarios | El responsable del tratamiento, mediante la configuración del proyecto (pestaña Integraciones). Sin comunicación ulterior. |
| Transferencia a terceros países | Ninguna. La entrada no sale de nuestro propio servidor. |
| Conservación | 30 días. Se establece como caducidad de Redis al escribirla; además, se limita a 25 entradas por proyecto. Caduca por sí misma y no necesita una ejecución de supresión. La cifra está en site_settings.retention_intlog_days y se puede ajustar en el área de administración. |
A.12 Perfiles de comportamiento — agrupación automatizada de visitas
| Campo | Entrada |
|---|---|
| Finalidad | Agrupar automáticamente las VISITAS grabadas según su desarrollo, para que el responsable no tenga que revisar una sesión tras otra, sino que vea grupos y pueda reproducir una visita típica por grupo. Además, secuencias recurrentes de páginas y eventos dentro de la ventana de cálculo. |
| Categorías de interesados | Visitantes de los sitios web de clientes. Se agrupan VISITAS, no personas: la misma persona con dos visitas puede acabar en dos grupos, y la interfaz está redactada en esos términos. No se calcula un perfil por PERSONA: requeriría el identificador de cliente proporcionado mediante setUserId, y 0 de 4226 sesiones llevan uno (medido el 27/08/2026). |
| Categorías de datos personales | Ninguna categoría nueva. El vector de características de A.8, reducido a las siete características con una tasa de cumplimentación superior al 90 %: duración, número de páginas, puntuación de atención, pausas, clics de rabia, clics muertos y cambios de pestaña. Derivado de ellas: a qué grupo pertenece una sesión y su distancia al centro del grupo. Por grupo, además, el ID de sesión de la visita más típica y de la menos típica, para poder reproducir ambas. Para las secuencias: la cadena de patrones de rutas y nombres de eventos, y hasta tres ID de sesión como ejemplos. Sin contenido de páginas, dirección IP ni entradas de formularios. |
| Dónde se almacena | mp_profile — una fila por canal y grupo (tamaño, proporción, centro, cifras clave, nombre calculado, nombre asignado por el propio usuario, representante, caso atípico); 15 filas. mp_profil_sitzung — sesión a grupo más distancia; 4226 filas. mp_sequenzmuster — cadena, soporte, lift, hasta tres ejemplos; 115 filas. Las tres son DERIVACIONES: pueden perderse y recalcularse en cualquier momento y no contienen ningún dato sin procesar que no exista también en otro lugar. Desde el 06/09/2026, mp_profil_sitzung contiene además la clave de persona (person_key, migración 112): una copia de la clave de A.4 (ID de cliente o, en su defecto, ID de visitante), que la ejecución de perfiles actualiza a diario; de ella se calcula la lista de visitantes recurrentes. Recuentos de filas de esta entrada: a 27/08/2026. |
| Base jurídica | Como A.8. Derivada de la grabación y, por tanto, amparada indirectamente por el consentimiento obtenido para ella. Instrucción: forma parte del servicio encargado; surge con el registro del cliente y se ejecuta en cuanto se graba a los visitantes. Conviene mencionar dos límites. La agrupación se CALCULA, no se genera: k-means decide a qué grupo pertenece una visita a partir de las siete características de ai/profile.py, y los nombres de los grupos proceden de la posición relativa del centro, no de un texto. Cuando un modelo de lenguaje escribe una frase sobre un grupo, solo recibe las cifras del GRUPO —porcentajes y promedios—, nunca un ID de sesión o visitante, y el mismo control que en A.8 rechaza cualquier número que no esté entre esas cifras. Sin embargo, no hay un interruptor por proyecto: profile_aktiv es una configuración global del operador, y la selección de secciones de IA por proyecto (projects.ki_module) no cubre esta pestaña. Consta como carencia en el apartado 10. |
| Categorías de destinatarios | El cliente, mediante la pestaña Perfiles de comportamiento (cfg/project_profiles.php). Sin transferencia a terceros: la pertenencia a grupos no entra en ninguno de los puentes de 4.1. Comprobado mediante una búsqueda de profil_key en cfg/, srv/, www/ y class/ — solo aparece en la vía de lectura y en el reproductor, ni en www/mp.js ni en class/Server.class.php, por lo que tampoco llega nunca al navegador del visitante. |
| Transferencias a terceros países | Ninguna. El cálculo se ejecuta en la misma máquina (ai/profile.py, iniciado por srv/ai_worker.php). La frase opcional por grupo la formula el modelo de lenguaje en una de nuestras propias máquinas con tarjeta gráfica de la misma red local (véase el apartado 4), que obtiene solo las cifras del grupo mediante HTTPS. No se envía nada a un servicio externo de IA. |
| Conservación | Con la sesión: mp_profil_sitzung forma parte de mp_sitzungen_loeschen(). Además, 180 días, con punto de partida en el INICIO DE LA SESIÓN y no en el momento del cálculo: la ejecución diaria actualiza este último cada vez, de modo que un plazo vinculado a él nunca caducaría y nadie lo advertiría. Las filas cuya sesión ya no existe se retiran sin plazo alguno, porque cualquier plazo deja de tener objeto si la fila ya ha desaparecido. La cifra está en site_settings.retention_profile_days, es ajustable en el área de administración y se eleva como mínimo hasta la ventana de cálculo para que la ejecución de eliminación no retire lo escrito por la ejecución de perfiles ese mismo día. mp_profile se elimina en cuanto no queda ninguna asignación para él, en la misma ejecución nocturna; por eso esta afirmación figura después de las dos anteriores. mp_sequenzmuster se elimina tras 180 días sin recalcularse e inmediatamente cuando su canal ya no tiene ninguna sesión. En ese caso, el punto de partida SÍ es el momento del cálculo, y correctamente: a diferencia de una asignación, un patrón describe la ventana ACTUAL y se reescribe íntegramente por canal en cada ejecución, por lo que una marca de tiempo reciente sí significa „describe los datos de hoy“. |
A.13 Nombre personalizado para un visitante — asignado por el responsable del tratamiento
| Campo | Entrada |
|---|---|
| Finalidad | El responsable asigna un nombre personalizado a un visitante individual para reconocerlo en listas y grabaciones. El nombre sustituye al apodo generado de A.4 en todos los lugares en que este aparecería. La ocasión es el caso de soporte: „este es el cliente que llamó“. |
| Categorías de interesados | Visitantes de los sitios web de clientes; concretamente, personas individuales elegidas por el responsable. A diferencia de A.1 a A.12, este tratamiento no surge por sí solo cuando alguien abre la página; exige una entrada deliberada. Sin ella no hay fila: el 28/08/2026, 0 de 3830 visitantes tienen un nombre personalizado. |
| Categorías de datos personales | TEXTO LIBRE de un máximo de 64 caracteres, más el momento y la cuenta de usuario de la asignación. La referencia es el identificador de visitante de A.4. El contenido no se prescribe ni se comprueba — puede ser un número de contrato, un apodo o un nombre en claro junto con un departamento. Esto diferencia el tratamiento de todos los demás de la Parte A: allí los datos proceden del visitante o se calculan a partir de su comportamiento; aquí los introduce el responsable. Consta como carencia en el apartado 10. |
| Dónde se almacena | visitor_nicknames.custom_label, label_set_at, label_set_by (migración 093): la misma fila que ya contiene el apodo generado, una por visitante, 3830 filas. Deliberadamente no es una tabla propia: el nombre sustituye exactamente al apodo almacenado allí, depende de la misma clave y, por tanto, se elimina con ella sin más actuaciones. Una tabla separada sería un quinto lugar de la cadena de eliminación, y uno que puede olvidarse. |
| Base jurídica | Instrucción del responsable del tratamiento (art. 28(3)(a)), dada por la propia entrada: ninguna tarea ni configuración por defecto crea un nombre. MousePlayer no puede juzgar si existe una base jurídica para el contenido introducido: el responsable elige el texto y conoce el contexto del que procede. Por ello, la indicación del campo de entrada expresa la finalidad („solo su equipo ve este nombre“) y no se limita a nombrar el campo. |
| Categorías de destinatarios | El cliente, en sus propias listas y en el reproductor. Sin comunicación a terceros: el campo no entra en ninguno de los puentes de 4.1, verificado mediante una búsqueda de custom_label en cfg/, srv/, www/ y class/; no aparece ni en www/mp.js ni en class/Server.class.php y, por tanto, tampoco llega nunca al navegador del visitante. El enlace para compartir (B.6) deliberadamente NO lo muestra, sino que muestra el apodo generado: reenviar un enlace que no exige iniciar sesión comparte una grabación, no la identidad que hay detrás. La misma consideración que en www/selbstauskunft.php. |
| Transferencias a terceros países | Ninguna. El campo solo sale de la base de datos hacia la interfaz del cliente que ha iniciado sesión. |
| Conservación | Con la última sesión del visitante, como la fila en la que está: mp_sitzungen_loeschen() retira esa fila en cuanto ya no existe ninguna sesión de ese identificador de visitante, en ambas vías: la ejecución diaria de eliminación y la eliminación de la cuenta. Sin plazo de calendario propio, deliberadamente: un plazo sobre el nombre significaría eliminarlo mientras el visitante sigue allí y se sigue grabando. El responsable puede retirarlo en cualquier momento; un campo vacío lo elimina y vuelve a aplicarse el apodo generado. |
A.14 Importación de Google Analytics 4 — cifras y sesiones de la cuenta propia del responsable del tratamiento
| Campo | Entrada |
|---|---|
| Finalidad | El responsable hace que se obtengan datos de su propia cuenta de Google Analytics 4 y se incorporen a MousePlayer. Dos vías, cada una activada por separado: la Data API solo devuelve totales diarios y responde a la cuestión de la cobertura: GA4 cuenta 3 000 sesiones en un día y MousePlayer grabó 40; sin esa cifra de referencia no puede explicarse ni siquiera advertirse la diferencia. La importación de BigQuery lee la exportación sin procesar de la propiedad y almacena sesiones individuales de GA4 con sus eventos, para que pueda verse qué ocurrió durante una visita que MousePlayer no pudo grabar. |
| Categorías de interesados | Visitantes de los sitios web de clientes: las mismas personas que en A.1, solo que observadas por un segundo sistema de medición. Lo que diferencia esto de A.1 a A.13 es el origen: estos datos no se recogieron aquí. Ya están en la cuenta de Google del responsable y MousePlayer los obtiene. La vía de Data API, además, no se refiere a ninguna persona individual; solo devuelve totales diarios. |
| Categorías de datos personales | Para la vía de Data API: ninguna — cuatro números por día (sesiones, usuarios, vistas de página, sesiones con interacción) sin ninguna referencia personal. Para la vía de BigQuery, por sesión de GA4: el identificador seudónimo user_pseudo_id, es decir, el ID de cliente de la cookie _ga; inicio, fin y duración; número de eventos y vistas de página; ruta de entrada; categoría de dispositivo y país; más origen, medio y campaña. Además, por nombre de evento, un contador, la última marca de tiempo y, cuando GA4 lo comunica, un valor sumado. Sin dirección IP, captura de página ni movimientos del ratón — GA4 no conserva nada de ello y no se genera. Por tanto, una sesión importada nunca puede reproducirse. |
| Dónde se almacena | ga4_daily, ga4_sessions y ga4_events (migración 097): tres tablas SEPARADAS. Deliberadamente no en visitor_sessions, session_pageviews o session_custom_events. No es una cuestión de orden: esas tres tablas no tienen ninguna columna que indique de dónde procede una fila, porque todo lo que contienen se midió aquí. Una fila importada sería indistinguible de una medida y, con ello, cambiaría silenciosamente el significado de cada cifra derivada: los perfiles de comportamiento de A.12, la valoración por visitante, el análisis de fricción. Por tanto, la importación se sitúa junto a los datos medidos, como ya ocurre con ai_visitor_value y mp_profile. |
| Base jurídica | Instrucción del responsable del tratamiento (art. 28(3)(a)), dada al activar la vía correspondiente y proporcionar una cuenta de servicio específica. La recogida original en Google es responsabilidad del responsable del tratamiento, no de MousePlayer: ocurrió antes de que se obtenga nada aquí y no puede verificarse a posteriori. Aun así, existe una barrera técnica: solo se importan filas que llevan un user_pseudo_id. Cuando se deniega el consentimiento, GA4 envía accesos sin cookies mediante Consent Mode y estos no lo llevan; quedan excluidos mecánicamente, no por una mera garantía. Es un indicio, no una prueba, y así consta entre las carencias del apartado 10. |
| Categorías de destinatarios | Ninguno nuevo. La vía RECUPERA, no entrega: no sale ningún dato de visitantes de nuestras instalaciones. El destinatario es el cliente en su propia interfaz. Google aparece aquí como FUENTE, no como destinatario: desde una cuenta que opera el responsable y cuyo contenido determina. |
| Transferencia a terceros países | Ninguna transferencia de datos de visitantes. La solicitud se dirige a analyticsdata.googleapis.com y a BigQuery; se transmiten las credenciales de la cuenta de servicio y el texto de la consulta, no datos de visitantes. Los datos fluyen en sentido contrario. Dónde residen los datos de GA4 en Google y con qué garantías depende de la cuenta propia del responsable y es una cuestión de su contrato con Google, no de este registro. |
| Conservación | 180 días, con punto de partida en el día que DESCRIBE la fila (ga4_daily.tag, ga4_sessions.start_time) y no en el momento de importación. Este último se actualiza en cada ejecución, porque GA4 completa datos anteriores durante un máximo de 48 horas y, por ello, se obtienen de nuevo los mismos días; un plazo vinculado a él nunca caducaría. Lo aplica la ejecución diaria en srv/db_worker.php, los eventos antes que sus sesiones. Una solicitud de supresión conforme al art. 17 los incluye desde el 01/09/2026, en la medida en que la fila pueda atribuirse mediante el identificador de cliente; la ejecución de eliminación del plan NO lo hace: los datos de GA4 tienen su propio calendario y, de otro modo, un cliente del plan gratuito los perdería tras 7 en lugar de 180 días. En cualquier caso, se eliminan con el proyecto, incluidas las filas que nunca pertenecieron a una de nuestras sesiones. Lo que esto no alcanza se expone en el apartado 10. |
A.15 Predicción de salida y la oferta que puede desencadenar
| Campo | Entrada |
|---|---|
| Finalidad | Estimar, a partir de los primeros segundos de una visita, la probabilidad de que el visitante se marche pronto sin una segunda vista de página. El responsable puede asociar una oferta a esa estimación, que se muestra al visitante en SU sitio web. A diferencia de A.8 a A.14, este tratamiento no termina en un análisis para el cliente, sino que repercute en el visitante; por eso tiene una entrada propia en lugar de ser un subapartado de A.8. Además, el responsable puede solicitar una propuesta de texto y diseño para esa oferta: un modelo de lenguaje los redacta a partir del contexto de su sitio web. Una propuesta nunca se publica por sí sola; el responsable la adopta únicamente parte por parte. |
| Categorías de interesados | Visitantes de sitios web de clientes y solo en la PRIMERA vista de página de una sesión: una vista posterior ya no es una llegada y no se puntúa. Nada de ello se ejecuta sin consentimiento: la puntuación está detrás del mismo control que la grabación. |
| Categorías de datos personales | Dieciséis características medidas de la visita actual, todas formadas en el navegador: dispositivo (móvil sí/no), visitante recurrente, clic de pago, motor de búsqueda, red social, entrada por la página de inicio, profundidad de la ruta de la página de entrada, hora nocturna, número de movimientos del ratón, eventos de scroll y clic dentro de la ventana, segundos hasta la primera entrada, posición de scroll más profunda como porcentaje de la página, número de inversiones del scroll, si la pestaña perdió el foco y si no hubo ninguna entrada. De ellas se obtiene UN porcentaje y hasta tres motivos en lenguaje claro. Sin contenido, coordenadas ni valores de campos. El marcador mp_seen_before en el almacenamiento local del navegador registra que el visitante ya estuvo aquí; mp_offer_<date> cuenta cuántas veces se le ha mostrado una oferta hoy. La propuesta de oferta no añade información sobre visitantes individuales, sino sobre el sitio web: título, descripción, encabezados y navegación de un máximo de diez capturas de páginas, un máximo de 40 direcciones que visitantes humanos abrieron al menos cinco veces en 30 días, la proporción de idiomas de las páginas y los colores, el redondeo de esquinas y la fuente del fondo de la página y del botón más frecuente, medidos en el navegador. Para ello se registra el idioma por vista de página (el atributo lang de la página). Las direcciones y los encabezados pueden contener todo lo que muestre el propio sitio web (véase A.17). |
| Dónde se almacena | El MODELO en projects.exit_modell (migración 100): pesos, medias, desviaciones, calidad y momento del entrenamiento; no contiene datos personales, solo cifras de la población. El RESULTADO por visita como evento en session_custom_events: exit_risk con el porcentaje y los motivos, más exit_offer_shown, exit_offer_click y exit_offer_dismiss cuando se mostró una oferta. El último valor también se conserva transitoriamente en el registro de conexión del servidor WebSocket (Redis, mp_websockets) para que la vista en vivo pueda mostrarlo; desaparece con la conexión. La propuesta de oferta se almacena en projects.exit_offer_vorschlag (migración 114), las mediciones de diseño como las últimas 60 por canal en Redis (mp_design:<channel>), el idioma de página en session_pageviews.lang. Para la redacción, el contexto pasa por ai_ki_queue a nuestras propias máquinas que ejecutan el modelo de lenguaje (apartado 4). |
| Base jurídica | Instrucción del responsable del tratamiento. El entrenamiento se realiza por proyecto y solo con las sesiones de ese proyecto, como mínimo 200; por debajo de ello no se crea ningún modelo. El consentimiento del visitante cubre la grabación de la que proceden las características: la misma base que en A.8. Solo el responsable decide si se muestra una oferta; él es el responsable del tratamiento para esa visualización en su sitio web, no nosotros. |
| Categorías de destinatarios | El cliente en su interfaz. El porcentaje y los motivos llegan además al NAVEGADOR DEL VISITANTE —se forman allí, no se envían allí— y están disponibles para el código propio del responsable mediante MousePlayer.on('exit_risk') y la capa de datos. La oferta que aparezca después la ve el propio visitante. Una propuesta de oferta solo la ve el responsable en su interfaz; llega al sitio web únicamente cuando la adopta. No se envía nada a terceros. |
| Transferencia a terceros países | Ninguna. El entrenamiento y la puntuación se ejecutan en la infraestructura de Łódź o en el navegador del visitante. La propuesta de oferta la redacta el modelo de lenguaje en nuestro propio hardware de Łódź (apartado 4); no se envía nada a un servicio externo de IA. |
| Conservación | Los eventos comparten la conservación de la sesión a la que pertenecen (A.7) y se eliminan con ella. El modelo se sobrescribe en cada ejecución; no hay historial. Los dos marcadores residen en el almacenamiento local del visitante: mp_seen_before sin caducidad hasta que lo borra o retira su consentimiento, mp_offer_<date> solo para el día actual (mp.js retira las entradas antiguas la próxima vez que establece una). Además, mp_design_sent en el almacenamiento de sesión de la pestaña registra que ya se ha medido el diseño. Al retirar el consentimiento, mp.js retira los tres. La propuesta de oferta permanece hasta que otra la sustituye; las mediciones de diseño caducan en Redis tras 30 días; el idioma de página comparte la conservación de su vista de página. |
A.16 Indicador de riesgo de fuga para visitantes recurrentes
| Campo | Entrada |
|---|---|
| Finalidad | Estimar a partir de las visitas anteriores de la misma persona si se está alejando, para que el responsable pueda responder. A diferencia de A.15, esta evaluación no examina la visita actual, sino el historial. |
| Categorías de interesados | Visitantes recurrentes de sitios web de clientes con al menos 2 sesiones. Quien vino una vez no recibe ninguna fila. La clave es la persona en el sentido de A.4: el identificador de cliente establecido por el responsable o, en su defecto, el identificador de visitante. |
| Categorías de datos personales | Un valor de riesgo entre 0 y 1, hasta cuatro motivos en lenguaje claro de una lista fija (descenso de la interacción, visitas breves, fricción, retraso; una compra en las dos últimas visitas reduce el valor), el número de visitas y el momento de la última. Sin contenido ni coordenadas. No es un modelo entrenado, sino cuatro observaciones contables: cada una figura en la fila como motivo, de modo que nunca aparece un valor sin uno. |
| Dónde se almacena | ai_churn (migración 100): channelid, person_key, visitor_id, risiko, gruende, sitzungen, letzte_sitzung, berechnet_am. Además, un hash de Redis por canal, mp_churn:<channel>, que caduca tras dos días y del que lee el servidor WebSocket al conectarse; solo se incluyen allí los que superan el umbral. |
| Base jurídica | Instrucción del responsable del tratamiento; las sesiones subyacentes se basan en el consentimiento del visitante (A.1). Se calcula por proyecto, nunca entre clientes. |
| Categorías de destinatarios | El cliente en su interfaz. El valor también se envía al NAVEGADOR DEL VISITANTE en cuanto se conecta y está disponible para el código propio del responsable mediante MousePlayer.on('churn_risk'); puede asociarle una oferta. Esta transferencia al propio dispositivo del interesado explica por qué esta entrada figura aquí y no en A.8. No se envía nada a terceros. |
| Transferencia a terceros países | Ninguna. |
| Conservación | La fila se reescribe para el canal en cada ejecución y se elimina con las sesiones de las que procede. La entrada de Redis caduca por sí sola tras dos días. |
A.17 Informe resumido sobre un visitante
| Campo | Entrada |
|---|---|
| Finalidad | Reunir todas las visitas de UNA persona en un informe legible: de dónde llegó, por qué se pagó, dónde encontró dificultades y si se alcanzó algún objetivo. Los hallazgos se calculan; un modelo de lenguaje, como máximo, los reformula. Un informe lo solicita el cliente para un visitante concreto o se solicita automáticamente para un máximo de 5 visitantes por proyecto y noche, elegidos entre visitas de pago sin compra. |
| Categorías de interesados | Visitantes de sitios web de clientes para los que existe más de una visita. La clave es la persona en el sentido de A.4. |
| Categorías de datos personales | Un máximo de catorce hallazgos calculados en forma de texto: número de visitas y páginas, período, dispositivos, origen incluida la campaña, compras y objetivos alcanzados, los tres mayores cuellos de botella con su ruta, la última sesión y las ETIQUETAS de los elementos pulsados (hasta cinco, de 60 caracteres cada una). Además, el texto generado. No incluyen valores de campos de formularios: estos nunca salen del navegador. Las etiquetas y las rutas, en cambio, proceden de lo que muestra el propio sitio web del responsable y, por tanto, pueden contener un nombre o una dirección si los muestra allí o los escribe en la URL; consta como carencia en el apartado 10. |
| Dónde se almacena | ai_besucher_bericht (migración 100) con channelid, person_key, lang, los hallazgos, su hash, el texto y el nombre del modelo. Para la redacción, los HALLAZGOS —no la grabación— pasan por ai_ki_queue a las máquinas que ejecutan el modelo de lenguaje (hardware propio en la misma red local, véase el apartado 4). Cada informe consume una cuota (ai_ki_kontingent por espacio de trabajo y mes, 3 en el plan gratuito y, en los demás casos, 200). |
| Base jurídica | Instrucción del responsable del tratamiento; las sesiones subyacentes se basan en el consentimiento del visitante (A.1). El modelo de lenguaje no se entrena ni se modifica; solo redacta. |
| Categorías de destinatarios | El cliente en su interfaz. El visitante no se entera: a diferencia de A.15 y A.16, nada aquí repercute sobre él. |
| Transferencia a terceros países | Ninguna. El modelo de lenguaje se ejecuta en nuestro propio hardware de Łódź (apartado 4); no se envía nada a un servicio externo de IA. |
| Conservación | 180 días desde la solicitud, aplicados por la pasada posterior del proceso de IA. Si la última sesión del visitante desaparece antes, el informe se elimina con ella. |
A.18 Acceso de autoservicio y solicitud de supresión del visitante
| Campo | Entrada |
|---|---|
| Finalidad | Mostrar a un visitante qué se almacena sobre él y permitirle solicitar su supresión: asistencia al responsable con los derechos de los interesados conforme al art. 28(3)(e) del RGPD. Accesible en /my-data, /meine-daten y /moje-dane. |
| Categorías de interesados | Visitantes de sitios web de clientes y solo los que aportan su propio identificador. El responsable debe colocar el enlace; él es el responsable frente a sus visitantes y la información del art. 13 corresponde a su propia política. |
| Categorías de datos personales | Se muestran el número, el período y los dominios de las sesiones, pero ninguna grabación. El identificador es un token al portador; quien conoce el de otra persona no debe poder ver el comportamiento de un extraño. Por el mismo motivo, la respuesta se limita al DISPOSITIVO y no utiliza mp_person_sql() para reunir lo que pertenece a una persona: la combinación revelaría MÁS, no menos. De la solicitud de supresión almacenamos el identificador, el momento de la solicitud y el momento de ejecución. |
| Dónde se almacena | visitor_deletion_requests (visitor_id, requested_at, done_at) — 0 filas. La propia página no almacena nada; lee. El trabajador ejecuta la solicitud mediante la misma cadena de eliminación que activa el responsable: una segunda vía de eliminación sería un segundo lugar para la misma información. |
| Base jurídica | Art. 28(3)(e) del RGPD (asistencia al responsable) y sus instrucciones. Se comprueba el formato del identificador (^v_[a-z0-9]{9}_\d{13}$); se rechaza cualquier otro valor. |
| Categorías de destinatarios | El propio visitante. No se envía nada al cliente; solo se entera de una solicitud de supresión porque desaparecen las sesiones. |
| Transferencia a terceros países | Ninguna. |
| Conservación | La fila permanece como prueba de que se realizó la supresión y de cuándo ocurrió. No contiene datos de comportamiento. Si se restaura una copia de seguridad, las solicitudes registradas se ejecutan de nuevo antes de que el sistema vuelva al servicio (cláusula 24.2 de los Términos del servicio). |
A.19 Revisión posterior de la detección de bots — decisiones del operador como ejemplos de aprendizaje
| Campo | Entrada |
|---|---|
| Finalidad | Un supervisor vuelve a comprobar las sesiones que la detección de oleadas ha marcado retroactivamente como bots, y los casos dudosos se comunican en los Registros urgentes. Allí, el operador decide con un clic: Humano o Bot. Cada decisión se convierte en un ejemplo de aprendizaje a partir del cual se recalculan los pesos de las siete señales: solo los pesos, no el umbral, y únicamente a partir de un número mínimo de decisiones que puede establecerse en el área de administración (bot_revision_lern_min). Por debajo se aplican valores fijos. |
| Categorías de interesados | Visitantes de sitios web de clientes cuya sesión se comunicó como caso dudoso y la persona que decidió (personal del cliente o nuestro). |
| Categorías de datos personales | Ningún contenido de visitantes. Se almacenan el canal, el identificador de sesión, la decisión, la puntuación, los nombres de las señales que se aplicaron (por ejemplo: identificador distinto del de la oleada, referrer presente, dirección de una red privada) y el identificador de quien decide. El vector de características forma parte del ejemplo porque la propia sesión desaparece tras su plazo de conservación y el aprendizaje sigue necesitándolo. |
| Dónde se almacena | bot_review_labels (migración 140): una fila por sesión; quien cambia de opinión sobrescribe. Lo lee cfg/bot_revision_lib.php. Sin la tabla, los supervisores funcionan con pesos fijos. |
| Base jurídica | Instrucción del responsable del tratamiento; A.1 se aplica a las propias sesiones. El procedimiento mejora la distinción entre bots y humanos y, con ello, la exactitud del análisis (art. 5(1)(d) del RGPD). No depende de él ninguna decisión sobre el visitante; una liberación retira la marca de una sesión, nada más. |
| Categorías de destinatarios | Ninguno fuera de la interfaz; los ejemplos solo son visibles para el operador. |
| Transferencia a terceros países | Ninguna. |
| Conservación | Por defecto: sin eliminación automática — un ejemplo es seudónimo y no contiene contenido de visitantes, y su valor aumenta con el conjunto. El plazo puede establecerse en años en el área de administración (retention_bot_labels_years, 0 = ilimitado); a partir de 1, el supervisor de estado (srv/cron_status.php) elimina las filas tras ese número de años. No forma parte de ninguna cadena de eliminación de sesiones: cuando desaparece la sesión, el ejemplo permanece; es intencionado, pero consta como carencia en el apartado 10. |
A.20 Seguimiento de elementos — clics en elementos marcados de la página
| Campo | Entrada |
|---|---|
| Finalidad | En el asistente de elementos, el responsable marca elementos de sus páginas —individualmente o como grupo de elementos similares, mediante un selector CSS— y recibe clics, sesiones con clic, visitantes y tasa de clics para cada marca. El recuento es retroactivo: srv/element_worker.php asigna clics ya grabados (A.1, mouse_events_analytik) al elemento marcado en la captura de su propia vista de página. Una marca también puede ser un objetivo o un paso de embudo; sus coincidencias cuentan entonces como objetivo o paso alcanzado. |
| Categorías de interesados | Visitantes de sitios web de clientes cuyos clics se grabaron. |
| Categorías de datos personales | Un complemento de la grabación de clics (A.1); por lo demás, no se recogen nuevos datos: cuando un visitante hace clic en un elemento que apareció después de la captura (por ejemplo, un menú abierto o una ventana emergente), mp.js envía también desde el 27/09/2026 su estructura: etiqueta, clases, algunos atributos (role, type, name, ruta del enlace sin consulta, data-*), la posición entre elementos hermanos del mismo tipo y la etiqueta visible; en zonas enmascaradas, solo etiqueta e identificador. Se almacena con los eventos de la vista de página (A.1) y comparte su conservación. Para cada coincidencia se almacenan: identificadores de canal, sesión y vista de página, inicio de la sesión, tipo de clic (click o tap), etiqueta visible del elemento alcanzado, tomada de la captura —enmascarada exactamente como la contiene la grabación— y, si el responsable así lo decide, el valor de un atributo de ese elemento (por ejemplo, data-id) para el desglose. Desde el 27/09/2026, el trabajador de elementos mantiene una nota de los clics cuyo destino falta en la captura y para los que no se envió ninguna estructura (clics anteriores): identificador de canal, sesión y vista de página, momento y un hash de la ruta de página y la etiqueta; la propia etiqueta no se almacena allí. A partir de los clics resueltos aprende, por marca, qué etiqueta en qué ruta de página coincide con la marca (ruta, etiqueta, dos contadores, sin vínculo con un visitante). Si todas las observaciones coinciden, un clic anotado se asigna como coincidencia —marcada como transferida— o como no coincidencia. La propia marca (nombre, selector, zona de página) y los contadores diarios de cobertura no contienen ninguna referencia a un visitante. |
| Dónde se almacena | mp_element_regeln, mp_element_klicks y mp_element_tag (migración 152), mp_element_offen y mp_element_muster (migración 155). Lo lee cfg/element_lib.php. |
| Base jurídica | Instrucción del responsable del tratamiento (art. 28(3)(a) del RGPD), dada al crear una marca; A.1 se aplica a los propios clics. La evaluación resume grabaciones existentes; la única incorporación es la estructura de destinos de clic creados después de la captura (arriba), que describe lo mismo que la captura de la página. No depende de ello ninguna decisión sobre el visitante. |
| Categorías de destinatarios | Ninguno fuera de la interfaz mientras solo se evalúe la marca. Si el responsable la utiliza como objetivo o paso de embudo, los objetivos alcanzados y los abandonos de embudo pasan a las transmisiones que haya activado (4.1), con el identificador de sesión, el nombre del objetivo o del embudo y la etiqueta del elemento pulsado, y solo para clics cuya antigüedad no supere lo establecido en el área de administración (por defecto, dos horas). Las coincidencias más antiguas cuentan en la interfaz, pero no se transmiten. |
| Transferencia a terceros países | Ninguna. |
| Conservación | Una coincidencia se elimina con la sesión de la que procede: mp_element_klicks forma parte de la cadena de eliminación (mp_sitzungen_loeschen() en srv/db_worker.php), y el trabajador de elementos retira cada hora las coincidencias cuya vista de página ya no existe; por tanto, también después de vías de eliminación ajenas a esa cadena, en el plazo máximo de una hora. Los clics anotados (mp_element_offen) se eliminan con su sesión por las mismas vías. Eliminar una marca elimina sus coincidencias, contadores, notas y patrones; los patrones no están vinculados a un visitante y también se eliminan al cambiar el selector o tras un año sin nuevas observaciones. Deliberadamente no existe un plazo separado: sería más largo o más corto que el de la grabación y ambas opciones serían incorrectas. |
A.21 Encuestas de opinión — una pregunta al visitante y la respuesta junto a la grabación
| Campo | Entrada |
|---|---|
| Finalidad | El responsable plantea a los visitantes de su sitio una pregunta breve —probabilidad de recomendar de 0 a 10, cinco caras, sí/no o una opción— y, si lo desea, una pregunta complementaria de texto libre. La respuesta se vincula a la visita para que pueda ver las grabaciones de los visitantes insatisfechos. El responsable establece la pregunta, el momento, la proporción de visitantes y el idioma. |
| Categorías de interesados | Visitantes de sitios web de clientes a los que se mostró una encuesta —según una muestra establecida por el responsable y como máximo una vez por intervalo de pausa establecido por él— y visitantes que abrieron una encuesta por sí mismos mediante un botón en el borde de la página; en este caso, la pausa comienza solo con una respuesta. Solo se recoge lo que introduce el visitante: quien descarta la pregunta solo deja constancia de que se mostró y se cerró. |
| Categorías de datos personales | La valoración (un número o la opción elegida) con su sentimiento (negativo, neutro, positivo), momento e identificador de encuesta como evento de la visita (A.7): survey_shown, survey_answer y survey_dismiss. Para una pregunta complementaria, un TEXTO LIBRE de un máximo de 500 caracteres con el idioma de la página. Antes de enviarlo, mp.js retira direcciones de correo electrónico, direcciones IP y números de teléfono, y el trabajador lo hace por segunda vez (mp_umfrage_text_filtern()); bajo el campo se pide a los visitantes que no introduzcan datos personales. En el navegador del visitante, mp_umfrage (localStorage) conserva, por encuesta, el resultado del sorteo de la muestra y el momento en que se mostró por última vez; para el botón del borde de la página, el momento de la última respuesta. |
| Dónde se almacena | La valoración en session_custom_events y session_custom_event_params (A.7); el texto libre en mp_umfrage_text (migración 157), deliberadamente separado: es la parte más sensible de una encuesta y no corresponde a la tabla de la que leen los webhooks y los puentes. Las propias encuestas, es decir, solo el texto del responsable, en projects.survey_json. |
| Base jurídica | Instrucción del responsable del tratamiento (art. 28(3)(a) del RGPD), dada al crear y activar una encuesta. Responder es voluntario. Corresponde al responsable determinar si existe una base jurídica para la pregunta y la pregunta complementaria y si se mencionan en su aviso de privacidad; el módulo de texto para clientes menciona la encuesta como elemento separado. No depende de ello ninguna decisión sobre el visitante. |
| Categorías de destinatarios | El cliente, en la vista de resultados y en el reproductor. La valoración es un evento personalizado y, por tanto, pasa a las transferencias que el responsable haya activado para esos eventos (4.1). El texto libre no pasa a ningún puente: mp_umfrage_text solo lo lee cfg/umfrage_lib.php. |
| Transferencia a terceros países | Ninguna, salvo mediante una transferencia activada por el responsable (4.1), y en ese caso solo la valoración. |
| Conservación | Con la sesión: mp_umfrage_text forma parte de mp_sitzungen_loeschen(), la vía de eliminación del reproductor, mp_konto_loeschen() y la eliminación de proyectos y espacios de trabajo en el panel; la valoración se elimina con session_custom_events. Deliberadamente no existe un plazo propio: sería más largo o más corto que el de la grabación, y ambas opciones serían incorrectas. La clave mp_umfrage del navegador se retira al retirar el consentimiento. |
A.22 Búsqueda de texto mostrado — qué visitas tuvieron un texto determinado en la página
| Campo | Entrada |
|---|---|
| Finalidad | El cliente encuentra las visitas en las que un texto determinado figuró en su página —al cargarla o mostrado después, como un mensaje de error, un aviso o “Agotado”— para ver sus grabaciones. La búsqueda está en el explorador de usuarios. |
| Categorías de interesados | Visitantes de sitios web de clientes cuya visita se grabó (A.2) y no se reconoce como automatizada. |
| Categorías de datos personales | Los fragmentos de texto que figuraban en la captura y en los cambios de la página (A.2), uno por nodo de texto, más su asignación a la vista de página. Lo que se lee ya se ha grabado: las zonas enmascaradas y las entradas de formularios ya están sustituidas allí y no se encuentran. Si la propia página muestra datos personales (una página de confirmación con nombre y dirección), también están aquí, como en la grabación. |
| Dónde se almacena | mp_text_block (diccionario por proyecto, cada fragmento de texto una vez), mp_text_pv (qué vista de página contenía qué fragmento) y mp_text_stand (qué vista se ha leído), migración 175. Lo rellena cada diez minutos srv/textsuche_lauf.php en nuestro propio servidor. |
| Base jurídica | Instrucción del responsable del tratamiento (art. 28(3)(a) del RGPD): la búsqueda permite acceder a la misma grabación que encargó el responsable. No depende de ello ninguna decisión sobre el visitante. |
| Categorías de destinatarios | El cliente, como filtro en el explorador de usuarios. Sin transferencia ni puente. |
| Transferencia a terceros países | Ninguna. |
| Conservación | 30 días desde el inicio de la vista de página, menos que la grabación: después se retiran la asignación y el estado, y un fragmento de texto se retira con su vista más reciente. Si la sesión se elimina antes (plazo de conservación, solicitud de supresión, eliminación en el reproductor, eliminación de proyecto o cuenta), la asignación se elimina con ella: directamente en mp_sitzungen_loeschen() y en la eliminación del proyecto; en todas las demás vías, como máximo tras diez minutos mediante la ejecución que retira asignaciones sin vista de página. |
4. Parte A — destinatarios, subencargados y transferencias a terceros países
La propia vía de grabación no contiene ninguna llamada de salida a terceros. Se estableció el 10/08/2026 mediante una búsqueda en cfg/, srv/, class/ y www/ (excluidos vendor y node_modules) de curl_init, curl_exec, file_get_contents con http, fsockopen y stream_context_create, y de todos los literales https. La geolocalización se resuelve con archivos locales de MaxMind, la hoja de estilo de la interfaz se sirve como archivo previamente compilado desde nuestro propio servidor y las imágenes de banderas proceden de /img/flags/. Desde el 23/09/2026 se envía correo mediante SMTP a través de Namecheap Private Email (mail.privateemail.com, puerto 465, TLS), con el remitente office@mouseplayer.com; la función PHP mail() solo se utilizaría si no hubiera ningún servidor SMTP configurado, lo que no ocurre. Límite de esta búsqueda: no se examinaron los directorios de proveedores (Stripe SDK, Google Cloud SDK, PHPMailer, Symfony); allí se encuentran los endpoints de los servicios enumerados a continuación.
| Destinatario | Función y qué se transfiere | Destino | Garantía | Estado |
|---|---|---|---|---|
| Stripe | Procesamiento de pagos para cuentas de CLIENTES. Correo electrónico, nombre, dirección de facturación y datos de pago de los clientes. www/billing_ajax.php:134 establece la clave de API; las líneas 381 y 687 transmiten customer_email; la línea 48 establece billing_address_collection='required'; la línea 54, customer_update para dirección y nombre; las líneas 462/527/672 transmiten metadatos. Canal de retorno www/api/webhook_stripe.php, tabla stripe_events. Ningún dato de visitantes. | EE. UU. | DPA aceptado el 01/08/2026 como parte de las condiciones aceptadas al abrir la cuenta (declaración del responsable del tratamiento). Parte contratante: Stripe Payments Europe, Ltd.; para transferencias a Estados Unidos, Stripe, Inc. Módulo 2 (de responsable a encargado del tratamiento). Se deriva de la distribución de funciones, no de una consulta: MousePlayer es el responsable de los datos de cuenta y facturación transmitidos, y Stripe el encargado de esa parte. No se ha examinado la propia versión aceptada; si difiere, prevalece. | A 16/10/2026 no está en funcionamiento real: ambos campos de claves contienen claves de prueba y no se procesan pagos reales. |
| VIES (Comisión Europea) | Verificación de un número de identificación a efectos del IVA proporcionado por un CLIENTE mediante la interfaz REST pública del Sistema de Intercambio de Información sobre el IVA (cfg/lib.php). Se transmiten el código de país y el número de IVA; se devuelven la validez y, cuando están disponibles, el nombre y la dirección de la empresa, y se almacenan con la cuenta (B.1). Ningún dato de visitantes. | UE | Organismo público de la Unión; no es encargado del tratamiento y no requiere contrato. La consulta sirve para verificar los datos fiscales del cliente. | En uso en cuanto un cliente introduce un número de IVA. |
| Telegram | Notificación de soporte. Hasta el 11/08/2026 cfg/lib.php transmitía TODO el caso de soporte: estado del usuario incluido el ID de usuario, dirección de correo electrónico, asunto, 'IP / Kraj' con la dirección IP SIN TRUNCAR, URL de origen y texto íntegro del mensaje. Desde el 11/08/2026 (commit 02846c2, cfg/lib.php) se envía una única cadena fija y nada más: 'MousePlayer: es liegt eine neue Supportanfrage vor.' Ni una sola variable, ningún parse_mode y, deliberadamente, ningún número de caso ni enlace tomado de la solicitud. La propia solicitud sigue almacenándose sin cambios en support_requests: los datos ya no salen, no desaparecen. | Fuera de la UE | Hasta el 11/08/2026: ninguna; Telegram no ofrece un acuerdo de tratamiento de datos para bots. Desde el 11/08/2026 no se requiere ninguno: la notificación no contiene datos personales, por lo que Telegram no es encargado del tratamiento ni destinatario. Decisión del propietario del 11/08/2026: se mantiene el canal, el mensaje se reduce a una señal mínima y se retira la dirección IP. Un control (ai/pruefstand/test_telegram_signal.php) comprueba no el resultado, sino la posibilidad: qué variables pueden llegar al mensaje; se permiten cuatro, se prohíben 15 atributos y el texto debe ser una cadena entre comillas simples sin interpolación. | ACTIVO, pero sin datos personales: mitigado el 11/08/2026. TELEGRAM_BOT_TOKEN y TELEGRAM_CHAT_ID siguen configurados en .env; solo sale la señal. |
| Google reCAPTCHA | Inicio de sesión, registro, formulario de soporte, página de facturación. Verificación del lado del servidor en www/login.php:31-45 y cfg/lib.php:6337 mediante https://www.google.com/recaptcha/api/siteverify; del lado del navegador en www/billing.php:1290. | EE. UU. | reCAPTCHA permanece en producción. Condiciones de tratamiento de datos de Google aceptadas el 01/08/2026 (declaración del responsable del tratamiento). Parte contratante: Google Ireland Limited; para transferencias a Estados Unidos, Google LLC. En el sistema de desarrollo, el servicio está desactivado (mp_recaptcha_aktiv() devuelve !mp_ist_dev()), en producción está activado: allí la transferencia se produce en cada acción de inicio de sesión, registro, contraseña y facturación. | Inactivo solo en esta instancia: mp_recaptcha_aktiv() se define en cfg/config.php:131-133 como !mp_ist_dev() y APP_ENV=dev. Activo en producción. |
| Google BigQuery | Exportación nocturna al proyecto PROPIO de GCP del cliente. srv/cron_integration_bigquery.php:95-100 selecciona 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 y los carga como NDJSON en visitor_sessions_YYYYMMDD. | Región elegida por el cliente | El destino es el proyecto propio del cliente, por lo que el cliente es el importador. La clave de la cuenta de servicio se almacena cifrada en projects.bigquery_sa_json (decrypt_sa_key, clave BIGQUERY_SA_AES_KEY de .env). | INACTIVO. projects.bigquery_active=0 para los 7 proyectos, bigquery_project_id NULL en todos y el proceso no está en ejecución. |
| Webhooks del cliente | srv/cron_integration_webhook.php:63-80. Cuerpo construido en srv/db_worker.php:1313-1323: timestamp, event_type, channel_id, session_id, un enlace directo al reproductor 'https://<host>/player?id=...&session=...' y los parámetros del evento. Formato especial para Slack y Discord (mp_format_webhook_body, cfg/lib.php:5978). | Indeterminado: establecido por el cliente | El destino lo elige el cliente y, por tanto, queda bajo la propia responsabilidad del responsable del tratamiento. Sí, el destino se registra por Cliente (decisión del responsable del tratamiento, 17/08/2026). Ya está en el proyecto; falta el registro de QUIÉN lo estableció y cuándo. Desde el 17/08/2026 cada cambio del destino del webhook aparece en el registro de cambios (log_audit, acción update_integrations, campo webhook_host). Solo se registra el host, no la dirección completa: una ruta de webhook suele contener un secreto —Slack y Discord colocan la clave en la URL— y un registro de cambios no es el lugar adecuado para ello. Para saber adónde salen los datos de eventos de nuestras instalaciones, basta con el host. | INACTIVO. projects.webhook_active=0 y webhook_url NULL para los 7 proyectos. El proceso de envío está en ejecución. |
| Meta (Conversions API) | Solo si el responsable activa el puente y almacena su propio token de acceso. Se transmiten exclusivamente objetivos cumplidos del proyecto correspondiente: nombre del objetivo, marca de tiempo, un identificador de evento derivado de la sesión y del objetivo para eliminar duplicados, valor y moneda cuando estén establecidos, más las cookies _fbp y _fbc y la cadena de agente de usuario. No se transmiten nombre, dirección de correo electrónico, número de teléfono ni dirección IP — MousePlayer solo dispone de una IP truncada, que no serviría para la correspondencia. El envío se realiza exclusivamente para sesiones con consent_state = 'granted'; sin _fbp/_fbc se omite por completo la transmisión, porque sin una clave de correspondencia no tendría ninguna utilidad. Código: mp_capi_meta_ausloesen() y mp_capi_meta_zustellen() en cfg/lib.php, envío mediante srv/cron_integration_webhook.php. | EE. UU. | Meta no es subencargado de MousePlayer. MousePlayer realiza la transmisión por instrucciones del responsable; esas instrucciones consisten en activar el puente y almacenar el token. El destinatario es la cuenta publicitaria propia del responsable; la relación contractual con Meta, incluidas las garantías para transferencias a Estados Unidos, existe entre el responsable y Meta, no entre Meta y MousePlayer. Meta trata los datos para sus propios fines y, en esa medida, como responsable independiente del tratamiento. | Puente disponible desde el 19/08/2026, activado para ningún proyecto en la configuración inicial. |
| HubSpot / Pipedrive | Solo si el responsable activa el puente y almacena su propio token de API. Se transmite el identificador de cliente que el propio responsable estableció (setUserId()), utilizado para localizar al contacto, seguido de una nota con la URL de reproducción de la sesión. Sin datos de comportamiento ni contenido de grabaciones. Si la búsqueda no encuentra ningún contacto, la operación termina sin ninguna transmisión adicional. Código: mp_crm_kontakt_suchen() y mp_crm_notiz_anhaengen() en cfg/lib.php. | Estados Unidos (HubSpot), UE (Pipedrive) | Como en Meta: el destinatario es la cuenta propia de CRM del responsable, y la relación contractual existe entre este y el proveedor. MousePlayer transmite por sus instrucciones. | Puente disponible desde el 19/08/2026, activado para ningún proyecto en la configuración inicial. |
| Google Cloud Storage (Varsovia) | Copia externa de la copia diaria de seguridad. Documentada en OFFENE_PUNKTE.md, apartado 3.3: 'mysqldump --all_databases' y 'tar /var/www/': todas las bases de datos y todo el árbol web, incluido cada archivo .env. Acreditada localmente con 653 MB de base de datos y 678 MB de archivos. Hasta el 11/08/2026 la copia de seguridad se ejecutaba a diario a las 02:00 y salía sin cifrar. Desde el 11/08/2026 se cifra en nuestro propio servidor antes de transferirse (rclone crypt; los nombres de archivos y directorios también se cifran), y los dos archivos de claves se conservan en ese mismo servidor con modo 600; Google no los tiene; desde entonces, la ejecución programada se realiza a las 03:00. La carpeta de destino anterior sin cifrar, que contenía las copias anteriores al 11/08/2026, se eliminó el 12/08/2026. | Polonia (UE) – bucket en la región europe-central2 (Varsovia), desde el 05/09/2026. Hasta entonces, la copia se conservaba en una cuenta privada de Google Drive para la que no se puede contratar una región de datos; el destino debía indicarse como Estados Unidos / todo el mundo. | Tratamiento por nuestra cuenta al amparo del Google Cloud Data Processing Addendum, aceptado para el proyecto de Cloud; parte contratante Google Ireland Limited. Esto elimina la desviación indicada aquí del 17/08/2026 al 05/09/2026: esas condiciones no están disponibles para una cuenta privada de Google y las condiciones generales de uso no establecen un tratamiento por cuenta ajena conforme al art. 28 del RGPD. La copia se sigue cifrando antes de transferirse (rclone crypt, incluidos los nombres de archivos y directorios) y las claves están exclusivamente en poder del responsable — Google ve bloques sin significado. Eso retira el contenido de Google, no su función. | ACTIVO. Hasta el 11/08/2026, sin cifrar y sin verificación en destino: la ejecución utilizaba la configuración de rclone de root y el script no registraba nada. Desde el 11/08/2026, cifrada; las ejecuciones del 11/08/2026 (iniciada manualmente) y del 12/08/2026 (programada, a las 03:00) están registradas y ambas superaron una comprobación en destino (número de bytes del volcado de la base de datos). Por tanto, el funcionamiento diario está acreditado, no solo el primer intento. El operador ha probado el descifrado; no existe una medición propia de ello. La carpeta de destino anterior sin cifrar se eliminó el 12/08/2026. Desde el 05/09/2026, la copia se envía a Google Cloud Storage en Varsovia; las copias conservadas anteriormente en la cuenta de Drive se eliminaron el 06/09/2026, después de verificar una restauración desde el nuevo destino. Por tanto, el tipo de cuenta, la región de datos y el contrato están resueltos. Desde el 06/10/2026, la copia de seguridad también contiene el archivo de los eventos de grabación trasladados (/mnt/mouseplayer-dev-archive, A.1); localmente, este archivo está en el mismo disco que el sistema y solo la copia cifrada proporciona almacenamiento en otra ubicación. Se realizaron pruebas de restauración desde la copia el 05/09/2026 y el 06/09/2026 y el 07/10/2026 (restauración completa de los datos). Las copias diarias se conservan durante 7 días y las semanales durante 364 días. |
| Namecheap | Registro de dominios, DNS autoritativo, reenvío de correo entrante; desde el 23/09/2026, también envío de correo saliente mediante Namecheap Private Email. Datos de dominio; contenido y remitente de correos dirigidos a MousePlayer. Para el correo saliente: nombre, dirección de correo electrónico y contenido del mensaje al titular de la cuenta; para el aviso de inicio de sesión, también dirección IP, dispositivo y ubicación aproximada. | EE. UU. | Data Processing Addendum aceptado el 01/08/2026 (declaración del responsable del tratamiento); cubre las cláusulas contractuales tipo vigentes. El correo entrante pasa permanentemente por el reenvío de Namecheap; no interviene ningún otro proveedor de buzón (decisión del responsable del tratamiento, 17/08/2026). Desde el 23/09/2026, el correo saliente se envía mediante el servicio SMTP de Namecheap Private Email (TLS): avisos contractuales, avisos de cuenta, avisos de inicio de sesión y alertas de los monitores. | En uso. |
| Let's Encrypt (ISRG) | Emisión y renovación de certificados TLS. Solo nombres de dominio. | EE. UU. | Autoridad de certificación pública; no trata datos personales por nuestra cuenta. | En uso. |
| consented.eu | CMP en las páginas PROPIAS de MousePlayer, cargada en el navegador del visitante: cfg/header.php:48 (stub.js) y línea 50 (cmp.js). Se refiere a visitantes de mouseplayer.com, no a la grabación en los sitios de los clientes. | Lugar de tratamiento: el mismo servidor que MousePlayer (/var/www/html/ConsentedEU en la misma máquina, medido el 17/08/2026). Base contractual: no es aplicable; consented.eu lo opera la misma entidad jurídica (declaración del responsable del tratamiento). No hay transferencia a un tercero. | No es aplicable por el mismo motivo: no hay tercero ni, por tanto, acuerdo. | En uso en las páginas propias. |
Alojamiento: no es aplicable — operado por nosotros en hardware propio mediante la conexión de Toya (AS16342, Łódź), sin transferencia a terceros (decisión del responsable del tratamiento, 17/08/2026); si la operación se traslada a un centro de datos o proveedor de nube, debe reescribirse este párrafo. El hardware propio comprende el servidor que ejecuta la aplicación, la base de datos y la grabación, y las máquinas con tarjeta gráfica que ejecutan el modelo de lenguaje — actualmente una, que ejecuta nuestra propia IA, alojada por nosotros en nuestro propio hardware. Todas están en la misma ubicación y red local y pertenecen a MousePlayer; lo mismo se aplica a cualquier máquina adicional. Obtienen los hallazgos calculados mediante HTTPS desde ai_ki_queue, con cada solicitud firmada con su propio secreto, y devuelven el texto redactado. La propia grabación nunca llega a ellas y no se envía nada a un servicio externo de IA (A.8, A.12, A.15, A.17). Mientras una de esas máquinas está parada por mantenimiento, las tareas esperan a que vuelva; entretanto, la interfaz muestra la versión calculada y no se deriva ninguna tarea a otro servicio.
4.1 Destinatarios activados por el responsable del tratamiento
La tabla anterior enumera los destinatarios que contrata el propio MousePlayer. Junto a ellos existen puentes que el responsable del tratamiento activa y para los que almacena sus propias credenciales. No son subencargados de MousePlayer; la relación contractual existe entre el responsable y el destinatario, incluidas las garantías para terceros países. Lo que se indica son categorías en lugar de proveedores — los proveedores disponibles dentro de una categoría cambian con las funciones; lo determinante es la selección en la configuración del proyecto. Cada transmisión se inicia del lado del servidor desde srv/cron_integration_webhook.php; el resultado se registra en el registro de entregas (A.11).
| Categoría | Qué sale | Qué lo desencadena |
|---|---|---|
| Webhook a una dirección elegida libremente | Nombre del evento, ID de canal y sesión, URL de reproducción, parámetros del evento. Firmado con HMAC-SHA256 sobre la marca de tiempo y el cuerpo. | un evento al que se ha suscrito el responsable |
| Sistema de relación con clientes (CRM) | El ID de cliente que el propio responsable asignó al visitante, más la URL de reproducción, adjuntos como nota a un contacto existente. Si no existe ningún contacto, no se crea ninguno. | fin de sesión con un ID de cliente establecido |
| Asistencia y gestión de incidencias | El mismo elemento como nota interna en la incidencia abierta más reciente del remitente. Si no hay ninguna incidencia abierta, no ocurre nada. | fin de sesión con un ID de cliente establecido |
| Marketing por correo electrónico y de ciclo de vida | ID de cliente, nombre de evento y URL de reproducción como evento en el sistema del responsable. | fin de sesión con un ID de cliente establecido |
| Redes publicitarias (Conversions API) | El ID de clic de la cookie propia de la red publicitaria, nombre del evento, valor y moneda. Nombre, dirección de correo electrónico, número de teléfono y dirección IP no se transmiten. | un objetivo cumplido con consentimiento otorgado |
| Almacenamiento de objetos y hojas de cálculo | ID de cliente, marca de tiempo y URL de reproducción como objeto o fila en el almacenamiento propio del responsable. | fin de sesión con un ID de cliente establecido |
| Seguimiento de incidencias y tareas | Título y descripción de un elemento que contiene la URL de reproducción. | una señal de frustración o un error de JavaScript |
| Los agentes de IA del responsable mediante el servidor MCP | Solo lectura: proyectos, cifras clave, listas de sesiones con enlace a la reproducción, sesiones individuales con vistas de página y eventos, páginas, señales de frustración y objetivos, pero no la captura de página. La autenticación utiliza una clave de lectura de la API REST del responsable. | una consulta del agente, solo cuando el acceso está habilitado para el proyecto (projects.mcp_active) y con un plan de pago |
Transferencia a terceros países: indeterminada. El responsable elige el destino y el proveedor; por tanto, le corresponden las garantías del capítulo V del RGPD. En ningún caso se transmite el contenido grabado de las páginas, la trayectoria del ratón ni el texto de formularios: los puentes transmiten identificadores y nombres de eventos, no la reproducción.
5. Parte B — Art. 30(1): actividades realizadas como responsable del tratamiento
Responsable de todo lo contenido en esta parte: LW IT Solutions Company Lukas Wójcik, al. Tadeusza Kościuszki 80/82 lok. 301, 90-437 Lodz, Poland, office@mouseplayer.com. No se requiere representante (establecido en la Unión). No se ha designado delegado de protección de datos: apartado 9. Medidas técnicas y organizativas: apartado 8.
B.1 Cuentas de clientes, espacios de trabajo y facturación
| Campo | Entrada |
|---|---|
| Finalidad | Gestionar las cuentas de los propios clientes de MousePlayer, los espacios de trabajo y la facturación. |
| Categorías de interesados | Usuarios clientes. Medido: 4 cuentas; workspace_users, 4 propietarios, 1 administrador, 1 lector. |
| Categorías de datos personales | Correo electrónico, correo normalizado, nombre y apellidos, tipo de empresa, tipo de cuenta (empresa o consumidor, customer_type), idioma, tema. Datos de empresa: nombre y dirección de la empresa, país y número de identificación a efectos del IVA junto con el resultado, momento y origen de la comprobación, y nombre y dirección según VIES. Logotipo de empresa (nombre de archivo y momento; el propio archivo fuera del directorio web). Hash de contraseña, tokens de verificación y restablecimiento, caducidad del restablecimiento. Inicio de sesión en dos pasos (TOTP, migración 132): el secreto cifrado, el último paso temporal utilizado, el momento de configuración y los códigos de recuperación con hash. Interruptor de la notificación de inicio de sesión (login_alert, B.7). Identificador de dispositivo (device_id), indicador de sospecha is_suspicious. Última dirección IP COMPLETA, país, ciudad, número de ASN y organización del ASN. Datos de facturación: plan, moneda, ID de cliente de Stripe, suscripción de Stripe, período de facturación, estado, cancelación al final del período. Momento de una advertencia de inactividad. Historial de IP por usuario. |
| Dónde se almacena | 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 filas, 0 de ellas truncadas. workspace_users (workspace_id, user_id, role); workspace_invites (token, workspace_id, email, role, invited_by, created_at). Mencionados además en users desde esta versión: 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. Recuentos de filas de esta entrada: a 10/08/2026. |
| Base jurídica | No documentada en el código. Art. 6(1)(b) para ejecutar el contrato (cuenta, espacio de trabajo, facturación) y art. 6(1)(c) para la conservación legal de facturas (decisión del responsable del tratamiento, 17/08/2026). El plazo figura en la fila de conservación. |
| Categorías de destinatarios | Stripe (facturación, véase el apartado 4). VIES de la Comisión Europea (verificación del número de IVA, apartado 4). Namecheap Private Email como servicio de envío de correos al titular de la cuenta: confirmación de cuenta, restablecimiento de contraseña, invitaciones, notificación de inicio de sesión, advertencia previa a la eliminación por inactividad, aviso de cambios en documentos contractuales, informe semanal, respuestas de soporte (apartado 4). Los miembros del mismo espacio de trabajo ven el nombre, correo electrónico y rol de los demás miembros, así como el tipo de cuenta del espacio de trabajo, es decir, el de su propietario (cláusula 6.6 de los Términos del servicio), y el logotipo de empresa del propietario; una persona invitada ve este logotipo mediante el enlace de invitación mientras esta permanece abierta. |
| Transferencia a terceros países | Stripe (Estados Unidos) y Namecheap (Estados Unidos); partes contratantes y garantías en el apartado 4. VIES está situado en la Unión. |
| Conservación | Íntegramente al terminar la cuenta, que termina incluso sin actuación del propietario. Si este solicita la eliminación en la configuración de la cuenta, mp_konto_loeschung_ausfuehren() (cfg/lib.php) elimina, entre otros, user_ip_history, live_tokens, login_sessions, remember_tokens, report_subscriptions, los contadores de la cuota de grabación, api_keys, workspace_invites, workspace_users, workspaces y users; audit_logs, bot_review_labels y las entradas de mp_loesch_archiv se despersonalizan. Desde el 07/10/2026 (migración 189), esta vía archiva primero: se suspende la cuenta, se revocan los inicios de sesión, se ocultan sus propios espacios de trabajo y proyectos y dejan de grabarse; lo que puede restaurarse se conserva en mp_loesch_archiv. Tras 30 días – o inmediatamente si el propietario así lo decide – el db_worker suprime definitivamente mediante la cadena mencionada arriba y después cuenta si queda algo. Una cuenta suprimida definitivamente no deja ni identificador ni nombre en el archivo. Si el propietario permanece inactivo, la ejecución diaria advierte tras 24 meses sin iniciar sesión y elimina 30 días después mediante la misma cadena. El plazo se cuenta desde el último inicio de sesión o desde el registro para una cuenta nunca utilizada. La eliminación solo sigue a una advertencia que se haya entregado; si falla el envío, el plazo no comienza. Ambos valores están en site_settings y son configurables en el área de administración. Las facturas y los registros contables asociados se conservan durante cinco años, contados desde el final del año natural en el que venció el plazo de pago del impuesto (declaración del responsable del tratamiento, 17/08/2026: "5 lat, licząc od końca roku kalendarzowego, w którym upłynął termin płatności podatku"). Por tanto, los datos de facturas quedan exentos de la eliminación de la cuenta; los demás campos de la cuenta se eliminan con ella. Desde el 16/10/2026 solo se advierte y elimina por inactividad a cuentas del plan gratuito: plan propio free y sin pertenencia a un espacio de trabajo cuyo propietario tenga un plan de pago. Esta eliminación no archiva primero, sino que elimina directamente mediante la cadena mencionada arriba. El logotipo de empresa se elimina con la cuenta, como último paso de la eliminación. |
| Logotipo de empresa (desde el 07/10/2026) | El cliente puede subir un logotipo en la configuración (PNG, JPEG, WebP). No se almacena el archivo entregado, sino una imagen redibujada en el servidor, fuera del directorio web (daten/firmenlogos/, migración 184). Es visible para la propia cuenta, el superadministrador, los miembros de los espacios de trabajo propiedad de la cuenta y las personas invitadas mediante el enlace de invitación mientras esta permanece abierta; todas las demás solicitudes reciben la misma respuesta que para un logotipo inexistente. |
| Exportación de cuenta (art. 15(3), art. 20 del RGPD) | Después de introducir su contraseña, el titular de la cuenta puede descargar desde la configuración un archivo ZIP con los datos de su cuenta en JSON y el logotipo de empresa. Las tablas se determinan a partir del esquema (columnas que se refieren a la cuenta); se excluyen secretos como el hash de contraseña, los tokens y el secreto TOTP. Los intentos fallidos se cuentan en el registro de cambios y bloquean la exportación tras cinco intentos en 15 minutos. El archivo se crea solo como archivo temporal para su entrega. |
| Otros datos de cuenta (a 16/10/2026) | legal_acceptances: aceptación de los documentos contractuales (incluidos el aviso de desistimiento y la solicitud de inicio inmediato) y avisos de cambios entregados, cada uno con cuenta, dirección IP completa, identificador del navegador, idioma, sumas de comprobación de las versiones y origen de la entrada; la aceptación más reciente (no los avisos) de una cuenta existente se conserva mientras exista la cuenta, para poder demostrar qué versión aceptó un cliente actual (desde el 16/10/2026); las aceptaciones anteriores, los avisos y las filas de cuentas eliminadas se eliminan 730 días después de la respectiva aceptación o aviso (el responsable tiene pendiente clasificar la base jurídica de la conservación tras el fin de la cuenta). report_subscriptions: suscripción al informe semanal con token de baja y último envío; se elimina con la cuenta. workspace_transfers: transferencia de un espacio de trabajo a una dirección de correo electrónico con token y caducidad; se elimina con el espacio de trabajo. mp_dashboards: paneles propios de una cuenta por proyecto; se eliminan con la cuenta o el proyecto. SSO de Enterprise (sso_providers, sso_identities, sso_requests, sso_assertions, sso_policies, migraciones 187 y 188): la configuración del proveedor de identidad elegido por el propietario del espacio de trabajo está cifrada; por cuenta solo se conserva un hash del identificador en el proveedor, solicitudes de inicio de sesión válidas durante cinco minutos; el servidor llama a los endpoints de ese proveedor y el destinatario es el proveedor elegido por el cliente. A 16/10/2026, ningún espacio de trabajo tiene configurado un proveedor. Cuota de grabación (mp_aufnahme_monat, mp_aufnahme_sitzung, migración 178): contadores por propietario y mes; por sesión, solo un hash del identificador de proyecto y sesión; una ejecución diaria elimina los hashes de meses anteriores y los contadores se eliminan con la cuenta. |
B.2 Registros de acceso, seguridad y auditoría del portal
| Campo | Entrada |
|---|---|
| Finalidad | Registrar accesos, seguridad y cambios del portal propio de MousePlayer. |
| Categorías de interesados | Visitantes y usuarios de mouseplayer.com y www.mouseplayer.com. |
| Categorías de datos personales | Dirección IP COMPLETA, agente de usuario, ruta completa de la solicitud, país, ciudad, tipo de dispositivo, sistema operativo, navegador, ASN. Eventos de seguridad con IP parcialmente truncada: WSS_CONNECT 1261, url_excluded 71, consent_blocked 24. Registro de cambios: usuario, espacio de trabajo, acción, objetivo, detalles como JSON, IP. |
| Dónde se almacena | 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) — el 10/08/2026, 36409 filas, 8,5 MB, sin valores de IP truncados. Desde el 17/08/2026, log_mouseplayer_traffic() (cfg/lib.php) solo coloca una fila sin procesar por solicitud en la cola de Redis queue:traffic_logs; la resolución de GeoIP y ASN, la clasificación del navegador y dispositivo y la escritura —incluidos users.last_ip y los campos de ubicación de la cuenta— las realiza el db_worker. La dirección se determina mediante getBestClientIP(); solo se confía en las cabeceras cuando la conexión procede del nginx situado delante. security_access_logs (id, ip_address, user_agent, event_type, details, created_at) — el 10/08/2026, 1354 filas, 350 de ellas truncadas. audit_logs (log_id, user_id, workspace_id, action, target_id, details, ip_address, created_at) — el 10/08/2026, 666 filas, sin truncar. banned_ips (ip_address, scope, reason, banned_at, expires_at). |
| Base jurídica | No documentada en el código. El único razonamiento registrado es el comentario de class/Server.class.php:421-425, que distingue la regla A (dirección completa, para acceso DIRECTO a nuestra propia aplicación) de la regla B (truncada, para datos de visitantes). Explica la decisión de diseño, pero no es una base jurídica. Art. 6(1)(f). Finalidad: defensa frente a abusos y responsabilidad proactiva (confirmado por el responsable del tratamiento, 17/08/2026). Ponderación: sin registros no puede detectarse un ataque ni determinarse después quién hizo un cambio. No hay un medio menos intrusivo que logre lo mismo: un registro anonimizado pierde precisamente la atribución en cuestión. La injerencia se limita mediante los plazos (72 horas para el registro de seguridad, 60 días para el registro de acceso, 60 días para el registro de cambios) y porque los registros solo afectan al acceso a la propia aplicación, no a los visitantes grabados. Los afectados son usuarios Clientes que utilizan deliberadamente el servicio y esperan que se registren sus acciones administrativas. |
| Categorías de destinatarios | El propio MousePlayer. audit_logs también es visible para el superadministrador (www/admin.php). |
| Transferencia a terceros países | Ninguna. |
| Conservación | mouseplayer_logs: 60 días. security_access_logs: 72 horas. banned_ips: al caducar expires_at; las entradas establecidas manualmente sin caducidad permanecen hasta que el operador las levanta. audit_logs: 60 días, nuevo desde el 17/08/2026. user_ip_history: 90 días desde la última vez que se observó una dirección, nuevo desde el 24/09/2026; como máximo, hasta la eliminación de la cuenta. Todos los valores están en site_settings y son configurables en el área de administración. Que el registro de cambios sobreviva al de seguridad es deliberado: el registro de acceso responde a quién estuvo allí; el de cambios, a quién modificó algo. Este último es el registro de responsabilidad proactiva conforme al art. 5(2) y debe sobrevivir a una controversia que solo salga a la luz meses después. |
B.3 Solicitudes de soporte
| Campo | Entrada |
|---|---|
| Finalidad | Recibir y tramitar solicitudes de soporte. Desde el 30/09/2026, esto incluye que un modelo de lenguaje en nuestro propio hardware traduzca un mensaje y prepare un borrador de respuesta; una persona revisa y envía cada borrador. |
| Categorías de interesados | Personas que presentan una solicitud, hayan iniciado sesión o no. |
| Categorías de datos personales | Dirección de correo electrónico, asunto, texto libre del mensaje. Dirección IP COMPLETA: REMOTE_ADDR, sobrescrita con HTTP_X_FORWARDED_FOR, sin truncar. Agente de usuario, URL de origen. El campo de código de país se lee de la cabecera HTTP_CF_IPCOUNTRY; como no hay Cloudflare delante, siempre contiene el valor de reserva XX o nada. |
| Dónde se almacena | support_requests (id, user_id, channelid, email, reason, message, status, ip_address, user_agent, source_url, country_code, created_at). Desde el 30/09/2026, también mp_support_ki: una fila por tarea (traducción, borrador, traducción de nuestro propio borrador) con el texto preparado para el modelo, el resultado, el nombre del modelo y la duración; vinculada a la solicitud mediante una clave foránea. |
| Base jurídica | Art. 6(1)(b) cuando quien pregunta es un cliente y la solicitud se refiere a la ejecución del contrato; en los demás casos, art. 6(1)(f). La dirección IP completa se basa en el mismo fundamento: sirve para defender el canal de soporte frente a abusos. Sin ella no pueden detectarse ni detenerse envíos masivos o repetidos, amenazas y otros perjuicios, y una dirección truncada no permite esa distinción. Decisión del responsable del tratamiento, 17/08/2026. |
| Categorías de destinatarios | Hasta el 11/08/2026: Telegram. cfg/lib.php enviaba a api.telegram.org el estado del usuario, dirección de correo electrónico, asunto, dirección IP SIN TRUNCAR con país, URL de origen y texto íntegro del mensaje. Desde el 11/08/2026: ninguno. Lo único que llega a api.telegram.org es la cadena fija 'MousePlayer: es liegt eine neue Supportanfrage vor.', sin ninguna variable; por tanto, Telegram no recibe datos personales y no es destinatario. La propia solicitud permanece sin cambios en support_requests. Modelo de lenguaje (desde el 30/09/2026): ninguno. Se ejecuta en nuestras propias máquinas con tarjeta gráfica, en la misma red local y ubicación que el servidor; obtienen la tarea mediante HTTPS, con cada solicitud firmada con su propio secreto. Reciben el texto del mensaje, el asunto, si quien pregunta tiene una cuenta y la ruta de la página de origen – las direcciones de correo electrónico y las secuencias de seis o más dígitos se sustituyen previamente (mp_supki_saeubern() en cfg/support_ki_lib.php), en nuestro propio borrador solo las direcciones de correo electrónico. No la dirección IP ni la dirección de correo electrónico de quien pregunta. Ningún servicio externo de IA, ni siquiera como alternativa de reserva. |
| Transferencia a terceros países | Hasta el 11/08/2026: Telegram, fuera de la UE; no se ofrece ningún acuerdo de tratamiento de datos para bots: véase el apartado 4. Desde el 11/08/2026: ninguna. La notificación a api.telegram.org ya no contiene datos personales, por lo que no se produce ninguna transferencia a un tercer país. El canal sigue existiendo como señal mínima: véase el apartado 4. |
| Decisión automatizada | Ninguna. El modelo solo propone texto; no se envía nada automáticamente – una persona lee el borrador, lo modifica cuando es necesario y lo envía. No es una decisión en el sentido del art. 22 del RGPD. |
| Conservación | 730 días, aplicado por la ejecución diaria en srv/db_worker.php; el valor está en site_settings bajo retention_evidence_days y es configurable en el área de administración. Al eliminar la cuenta, la solicitud permanece, pero pierde su vínculo con la cuenta (user_id pasa a NULL); la política de privacidad lo indica expresamente. Las filas de mp_support_ki se eliminan con su solicitud (ON DELETE CASCADE, migración 168), en todas las vías de eliminación. |
B.4 Aceptación por el cliente de las reglas regionales de grabación
| Campo | Entrada |
|---|---|
| Finalidad | Acreditar la aceptación por el cliente de las reglas regionales de grabación: una declaración contractual. |
| Categorías de interesados | Usuarios clientes. |
| Categorías de datos personales | ID de usuario, correo electrónico, regiones, versión del texto, suma de comprobación del texto, idioma. Dirección IP COMPLETA y agente de usuario: deliberadamente, y la razón consta en ai/migrations/018_consent.sql: es la aceptación de un contrato por una contraparte comercial, no datos de visitantes. |
| Dónde se almacena | 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 filas. |
| Base jurídica | Prueba de una declaración contractual, tal como se razona en la cabecera de la migración. |
| Categorías de destinatarios | El propio MousePlayer. |
| Transferencia a terceros países | Ninguna. |
| Conservación | 730 días desde la aceptación: el mismo plazo que los demás registros de consentimiento a condiciones (support_requests, legal_acceptances; para legal_acceptances la aceptación más reciente de una cuenta existente se conserva más allá de ese plazo, véase B.1), porque responden a la misma pregunta: quién aceptó qué y cuándo. El valor está en site_settings bajo retention_evidence_days; lo aplica la ejecución diaria en srv/db_worker.php. |
B.5 Visitantes de nuestro propio sitio web
| Campo | Entrada |
|---|---|
| Finalidad | Funcionamiento del propio mouseplayer.com: diálogo de consentimiento, defensa frente a accesos automatizados, demostración en la página de inicio y registros del servidor web. |
| Categorías de interesados | Visitantes de mouseplayer.com. |
| Categorías de datos personales | Dirección IP — sin truncar en los registros del servidor—, momento, dirección solicitada, código de estado, identificación del navegador. Para la demostración, además, posiciones del puntero y de los clics, un identificador de sesión asignado aleatoriamente y el país derivado de la dirección. Para reCAPTCHA, la dirección más características de dispositivo y comportamiento. |
| Dónde se almacena | Registros de acceso de nginx (/var/log/nginx/) y Apache, ambos con la dirección completa, logrotate diario con 14 rotaciones. Desde el 16/08/2026, nginx es la primera capa que ve una dirección de visitante; Apache está detrás de él en el bucle local y la recibe mediante el protocolo PROXY o X-Forwarded-For. Los datos de la demostración no se almacenan; solo se transmiten en el momento. |
| Base jurídica | Demostración: consentimiento, art. 6(1)(a); su control está en vigor desde el 17/08/2026. reCAPTCHA y registros del servidor: interés legítimo, art. 6(1)(f). Art. 6(1)(f). Finalidad: defensa frente a abusos y responsabilidad proactiva (confirmado por el responsable del tratamiento, 17/08/2026). reCAPTCHA: sin protección frente a accesos automatizados, las páginas de inicio de sesión, registro, formulario de soporte y facturación quedan expuestas a ataques. El medio menos intrusivo —un simple límite de frecuencia— también está en vigor desde el 17/08/2026, pero no sustituye completamente a la puntuación. Registros del servidor: la dirección sin truncar es necesaria para atribuir accesos repetidos o masivos al mismo remitente; una dirección truncada no permite esa distinción. La injerencia está limitada por el plazo de 14 días y porque los registros no se combinan con otros datos. |
| Categorías de destinatarios | Google Ireland Limited (reCAPTCHA) y consented.eu (diálogo de consentimiento). Para la demostración, además, los demás visitantes que tienen abierta la página de inicio en el mismo momento: ven el puntero y el país, no la dirección. |
| Transferencia a terceros países | Estados Unidos mediante reCAPTCHA; base y fecha de aceptación, véase el apartado 4. |
| Conservación | Registros del servidor, 14 días. La demostración no almacena nada. |
Esta entrada faltaba hasta el 17/08/2026, aunque el apartado 4 ya mencionaba el diálogo de consentimiento y reCAPTCHA como destinatarios: el tratamiento correspondiente no figuraba en ninguna parte. La política pública de privacidad se amplió ese mismo día para cubrir la misma materia (su apartado 10); ambos textos deben leerse contrastándolos.
B.6 Accesos a un enlace para compartir
| Campo | Entrada |
|---|---|
| Finalidad | Prueba de con qué frecuencia y desde dónde se utilizó un enlace para compartir. Un enlace así abre una grabación completa sin iniciar sesión; sin este registro no puede determinarse después con qué frecuencia se utilizó o si salió del círculo previsto. |
| Categorías de interesados | Personas que abren un enlace para compartir: normalmente personal del Cliente o destinatarios elegidos por él. No los visitantes grabados; son personas distintas. |
| Categorías de datos personales | Dirección IP de quien accede (sin truncar), identificación del navegador, momento, identificador del enlace. |
| Dónde se almacena | share_views (migración 043), vinculado a session_shares mediante una clave foránea con ON DELETE CASCADE. |
| Base jurídica | Art. 6(1)(f). Finalidad: defensa frente a abusos: un enlace sin inicio de sesión es precisamente el tipo de dirección que se reenvía. Ponderación: no existe un medio menos intrusivo: una dirección truncada no permite responder a si dos accesos proceden del mismo lugar y, sin ella, el reenvío no puede detectarse ni probarse. La injerencia está estrictamente limitada: no afecta a la persona grabada, sino a quien accede, y la fila desaparece con el enlace. Los afectados son personas que abren un enlace a la grabación de otra persona y deben contar con que se registre ese acceso. (decisión del responsable del tratamiento, 17/08/2026) |
| Categorías de destinatarios | Ninguno. El registro no sale de nuestra propia base de datos. |
| Transferencia a terceros países | Ninguna. |
| Conservación | Con el enlace. Cuando caduca o se revoca, el registro se elimina con él mediante la clave foránea. Un enlace tiene una duración máxima de 90 días, 7 por defecto; la aplicación no puede crear uno de mayor duración. |
Que la fila desaparezca con el enlace no es aquí una comodidad, sino la mitad de la base jurídica: un registro que sobrevive al enlace ya no tiene una finalidad que lo ampare.
B.7 Inicios de sesión activos y su revocación
| Campo | Entrada |
|---|---|
| Finalidad | Mostrar al titular de la cuenta dónde está iniciada su sesión y permitirle finalizar la de un dispositivo o las de todos los demás. Sin esta lista no puede detectarse ni finalizarse un inicio de sesión secuestrado: hasta el 28/08/2026, un cambio de contraseña solo invalidaba las cookies de “mantener la sesión iniciada”, mientras que las sesiones en curso seguían existiendo como archivos — entre 24 y 54 minutos, según la medición. |
| Categorías de interesados | Titulares y miembros de una cuenta de cliente. No los visitantes grabados; son dos personas distintas. |
| Categorías de datos personales | Dirección IP (sin truncar), agente de usuario y, derivados de él, navegador, sistema operativo y tipo de dispositivo; ubicación aproximada (ciudad y país) a partir de la dirección; momento del inicio de sesión y de la última actividad. No se almacena el propio identificador de sesión, solo su hash SHA-256. Junto a él, una huella de dispositivo — un hash del navegador, sistema operativo, tipo de dispositivo y rango de direcciones (/24 o /48, nunca la dirección completa), mediante el que se reconoce un dispositivo ya conocido. |
| Dónde se almacena | login_sessions (migración 094), vinculado mediante remember_selector a remember_tokens (migración 037). |
| Base jurídica | Art. 6(1)(b) en relación con el art. 32. Finalidad: seguridad de la cuenta — este tratamiento es la medida técnica, no un subproducto de ella. Ponderación: no existe un medio menos intrusivo. Una dirección truncada falla precisamente en la pregunta para la que existe la lista (“¿fui yo?”) y, sin navegador y ubicación, no puede distinguirse una fila de otra. Los datos se generan de todos modos en cada inicio de sesión; lo único nuevo es que se hacen visibles y revocables. Solo son visibles para el titular de la cuenta. |
| Categorías de destinatarios | Ninguno. La lista no sale de nuestra propia base de datos. |
| Transferencia a terceros países | Ninguna. |
| Conservación | 90 días desde la última actividad, e íntegramente al terminar la cuenta. El punto de partida es la última actividad y no la creación: un dispositivo con la sesión iniciada desde hace meses pero utilizado ayer es un inicio de sesión actual y corresponde a la lista. |
Desde el 28/08/2026, los mismos datos producen además un aviso al titular de la cuenta cuando su cuenta se abre desde un dispositivo que no había aparecido antes. Se envía a la propia dirección del interesado que consta en el sistema y a nadie más; no añade ningún destinatario en el sentido del art. 4(9). Cualquier cuenta puede desactivarlo en la configuración sin perder la propia lista — el valor por defecto es activado, porque un aviso de seguridad que primero hay que habilitar no llega precisamente a quienes lo necesitan. La huella se basa deliberadamente en el rango de direcciones, no en la dirección completa: un hogar recibe una IP distinta al reconectarse cada noche y, con la dirección completa, llegaría un aviso cada mañana — la señal carecería de valor y, con ella, el aviso.
Hay que explicar dos decisiones. Lo que se almacena es el hash del identificador de sesión y nunca el propio identificador: de otro modo, un volcado de la base de datos entregaría cookies de sesión válidas, y un volcado en manos equivocadas es precisamente el caso contra el que se construye esta tabla. Además, una fila revocada no se elimina, sino que se marca como revocada — una fila eliminada sería una sesión desconocida para la comprobación que se ejecuta en cada solicitud, y una desconocida puede volver a escribirse. La revocación se habría deshecho a sí misma.
B.8 Alertas operativas y correos retenidos (urgent_logs)
| Campo | Entrada |
|---|---|
| Finalidad | Alertas operativas para el superadministrador: fallos detectados por los supervisores en srv/cron_status.php, casos dudosos de la revisión de bots (A.19), anomalías de un proyecto en lugar de correo electrónico si así lo elige el superadministrador, y correos salientes retenidos por una lista de bloqueo. El bloqueo impide enviar correos a direcciones propias incluidas en la lista o a dominios reservados de prueba y ejemplo; el correo retenido se almacena aquí para que siga siendo trazable qué se habría enviado. |
| Categorías de interesados | Usuarios clientes y otros destinatarios de un correo retenido; indirectamente, visitantes cuyo ID de sesión aparece en una alerta de revisión de bots. |
| Categorías de datos personales | Origen, asunto, texto de la alerta, momentos de creación, última repetición, resolución y envío de correo. Para un correo retenido, dirección del destinatario y texto íntegro del correo en claro: según su tipo, por ejemplo, nombre y dirección de correo electrónico y, para una notificación de inicio de sesión, además dirección IP, dispositivo y ubicación aproximada. |
| Dónde se almacena | urgent_logs (id, quelle, betreff, meldung, erstellt_am, zuletzt_am, erledigt_am, mail_status, mail_am, stoerung_beendet_am). |
| Base jurídica | Art. 6(1)(f). Finalidad: seguridad operativa y trazabilidad del envío de correo. Las alertas solo son accesibles para el superadministrador y se eliminan dentro de un plazo establecido tras su resolución. |
| Categorías de destinatarios | El superadministrador. Las alertas de fallo también se envían por correo electrónico a la dirección de alertas del operador (mediante Namecheap Private Email, apartado 4); un correo retenido no se envía a nadie. |
| Transferencia a terceros países | Ninguna; para el envío a la dirección de alertas, véase Namecheap en el apartado 4. |
| Conservación | Una fila permanece hasta que se resuelve, por el supervisor una vez subsanado el fallo o manualmente; un correo retenido nunca se resuelve automáticamente. El supervisor de estado elimina las filas resueltas 180 días después de su resolución (site_settings.retention_urgent_days, configurable en el área de administración, como mínimo 7 días). |
6. Conservación — qué cubre la purga diaria y qué no
Existe eliminación automática y, desde el 17/08/2026, abarca todas las tablas con datos personales, ya sea mediante un plazo propio o mediante la cadena de eliminación de la sesión. Su núcleo está en srv/db_worker.php en el bloque marcado DAILY DATA PRUNING y se ejecuta dentro del proceso trabajador permanente una vez por día natural (controlado por $lastPurgeDate). Los plazos de sesiones bot (cada hora), la eliminación definitiva de entradas archivadas (cada 30 segundos) y las solicitudes de eliminación desde el acceso de autoservicio tienen sus propios ciclos en el mismo proceso. Desde el 07/10/2026, las tareas programadas se ejecutan desde /etc/cron.d/mouseplayer mediante srv/cron_run.sh con un bloqueo por tarea, entre ellas el traslado de eventos al archivo (cada hora) y el mantenimiento del índice de texto (cada diez minutos); el agregado diario del mapa de clics se construye cada noche.
Prueba de su ejecución (a 16/10/2026): el registro del trabajador recoge la ejecución diaria todos los días, la más reciente el 16/10/2026 a las 00:00:11, completada diez segundos después, y el plazo aplicado cada hora para sesiones bot con sesiones y filas eliminadas (por ejemplo, a las 10:00:18 de ese mismo día, 478 sesiones con 3294 filas). Hasta ese día, el plazo del plan no había tenido nada que eliminar: los proyectos con sesiones más antiguas están en el plan Enterprise (365 días) y las sesiones más antiguas del plan gratuito son más recientes que su plazo. El supervisor de cron comprueba si una ejecución programada falla o no se produce en srv/cron_status.php, y lo comunica en los Registros urgentes (B.8) y por correo electrónico.
6.1 Cubierto por la purga diaria
| Tabla | Condición de activación y plazo | Prueba |
|---|---|---|
| mouseplayer_logs | Más de 60 días de antigüedad (site_settings.log_retention_days) | srv/db_worker.php, DAILY DATA PRUNING |
| security_access_logs | Más de 72 horas de antigüedad (site_settings.security_log_retention_hours) | srv/db_worker.php, DAILY DATA PRUNING |
| banned_ips | expires_at está en el pasado; las entradas sin expires_at permanecen hasta que las levanta el operador | srv/db_worker.php, DAILY DATA PRUNING |
| visitor_sessions y todo lo asociado (mouse_events, session_pageviews, session_custom_events con parámetros y las demás tablas de la cadena de eliminación) | Por sesión, una vez vencido el plazo del plan: Gratis 7 días, Small 30, Business 90, Enterprise IFNULL(enterprise_custom_tiers.retention_days, 365). Caso especial free + is_suspicious = 24 horas. Período de gracia tras bajar de plan mediante GREATEST(...) con users.retention_grace_until y retention_grace_days. Se elimina mediante mp_sitzungen_loeschen(). | srv/db_worker.php, DAILY DATA PRUNING |
| payload_blob y mouse_events de sesiones bot | La grabación de una sesión reconocida como bot se vacía una vez transcurrido el plazo (site_settings.retention_bot_recording_days, plazo en días: 1; 0 lo desactiva) | srv/db_worker.php, cada hora |
| visitor_sessions de sesiones bot con todo lo asociado | 14 días después del inicio de la sesión (site_settings.retention_bot_session_days, como mínimo 8; 0 = sin plazo separado) | srv/db_worker.php, cada hora, mp_sitzungen_loeschen() |
| mouse_events → archivos | se trasladan a archivos comprimidos por sesión tras 7 días; los archivos se eliminan con su sesión | srv/cron_archiv.php (cada hora), mp_sitzungen_loeschen() |
6.2 Lo que también se cubre desde el 17/08/2026
Este apartado enumeraba antes trece tablas sin plazo alguno. Eso está resuelto. Cinco tablas forman parte de la cadena común de eliminación mp_sitzungen_loeschen() desde el 12/08/2026, otras seis recibieron un plazo propio el 17/08/2026 y dos no figuraban en la lista: las puntuaciones por visitante y día y los textos generados a partir de ellas.
Las cifras de la tabla siguiente no son transcripciones. Se leen de site_settings cuando se sirve esta página, de la misma fila que lee la purga, y son configurables en el área de administración. Una cifra transcrita sería un segundo lugar para la misma información y, con el tiempo, ambas acabarían divergiendo.
| Tabla | Plazo | Qué lo aplica |
|---|---|---|
| ai_session_features | con la sesión | mp_sitzungen_loeschen() |
| ai_timelines | con la sesión | mp_sitzungen_loeschen() |
| session_comments | con la sesión | mp_sitzungen_loeschen() |
| session_shares | con la sesión; el propio enlace caduca tras un máximo de 90 días, 7 por defecto; la fila de un enlace caducado o revocado se elimina 90 días después y los accesos de share_views se eliminan con ella | mp_sitzungen_loeschen(), mp_share_erstellen(), ejecución diaria |
| visitor_nicknames | con la última sesión del visitante; desde el 28/08/2026 también cubre el nombre asignado por el responsable (A.13), que está en la misma fila | mp_sitzungen_loeschen() |
| ai_visitor_value | 60 días desde el día puntuado; para Enterprise, la conservación del plan. Además, con el visitante en cuanto no quede ninguna sesión suya | ejecución diaria, mp_sitzungen_loeschen() |
| ai_insights (scope “visitor”) | igualmente | ejecución diaria, mp_sitzungen_loeschen() |
| consent_events | 730 días desde the withdrawal; nunca mientras una sesión siga refiriéndose a él | ejecución diaria |
| ip_lifetime_stats | 365 días desde first_seen | ejecución diaria |
| audit_logs | 60 días | ejecución diaria |
| support_requests | 730 días | ejecución diaria |
| consent_region_acceptances | 730 días | ejecución diaria |
| legal_acceptances | 730 días después de la aceptación o aviso; la aceptación más reciente de una cuenta existente se conserva mientras exista la cuenta (desde el 16/10/2026) | ejecución diaria |
| user_ip_history | 90 días desde la última vez que se observó la dirección; como máximo, hasta la eliminación de la cuenta | ejecución diaria |
| users (incluido last_ip), workspace_users, workspace_invites | con la cuenta; sin inicio de sesión, tras 24 meses más un plazo de advertencia de 30 días | mp_konto_loeschung_ausfuehren(), ejecución diaria |
| heatmap_page_stats | no es aplicable: la tabla se retiró el 18/08/2026 (migración 045) | — |
| mp_profil_sitzung | 180 días desde el INICIO de la sesión, como mínimo la ventana de cálculo; sin plazo alguno en cuanto la propia sesión haya desaparecido | ejecución diaria, mp_sitzungen_loeschen() |
| mp_profile, mp_sequenzmuster | mp_profile en cuanto no quede ninguna asignación para él; mp_sequenzmuster tras 180 días sin recalcularse e inmediatamente cuando su canal ya no tenga ninguna sesión | ejecución diaria |
| ga4_daily, ga4_sessions, ga4_events | 180 días desde el día descrito o desde el inicio de la sesión de GA4, respectivamente; no desde el momento de importación (A.14) | ejecución diaria |
| mp_hm_tag, mp_hm_tag_stand | sin plazo propio: un día almacenado se recalcula a partir de las sesiones que aún existen como máximo 7 días después de su último cálculo, la próxima vez que se abre la lista; en ese momento se retiran los días anteriores a la sesión más antigua restante del proyecto; todo se elimina con el proyecto (A.8) | al abrir la lista de mapas de calor; mp_konto_loeschen() |
| mp_umfrage_text | con la sesión (A.21); deliberadamente sin plazo propio | mp_sitzungen_loeschen(), la vía de eliminación del reproductor, mp_konto_loeschen() |
| mp_loesch_archiv, mp_loesch_archiv_sitzung | cuentas, espacios de trabajo, proyectos y visitantes o direcciones IP archivados (supresión conforme al RGPD): un máximo de 30 días y, después, supresión definitiva. Permanece un registro sin nombre – para visitantes y direcciones IP, un HMAC del identificador, para poder repetir la supresión tras restaurar una copia de seguridad; para cuentas, ningún identificador – que se retira tras 730 días | db_worker, cada 30 segundos |
| mp_hm_klick_tag, mp_hm_ansicht_tag | 730 días desde el día que describe la fila; inmediatamente con el proyecto. Sin eliminación por persona: las filas no contienen ninguna referencia personal (A.1) | srv/hm_aggregat_lauf.php, mp_konto_loeschen() |
| mouse_events_analytik | con la vista de página – desde el 07/10/2026 también en todas las vías que eliminan sesiones individuales; antes, solo junto con todo el proyecto (A.8) | mp_sitzungen_loeschen(), la vía de eliminación del reproductor, mp_konto_loeschen() |
| login_sessions | 90 días desde la última actividad; íntegramente con la cuenta (B.7) | ejecución diaria, eliminación de la cuenta |
| share_views | con el enlace para compartir, mediante la clave foránea con ON DELETE CASCADE (B.6) | clave foránea |
| ai_churn | se reescribe por proyecto en cada ejecución; se elimina con las sesiones de las que deriva la fila (A.16) | srv/ai_worker.php |
| ai_besucher_bericht | 180 días desde la solicitud; antes si desaparece la última sesión del visitante (A.17) | ejecución posterior en srv/ai_worker.php |
| mp_cwv, mp_element_klicks, mp_element_offen | con la sesión o vista de página; las filas cuya vista de página falta se retiran cada hora (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 días desde el inicio de la vista de página; antes con la sesión (A.22) | srv/textsuche_lauf.php, mp_sitzungen_loeschen() |
| bot_review_labels | por defecto: sin eliminación automática; configurable en años (retention_bot_labels_years) (A.19) | srv/cron_status.php |
| urgent_logs | 180 días después de la resolución (site_settings.retention_urgent_days) (B.8) | srv/cron_status.php |
| mp_aufnahme_quittung | 7 días (A.1) | srv/db_worker.php |
| mp_native_apps, mp_native_sessions | hasta que venza el plazo establecido por sesión o hasta la revocación; la versión preliminar está desactivada y solo existe en la instancia de desarrollo (A.1) | cfg/native_store.php |
Dos puntos medidos, no supuestos. Primero, la ejecución diaria realmente se ejecuta. Este documento afirmó en un momento que nunca lo había hecho; la ejecución del 17/08/2026 a las 17:37:09 consta en el registro del trabajador. Ese día no eliminó nada porque ambos proyectos con sesiones están en el plan Enterprise y la sesión más antigua tenía 27 días: es el estado previsto, no un fallo. Segundo, el plazo de las puntuaciones derivadas tiene como punto de partida el día que describe la fila, no cuándo se calculó. Según la medición, 167 filas contenían 28 días descritos distintos, pero solo 6 momentos de cálculo distintos, el más reciente de unos minutos antes: el precálculo recalcula, y cada recálculo habría reiniciado un plazo vinculado a él. Nunca habría caducado y nadie lo habría advertido.
6.3 Hallazgos sobre la cadena de eliminación (a 16/10/2026)
- LA CADENA SE EJECUTA EN FUNCIONAMIENTO. El 10/08/2026 nunca se había ejecutado, por lo que aquí se describía como no probada. Desde el 17/09/2026, el plazo de sesiones bot elimina cada hora mediante la misma cadena de eliminación
mp_sitzungen_loeschen()que también utilizan el plazo del plan y las solicitudes de eliminación; el 16/10/2026, por ejemplo, 401 y 478 sesiones por ejecución. El propio plazo del plan no había tenido nada que eliminar hasta ese día (apartado 6). - PROYECTOS ELIMINADOS. La selección del plazo del plan sigue combinando visitor_sessions mediante INNER JOIN con proyecto, espacio de trabajo y propietario, y no ve sesiones sin proyecto. Sin embargo, en el proceso habitual ya no se genera una sesión así: desde el 07/10/2026, primero se archiva un proyecto y, en la eliminación definitiva, se retira con todas sus sesiones mediante la eliminación del canal (
mp_kanaele_loeschen()). A 16/10/2026 no hay ninguna sesión sin proyecto. - REGISTROS HUÉRFANOS. Todo lo derivado de una sesión forma parte de la cadena de eliminación o tiene un plazo propio (apartado 6.2). Las vistas de página cuya sesión falta —por ejemplo, tras una interrupción en mitad de una eliminación— las cuenta una vez al día el supervisor de estado y se retiran automáticamente junto con sus eventos cuando tienen más de diez minutos.
- LA PURGA DEPENDE DE QUE FUNCIONE EL TRABAJADOR. Un trabajador detenido también detiene la eliminación. Desde el 19/08/2026, los supervisores comunican fallos por correo electrónico; desde el 23/09/2026 ese correo sale realmente mediante SMTP y, desde el 02/10/2026, una máquina propia separada de la misma red local comprueba cada minuto desde fuera si están en orden la base de datos, Redis, servidor WebSocket, procesos permanentes y cola. Debe señalarse que ActiveState=active no prueba que el trabajador esté vivo; la lista de procesos es fiable.
Vías de eliminación manual, por exhaustividad: el reproductor (delete_session y delete_visitor, limitadas al channelid, roles de propietario y administrador) y mp_sitzungen_loeschen() en srv/db_worker.php. Una retirada solo elimina si projects.consent_delete_on_withdraw está establecido; a 16/10/2026 no está establecido en ningún proyecto. No existe ON DELETE CASCADE desde visitor_sessions hacia abajo: la cadena recorre manualmente todas las tablas dependientes, y el obstáculo es mouse_events, porque los eventos dependen de pageview_id y no de session_id; desde el 07/10/2026 también incluye la copia de clics mouse_events_analytik.
Fuera de la base de datos: los registros de acceso de nginx y Apache contienen direcciones IP completas y se conservan durante 14 rotaciones diarias (logrotate). Redis de la instancia de desarrollo escucha solo en 127.0.0.1 (puerto 6381), tiene acceso restringido y escribe sus datos en disco para persistencia (AOF y capturas RDB); las colas contienen la IP truncada, URL completa y carga útil del DOM hasta que el trabajador las recoge, y mp_autoban: conserva la dirección completa de un remitente bloqueado durante el bloqueo (24 h). Los archivos de eventos trasladados están bajo /mnt/mouseplayer-dev-archive en el mismo disco que el sistema y se incluyen en la copia de seguridad desde el 06/10/2026.
7. Toma de decisiones automatizada, elaboración de perfiles y puntuación
Se realizan puntuaciones y clasificaciones. No se encontró ninguna decisión que produzca efectos jurídicos sobre un VISITANTE o le afecte significativamente de modo similar: ninguna decisión de crédito, precio o acceso, ni comunicación de las evaluaciones a nadie distinto del cliente. Según las pruebas, el art. 22 no se aplica respecto de los visitantes. Sí existen tres consecuencias automatizadas, y dos merecen un examen más detenido del que suele ofrecer un registro. La tercera se añadió el 02/09/2026 y es la única que repercute sobre el VISITANTE: la predicción de salida (A.15) o el indicador de riesgo de fuga (A.16) pueden dar lugar a una superposición en el sitio web del responsable. Solo aparece si este la activa, su contenido es propio y puede cerrarse. No se deriva de ello ningún efecto jurídico ni impacto de importancia similar en el sentido del art. 22(1) del RGPD: es una invitación, no una decisión sobre precio, acceso o solvencia. Aun así, debe figurar en el registro, porque aquí una evaluación sale por primera vez del panel del cliente.
| Mecanismo | Qué hace | Dónde |
|---|---|---|
| Puntuación de interacción | Un entero pequeño construido a partir de puntos de profundidad (duración, número de páginas, profundidad del scroll) y carácter llamativo (clics de rabia y muertos, saltos hacia atrás, pestañas paralelas). Los bots y las sesiones triviales reciben 0. Se almacena en ai_session_features.engagement_score (TINYINT UNSIGNED), índice idx_engagement. Efecto: orden de la lista de recomendaciones del panel del cliente. | ai/features.py:33-70; cfg/project_ai_overview.php:126-136 y 150; cfg/project_live_users.php:190 |
| Calidad de la sesión | Distingue las sesiones en las que casi no ocurrió nada. | visitor_sessions.session_quality; srv/db_worker.php:706-780 y 1103-1140 |
| Clasificación de bots | Establece visitor_sessions.is_bot y bot_reason (varchar 32), índice idx_is_bot. Téngase en cuenta que la comprobación de bots de mp.js se ejecuta ANTES del control de consentimiento. | srv/db_worker.php:963-1000 |
| Detección de frustración en el navegador | Genera rage_click, dead_click y mouse_thrashing. Medido: dead_click 355, rage_click 52, mouse_thrashing 5. Ante rage_click, el script también transmite un indicador a widgets de chat de terceros presentes en el navegador del VISITANTE — Intercom('update', {'mouseplayer_rage_click':'DETECTED_NOW'}) y LiveChatWidget.call('set_session_variables', ...). Es una comunicación ulterior automatizada de un juicio sobre el comportamiento a un tercer sistema de la página del cliente. | www/mp.js:5786 y 5793-5794 |
| Registro textual de sesión | Prosa generada por una máquina sobre el desarrollo de la sesión, producida por ai/build.py. Desde el 12/08/2026, srv/ai_worker.php invoca la propia construcción (con directorio de trabajo y PYTHONPATH); a 16/10/2026 funciona y la línea de tiempo más reciente es de ese mismo día. Los mensajes de error de ai_build.log proceden de la invocación anterior, retirada desde entonces, y se escribieron por última vez el 18/08/2026. | ai/build.py; srv/ai_worker.php; ai_timelines |
| is_suspicious al registrarse | Se establece automáticamente al registrarse, utilizando device_id y el correo electrónico normalizado, entre otras señales. Consecuencia: para el plan gratuito, el plazo de conservación se reduce a 24 horas. | www/register.php:159-191; srv/db_worker.php:824 |
| Bloqueo automático | Más de 15 conexiones en 10 segundos, más de 15 conexiones simultáneas desde una IP, más de 50 mensajes por segundo y mensajes demasiado grandes (salvo una captura grande de página) o ilegibles provocan un bloqueo de 24 h en el servidor WebSocket (site_settings.autoban_stunden, de 1 a 168), conservado en Redis (mp_autoban:) y registrado sin la dirección completa. Delante del servidor web, fail2ban bloquea una dirección durante una hora si alcanza el límite de frecuencia de nginx más de 100 veces en un minuto (jaula mp-nginx-429). Según el código a 16/10/2026, las entradas de banned_ips solo las establece ahora el operador; las entradas automáticas anteriores caducaban tras 7 días. | class/Server.class.php (autoBanIp); /etc/fail2ban/jail.d/mp-nginx-429.conf; /etc/nginx/conf.d/mouseplayer.conf |
| Perfiles de comportamiento — agrupación de visitas (A.12) | k-means sobre siete características por sesión asigna cada visita reproducible a uno de un máximo de ocho grupos y lo nombra a partir de la posición relativa del centro del grupo. Las sesiones triviales y las reconocidas como bots se separan previamente mediante una regla y no se agrupan. Efecto: una VISUALIZACIÓN —una pestaña, un filtro en forma de etiqueta y una cola de reproducción—. No depende de ello ninguna decisión. | ai/profile.py; cfg/project_profiles.php; mp_profil_sitzung |
| Puntuación de fricción y anomalías | Por sesión, un valor de 0 a 100 derivado de señales ponderadas de frustración y error junto con motivos (desde el 26/09/2026); ordena y filtra listas y puede activar un webhook al que se haya suscrito el cliente al alcanzar un umbral. Una vez al día se compara el día anterior de cada proyecto con las semanas precedentes (sesiones, tasa de objetivos, proporción con fricción o errores de JavaScript, Web Vitals) y se comunica una anomalía: recuentos del proyecto, no una evaluación de visitantes individuales. No depende de ello ninguna decisión sobre el visitante. | cfg/reibung_lib.php; cfg/anomalie_lib.php; visitor_sessions.friction_score; mp_anomalie |
El bloqueo automático es el único mecanismo de esta lista que deniega el acceso a un servicio sin intervención humana y puede afectar a un usuario cliente, no solo a un visitante. Este registro no decide si alcanza el umbral del art. 22(1). Evaluado el 17/08/2026, actualizado el 16/10/2026: el bloqueo del servidor WebSocket caduca por sí solo tras 24 h y el de fail2ban tras una hora; el bloqueo automático anterior de banned_ips caducaba tras 7 días. La oposición se presenta mediante el formulario de soporte o a office@mouseplayer.com y la tramita una persona; el operador puede levantar un bloqueo antes de tiempo. Por tanto, el procedimiento tiene un efecto limitado, revisión humana previa solicitud y una vía identificada para solicitarla: las características de las que depende el art. 22. La clasificación en sí sigue siendo una cuestión jurídica; lo decidido es la garantía, no la interpretación. (Decisión del responsable del tratamiento, 17/08/2026)
La agrupación de A.12 es elaboración de perfiles en el sentido del art. 4(4) del RGPD: se evalúan automáticamente datos de comportamiento para valorar aspectos del comportamiento. El art. 22(1) exige algo más: una DECISIÓN que produzca efectos jurídicos o afecte de modo similar y significativo a la persona. No se encontró ninguna, tras comprobar tres vías. La pertenencia al grupo la escribe ai/profile.py y se lee exactamente en cuatro vías: las funciones de lectura de cfg/lib.php, la pestaña cfg/project_profiles.php, el reproductor www/player.php y el generador de frases cfg/ki_lib.php —y en ninguna otra. No entra en ninguno de los puentes de 4.1: una búsqueda de profil_key en cfg/, srv/, www/ y class/ no devuelve ni www/mp.js ni class/Server.class.php, por lo que tampoco llega al navegador del visitante. Y no cambia el plazo de conservación, la grabación ni nada que el visitante encuentre en el sitio del cliente. Además, se agrupan VISITAS, no personas: un perfil por persona presupondría el identificador de cliente de setUserId, y 0 de 4226 sesiones llevan uno. Permanecen los arts. 13(1)(c) y 30: el deber de información y esta entrada. Ambos se cumplen. La clasificación en sí sigue siendo una cuestión jurídica; lo resuelto es el estado de hechos medido, no su interpretación. (Evaluado el 27/08/2026.)
8. Medidas técnicas y organizativas (art. 32) — descripción general
Este apartado es la descripción general exigida por los arts. 30(1)(g) y 30(2)(d). Cada medida siguiente se verificó en el código o la configuración; se indican archivo y línea para que el lector compruebe en lugar de confiar. Las carencias al final de este apartado están igualmente verificadas y se indican al mismo tiempo, porque una descripción de TOM que solo enumera lo existente es publicidad.
| Área | Medida vigente | Prueba |
|---|---|---|
| Cifrado del transporte | Las conexiones desde Internet están cifradas mediante TLS: TLS termina en nginx (192.168.20.2:443) y toda solicitud HTTP se redirige a HTTPS. El servidor WebSocket escucha solo en 127.0.0.1:8081 sin TLS propio y solo puede alcanzarse mediante nginx (ruta /mp_wss/); asimismo, el túnel HTTP /mp_wst, la subida de capturas grandes de páginas /mp_dom y el punto de medición /mp_wsfail funcionan mediante HTTPS. Dentro de nuestra propia red local en la misma ubicación, las conexiones de base de datos y Redis funcionan sin cifrar (véase 8.1). | /etc/nginx/conf.d/mouseplayer.conf; srv/server.php (MP_WSS_BIND, MP_WSS_TLS); www/.htaccess |
| Minimización de datos en la recogida — IP | La dirección IP del visitante se trunca inmediatamente después de determinarse y, por tanto, antes de que la utilice ningún componente (último octeto IPv4, último grupo IPv6). El 10/08/2026, 236 filas heredadas aún contenían direcciones completas; a 16/10/2026, ninguna fila de visitor_sessions o ip_lifetime_stats contiene una dirección sin truncar. | class/Server.class.php (regla B) |
| Minimización de datos en la captura — entradas de formularios | Enmascaramiento con una protección mínima incondicional: en el nivel 0 se sustituye cada carácter; con independencia del nivel, siempre se sustituyen contraseñas y datos de pago (categorías password y payment, tipos password/email/tel/hidden, patrones de clase y nombre card|cc|cvv|cvc|password|credit|social|pesel|nip). Los 7 proyectos utilizan smart_masking=0. | www/mp.js:4818-4853 |
| Minimización de datos en la captura — DOM | Dentro de data-mp-mask o .mp-masked se sustituye cada carácter que no sea un espacio en blanco por '*' y todos los atributos ajenos a MASK_KEEP_ATTRS se establecen en '[FILTERED]'. También se aplica a los cambios en curso. | www/mp.js:3934-3970 y 4732-4768 |
| Minimización de datos en la captura — nombres de campos | No se transmite el nombre o id sin procesar de un campo de entrada; solo se envía la categoría clasificada, porque en muchas tiendas el nombre sin procesar es suficientemente descriptivo para identificar a la persona. | www/mp.js:4653-4674 |
| Aplicación del consentimiento | Lista de exclusión de rutas evaluada ANTES del control de consentimiento, con coincidencia sobre la ruta y no la URL completa (71 conexiones bloqueadas). Aplicación del lado del servidor como segunda protección: solo pasan GRANTED, GRANTED_LATE o una exención regional explícita; WITHDRAWN, un país desconocido y cualquier situación dudosa dan lugar a close(1008) (24 conexiones bloqueadas). Interruptor de desactivación site_settings.consent_gate_active=1. | class/Server.class.php:963-975 y 977-1004 |
| Minimización de las pruebas de consentimiento | La cadena TC no se almacena en claro; solo se conserva su SHA-256. | visitor_sessions.tcf_hash CHAR(64); ai/migrations/018_consent.sql |
| Seguridad de la aplicación | Tokens CSRF de random_bytes(32) comparados con hash_equals(). Cookie de sesión con httponly=true, samesite='Lax' y secure condicionado a HTTPS. Contraseñas almacenadas como hashes y verificadas con password_verify(). Sentencias preparadas en todas las vías de escritura auditadas. Límite de frecuencia de inicio de sesión. | cfg/lib.php:118-132 y 110-112; www/login.php:60 y 28 |
| Prevención de abusos | Bloqueo automático y límite de conexiones en el WebSocket (contador de Redis con caducidad de 10 s; 15 conexiones simultáneas por IP; bloqueo de 24 h en Redis, truncado en el registro). Límites de frecuencia y de conexiones por dirección en nginx para páginas y establecimiento de conexiones WebSocket. fail2ban con la jaula mp-nginx-429: quien sea rechazado más de 100 veces en un minuto queda bloqueado para HTTP y HTTPS durante una hora. | class/Server.class.php; /etc/nginx/conf.d/mouseplayer.conf; /etc/fail2ban/jail.d/mp-nginx-429.conf |
| Control de acceso | Modelo de roles por espacio de trabajo (propietario / administrador / lector). La eliminación en el reproductor está limitada a propietario y administrador, y cada eliminación se limita además al channelid, descrito en el código como el verdadero límite de seguridad. | workspace_users.role; www/player.php:267 y 275-282 |
| Registro de cambios | log_audit() registra usuario, espacio de trabajo, acción, objetivo, detalles e IP. 666 entradas, incluidas create_share, revoke_share, delete_comment, player_delete_*, firewall_auto_ban (24) y superadmin_*. | cfg/lib.php:2878-2890 |
| Enlaces para compartir | channelid y session_id proceden exclusivamente del token; el resto de la cadena de consulta se SUSTITUYE, no se ignora; user_role permanece en NULL, de modo que la eliminación y la creación de nuevos enlaces para compartir quedan excluidas del lado del servidor, no solo de la interfaz; los tres endpoints se limitan a la sesión del token; los tokens inventados, caducados y revocados devuelven la misma respuesta. | www/share.php; www/.htaccess:77 |
| Superficie de la API | La carga útil completa de la reproducción no forma parte deliberadamente de la API pública. | www/api/v1_session_detail.php:25 |
| Gestión de claves | La clave de la cuenta de servicio de Google se almacena cifrada en projects.bigquery_sa_json y se descifra mediante decrypt_sa_key() con BIGQUERY_SA_AES_KEY de .env; la interfaz indica AES-256. | srv/cron_integration_bigquery.php:57; cfg/lib.php:993 |
| Secretos fuera del control de versiones | Confirmado en el índice actual: .gitignore incluye .env y git ls-files solo encuentra .env.example. | git ls-files |
| Exposición en la red | Desde Internet solo son accesibles los puertos 80 y 443 mediante nginx; no hay redirección de puertos para la base de datos o Redis. Redis de la instancia de desarrollo está vinculado solo a 127.0.0.1 (puerto 6381); una instancia anterior y compartida de Redis (puerto 6379) también escucha en la red local. MariaDB escucha en 127.0.0.1 y en la red local. La base de datos y Redis tienen acceso restringido y solo son accesibles desde nuestra propia red local. Hay una restricción de acceso adicional delante de www.mouseplayer.com. | ss -ltn; configuración de Redis; www/.htaccess |
8.1 Medidas que se ha demostrado que NO están implementadas
- Sin cifrado en reposo. innodb_encrypt_tables, innodb_encrypt_log e innodb_encrypt_temporary_tables están en OFF, y no hay ningún volumen cifrado (lsblk muestra sda1 sin crypt).
- Sin TLS en las conexiones de base de datos. have_ssl=YES, pero ssl_cert, ssl_key y ssl_ca están vacíos. MariaDB escucha en 127.0.0.1 y en la red local (192.168.20.2:3306); por tanto, las conexiones desde la red local funcionan sin cifrar. Tienen acceso restringido y no son accesibles desde Internet (sin redirección de puertos).
- Sin cifrado de transporte para Redis. Las conexiones a Redis funcionan sin cifrar mediante la interfaz local o en la red local; ambas instancias tienen acceso restringido. La instancia de desarrollo escribe sus datos en disco para persistencia (AOF), incluidas las colas con IP truncada, URL completa y carga útil del DOM y, durante el bloqueo (24 h), la dirección completa de los remitentes bloqueados.
- NO SE REGISTRA QUIÉN VIO CADA GRABACIÓN. audit_logs solo registra acciones de escritura; una llamada a player.php, ajax_get_events.php o player_theatre.php no se registra en absoluto. Por tanto, es imposible responder a posteriori a quién vio una sesión determinada.
- Los registros de acceso de Apache contienen direcciones IP completas, conservadas durante 14 días.
- Los archivos de eventos de grabación trasladados están en el mismo disco que el sistema y la base de datos. Un fallo de ese disco afecta a ambos; solo la copia de seguridad cifrada, que contiene el archivo desde el 06/10/2026, proporciona almacenamiento en otra ubicación.
- Todos los límites contra la sobrecarga —nginx, fail2ban y el bloqueo del servidor WebSocket— cuentan por dirección. Nada situado delante de la máquina ayuda frente a un ataque distribuido desde muchas direcciones: no hay ninguna CDN ni servicio de filtrado delante.
- Seguridad física: el acceso corresponde exclusivamente al responsable del tratamiento. La sala está cerrada con llave y bajo videovigilancia; ninguna otra persona — incluidos los arrendadores o los servicios de limpieza — tiene acceso (declaración del responsable del tratamiento, 17/08/2026). La dirección exacta no se indica aquí deliberadamente.
- Supervisión y recuperación: desde el 19/08/2026, los supervisores de
srv/cron_status.phpcomunican fallos, poco espacio en disco, copias de seguridad ausentes y ejecuciones programadas fallidas en los Registros urgentes (B.8) y por correo electrónico; desde el 23/09/2026 ese correo sale realmente mediante SMTP. Desde el 02/10/2026, una máquina propia separada de la misma red local comprueba cada minuto la base de datos, Redis, servidor WebSocket, procesos permanentes y cola mediante un endpoint de estado (www/health.php) y comunica un fallo; no puede detectar un fallo de la propia conexión a Internet. Objetivo de tiempo de recuperación: como máximo 24 horas. Se realizaron pruebas de restauración desde la copia externa el 05/09/2026 y el 06/09/2026 y el 07/10/2026 (restauración completa de los datos); se prevén mensualmente (declaración del responsable del tratamiento, 17/08/2026). El disco USB de copias de seguridad está en la misma sala que el servidor; por tanto, un único suceso en esta ubicación afecta a ambos y solo la copia cifrada proporciona almacenamiento externo. Los dos archivos de claves se conservan impresos en una caja fuerte a la que solo puede acceder el responsable y, por ello, sobreviven a la pérdida de la máquina.
9. Delegado de protección de datos — evaluación conforme al art. 37 del RGPD
RESULTADO: no se demuestra una obligación de designar un delegado de protección de datos con las cifras disponibles hoy, pero la evaluación depende de una sola variable, esa variable solo se mueve en una dirección y, hasta el 19/08/2026, nada la vigilaba. Ahora se mide a diario (véase la consecuencia 2). La respuesta es "todavía no", no "no".
El art. 37(1) exige la designación en tres casos. El caso (a), una autoridad u organismo público, no es aplicable. El caso (c), actividades principales consistentes en el tratamiento a gran escala de categorías especiales del art. 9 o de datos de condenas penales del art. 10, no se cumple: no se tratan intencionadamente datos de categorías especiales. Eso no agota la cuestión: como se indica en A.2, la captura del DOM almacena todo lo que muestra la página del cliente, por lo que pueden entrar incidentalmente datos de categorías especiales en una grabación de un sitio de salud o finanzas. La captura incidental no es una actividad principal consistente en ese tratamiento, por lo que no activa el caso (c); pero la exposición es real y corresponde tratarla al incorporar clientes, no descartarla aquí por escrito.
El caso (b) es el relevante y tiene dos elementos. El primero —actividades principales consistentes en un tratamiento que requiere OBSERVACIÓN HABITUAL Y SISTEMÁTICA de interesados— se cumple sin discusión. La grabación de sesiones es una observación continua y automatizada del comportamiento individual; no es accesoria al negocio, ES el negocio. Quien lea este registro y sienta la tentación de discutir el primer elemento debería detenerse: se cumple, y discutirlo desperdicia la credibilidad necesaria para el segundo.
El segundo elemento es la GRAN ESCALA, y aquí la respuesta sigue siendo actualmente negativa. Las directrices del Grupo de Trabajo del Artículo 29 ponderan cuatro factores: número de interesados, volumen y variedad de datos, duración o permanencia del tratamiento y extensión geográfica. Medido el 10/08/2026: 706 sesiones de visitantes, 329 registros de visitantes distintos, 7 proyectos, 4 cuentas de clientes. Por número de interesados, no se aproxima en absoluto a la gran escala y, además, son cifras de la instancia de desarrollo. A 16/10/2026: 3514 ID de visitantes distintos clasificados como humanos en los últimos 30 días en todos los proyectos, todavía muy por debajo del umbral de la consecuencia 2.
No obstante, dos de los cuatro factores apuntan en sentido contrario, y el registro debería indicarlo en lugar de apoyarse en el factor cómodo. La VARIEDAD de datos por persona es excepcionalmente amplia: HTML completo de páginas, incluido todo lo que muestra la página, entradas de formularios al nivel de cada pulsación, comportamiento de movimientos y clics, puntuación de comportamiento derivada y un relato de la sesión en prosa. La DURACIÓN es larga: según el plan, las grabaciones permanecen hasta 365 días y en la copia de seguridad hasta 364 días adicionales, aunque existen y se aplican plazos de eliminación para todas las tablas desde agosto de 2026 (apartado 6). Solo el número de personas mantiene la evaluación por debajo del umbral, y ese número es precisamente la magnitud que MousePlayer no controla: lo determina el tráfico que recibe el sitio web de cada cliente. Un solo cliente de comercio electrónico de tamaño medio podría hacer que el producto superase el límite por sí mismo, sin que aquí se tomara ninguna decisión.
- Consecuencia 1: documentar la evaluación con su fecha. El art. 5(2) impone la responsabilidad proactiva; una evaluación negativa que nunca se registró es indistinguible de una que nunca se realizó.
- Consecuencia 2: definir la condición que obliga a reabrirla. La condición razonable es el número de visitantes observados al mes en el conjunto de clientes, más una revisión con cada nuevo cliente de tamaño significativo. Umbral y frecuencia: la evaluación del art. 37 se repite en cuanto se observan más de 100000 usuarios finales al mes en el conjunto de Clientes y, en cualquier caso, anualmente. Responsable: Lukas Wójcik, propietario. (decisión del responsable del tratamiento, 17/08/2026) Implementado el 19/08/2026: el número de usuarios finales distintos observados en los últimos 30 días se cuenta una vez al día mediante el proceso supervisor y se compara con este umbral y con la fecha de la última evaluación registrada; superar cualquiera de ellos envía una advertencia por correo electrónico. El umbral y la fecha son configuraciones leídas de la misma fila que cita esta frase, de modo que el documento y la medición no pueden divergir. Una condición que nadie mide es una nota, no un control – esa era la carencia que este párrafo describía y ya no describe.
- Consecuencia 3: comprobar el Derecho nacional. El art. 37(4) permite que el Derecho de la Unión o de los Estados miembros exija la designación en otros casos. pendiente de completar: confirmación de un asesor jurídico polaco de si el Derecho polaco exige un delegado de protección de datos en otros casos además de los del art. 37(1)
- Consecuencia 4: sigue abierta la designación voluntaria. Si se designa voluntariamente un delegado de protección de datos, los arts. 37 a 39 se aplican íntegramente, incluidas la publicación y notificación de los datos de contacto. Es una decisión, no un valor por defecto.
- Consecuencia 5, distinta pero relacionada: muy probablemente se exige una evaluación de impacto relativa a la protección de datos conforme al art. 35 a cada CLIENTE como responsable, dada la observación sistemática combinada con evaluación y puntuación. Como encargado, MousePlayer debe prestar asistencia conforme al art. 28(3)(f). Existe una evaluación de impacto del producto: la publicada bajo “Evaluación de impacto relativa a la protección de datos”. Una copia separada no se entrega a los Clientes (decisión del responsable del tratamiento, 17/08/2026). La asistencia conforme al art. 28(3)(f) se presta previa solicitud y se basa en los documentos públicamente disponibles: este registro, la evaluación de impacto publicada, las medidas técnicas y organizativas y la lista de subencargados.
10. Carencias conocidas
Todo lo siguiente está demostrado, no es una sospecha. Este apartado existe porque un registro de actividades de tratamiento es un instrumento de trabajo: el objetivo es ver los puntos pendientes, no presentar una hoja impecable. Los puntos se ordenan según lo mal que se leerían en una auditoría, no por lo difícil que sea corregirlos.
| Carencia | Qué está demostrado | Por qué importa |
|---|---|---|
| Direcciones IP completas en registros de nuestra propia aplicación | A 16/10/2026, los datos heredados de visitor_sessions e ip_lifetime_stats están truncados (el 10/08/2026, 236 y 291 filas sin truncar, respectivamente). mouseplayer_logs, audit_logs, user_ip_history, login_sessions, share_views y support_requests (parte B), así como los registros de acceso de nginx y Apache, permanecen deliberadamente sin truncar | Para la parte B, la dirección completa está justificada (B.2 a B.7) y limitada por plazos. Aun así, se enumera aquí porque estas tablas entran en todas las copias de seguridad. |
| Datos heredados con entradas de formularios en claro | El 10/08/2026, 173 filas de mouse_events con event_type='input' contenían valores sin enmascarar del 21/07/2026 al 27/07/2026, incluidos nombres de personas. Las filas se eliminaron el 17/08/2026, antes de introducir los archivos el 18/08/2026; a 16/10/2026 no queda ninguna de ellas en mouse_events | Las filas actuales están enmascaradas, por lo que el control funciona. Los valores anteriores no pueden estar en el archivo ni en la copia de seguridad actual; no se conoce ninguna copia anterior al 17/08/2026, pero no se ha verificado en detalle su ausencia. |
| Los enlaces para compartir omiten por completo el inicio de sesión | /s/<40-hex-token> conduce directamente a player.php?share=<token>; el token constituye toda la barrera | El enlace puede reenviarse a cualquiera, por lo que la categoría de destinatarios de A.1, A.2, A.3 y A.9 está, de hecho, abierta. Se limita mediante la duración máxima (7 días por defecto, un máximo de 90), la revocación en cualquier momento y el registro de acceso (B.6). |
| No se registra quién vio una grabación | audit_logs solo registra acciones de escritura; no se registran las llamadas a player.php, ajax_get_events.php y player_theatre.php | Después de un incidente es imposible determinar quién vio cada sesión. Es la medida cuya ausencia resulta más difícil de explicar a una autoridad de control. |
| Todo el servidor se copia externamente cada día | srv/backup-crypt.sh copia cada día todas las bases de datos y todo el árbol web, incluido cada archivo .env, y desde el 06/10/2026 también el archivo de eventos de grabación; la copia se cifra en nuestro propio servidor antes de transferirse (rclone crypt) y desde el 05/09/2026 se almacena en un bucket de Google Cloud Storage en Varsovia, amparada por las condiciones de tratamiento de datos de Google Cloud (apartado 4) | Lo que sale cada día de las instalaciones no es solo una copia de las grabaciones de sesiones, sino el servidor completo, con los secretos de producción de varios sistemas. El cifrado retira el contenido de Google, no el alcance. Si se pierden ambos archivos de claves, la copia de seguridad es irrecuperable; por ello también se conservan impresos en la caja fuerte (apartado 8.1). |
| Se supervisa si llega la copia de seguridad | No demostrado hasta el 11/08/2026. Desde entonces, la ejecución escribe un registro y verifica en destino; desde el 19/08/2026, un supervisor compara la última ejecución satisfactoria con un plazo y comunica una ejecución ausente en los Registros urgentes y por correo electrónico | La carencia de esta fila está cerrada. Permanece en la lista para que pueda seguirse que la copia de seguridad se ejecutó sin prueba hasta el 11/08/2026. |
| Scripts antiguos de copias de seguridad | Los scripts antiguos de copias de seguridad se retiraron el 16/10/2026. Ninguno seguía ejecutándose; desde el 11/08/2026, la copia diaria se ejecuta mediante srv/backup-crypt.sh | La carencia de esta fila está cerrada. Permanece en la lista para que pueda seguirse que hasta el 11/08/2026 quien obtuviera la cuenta SSH pi tenía privilegios de root a las 02:00. |
| Sin cifrado en reposo ni TLS en las conexiones de base de datos y Redis | innodb_encrypt_* en OFF, sin volumen cifrado; ssl_cert/ssl_key/ssl_ca vacíos, MariaDB también accesible en la red local; Redis con acceso restringido, pero sin cifrar y con persistencia en disco (AOF) | Las grabaciones —incluidas la carga útil del DOM de la cola de Redis y los archivos— son legibles para cualquiera con acceso al sistema de archivos; en la red local, las conexiones de base de datos funcionan en claro. Ninguna de estas vías es accesible desde Internet. |
| Algunos registros de consentimiento son datos de prueba | El 10/08/2026, 671 de 706 sesiones llevaban consent_source='testdata' con consent_ts IS NULL, establecido por ai/devdata/001_altsitzungen_markieren.sql; a 16/10/2026 todavía hay 566 sesiones de ese tipo | Para estas sesiones, el registro de consentimiento no puede servir de prueba. Es un efecto del sistema de desarrollo, pero la misma consulta en producción necesitaría la misma comprobación. |
| La retirada no elimina nada | A 16/10/2026, projects.consent_delete_on_withdraw no está establecido para ningún proyecto (evaluado en la rama consent_withdrawn de srv/db_worker.php) | La retirada detiene nuevas grabaciones, como exige el art. 7(3), pero un cliente que suponga que también elimina la grabación anterior se equivoca. Esta distinción debe indicarse en la documentación dirigida al cliente. |
| Todo lo expuesto aquí se mide en la instancia de desarrollo | APP_ENV=dev; el proyecto de prueba mpconsenttest01 y los datos de prueba s_mptest_ están incluidos en los recuentos | La estructura de este registro se traslada a producción; las cifras, no. Debe medirse producción antes de utilizar este registro externamente. |
| La búsqueda de llamadas de salida no fue exhaustiva | Se buscaron en cfg/, srv/, class/ y www/ curl_init, curl_exec, file_get_contents con http, fsockopen, stream_context_create y todos los literales https; no se examinaron los directorios de proveedores | Los árboles de proveedores contienen los endpoints de Stripe, Google Cloud, PHPMailer y Symfony. Esos servicios se mencionan en el apartado 4, pero la afirmación 'no existe ninguna otra llamada de salida' está limitada por la búsqueda. |
| Sin interruptor por proyecto para los perfiles de comportamiento | profile_aktiv es una configuración global del operador. mp_ki_module_katalog() en cfg/lib.php enumera nueve secciones de IA seleccionables y ninguna son los perfiles, por lo que projects.ki_module no cubre esta pestaña; la entrada de navegación de www/project.php es incondicional. Medido el 27/08/2026. | Un cliente que no quiera que se agrupen las visitas de sus visitantes no puede desactivarlo. Controla la grabación; la derivación a partir de ella, no. Cualquier otra sección derivada puede deseleccionarse por proyecto: esta es la excepción. La carencia de conservación que figuraba aquí hasta el 27/08/2026 está cerrada: mp_profile y mp_sequenzmuster tienen ahora plazos propios, véase 6.2. |
| Una solicitud de supresión solo alcanza las sesiones importadas de GA4 cuando el puente de análisis está activado | Desde el 01/09/2026, mp_sitzungen_loeschen() incluye ga4_sessions y ga4_events en una solicitud del art. 17, vinculadas mediante ga4_sessions.user_pseudo_id = visitor_sessions.custom_user_id y limitadas al canal. Ese vínculo solo existe cuando el cliente ha activado el puente de análisis de GA4: es lo que escribe allí el ID de cliente de la cookie _ga. Si, en cambio, rellena custom_user_id mediante setUserId() con un identificador propio, no existe ninguna vía del visitante a su fila importada. El caso tiene una prueba propia (test_ga4_import.php, apartado J) para que no se olvide. | Para esos clientes, la fila importada permanece tras una solicitud de supresión hasta que la elimina el plazo de A.14. Es seudónima y no podemos atribuirla: precisamente por eso no puede eliminarse de forma selectiva. Una vía de eliminación mediante la propia propiedad de GA4 corresponde al responsable que la opera. |
| El consentimiento de las filas importadas no puede acreditarse, solo inferirse | Se importa lo que lleva un user_pseudo_id; los accesos sin cookies cuando se deniega el consentimiento no lo llevan y quedan excluidos (A.14). No hay para estas filas ningún registro comparable a consent_events: GA4 no proporciona en la exportación ningún atributo de consentimiento que pueda almacenarse aquí. | Para sus propias grabaciones, MousePlayer puede mostrar por sesión en qué se basan; para una sesión importada, no. La barrera es mecánica y funciona, pero solo prueba que se estableció una cookie, no qué aceptó el visitante. La responsabilidad corresponde al responsable del tratamiento, que controla la recogida en Google. |
| El nombre personalizado del visitante es texto libre sin comprobar | A.13, desde el 28/08/2026. mp_besucher_label_setzen() trunca a 64 caracteres, retira saltos de línea y verifica que el visitante pertenece al proyecto; nada comprueba el CONTENIDO y no hay ninguna especificación del tipo que debería tener. | El responsable puede escribir categorías especiales del art. 9 en él („Sr. X, silla de ruedas“) sin ninguna barrera ni advertencia. El cumplimiento es responsabilidad suya, no del encargado, pero un encargado que ofrece un campo de texto libre y no dice nada al respecto ha creado la oportunidad. No es posible una comprobación técnica: una máquina no puede distinguir un nombre de un dato de salud. Lo que sí sería posible es una nota junto al campo. |
| Ejemplos de revisión posterior de bots sin plazo de eliminación | Un vector de características seudónimo por sesión decidida (bot_review_labels, A.19) permanece después de la sesión mientras no se establezca un plazo. El valor por defecto de retention_bot_labels_years es 0 (ilimitado); el operador puede establecerlo en años. | No son contenido de visitantes, pero contienen el identificador de sesión. Establecer un plazo es una decisión del operador. |
| El texto libre de una encuesta solo se filtra de forma aproximada | A.21, desde el 27/09/2026. mp_umfrage_text_filtern() sustituye direcciones de correo electrónico, direcciones IP y números de teléfono, en el navegador y de nuevo en el trabajador. No reconoce nombres, direcciones postales, números de cliente ni información de salud. | Un visitante puede escribir cualquier cosa en la pregunta complementaria, incluidas categorías especiales del art. 9. La nota bajo el campo le pide que no lo haga; no es un bloqueo. Como ocurre con el nombre de visitante propio del responsable (A.13), el contenido no puede clasificarse de forma fiable mediante una máquina. |
11. Mantenimiento de este registro
Los arts. 30(1) y 30(2) exigen que el registro se mantenga por escrito y se ponga a disposición de la autoridad de control previa solicitud. Esto hace necesarias dos cosas que no están en el propio documento: alguien que se haga cargo y un intervalo para contrastarlo con el sistema, no con la versión anterior de sí mismo.
- Responsable e intervalo de revisión: Responsable: Lukas Wójcik, propietario. Se revisa anualmente y con cada cambio del tratamiento. Las versiones fechadas se conservan en el control de versiones bajo
ai/cms/. (decisión del responsable del tratamiento, 17/08/2026) - Acontecimientos que obligan a actualizarlo con independencia del intervalo: un nuevo subencargado o un cambio de destino; una nueva tabla con datos personales; un cambio en la cadena de eliminación
mp_sitzungen_loeschen()o en la purga diaria de srv/db_worker.php; activación de la exportación a BigQuery o de webhooks para cualquier cliente; un cambio en los valores por defecto de enmascaramiento; el primer cliente cuyo sitio muestre datos de categorías especiales. - Método: cada cifra de este registro procede de una medición frente al código, el esquema o la base de datos en una fecha indicada. Una revisión que solo relee el texto no ha revisado nada: las cifras deben medirse de nuevo y los marcadores deben completarse o mantenerse expresamente con un motivo.
- Este registro no sustituye la lista de subencargados, el documento de medidas técnicas y organizativas, el acuerdo de tratamiento de datos ni el aviso de privacidad. Si esos documentos y este registro discrepan, la discrepancia es un hallazgo, no una cuestión de formato.