Overview y stack
EMA Clinic es el sistema clínico institucional B2B del ecosistema EMA Health, orientado a clínicas privadas chilenas. Cubre el flujo ambulatorio completo y la atención de urgencia de baja complejidad, con scheduling multi-recurso, CPOE, portal de paciente y la regulación chilena (GES, ENO, DTE, Ley 20.584) integrada como parte del producto en lugar de una capa de extensión. La arquitectura es FHIR-native multi-tenant: una sola instancia de Aidbox sirve a todos los clientes, con aislamiento server-side por ORGBAC.
Estado del producto
Sección titulada «Estado del producto»La versión actual es 0.2.0, con el sprint S9 (Aidbox ORGBAC
Multi-Tenancy) cerrado el 2026-05-08 y Wave 3 v2.0 finalizada. El
sistema está en producción en clinic.emahealth.io y se considera
listo para piloto controlado con un cliente real. Como métricas
gruesas, el repo tiene 520 tests pasando con 57 omitidos (env-gated),
expone 53 rutas API en 45 páginas SPA, y acumula más de 236
decisiones formales registradas en docs/decisions.md (F001 a F236).
La tabla siguiente resume el estado de cada área funcional. La mayoría está en GA; las dos excepciones son urgencia (implementada parcialmente, con flujos L2+ todavía pendientes) y firmas (QR-based, con FEA planificada para la versión 1.5).
| Área | Estado | Hito reciente |
|---|---|---|
| Auth multi-tenant | GA | OTP portal y proveedores configurables por tenant |
| FHIR multi-tenancy | GA | S9 ORGBAC con credenciales per-tenant decryptadas runtime |
| Billing | GA | Pricing en tres niveles más DTE SII |
| GES (90 patologías) | GA | Auto-detección, declaración y task con SLA |
| ENO (150 CIE-10) | GA | Notificación automática al MINSAL |
| Scheduling | GA | Multi-recurso, colisiones soft/hard, excepciones |
| CPOE | GA | Catálogo, order sets y autocomplete |
| Urgencia (L1.5) | Parcial | ESI triaging y métricas listos; L2+ pendiente |
| SDC / Questionnaires | GA | Cuestionarios GES y assemble de subQuestionnaire |
| REM (DEIS export) | GA | Filtrado por establishment code por tenant |
| Portal paciente | GA | Read-only con OTP y booking integrado |
| Firmas | Parcial | QR-based; FEA en V1.5 |
| EMI integration | GA | Proxy server-side con gating por tenant |
Stack tecnológico
Sección titulada «Stack tecnológico»El stack se decidió privilegiando dos cosas: el ecosistema TypeScript end-to-end (un solo lenguaje en frontend, backend, tests y schemas) y la operación sobre el edge de Cloudflare. Esa segunda decisión condicionó mucho del resto: descarta runtimes pesados, fuerza el uso de bibliotecas compatibles con Workers, y empuja a delegar la base de datos a servicios externos (Aidbox para FHIR, Supabase para operacional) en lugar de auto-hostearlos.
| Capa | Tecnología | Versión |
|---|---|---|
| Backend | Hono | ^4.7 |
| Runtime | Cloudflare Workers | — |
| Frontend | React 19 + React Router 7 + Vite 6 | 19 / 7.3 / 6.2 |
| Estilos | Tailwind v4 con Design System v1.0 | ^4 |
| UI primitives | Radix UI | ^1.x |
| Formularios | React Hook Form + Zod | ^7.54 / ^3.24 |
| State | Zustand | ^5 |
| Gráficos | Recharts | ^2.15 |
| BD clínica | Aidbox FHIR R4 | instancia compartida, aislamiento ORGBAC |
| BD operacional | Supabase (proyecto emahub) | schemas emaclinic y emashared |
| FHIR client | emafhir | ^0.6.0 (createEmaClient, post-Wave 1) |
| Tests | Vitest | ^4.1 |
| Deploy | Wrangler | ^4 |
Dominios y entornos
Sección titulada «Dominios y entornos»El tenant demo del producto vive en clinic.emahealth.io con slug
clinic y RUT 76.000.000-0; es la instalación que ve el equipo de
EMA cuando hace QA o demo a un prospect. Los tenants reales se
provisionan desde EMA Vault y reciben un dominio propio bajo el
patrón <slug>.emahealth.io, lo que permite separar la experiencia
de marca y el routing de auth por cliente sin replicar la
infraestructura del worker.
El repositorio del proyecto es github.com/emahealth/emaclinic.
Decisiones formales más relevantes
Sección titulada «Decisiones formales más relevantes»Las 236+ decisiones registradas se distribuyen entre áreas, pero un puñado son estructurales y conviene tener presentes al leer el resto de la documentación técnica.
El sprint S9, materializado en las decisiones F141, F225 y F226, introdujo el per-tenant FHIR client con decryption runtime y la política ORGBAC server-side. Es el cambio arquitectónico más relevante del último ciclo y es la base sobre la que opera todo el aislamiento entre clínicas. Las decisiones F55 a F62 modelan la auto-detección de Conditions y la evaluación contra el catálogo GES de 90 patologías, con creación automática de tasks por SLA; F63-F64 hacen lo análogo para ENO sobre 150 códigos CIE-10.
El motor de pricing en tres niveles (F78-F82) maneja los modos
particular, aseguradora y convenio empresa; el de scheduling
multi-recurso (F94-F101) resuelve la combinatoria de
disponibilidades cuando una consulta requiere médico, sala y equipo
simultáneamente. La emisión DTE SII sin intermediarios queda en
F102-F106, el reporte REM con establishment_code por tenant en
F207, y la configuración de proveedores de auth por tenant en
F122.
El detalle completo de cada decisión vive en docs/decisions.md del
repo, accesible al equipo técnico y de producto.