Saltar a contenido

ADR-003: Estrategia Offline-First con Zero-Knowledge

Estado: ACEPTADO Fecha: 2025-12-07 Actualizado: 2025-12-07 (integración Zero-Knowledge) Autor: ArchitectureDrone (MTS-DRN-ARC-001) Revisores: SpecQueen, Director


1. Contexto

MedTime es una app de salud crítica donde:

  • Los recordatorios de medicamentos NO pueden fallar por falta de conexión
  • Los datos de salud (PHI) son extremadamente sensibles
  • El servidor NO debe poder ver datos PHI (Zero-Knowledge)
  • La sincronización debe funcionar con datos cifrados E2E

2. Decisión

Adoptamos una estrategia Offline-First + Zero-Knowledge donde:

  1. 95% del procesamiento ocurre en el dispositivo
  2. El servidor solo recibe blobs cifrados E2E (no puede leerlos)
  3. La sincronización maneja datos opacos para el servidor
  4. Conflictos de metadata se resuelven por timestamp; conflictos de PHI requieren intervención del usuario

2.1. Arquitectura Dual

┌─────────────────────────────────────────────────────────────┐
│                    DISPOSITIVO (95%)                         │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐ │
│  │ Local DB │ → │ Cifrado  │ → │  Sync    │ → │  API     │ │
│  │ (claro)  │   │   E2E    │   │  Queue   │   │ Client   │ │
│  └──────────┘   └──────────┘   └──────────┘   └──────────┘ │
└─────────────────────────────────────────────────────────────┘
                              ↓ Solo blobs cifrados
┌─────────────────────────────────────────────────────────────┐
│                    SERVIDOR (5%)                             │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐                │
│  │PostgreSQL│ ← │   API    │ ← │ Firebase │                │
│  │(blobs)   │   │  Sync    │   │   Auth   │                │
│  └──────────┘   └──────────┘   └──────────┘                │
│  NO puede descifrar los blobs - Zero-Knowledge              │
└─────────────────────────────────────────────────────────────┘

2.2. Clasificación de Datos para Sincronización

Clasificación Qué contiene Cómo se sincroniza
LOCAL_ONLY Patrones ML, claves NUNCA sale del dispositivo
SYNCED_E2E PHI (medicamentos, dosis) Blob cifrado AES-256-GCM
SYNCED_HASH Email, teléfono Blind Index (HMAC-SHA256)
SYNCED_PLAIN Tier, timestamps Texto claro (no es PHI)
SERVER_SOURCE Catálogo medicamentos Usado para construir catálogo local
ANONYMIZED_DATA Datos para enriquecer catálogos Anonimizado con DP antes de enviar

NOTA sobre SERVER_SOURCE: Los clientes NO cachean catálogos públicos directamente. Construyen sus propios catálogos combinando datos públicos + entradas manuales.

NOTA sobre ANONYMIZED_DATA: Ver INV-010 para detalles del proceso de anonimización con Differential Privacy.

IMPORTANTE: La anonimización usaseparación de identidad, NO generalización a categorías. - SÍ se envía: Nombre específico del medicamento (ej: "Glucophage"), dosis exacta - NO se envía: user_id, email, device_id, IP, timestamps exactos - Consentimiento: OBLIGATORIO para usuarios con cuenta (requisito para usar la app)

2.3. Resolución de Conflictos

Tipo de dato Escenario Resolución
SYNCED_PLAIN Mismo campo, diferente valor Server timestamp gana
SYNCED_E2E Mismo blob, diferentes versiones UI de merge manual (servidor no puede comparar)
SYNCED_HASH Hash diferente Server timestamp gana
LOCAL_ONLY N/A No hay conflicto (no sincroniza)

IMPORTANTE: Para datos cifrados E2E, el servidor NO puede hacer merge automático porque no puede leer el contenido. El cliente debe resolver estos conflictos.

3. Consecuencias

3.1. Positivas

  • Confiabilidad: App funciona sin red
  • UX fluida: Sin spinners de carga
  • Critico para salud: Recordatorios nunca fallan
  • Bateria: Menos conexiones de red

3.2. Negativas

  • Complejidad: Logica de sincronizacion compleja
  • Storage local: Requiere mas espacio en dispositivo
  • Consistencia eventual: Datos pueden estar desactualizados temporalmente

3.3. Riesgos

  • Conflictos de datos: Edicion simultanea offline
  • Mitigacion: UI de resolucion de conflictos clara

4. Alternativas Consideradas

4.1. Online-Only

  • Rechazado porque: No aceptable para app de salud critica

4.2. Cache Simple

  • Rechazado porque: No permite escrituras offline

5. Referencias


ADR actualizado - RESET-02 (integración Zero-Knowledge)