44 · Actividad 360 — el tracker propio
Idea de Juanjo (24-ago): que ella pueda registrar sus paseos, carreras y pasos
dentro de NutriSync — como haría en Strava o Runna, pero sin salir de aquí. Epic O,
tramo nuevo O7. Este doc responde a las dos preguntas: qué construiríamos y con qué
piezas open-source se puede hacer sin añadir un solo vendor de pago.
La idea, y por qué encaja
NutriSync ya entiende su ciclo, su comida y su descanso. Le falta el movimiento
capturado, no tecleado: hoy el checklist pregunta «¿qué entrenaste?», y la respuesta
honesta muchas veces es «déjame mirar el otro app». Una aplicación 360 cierra ese hueco:
el teléfono es el sensor (GPS + podómetro), el paseo alimenta el anillo del día y la
usuaria no necesita otra app si no quiere.
El reloj ya está cubierto — y no por este tramo. Lo que ella
grabe con su Apple Watch o Garmin entra en Salud, y O1 (firmado hoy en la UST-06) lo lee de
ahí. O7 es para quien no tiene reloj, o quiere el mapa y el directo en nuestra app.
Y la app de reloj propia es O6, ya decidida (Juanjo, 24-ago): habrá apps de
watchOS/Wear OS con alertas, capturas simples y entreno desde la muñeca — su diseño está por
definir y el doc 45 abre esa conversación.
El listón: qué hacen las apps de referencia, y qué es esencial
Instrucción de Juanjo: mirar Strava, Runna, Nike Run Club y las apps de pasos como
ejemplos — lo nuestro sería mucho más simple, pero las features esenciales tienen que
estar.
- Strava: registro con mapa, feed social, segmentos y rankings, clubs, mapas de
calor. Su corazón es la comparación pública.
- Runna: planes de entrenamiento personalizados con coaching — su corazón es el plan.
- Nike Run Club / apps de pasos (Pacer, StepsApp): carreras guiadas, retos,
objetivos diarios y rachas — su corazón es el hábito.
De ahí, las esenciales que sí van: registro en vivo con
mapa · agregación de actividades (historial, semana/mes, totales, rachas) ·
objetivos personales · y actividades en compañía (quedar con otra usuaria para
salir juntas). Lo que NO va: segmentos, rankings públicos, feed abierto, mapas de calor,
planes de coaching — ni comparación pública ni rendimiento contra nadie.
Qué existe ya (por qué esto no parte de cero)
- El anillo de movimiento y el checklist con intensidad — el destino del dato ya está pintado.
health_signal con clave única y procedencia obligatoria — un paseo propio es una señal más, fuente nutrisync.
- Decisión G1c de la UST-06 (24-ago):
expo-sensors y expo-location
viajan como librerías en la 0.23.0 — sin modos background, permiso «mientras se usa». Si los
textos de permiso (ubicación + motion) van compilados en ese build, las pantallas de O7
pueden llegar después por OTA sin esperar a otro build nativo.
Qué se construiría — cinco tramos, cada uno con su vehículo
O7a · Pasos
El podómetro del teléfono
(Pedometer). Sin GPS, sin mapa, sin permiso de ubicación. Los pasos calibran la
recomendación de movimiento y suman al anillo. Vehículo: OTA tras la 0.23.0 (la
librería ya viaja).
O7b · Tracker GPS
Caminar/correr con pantalla
en vivo — tiempo, distancia, ritmo — y la ruta en un mapa. Al guardar: entrenamiento del día
+ anillo + señal propia. Fase 1 foreground (con la app abierta); el seguimiento con
pantalla bloqueada exige permiso «Always» y es fase 2. Vehículo: el mapa es dependencia
NATIVA → build posterior (pantallas y lógica, OTA).
O7c · Devolverlo a Salud
El entrenamiento
guardado aquí se escribe en HealthKit / Health Connect con su ruta — la misma reciprocidad
que el write-back del período (F2 de la UST-06). Quien mire Salud ve el paseo de NutriSync.
O7d · Agregación y objetivos
El historial de
actividades con su semana/mes, totales, rachas — y objetivos personales (pasos/día, salidas
o minutos/semana) que la app propone conscientes de la fase y ella ajusta. Todo JS +
SQL sobre health_signal: vehículo OTA, sin build.
O7e · Actividades en compañía
Invitar a otra
usuaria (o a un grupo privado) a salir juntas: proponer día y hora, confirmar, y que la
actividad quede en el día de ambas. Social íntimo y por invitación — no un feed. Es
la puerta natural de la capa comunidad (item P5 en 💡) y hereda su puerta: la política de
moderación (doc 20) antes de encenderse.
El esfuerzo: latidos, calorías y límites (estándares)
Petición de Juanjo (24-ago): que el esfuerzo se mida con estándares, no a ojo.
- Zonas de frecuencia cardíaca (Z1-Z5 sobre la FC máxima): FC máx estimada con
Tanaka (208 − 0,7 × edad; más fiable que el clásico 220 − edad) y, si el reloj aporta
FC en reposo, afinada con Karvonen (% de la reserva cardíaca). La FC en vivo viene del
RELOJ (doc 45 / señales O1); el teléfono solo no la tiene.
- Calorías activas: si hay sensor, las del reloj (vía Salud, con procedencia D32);
si no, estimación por MET (Compendio de Actividades Físicas) a partir de tipo, ritmo
y duración — siempre marcada como estimación.
- Límites: umbral personal configurable (p. ej. sostener Z4+ demasiado tiempo →
aviso suave). Los umbrales por fase los firma Constanza — son juicio clínico, no
ingeniería — y rigen los no negociables de Pilar: informativo, jamás diagnóstico; ante
señales de alarma, silencio prescriptivo y sugerencia de consultar.
La recomendación: qué actividad toca hoy (ciclo + alimentación)
Adición de Juanjo (24-ago): el recomendador cruza dos fuentes que ya tenemos —
la fase del ciclo (scoring de Constanza, determinista) y lo que ha comido hoy (los
macros reales del pipeline nutricional UST-05). Ejemplos del tono: «fase lútea + comida
ligera hoy → paseo suave o movilidad, mejor que series»; «folicular + buen desayuno →
día para apretar, si te apetece». Reglas deterministas con firma de Constanza (energía
disponible + fase → intensidad sugerida), cero LLM, y siempre en sugerencia — ella decide,
el anillo cuenta lo que haga. Es el cierre del círculo 360: la comida informa el movimiento
y el movimiento vuelve al día.
El stack abierto (la respuesta a «¿hay open source para esto?»)
| Pieza | Qué resuelve | Licencia / coste |
expo-location | GPS: posición, rutas, precisión, tipo de actividad
fitness (ahorra batería). Primera parte de Expo — cero vendor nuevo. |
MIT · ya embarcada (G1c) |
expo-sensors (Pedometer) | Pasos del teléfono, iOS y Android, sin
ubicación. | MIT · ya embarcada (G1c) |
| MapLibre React Native | El mapa nativo dentro de la app. Fork comunitario
de Mapbox GL anterior a su cambio de licencia (dic-2020): mismo motor, gobernanza abierta,
compatible con Expo vía config plugin. | BSD · gratis · dependencia nativa (build) |
| Protomaps (teselas, DIRECTO) | Decisión Juanjo (24-ago): sin escala
intermedia — el mapa en un fichero .pmtiles (extracto España/Iberia, unos pocos
GB) servido desde nuestro R2/Cloudflare. Tres razones: cero dependencia externa desde
el día 1, coste ≈ céntimos de almacenamiento, y privacidad — cada tesela que el móvil
pide revela por dónde anda la usuaria, y así esa petición llega a NUESTRO dominio, no a un
tercero. Mantenimiento: refrescar el extracto (mensual/trimestral, un cron). |
Open source · coste R2 |
| OpenFreeMap (plan B) | Teselas OSM públicas
sin clave ni límites — la red de seguridad si el pmtiles se retrasa o R2 diera guerra. No es
el camino: es el paracaídas. | Gratuito |
turf.js | Distancia y geodesia sobre la traza (JS puro, funciones
puras → unitarios). | MIT |
| Descartado: react-native-background-geolocation (Transistorsoft) |
El estándar comercial del tracking en background. No hace falta en fase 1
(foreground) y su licencia Android es de pago. | De pago |
MapTiler queda descartado: con Protomaps directo no hace falta ningún
vendor con API key.
Privacidad — la línea dura antes de escribir una línea de código
Una ruta GPS dibuja tu casa, tu portal y tu rutina. Es de lo más sensible que una
app puede guardar, y aquí se trata como tal desde el diseño:
- La ruta se queda en el dispositivo por defecto. A la base suben agregados:
fecha, tipo, duración, distancia, pasos, fuente. Subir la traza completa sería opt-in
explícito y cifrado como el resto — y no hace falta para nada de lo que el producto promete.
- Las rutas jamás entran a un LLM (P32 §2, la misma regla que los datos de salud).
- Nada social PÚBLICO: ni mapas públicos, ni heatmaps, ni rankings. Lo social de
O7e es íntimo y por invitación: si una ruta se comparte con la compañera, nace con
recorte automático de inicio y fin (zonas de privacidad) y sin ubicación en vivo por defecto.
- D16 intacto: los pasos y el GPS son datos objetivos — rellenan lo objetivo y
correlacionan con lo subjetivo. El ánimo sigue siendo suyo.
El diferenciador — esto no es otro Strava
Strava mide el rendimiento contra los demás. Aquí el paseo se lee contra su fase:
«hoy tu cuerpo pide suave» antes de salir, y al volver el esfuerzo cuenta en el anillo del
día que ya conoce su ciclo. La evaluación por fase sigue siendo la consulta determinista
contra el scoring de Constanza — el tracker aporta el dato, no el juicio.
Riesgos, con su antídoto
- Batería: tipo de actividad fitness + entregas diferidas de posición. Fase 1
foreground = el riesgo casi desaparece.
- App Review (fase 2): pedir ubicación en background exige una feature visible que lo
justifique. Por eso la fase 1 no lo pide — y por eso las librerías embarcadas en la 0.23.0
van SIN modos background.
- Play Console (fase 2): la ubicación en background lleva declaración propia y vídeo.
Conocido, documentado, para cuando toque.
- Coste de mapas a escala: Protomaps directo en R2 lo deja en céntimos desde el
día 1.
Calendario propuesto y decisión pedida
O7 no toca el camino al 8-oct. La recomendación de ingeniería:
- Ya decidido (G1c): las librerías viajan en la 0.23.0 con sus textos de permiso
compilados. Coste marginal cero para el build de wearables.
- O7a (pasos): candidata a OTA en septiembre si el piloto la pide — no antes de
cerrar wearables. Nacería con su UST.
- O7b + O7c (GPS, mapa, write-back): v2, tras el lanzamiento. MapLibre NO se mete
en la 0.23.0 — añadir una dependencia nativa a días del freeze es exactamente el tipo de
riesgo que la regla «no tenemos espacio para regresiones» prohíbe.
- O7d (agregación + objetivos): puede acompañar a O7a por OTA — es JS + SQL, sin
dependencia nueva. Los objetivos nacen fase-aware desde el primer día.
- O7e (en compañía): el último tramo, detrás de la política de moderación (doc 20)
— compartir personas es más delicado que compartir kilómetros.
- Decisión founders: validar O7 como tramo del Epic O y su orden (¿O7a+O7d en
septiembre u O7 entero a v2?). El item vive en 💡 Ideation hasta esa decisión.
Fuentes
- MapLibre React Native — github.com/maplibre/maplibre-react-native · maplibre.org
- OpenFreeMap — openfreemap.org (teselas OSM sin clave ni límites) · Protomaps — protomaps.com
- Expo — docs.expo.dev/versions/latest/sdk/location · /sdk/pedometer · blog «How to build a resilient activity tracker with Expo»
- Apple — developer.apple.com HKWorkoutBuilder · HKWorkoutRouteBuilder (escribir entrenos con ruta)
- turf.js — turfjs.org · Transistorsoft (descartada) — github.com/transistorsoft/react-native-background-geolocation
Doc 44 · 24-ago-2026 · origen: idea de Juanjo (chat de
ingeniería) · relacionado: Propuesta 33 (wearables), UST-2026-08-24-06 (firmada), doc 42
(decisiones D15-D17). El item O7 vive en 💡 Ideation del hub.