lección 2

Día 1 -- Derecho al olvido en datos de salud

Un paciente ejerce su derecho al olvido. Inventarias sus datos en 6 tablas, diseñas el proceso de borrado selectivo respetando excepciones legales sanitarias y generas evidencia auditable.

45 min

### Lunes, 9:00 AM -- La solicitud de Rosa

Datasets de esta lección (en tu carpeta datos/): datos/pacientes.csv (columnas id, nombre, email, telefono, dni, fecha_nacimiento, direccion, consent_investigacion, consent_marketing), datos/diagnosticos.csv (codigo_cie10, es_cronico, estado), datos/prescripciones.csv (medicamento, principio_activo, fecha_inicio, fecha_fin, renovada — fecha_fin vacía o futura indica tratamiento ACTIVO que NO se puede borrar), datos/citas.csv, datos/lecturas_wearable.csv, datos/consentimientos.csv y datos/peticiones_supresion.csv (paciente_id, fecha_recepcion, fecha_limite, dias_restantes, estado). Recuerda: el inventario del paciente PAC-284719 es un ejercicio de diseño conceptual (ese id no aparece literalmente en los CSV, donde los ids son numéricos en la columna id).

Llevas 3 días en MediTrack. Laura te ha enseñado el lake, te ha dado accesos (con permisos mínimos, como manda Rosa) y has empezado a entender el flujo de datos. Javier está a tu lado, aprendiendo contigo. Entonces llega el mensaje de Rosa al canal #data-privacy con prioridad máxima:

1Rosa Martinez 09:03 AM #data-privacy
2@equipo-datos URGENTE
3
4Solicitud ARCO de supresión recibida. Paciente PAC-284719.
5Art. 17 GDPR -- derecho al olvido.
6
7Plazo legal: 30 días (recibida hoy 4 de marzo).
8Deadline interno: 20 de marzo (10 días de margen por seguridad).
9
10Este paciente tiene historial de 2 años:
11- 14 consultas de telemedicina
12- 3 prescripciones (2 finalizadas, 1 ACTIVA hasta junio)
13- Datos de pulsera IoT (8 meses de telemetria cardiaca)
14- 1 derivacion a especialista externo
15
16RESTRICCION LEGAL Art. 17.3.c: La prescripcion activa NO se puede
17borrar hasta su finalizacion. Obligacion legal de conservacion sanitaria.
18El resto: suprimir o anonimizar segun corresponda.
19
20Necesito de vosotros:
211. Inventario completo de DONDE viven los datos de este paciente
222. Plan de ejecucion con clasificacion por tabla (borrar/anonimizar/conservar)
233. Script REPRODUCIBLE y AUDITABLE (nada de queries manuales)
244. Certificado de supresión para el registro de actividades de tratamiento
25
26@tu -- esto es tuyo. Laura revisa. Javier observa y aprende.
27
28"Los datos son personas." -- Rosa

Rosa no improvisa. Tiene plantillas para todo y deadlines legales claros.

Javier se gira hacia ti: "Qué es una solicitud ARCO?" Le explicas rápidamente: "Acceso, Rectificación, Cancelación y Oposición. Son los derechos que tiene cualquier persona sobre sus datos personales. En este caso es supresión -- el paciente quiere que borremos todo lo que tenemos de él. Pero aquí es más complejo que en otros sitios porque hay datos que estamos OBLIGADOS a conservar por ley sanitaria."

Laura se acerca a tu mesa con un café. "Tu primer borrado GDPR en salud. Es más complejo que lo de NeoBank -- allí solo tenías transacciones y datos bancarios. Aquí tienes historiales clínicos, prescripciones activas con obligación legal, datos de wearables en S3, y además tienes que preservar utilidad estadística para el Dr. Martin. La gracia es que no puedes borrar TODO -- hay partes que la ley te OBLIGA a conservar aunque el paciente lo pida."

### El framework legal: Art. 17 vs Art. 17.3

Antes de tocar una sola línea de código, necesitas entender el marco legal. Rosa te manda un documento interno que resume las reglas:

  1. 01.Art. 17.1 GDPR: El paciente tiene derecho a obtener la supresión de sus datos personales sin dilación indebida.
  2. 02.Art. 17.3.b: EXCEPCION -- No aplica si el tratamiento es necesario para el cumplimiento de una obligación legal. Las prescripciones activas se conservan por la Ley de Garantías de Uso Racional del Medicamento.
  3. 03.Art. 17.3.c: EXCEPCION -- No aplica si es necesario por razones de interés público en salud pública.
  4. 04.Art. 17.3.d: EXCEPCION -- Fines de archivo en interés público, investigación científica o histórica, o fines estadísticos (si la supresión hace imposible el objetivo).
  5. 05.Art. 17.3.e: EXCEPCION -- Para la formulación, ejercicio o defensa de reclamaciones.
  6. 06.Ley 41/2002 (Autonomía del Paciente): Los datos clínicos se conservan MINIMO 5 años tras el alta. PERO esto aplica a centros sanitarios -- MediTrack como plataforma tecnológica tiene un estatus jurídico más complejo.

