Comparativa crítica de fuentes de Biodata HealthKit / Android Health Connect / Oura
Resumen técnico — 2026-06-21 — Fenotipo
Resumen de la sesión de análisis sobre las tres vías de adquisición de datos wearable
que alimentan BiodataDiaria, y de por qué se descarta construir un importador
para el export CSV masivo de Oura.
1. Las tres fuentes y su naturaleza
Fuente
Canal
Naturaleza
Apple HealthKit
Export ZIP (XML) → reducido semanal → agregación diaria, o pipeline JSON
Esquema estable y documentado (HKQuantityTypeIdentifier...). Pipeline propio, rápido de parsear.
Android / Health Connect
ZIP de Google Takeout → CSV por carpetas/tipo de métrica
Pipeline tan sólido arquitectónicamente como el de HealthKit, pero la calidad del dato depende del wearable real (Garmin validado vs smartband genérico) — variable externa, no defecto del sistema.
Oura Ring
API v2 en vivo (3 endpoints: daily_activity, sleep, daily_spo2) + export web manual (50 CSV)
Único caso en que tanto el canal (API incompleta, export desorganizado) como el dispositivo (pérdida de señal nocturna por movimiento) presentan problemas estructurales, no corregibles eligiendo "mejor" hardware Oura.
2. Hallazgos concretos de esta sesión
Bug real corregido:HealthKitBiodataMapper.cs no marcaba HrvOrigen en la vía XML/aggregator de HealthKit (solo lo hacía el pipeline JSON). Corregido.
Bug real corregido:GoogleHealthConnectImportService.cs etiquetaba el HRV de Android (SDNN, fichero HeartRateVariabilitySdnn) como HrvSource.OuraRMSSD, contaminando el baseline de Oura con datos Android. Corregido a HealthKitSDNN.
Análisis del export web de Oura (carpeta App Data, 50 CSV): JSON anidado en celdas, sin unidades ni algoritmo documentado, varios ficheros sin filas de datos (dailyresilience, dailymetabolicscore, sleeptime). Ninguno de los campos "exclusivos" de ese export (contributors, resiliencia, edad cardiovascular, VO2max, estrés intradía) tiene columna equivalente en BiodataDiaria.
Comparativa empírica HRV/sueño real (datos propios, 13–21/06/2026, HealthKit SDNN vs Oura RMSSD sobre las mismas noches):
HRV: magnitud comparable (18–33 ms en ambos), sin sesgo direccional estable día a día.
FC reposo/media: Oura sistemáticamente más baja — no es un error, es la ventana temporal distinta ya documentada (FcMediaOrigen: HealthKit = media de todo el día, Oura = media nocturna).
Sueño total: divergencias de hasta 79 min/noche (17/06: 515 vs 436 min).
Minutos de vigilia: el hallazgo más claro — 17/06, Apple 21 min vs Oura 122 min (casi 6×). Patrón compatible con pérdida/reclasificación de señal por movimiento nocturno en el anillo.
Sueño profundo/REM: desacuerdo alto en ambos sentidos, sin sesgo sistemático claro.
13/06/2026: Oura no produjo ningún dato esa noche (el registro conservó el valor de HealthKit por defecto) — evidencia directa de hueco no aleatorio.
3. Por qué la varianza no es el criterio correcto para "valor como referencia"
Comparando coeficiente de variación (Apple ≈ 18,7 %, n=9; Oura ≈ 20,6 %, n=5) y salto medio
noche a noche (Apple ≈ 6,6 ms; Oura ≈ 6,0 ms), no hay un ganador claro en ruido puro
cuando ambos dispositivos sí registran dato.
El factor decisivo es la completitud de la serie, no la varianza puntual: Oura parece
fallar de forma no aleatoria precisamente en noches de sueño inquieto — justo las noches más
informativas para un score de recuperación. Construir un RecoveryBaseline sobre una
serie con huecos sistemáticos en los días "malos" sesga la media/desviación hacia un escenario
artificialmente tranquilo (sesgo de supervivencia).
4. Ranking final de fiabilidad como fuente para Fenotipo
HealthKit (Apple Watch/iPhone) — pipeline más limpio, serie completa, sin huecos sistemáticos detectados.
Android / Health Connect (con wearable serio, p. ej. Garmin) — pipeline de adquisición arquitectónicamente equivalente al de HealthKit; su techo de fiabilidad lo pone el dispositivo elegido por el usuario, no el sistema.
Oura Ring — último. Sus limitaciones (API incompleta, export inservible, pérdida de señal por movimiento, huecos no aleatorios) son del propio producto y no se corrigen eligiendo mejor el dispositivo ni calibrando el algoritmo.
5. Por qué se descarta construir un importador del export CSV de Oura
No aporta nada que ya no se intente cubrir vía API: los tres campos que sí usa BiodataDiaria (HRV, sueño, SpO2/FC) ya se importan en vivo por OuraDailyImportService. El export no mejora esos campos, solo añade ruido de parseo (CSV con JSON anidado, sin documentación de escala/unidad).
El resto del export es "cuento celestial": contributors, resiliencia, edad cardiovascular, VO2max y estrés intradía no tienen columna en el modelo de dominio. Importarlos no alimentaría ningún cálculo existente.
El problema de fondo es de canal, no de cobertura de campos: parsear las 50 CSV no resolvería ni la pérdida de señal nocturna por movimiento ni el sesgo de huecos no aleatorios del baseline.
Relación coste/beneficio económico: no se considera justificado el coste de hardware/suscripción de Oura (≈400 € + 5 €/mes) frente a HealthKit (ya integrado) o Android+Garmin (pipeline ya corregido).