Ir al contenido

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.

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).

ÁreaEstadoHito reciente
Auth multi-tenantGAOTP portal y proveedores configurables por tenant
FHIR multi-tenancyGAS9 ORGBAC con credenciales per-tenant decryptadas runtime
BillingGAPricing en tres niveles más DTE SII
GES (90 patologías)GAAuto-detección, declaración y task con SLA
ENO (150 CIE-10)GANotificación automática al MINSAL
SchedulingGAMulti-recurso, colisiones soft/hard, excepciones
CPOEGACatálogo, order sets y autocomplete
Urgencia (L1.5)ParcialESI triaging y métricas listos; L2+ pendiente
SDC / QuestionnairesGACuestionarios GES y assemble de subQuestionnaire
REM (DEIS export)GAFiltrado por establishment code por tenant
Portal pacienteGARead-only con OTP y booking integrado
FirmasParcialQR-based; FEA en V1.5
EMI integrationGAProxy server-side con gating por tenant

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.

CapaTecnologíaVersión
BackendHono^4.7
RuntimeCloudflare Workers
FrontendReact 19 + React Router 7 + Vite 619 / 7.3 / 6.2
EstilosTailwind v4 con Design System v1.0^4
UI primitivesRadix UI^1.x
FormulariosReact Hook Form + Zod^7.54 / ^3.24
StateZustand^5
GráficosRecharts^2.15
BD clínicaAidbox FHIR R4instancia compartida, aislamiento ORGBAC
BD operacionalSupabase (proyecto emahub)schemas emaclinic y emashared
FHIR clientemafhir^0.6.0 (createEmaClient, post-Wave 1)
TestsVitest^4.1
DeployWrangler^4

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.

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.