La tensión legal en salud es REAL: el paciente tiene derecho al olvido, pero la ley sanitaria obliga a conservar ciertos datos. Cuando hay conflicto, la obligación legal de conservación GANA al derecho de supresión. Pero tienes que documentar POR QUE conservas cada dato -- no puedes simplemente "no borrar" sin justificación jurídica.

### El inventario de datos -- Donde vive PAC-284719

El primer paso es mapear TODOS los lugares donde existen datos de este paciente. Laura te da una pista: "No son solo las tablas de PostgreSQL. También hay Parquets en S3 con datos de wearables, logs de acceso en el audit trail, y potencialmente backups cifrados. El inventario tiene que ser COMPLETO o Rosa no lo acepta."

No todo se borra -- las excepciones legales son la parte difícil

### Diseño del proceso de supresión

Rosa necesita que el proceso sea REPRODUCIBLE y AUDITABLE. No vale hacer queries manuales en un DBeaver y "confiar" en que fue bien. Necesitas un script Python que ejecute cada paso, verifique el resultado, genere logs y produzca un certificado de supresión. Laura añade: "Y necesita tests. Si el día de mañana cambia el esquema y el script falla silenciosamente, tenemos un problema legal."

El proceso tiene 5 fases obligatorias:

  1. 01.VERIFICACION: Comprobar que el paciente existe y que no hay restricciones que impidan el borrado completo (prescripciones activas, reclamaciones abiertas, procedimientos judiciales).
  2. 02.INVENTARIO: Localizar todos los datos del paciente en todas las fuentes (PostgreSQL, S3, backups), contando registros en cada una.
  3. 03.CLASIFICACION: Determinar la acción correcta para cada tabla/fuente según las excepciones del Art. 17.3.
  4. 04.EJECUCION: Aplicar las acciones (borrar/anonimizar/conservar) en orden seguro, con transacciones y rollback en caso de error.
  5. 05.EVIDENCIA: Generar certificado de supresión firmado digitalmente para el registro de actividades de tratamiento (Art. 30 GDPR).

### Anonimización funcional -- el concepto clave

El Dr. Martin te para en el pasillo antes de comer: "Oye, ese paciente del que vais a borrar datos -- tenía un caso de fibrilación auricular detectada por la pulsera IoT. Es un caso interesante para mi estudio sobre detección precoz. No podemos perder ESE dato clínico." Rosa, que pasaba por allí (siempre pasa por allí cuando se habla de datos), interviene: "Puedes conservar el HECHO clínico si lo anonimizas de forma irreversible. El dato estadístico se queda; la persona desaparece. Pero tiene que ser realmente irreversible -- no pseudonimización con clave."

Esto es lo que se llama "anonimización funcional": transformar el registro de forma que sea IMPOSIBLE reidentificar al paciente, pero conservando el valor analítico. En la práctica significa eliminar todos los identificadores directos (nombre, DNI, email, teléfono) y generalizar los quasi-identificadores (fecha nacimiento -> rango de edad, código postal -> provincia, fecha exacta -> trimestre).

1# Ejemplo conceptual: anonimización funcional de un historial clinico
2
3# Registro ORIGINAL (tal como está en la BD):
4registro_original = {
5 "paciente_id": "PAC-284719",
6 "nombre": "Carlos Mendez Garcia",
7 "fecha_nacimiento": "1978-03-15",
8 "codigo_postal": "46021",
9 "diagnostico_cie10": "I48.0", # Fibrilacion auricular paroxistica
10 "fecha_diagnostico": "2023-09-14",
11 "notas_medicas": "Detectado via smartwatch. Paciente asintomatico. "
12 "Trabaja como profesor en el IES Lluis Vives.",
13 "medico_id": "MED-0451",
14 "especialidad": "cardiologia"
15}
16
17# Registro ANONIMIZADO (conserva valor clinico, persona irrecuperable):
18registro_anonimizado = {
19 "paciente_id": "ANON-8f2a4b9c", # Hash irreversible (SHA-256 + salt)
20 "nombre": None, # ELIMINADO
21 "rango_edad": "45-49", # Generalizado (edad exacta -> rango 5 años)
22 "provincia": "Valencia", # Generalizado (46021 -> Valencia)
23 "diagnostico_cie10": "I48.0", # CONSERVADO (valor clinico, no identifica)
24 "trimestre_diagnostico": "2023-Q3", # Generalizado (fecha exacta -> trimestre)
25 "notas_medicas": None, # ELIMINADO (texto libre = riesgo alto)
26 "medico_id": "MED-0451", # Conservado (identifica al medico, no al paciente)
27 "especialidad": "cardiologia" # Conservado (no identifica al paciente)
28}
29
30# POR QUE se elimina cada campo:
31# - nombre: identificador directo obvio
32# - fecha_nacimiento exacta: quasi-identificador (combinado con otros = reidentificacion)
33# - codigo_postal completo: quasi-identificador (46021 tiene ~3000 habitantes)
34# - notas_medicas: contienen información que reidentifica ("profesor en IES Lluis Vives")
35# - fecha exacta: quasi-identificador temporal

