Skip to main content

Visión general

proteus-gateway es un middleware que recibe datos clínicos de un cliente externo en FHIR, los valida y los reenvía de forma asíncrona y confiable a proteus-backend (el sistema Proteus / PAMI). El cliente nunca habla directo con Proteus: habla con el gateway.

Cliente externo proteus-gateway proteus-backend
│ │
│ POST /fhir (FHIR + x-api-key) │
├────────────────────────────► inbox (received) │
│ ◄── 202 Accepted / 422 ──┤ (validación síncrona controlada) │
│ │ │
│ │ explota → proyecta → outbox (pending) │
│ │ │
│ │ dispatcher: POST /inbound (x-api-key) │
│ └──────────────────────────────────────► │
│ 2xx sent / 4xx denied / 5xx retry

Por qué dos etapas (síncrona + asíncrona)

  • Síncrona (en POST /fhir): el gateway valida contra su propio dominio lo que puede saber al instante (ej.: un episodio que referencia un paciente inexistente) y responde un error controlado al cliente. Ver Contrato FHIR.
  • Asíncrona (inbox → outbox): una vez aceptado (202), el mensaje se procesa y despacha en segundo plano con reintentos, sin bloquear al cliente y sin perder mensajes si Proteus o RabbitMQ están caídos. Ver Flujo inbox/outbox.

Las dos piezas

RepoStackRol
proteus-gatewayNestJS 11 + MikroORM 6 + RabbitMQ + PostgreSQLRecibe FHIR, valida, proyecta a su dominio, despacha al backend
proteus-backendrouting-controllers + TypeORM + PostgreSQLExpone POST /inbound, proyecta al dominio real de Proteus

El endpoint del backend y su proyección se documentan en El endpoint /inbound.

Multi-tenant

Cada cliente del gateway corresponde a una empresa distinta del backend (1:1). El gateway guarda Client.proteusAppId y lo envía como clientAppId en cada mensaje; el backend lo resuelve a un Company vía COMPANIES.AJOLOTEAPPID. Así, un mismo planCode puede mapear a planes distintos según la empresa.

Autenticación (dos saltos distintos)

  • Cliente → gateway: token de Ajolote (SSO), validado por ApiKeyGuard. La API key viaja en el header x-api-key.
  • Gateway → backend: secreto compartido x-api-key (comparación timing-safe), distinto del anterior.

El detalle del primer salto (validación con ajolote, scopes y multi-tenant) está en Autenticación y scopes.

Los secretos no viven en la documentación

Las API keys de Ajolote, el secreto GATEWAY_INBOUND_API_KEY (gateway↔backend) y las credenciales de base de datos son variables de entorno de cada ambiente. Nunca se commitean ni aparecen en estos docs; los valores de ejemplo son placeholders.