Ir al contenido

Overview y stack

EMA Vault es la plataforma interna de operaciones, finanzas y producto del ecosistema EMA Health. Concentra en una sola aplicación todo lo necesario para correr el negocio: provisioning cross-país de clientes, pipeline comercial con AI integrada, contratos, finanzas multi-moneda, configuración fiscal por país, gestión del catálogo de productos con sync GitHub, brand, documentos, wiki interno, auditoría cross-product y moderación del asistente EMI. La diferencia con el resto de los productos del ecosistema es que Vault no se vende: es back-office exclusivamente interno y solo accesible a staff de EMA Health autenticado vía Google con correo @emahealth.io.

ItemValor
Versión actual0.2.0 (Wave 3 v1.0 + S9 ORGBAC)
Decisiones formalesF001 → F085 (ver docs/decisions.md)
Estado🟢 Producción interna vault.emahealth.io
AudienciaStaff EMA Health (@emahealth.io)
Repoemahealth/emavault
Workspace/home/cristianruiz/Dev/emahealth/emavault
CapaTecnologíaNotas
FrontendReact 19 + React Router 7SPA con sidebar de 7 grupos
BuildVite 6TypeScript estricto
UITailwind 4 directoDS de 3 capas en styles.css
Design systemCustom — violet accent #7C3AED2 themes (light + dark), 50+ tokens
BackendHonoCloudflare Workers
AuthSupabase OAuth (Google)Restringido a @emahealth.io
Auth checkvault_users.is_active=trueTabla custom + RBAC por módulo
DBSupabase emahubSchemas emavault + emashared
ChartsRechartsKPIs, MRR, analytics EMI
Iconslucide-reactSin SVG-as-component
AIAnthropic APISonnet para proposal, contract, summary
EMIProxy server-side a emi.emahealth.ioAudit log obligatorio
GitHubREST API + webhookSync de issues paginado + cron horario
TestsVitest 6 (unit + integration + regression)en construcción
Package managernpmregla global EMA
MóduloFuncionalidad
Clientes / TenantsProvisioning automático cross-product (clinic, lab, well) vía X-Platform-Key
PipelineKanban 7 etapas, conversión lead → cliente, MRR ponderado
DirectorioOrganizaciones (cliente / proveedor / partner) + personas + contactos
ContratosLifecycle, alertas vencimiento 30 días
FinanzasEntries, multi-moneda, exchange rates, MRR mensual UF
Facturación electrónicaConfiguración fiscal por tenant, log de emisiones (en Chile contra SII; en otros países contra el organismo equivalente)
CatálogoServicios EMA — costos, pricing, plans
Pricing toolQuotes con simulador, plans CRUD
ProductoCatálogo productos EMA — releases, roadmap, journeys, tech stack, GitHub sync
BrandPrint-to-PDF guidelines
EditorialPosts blog/LinkedIn, métricas
ChecklistTareas operativas
ObligacionesPagos, declaraciones, alertas
Time trackingHoras por proyecto
WikiDocumentación interna
DocumentosRepository ops
InfraInventario CF Workers, dominios, secrets
Equipo / Vault TeamVault users + roles + permisos
EMI gestiónAdmin matrix tenant_emi_access + analytics + lead linking
Audit logCross-product, sanitizado, queryable
Ema Well metrics5 KPIs read-only desde proyecto separado

5 roles con permisos a nivel módulo (no recurso):

RolDescripción
adminBypassea todos los checks — fundadores y admin staff
technicalProducto, infra, audit, wiki, equipo
commercialPipeline, contratos, directorio, catálogo, pricing
financeFinanzas, facturación electrónica, MRR, obligaciones, contratos read
viewerSolo lectura limitada

Tabla vault_permissions(role, module, can_read, can_write) — admin configura.

DecisiónResumen
F003RBAC a nivel módulo, no recurso — vault_permissions por rol × módulo
F040Themes light + dark con override [data-theme="dark"] global
F045DS 3 capas — primitives @theme + semánticos CSS vars + override dark
F068Provisioning cross-product orquestado desde /api/internal/tenants
F075AES-GCM helpers para encrypt/decrypt aidbox client secret
F078EMI conversacional via proxy server-side /api/emi/chat (no SDK frontend)
F080emi_invocations audit log — cada llamada a EMI queda con tenant + user + lead
F082EMI access matrix tenant_emi_access + analytics 30d
F083Lead-EMI conversation linking — leads con source='emi_chat' muestran badge
F085Audit trigger SECURITY DEFINER + sanitización secrets en 12 tablas

Decisiones completas en docs/decisions.md del repo.

  • No usa FHIR / Aidbox — datos en Supabase puro (Vault es ops, no clínico).
  • No usa alias @/ — imports relativos directos.
  • Prefiere type sobre interface (al revés que clinic).
  • Audit por trigger SQL (no por handler) — audit_trigger() SECURITY DEFINER con sanitización.
  • Carpeta middleware/ agregada en Wave 3 — auth + security headers centralizados.
  • DS con violet accent (vs blue de clinic/lab).
  • No replicar Vault auth en otros productos — RBAC por módulo es específico de Vault. Los productos cliente usan user_roles con tenant_id + product.
  • No exponer Anthropic API key en frontend/api/ai/* server-side proxy obligatorio.
  • No mezclar datos clínicos en Vault — Ema Well tiene proyecto Supabase separado por Ley 21.719.
  • No editar 77 archivos para dark mode — usar [data-theme="dark"] .bg-white en CSS global.
  • No usar Browser Rendering puppeteer en CF Workers para PDF user-triggered — usar window.print() con /print route limpia.