Ir al contenido

API routes

EMA Lab expone 38 módulos API bajo el worker Hono, organizados por dominio funcional. Cada ruta declara explícitamente su auth layer y su allowlist de roles RBAC, lo que permite auditar el contrato completo del producto sin inferir reglas globales. Cinco layers de autenticación cubren los distintos contextos de acceso —staff con JWT Supabase, paciente con token corto, hub on-premise con bearer rotable, plataforma con header compartido, y rutas estrictamente públicas— y seis roles RBAC distribuyen los permisos sobre los handlers que requieren autenticación de staff.

LayerCómo funcionaMounting
publicSin credencialesrutas explícitas antes de authMiddleware
supabaseJWT Supabase + tenantMiddleware + clientIsolationMiddlewareapp.use("/api/*", authMiddleware)
portal-tokenToken base64 firmado in-app, exp 1hmount antes de authMiddleware
hub-tokenBearer contra hub_registry.jwt_token activomount antes de authMiddleware
platform-keyHeader X-Platform-Key contra PLATFORM_API_KEYmount antes de authMiddleware
RolDescripción
lab_adminAdministración total
lab_directorFirma clínica + políticas (TAT, SLA, routing, exclusions)
lab_techTM/BQF — ingreso resultados, validación técnica, QC, micro
lab_receptionAdmisión, órdenes, check-in, facturación
lab_phlebotomistToma de muestras, check-in, etiquetas
lab_viewerSolo lectura informes
MétodoPathNotas
GET/api/healthLiveness probe
GET/api/configBootstrap: Supabase URL + anon key
GET/auth/me(supabase auth) user + tenants activos
GET/auth/resolve-tenantRate limit 30/min — slug → tenant name
GET/auth/callbackOAuth redirect
POST/api/portal/verifyRate limit 5/min — RUT + birthdate → portal token
GET/api/portal/verify/:codeRate limit 30/min — QR público sin PII
MétodoPathNotas
GET/api/portal/resultsDR finales del paciente
GET/api/portal/results/:idVerifica subject=Patient/{payload.patient_id}
GET/api/portal/results/:id/pdfPendiente implementación
MétodoPathNotas
POST/api/hub/heartbeatRate limit 60/min
GET/api/hub/worklistsPull worklists para equipos on-prem
POST/api/hub/resultsInbound + auto-consume inventario
POST/api/hub/renew-tokenRotación token Hub
MétodoPathNotas
POST/api/platform/tenantsProvisioning + seed RLS
GET/api/platform/tenantsListado
GET/POST/api/platform/tenants/:id/adminsListado + creación admin
POST/api/platform/tenants/:id/admins/:uid/reactivateReactivar
DELETE/api/platform/tenants/:id/admins/:uidDesactivar
POST/api/platform/tenants/:id/admins/:uid/resendReenviar invitación
PATCH/api/platform/tenants/:id/statusSuspender / reactivar tenant
PATCH/api/platform/tenants/:id/slugRename slug + history
POST/api/platform/tenants/:id/sync-orgRe-sync Organization FHIR
MóduloPathRoles permitidosJustificación
Catálogo/api/catalog/*admin, director, tech, receptionRecepción selecciona tests
Profiles/api/catalog/profiles/*idemPerfiles agrupan tests
Specimens/api/catalog/specimens/*idemTipos de muestra
Containers/api/catalog/containers/*idemTipos de tubo
Lab sites/api/lab-sites/*adminSedes del tenant
TAT/api/tat/*admin, directorPolíticas TAT por sección
SLA/api/sla/*admin, directorSLA cliente × sección
Routing/api/routing/*admin, directorReglas inter-sede
Exclusions/api/exclusions/*admin, directorTests excluidos por cliente
Barcode config/api/barcode-config/*adminEstrategia generación
Sections/api/sections/*admin, directorEstructura organizacional
Clientes/api/clients/*adminAdmisión clientes externos
Equipment/api/equipment/*admin, director, techInventario equipos
Maintenance/api/maintenance/*admin, director, techPlan + history mantenciones
Transport/api/transport/*admin, directorRutas de transporte
MóduloPathRoles permitidosNotas
Órdenes/api/orders/*admin, reception, techdirector no — su rol es firma
Muestras/api/samples/*admin, reception, phlebotomist, techToma + check-in
Check-in/api/checkin/*idemRecepción de muestras
Worklists/api/worklists/*admin, director, techCola técnica
Resultados/api/results/*admin, director, techTM ingresa, director firma
Validación/api/validation/*idem4 stages
QC/api/qc/*idemWestgard + Bull’s
Reportes/api/reports/*admin, director, tech, reception, viewerviewer solo aquí
No conformidades/api/nonconformities/*admin, director, tech, receptionCLSI GP41 16 razones
MóduloPathRoles permitidosNotas
Micro/api/micro/*admin, director, techCultures, antibiograma, MALDI
Molecular/api/molecular/*idemParser registry + sign
Stewardship/api/micro/stewardship/*idemCLSI M39 trimestral
Stewardship admin/api/admin/stewardship/*adminEmission failures, retry manual
Inventario/api/inventory/*admin, director, techStock + auto-consume
MóduloPathRoles permitidosNotas
Settings profile/api/settings/profileselfGET / PATCH propio
Settings org/api/settings/organizationadminWhitelabel, billing
Settings users/api/settings/usersadminTenant roster product=lab
Settings data/api/settings/data/*adminCatalog imports
MóduloPathRoles permitidosNotas
Billing/api/billing/*admin, receptionListas de precios, invoices y facturación electrónica
MóduloPathRoles permitidosNotas
Connectors/api/connectors/*adminHL7v2 + FHIR Subs admin
MóduloPathRoles permitidosNotas
EMI/api/emi/{chat,access}authenticatedServer-side proxy a EMI_BASE_URL, defense-in-depth tenant_emi_access
MóduloPathRoles permitidosNotas
Dashboard/api/dashboard/*authenticatedRead-only métricas
EndpointAuthFuente
POST /api/billing/invoices/:id/dte-callbackX-API-Key per-tenantema-dte worker (idempotente via invoice_id)
POST /api/connectors/fhir/inboundX-Tenant-Id + handler validationAidbox Subscription webhook
POST /api/hub/resultshub-tokenHub on-prem
  1. app.use("/api/<modulo>/*", requireRole(...)) ANTES del app.route en src/index.ts. No asumir herencia del prefix.
  2. Endpoint mutante (POST/PUT/PATCH/DELETE) → rol más permisivo debe ser lab_tech o más restringido. Nunca authenticated puro.
  3. Webhook/callback → documentar auth aquí + agregar a “multi-auth”.
  4. Endpoint público → debe justificarse (PII en endpoint público = vulnerabilidad clase A).
  5. Rate limiting pre-auth + endpoints de enumeración → vía src/middleware/rate-limit.ts (L086).
Ventana de terminal
# Listar todos los requireRole declarados
grep -n "app.use(\"/api/.*requireRole" src/index.ts
# Listar app.route — cualquiera sin requireRole precedente requiere revisión
grep -n "app.route" src/index.ts

Tests de RBAC: tests/security/rbac-matrix.test.ts — mutation testing sobre cada endpoint mutante. 100% cobertura desde S7 (L087).