# IPS Nodo Dominio Plataforma de interoperabilidad en salud basada en Docker Compose que implementa el **Nodo de Dominio IPS** (International Patient Summary). Actúa como gateway de integración entre servicios FHIR locales y el Bus nacional de salud (Federador MSAL). ## Arquitectura ``` Internet / Red interna │ nginx:80/443 │ ┌────┴─────────────────────────────────────────┐ │ /fhir/IPSTransaction → bus-gateway:3000 │ │ /fhir/IPSDocument → bus-gateway:3000 │ │ /fhir/DocumentReference→ bus-gateway:3000 │ │ /fhir/Patient → bus-gateway:3000 │ │ /fhir/* (resto) → hapi-fhir:8080 │ └──────────────────────────────────────────────┘ ``` ## Servicios | Servicio | Imagen / Fuente | Puerto | Descripción | |---|---|---|---| | `hapi-fhir` | `hapiproject/hapi:latest` | 8080 (interno) | Servidor FHIR R4 (Spring Boot) con búsqueda Lucene | | `hapi-db` | `postgres:14.6` | 5433 (interno) | Base de datos PostgreSQL para HAPI FHIR | | `bus-gateway` | `./bus-gateway` (Node.js) | 3000 (interno) | Gateway al Bus de salud nacional (MPI + Document Registry) | | `nginx` | `nginx:alpine` | 80 / 443 | Proxy inverso — punto de entrada HTTP/HTTPS | **Red interna**: todos los servicios se comunican a través de la red Docker `hapi-network`. **Volúmenes persistentes**: `hapi-data` (PostgreSQL de HAPI). ## Transacciones IHE implementadas El `bus-gateway` implementa los siguientes perfiles de interoperabilidad: | Transacción | Método | Ruta | Descripción | |---|---|---|---| | **ITI-65** | POST | `/fhir/IPSTransaction` | Provide Document Bundle (transacción) | | **ITI-65** | POST | `/fhir/IPSDocument` | Provide Document Bundle (documento IPS) | | **ITI-67** | GET | `/fhir/DocumentReference` | Find Document References | | **ITI-78** | GET | `/fhir/Patient` | Patient Demographics Query (búsqueda) | | **ITI-78** | GET | `/fhir/Patient/:id` | Patient Demographics Query (por ID) | | **ITI-104** | POST | `/fhir/Patient` | Patient Identity Feed (alta) | | **ITI-104** | PUT | `/fhir/Patient/:id` | Patient Identity Feed (actualización) | ## Requisitos - Docker >= 20.10.8 - Docker Compose >= 1.29.2 ## Instalación y configuración ### 1. Variables de entorno ```bash cp .env.example .env ``` Editar `.env` completando al menos las variables marcadas como requeridas. Ver la sección [Variables de entorno](#variables-de-entorno) para la descripción completa. ### 2. Certificados Los certificados se inyectan como **Docker secrets**. Las rutas se configuran en el `.env` (todas tienen valores por defecto apuntando a `./certs/`): | Archivo por defecto | Descripción | |---|---| | `./certs/server.crt` / `./certs/server.key` | Certificado TLS para nginx (solo modo HTTPS) | > Ver [certs/README.md](certs/README.md) para instrucciones de generación de certificados de prueba. ### 3. Configuración de nginx (HTTP o HTTPS) La variable `NGINX_CONF` en el `.env` selecciona el modo: **HTTP** (por defecto): ```env NGINX_CONF=http ``` **HTTPS** (requiere certificados válidos en `./certs/`): ```env NGINX_CONF=https SSL_CERT_PATH=./certs/server.crt SSL_KEY_PATH=./certs/server.key ``` En modo HTTPS el tráfico HTTP (puerto 80) se redirige automáticamente a HTTPS (443). Los certificados los lee nginx desde `/run/secrets/ssl_cert` y `/run/secrets/ssl_key`. Los archivos de configuración están en [nginx/http.conf](nginx/http.conf) y [nginx/https.conf](nginx/https.conf). ### 4. Configuración HAPI FHIR Los parámetros del servidor FHIR se ajustan en [hapi-config/application.yaml](hapi-config/application.yaml). El servidor usa **Lucene** como backend de búsqueda (índice local, no requiere servicio externo). CORS está habilitado para todos los orígenes (`*`). ## Levantar los servicios ```bash docker compose up -d ``` HAPI FHIR tarda aproximadamente **30–40 segundos** en inicializar. El `bus-gateway` espera activamente a que el servidor FHIR esté listo antes de aceptar conexiones (hasta ~3 minutos de reintentos). ## Verificar el despliegue ```bash # Estado de los contenedores docker compose ps # CapabilityStatement FHIR a través de nginx curl http://localhost/fhir/metadata # Health check del Bus Gateway a través de nginx curl http://localhost/fhir/Patient?_summary=count # Logs de un servicio específico docker compose logs -f bus-gateway ``` ## Detener los servicios ```bash # Solo detener docker compose down # Detener y eliminar volúmenes (borra todos los datos) docker compose down -v ``` ## Variables de entorno Todas las variables se definen en el archivo `.env` de la raíz del proyecto. ### Bus de salud (requeridas) | Variable | Requerida | Descripción | |---|---|---| | `BUS_URL` | Sí | URL base del Bus de salud nacional | | `BUS_JWT_SECRET` | Sí | Secreto compartido para firmar JWT (HS256) | | `BUS_ISSUER` | Sí | Identificador del emisor JWT (ej.: URL del repositorio) | | `MPI_SCOPE` | Sí | Scopes OAuth para el MPI (ej.: `Patient/*.read,Patient/*.write`) | | `DOCUMENT_REGISTRY_SCOPE` | Sí | Scopes OAuth para el Document Registry | ### Bus de salud (opcionales) | Variable | Default | Descripción | |---|---|---| | `MPI_URL` | `BUS_URL` | URL del Master Patient Index (si difiere del Bus principal) | | `DOCUMENT_REGISTRY_URL` | `BUS_URL` | URL del Document Registry (si difiere del Bus principal) | | `BUS_DEBUG` | `false` | Habilita logs detallados de requests/responses al Bus | ### Nodo | Variable | Default | Descripción | |---|---|---| | `NODO_URL_BASE` | `http://localhost` | URL base del nodo (usada por bus-gateway) | | `TZ` | `America/Argentina/Buenos_Aires` | Zona horaria para todos los servicios | ### FHIR local (gestionada internamente) | Variable | Valor fijo | Descripción | |---|---|---| | `FHIR_URL` | `http://hapi-fhir:8080/fhir` | URL del servidor FHIR interno (fijada en docker-compose) | ### Nginx | Variable | Default | Descripción | |---|---|---| | `NGINX_CONF` | `http` | Modo de operación: `http` o `https` | | `SSL_CERT_PATH` | `./certs/server.crt` | Ruta al certificado TLS del servidor | | `SSL_KEY_PATH` | `./certs/server.key` | Ruta a la clave privada TLS del servidor | ### HAPI FHIR / PostgreSQL | Variable | Default | Descripción | |---|---|---| | `SPRING_CONFIG_LOCATION` | `file:///data/hapi/application.yaml` | Ruta al archivo de configuración de HAPI | | `SPRING_DATASOURCE_URL` | `jdbc:postgresql://hapi-db:5433/root` | URL JDBC de la BD (debe usar puerto `5433`) | | `SPRING_DATASOURCE_USERNAME` | `root` | Usuario de la base de datos | | `SPRING_DATASOURCE_PASSWORD` | `hapifhir2023` | Contraseña de la base de datos | | `SPRING_DATASOURCE_DRIVERCLASSNAME` | `org.postgresql.Driver` | Driver JDBC | | `SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT` | `ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect` | Dialecto Hibernate | | `POSTGRES_DB` | `root` | Nombre de la base de datos PostgreSQL | | `POSTGRES_USER` | `root` | Usuario PostgreSQL | | `POSTGRES_PASSWORD` | `hapifhir2023` | Contraseña PostgreSQL | ## Estructura del proyecto ``` ips-nodo-dominio/ ├── docker-compose.yml # Orquestación principal (4 servicios) ├── .env.example # Plantilla de variables de entorno ├── hapi-config/ │ └── application.yaml # Configuración de HAPI FHIR (Spring Boot) ├── nginx/ │ ├── http.conf # Config nginx modo HTTP │ └── https.conf # Config nginx modo HTTPS ├── certs/ # Certificados TLS y claves de firma │ └── README.md # Instrucciones para generar certificados de prueba ├── bus-gateway/ # Gateway Node.js/Express │ ├── controllers/ # Manejadores de transacciones IHE (ITI-65/67/78/104) │ ├── routes/ # Definición de rutas Express │ ├── services/ # Clientes de servicios externos (MPI, Document Registry, FHIR) │ ├── utils/ # Utilidades (auth, logging) │ ├── docs/ # Diagramas de secuencia Mermaid │ └── tests/ # Suite de pruebas Jest ├── json/ # Fixtures y schemas JSON └── tests/ └── fixtures/ # Fixtures para pruebas de integración ``` ## Desarrollo ### Ejecutar tests del bus-gateway ```bash cd bus-gateway npm install npm test ``` ### Debug remoto El `bus-gateway` arranca con `--inspect=0.0.0.0:9229`, por lo que se puede conectar un debugger Node.js al puerto `9229`. ### Diagramas de secuencia Los flujos de cada transacción están documentados como diagramas Mermaid en [bus-gateway/docs/](bus-gateway/docs/).