El dato clínico (I48.0) se conserva para investigación; la persona desaparece para siempre

Las notas médicas en texto libre son una bomba de privacidad. Un médico puede escribir "el paciente, que trabaja de profesor en el IES Lluis Vives de Valencia, comenta que su mujer Maria le ha notado arritmias por la noche" -- eso reidentifica al paciente aunque borres su nombre. Las notas médicas SIEMPRE se eliminan en anonimización. NUNCA se generalizan ni se resumen.

### El flujo completo de supresión

1# flujo_supresion_gdpr.py -- Proceso completo de right-to-be-forgotten
2# Este es el 20% de código que se te DA como referencia.
3# Tu implementaras el 80% restante en los ejercicios.
4
5import logging
6from datetime import datetime, date
7from typing import Dict, List, Any, Optional
8from dataclasses import dataclass, field
9from enum import Enum
10
11logging.basicConfig(
12 level=logging.INFO,
13 format='%(asctime)s [%(levelname)s] %(message)s'
14)
15logger = logging.getLogger('gdpr_supresion')
16
17
18class AccionSupresion(Enum):
19 """Acciones posibles sobre datos de un paciente."""
20 BORRAR = "borrar" # Eliminacion fisica total
21 ANONIMIZAR = "anonimizar" # Eliminar PII, conservar valor clinico
22 CONSERVAR = "conservar" # Obligacion legal impide borrado
23 DIFERIR = "diferir" # Se borrara cuando expire la obligacion
24
25
26@dataclass
27class ResultadoInventario:
28 """Resultado del inventario de datos de un paciente."""
29 tabla: str
30 registros: int
31 accion: AccionSupresion
32 justificacion_legal: str
33 ejecutado: bool = False
34 timestamp_ejecucion: Optional[str] = None
35
36
37@dataclass
38class CertificadoSupresion:
39 """Certificado generado tras completar la supresión."""
40 solicitud_id: str
41 paciente_id: str
42 fecha_solicitud: str
43 fecha_ejecucion: str
44 acciones_ejecutadas: List[Dict[str, Any]] = field(default_factory=list)
45 restricciones_encontradas: List[str] = field(default_factory=list)
46 hash_evidencia: str = "" # SHA-256 del log completo
47
48
49# Este es el ESQUELETO. Tu implementas la clase GDPRSupresionSalud
50# en el ejercicio siguiente.

Estructura base -- tú implementas la lógica completa

Consejo de senior: El proceso de borrado GDPR en salud nunca es "DELETE FROM pacientes WHERE id = X". Es un workflow multi-paso con verificaciones legales en cada punto. Diséñalo como una máquina de estados donde cada transición requiere una comprobación: hay prescripción activa? hay reclamación abierta? hay obligación de archivo? Solo si todo dice "no restricción", procedes al borrado físico. Si hay alguna restricción, documentas POR QUE no borras y QUE harás cuando la restricción expire.

## ejercicios

[01]

Inventario completo de datos del paciente

Escribe una query SQL que localice TODOS los datos del paciente PAC-284719 en las tablas del sistema. Debe contar registros en cada tabla y asignar la accion correcta (BORRAR/ANONIMIZAR/CONSERVAR/DIFERIR) con su justificacion legal basada en el Art. 17.3 del GDPR.

Cargando editor...
[02]

Script de supresión GDPR completo

Implementa la clase GDPRSupresionSalud en Python. Debe: 1) verificar restricciones legales, 2) ejecutar borrado/anonimización por tabla, 3) generar log detallado de cada operación, 4) producir certificado de supresión. Incluye la logica de anonimización funcional (hash irreversible, generalizacion de quasi-identificadores).

Cargando editor...
[03]

Verificacion post-supresión y generacion de evidencia

Despues de ejecutar la supresión, necesitas VERIFICAR que realmente se completo correctamente y generar la evidencia para Rosa. Escribe queries SQL que comprueben: 1) el paciente ya no existe en tabla pacientes con PII visible, 2) los historiales tienen paciente_id anonimizado, 3) los wearables fueron eliminados, 4) la prescripcion activa sigue intacta.

Cargando editor...

Regístrate para guardar tu progreso.

## comentarios

Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.

Inicia sesión para comentar y responder.

cargando comentarios...