Overview y stack
EMA Well es la aplicación de autocuidado personal del ecosistema EMA
Health. A diferencia del resto de los productos —todos
institucionales y B2B— Well es B2C: cada cuenta corresponde a una
persona que cuida su salud y los datos viven aislados del resto del
ecosistema. La aplicación opera como un tracker simple sin jerga
clínica, con check-in diario en menos de sesenta segundos, racha,
achievements y un programa estructurado de doce semanas. La
diferencia frente a una app de hábitos genérica es que cada registro
queda almacenado como Observation FHIR canónica desde el primer
día, lo que vuelve los datos portables a cualquier sistema clínico
interoperable cuando el usuario lo requiera.
Estado del producto
Sección titulada «Estado del producto»Well se considera cerrado desde el punto de vista de doc mientras se ejecuta el Plan Consolidado. Ocho sprints de desarrollo quedaron cerrados, aproximadamente ochenta y dos features implementadas, integración con Stripe productiva, generación nativa de Observations FHIR, programa de doce semanas operativo y sistema de achievements completo. Las métricas agregadas —retención por cohorte, distribución de streaks, popularidad de pilares, actividad diaria— se exponen a EMA Vault para análisis interno sin comprometer la privacidad individual del usuario.
Stack tecnológico
Sección titulada «Stack tecnológico»El stack de Well combina dos decisiones que lo distinguen del resto
de los productos del ecosistema. La primera es la incorporación de
shadcn/ui sobre Tailwind como sistema de componentes (en lugar de
Radix UI con design system propio que usan Clinic y Lab), elegida
por la velocidad de iteración que permite en una app B2C donde la
estética debe sentirse cuidada sin requerir un equipo de diseño
dedicado. La segunda es el modelado de las Observations FHIR como
JSONB en Postgres bajo un schema dedicado fhir, en lugar de
delegar a Aidbox: para el volumen de datos por usuario, mantener el
schema en el mismo proyecto Supabase simplifica las queries
operacionales sin perder portabilidad estándar.
| Capa | Tecnología | Versión |
|---|---|---|
| Runtime | Cloudflare Workers más Pages | — |
| Backend | Hono | ^4.7 |
| Frontend | React, React Router, Vite | ^19 / ^7.3 / ^6.2 |
| Estilos | Tailwind con shadcn/ui | ^4 |
| Gráficos | Recharts | ^2.15 |
| Iconos | lucide-react | ^0.474 |
| Base de datos | Supabase (proyecto emawell propio) | client ^2.49 |
| FHIR | Schema fhir en Postgres con Observations JSONB | — |
| Pagos | Stripe | ^22 |
| IA | Claude API solo en tier Pro vía emaemi | haiku-4-5 |
Loops.so via mail.emahealth.io | — | |
| Auth | Supabase Auth con email/password y Google SSO | — |
| PWA | manifest.json más service worker | — |
| Tests | Vitest con coverage-v8 | ^4.1 |
| Deploy | Wrangler | ^4 |
Dominio y operación
Sección titulada «Dominio y operación»EMA Well opera en well.emahealth.io como subdominio propio del
ecosistema EMA Health. La PWA se instala desde Safari (en iOS) o
desde el navegador correspondiente (en Android y desktop) sin
requerir distribución por tiendas de aplicaciones, lo que evita la
fricción y los costos de revisión de Apple Store y Google Play.
El repositorio del proyecto es github.com/emahealth/emawell.
Aislamiento legal de los datos
Sección titulada «Aislamiento legal de los datos»La decisión más estructural del producto es vivir en su propio
proyecto Supabase, separado del proyecto compartido emahub que
usan Clinic, Lab y Vault. Es la única app del ecosistema con esta
separación, y responde a un requerimiento concreto: las leyes de
protección de datos personales de salud (en Chile la Ley 21.719,
en Brasil LGPD, en Estados Unidos HIPAA, en Europa GDPR) exigen
control estricto sobre datos personales de salud, y la forma más
limpia de cumplir es no permitir que esos datos compartan
infraestructura con datos institucionales de clínicas o vendors.
La consecuencia práctica es que ningún staff de EMA Health tiene acceso a los datos individuales de los usuarios desde Vault: solo las métricas agregadas (retención, streaks, pillars populares, actividad diaria) llegan al dashboard interno, y se calculan via queries server-side que nunca exponen filas individuales.