From 7e1b0585e7d92fba581994216983b732d58b5bd0 Mon Sep 17 00:00:00 2001 From: Alejandro Gomez Auad Date: Wed, 15 Jul 2026 15:58:32 +0000 Subject: [PATCH] Agregado filtro por tipo de documento en ITI-67 Find Document References ahora acepta un parametro opcional 'type' (IPS, MeOW, IT, o un token FHIR system|code) para buscar solo el tipo de documento pedido. Se extrae el mapa de tipos de documento a constants/documentTypes.js para compartirlo entre ITI-65 e ITI-67. Co-Authored-By: Claude Sonnet 5 --- bus-gateway/README.md | 2 +- bus-gateway/constants/documentTypes.js | 27 +++++++++++++++++++ bus-gateway/controllers/iti65.js | 27 +------------------ bus-gateway/controllers/iti67.js | 32 ++++++++++++++++++++--- bus-gateway/docs/iti67.mmd | 11 ++++---- bus-gateway/services/documentReference.js | 16 +++++++----- 6 files changed, 73 insertions(+), 42 deletions(-) create mode 100644 bus-gateway/constants/documentTypes.js diff --git a/bus-gateway/README.md b/bus-gateway/README.md index f8a750d..f96c0a5 100644 --- a/bus-gateway/README.md +++ b/bus-gateway/README.md @@ -20,7 +20,7 @@ El componente actúa exclusivamente como gateway: no contiene lógica de negocio | ITI-65 | `POST` | `/fhir/MeOWDocument` | Provide Document Bundle (MeOW - Medication Overview): variante document. | | ITI-65 | `POST` | `/fhir/ITTransaction` | Provide Document Bundle (IT - Consultation Note / respuesta de interconsulta): variante transacción. | | ITI-65 | `POST` | `/fhir/ITDocument` | Provide Document Bundle (IT - Consultation Note): variante document. | -| ITI-67 | `GET` | `/fhir/DocumentReference` | Find Document References: busca el paciente por ID local en el MPI para obtener su ID nacional y consulta los DocumentReferences en el Document Registry. | +| ITI-67 | `GET` | `/fhir/DocumentReference` | Find Document References: busca el paciente por ID local en el MPI para obtener su ID nacional y consulta los DocumentReferences en el Document Registry. Admite filtrar por tipo de documento con el parámetro opcional `type` (`IPS`, `MeOW`, `IT`, o un token FHIR `system\|code`). | | ITI-78 | `GET` | `/fhir/Patient` | Patient Demographics Query: búsqueda de pacientes en el MPI. | | ITI-78 | `GET` | `/fhir/Patient/:id` | Patient Demographics Query: obtención de un paciente por ID en el MPI. | | ITI-104 | `POST` | `/fhir/Patient` | Patient Identity Feed: alta de paciente en el MPI. | diff --git a/bus-gateway/constants/documentTypes.js b/bus-gateway/constants/documentTypes.js new file mode 100644 index 0000000..204ea2d --- /dev/null +++ b/bus-gateway/constants/documentTypes.js @@ -0,0 +1,27 @@ +/** + * Tipos de documento soportados por ITI-65 (Provide Document Bundle) e ITI-67 + * (Find Document References), cada uno con su código LOINC para + * DocumentReference.type. + */ +const DOCUMENT_TYPES = { + IPS: { + label: 'IPS', + system: 'http://loinc.org', + code: '60591-5', + display: 'Patient Summary Document', + }, + MEOW: { + label: 'MeOW', + system: 'http://loinc.org', + code: '56445-0', + display: 'Medication summary', + }, + IT: { + label: 'IT', + system: 'http://loinc.org', + code: '57133-1', + display: 'Referral note', + }, +}; + +module.exports = { DOCUMENT_TYPES }; diff --git a/bus-gateway/controllers/iti65.js b/bus-gateway/controllers/iti65.js index 8e82e9b..380ce8a 100644 --- a/bus-gateway/controllers/iti65.js +++ b/bus-gateway/controllers/iti65.js @@ -7,6 +7,7 @@ const { createDocumentReference, findDocumentReferenceById } = require('../servi const { logger } = require('../utils/logger'); const { v4: uuidv4 } = require('uuid'); const { getResourceByUrl, processDocumentBundleTransaction } = require('../services/fhir'); +const { DOCUMENT_TYPES } = require('../constants/documentTypes'); const DOCUMENT_REFERENCE_RESOURCE_TYPE = "DocumentReference"; @@ -20,32 +21,6 @@ const DNI_SYSTEM = 'http://www.renaper.gob.ar/dni'; const CUSTODIAN_ID_SYSTEM = 'http://federador.msal.gob.ar/uri'; const MASTER_ID_SYSTEM = 'urn:ietf:rfc:3986' -/** - * Tipos de documento soportados por ITI-65, cada uno con su código LOINC - * para DocumentReference.type (y, en la variante "document", también para - * el DocumentReference local generado dentro de la transacción). - */ -const DOCUMENT_TYPES = { - IPS: { - label: 'IPS', - system: 'http://loinc.org', - code: '60591-5', - display: 'Patient Summary Document', - }, - MEOW: { - label: 'MeOW', - system: 'http://loinc.org', - code: '56445-0', - display: 'Medication summary', - }, - IT: { - label: 'IT', - system: 'http://loinc.org', - code: '57133-1', - display: 'Referral note', - }, -}; - function extractResource(resources, resourceType) { return resources.filter(r => r.resourceType === resourceType)[0]; diff --git a/bus-gateway/controllers/iti67.js b/bus-gateway/controllers/iti67.js index 2f24cd0..d51504e 100644 --- a/bus-gateway/controllers/iti67.js +++ b/bus-gateway/controllers/iti67.js @@ -3,6 +3,7 @@ const config = require('../config'); const { getBusToken } = require('../utils/busAuth'); const { findPatient } = require('../services/patient'); const { findDocumentReferenceByPatient } = require('../services/documentReference'); +const { DOCUMENT_TYPES } = require('../constants/documentTypes'); const NATIONAL_ID_SYSTEM = 'https://federador.msal.gob.ar/patient-id'; @@ -14,6 +15,20 @@ function extractNationalIdentifier(patient) { return identifiers.find(id => id.system === NATIONAL_ID_SYSTEM) || null; } +/** + * Resuelve el parámetro de búsqueda `type` a un token FHIR (`system|code`). + * Acepta tanto las etiquetas conocidas (IPS, MeOW, IT — case-insensitive) + * como un token FHIR ya armado (`system|code` o `code`), que se pasa tal cual + * para no acoplar la búsqueda a los tipos de documento ya conocidos. + */ +function resolveDocumentType(rawType) { + if (!rawType) return undefined; + const knownType = Object.values(DOCUMENT_TYPES).find( + t => t.label.toLowerCase() === rawType.toLowerCase() + ); + return knownType ? `${knownType.system}|${knownType.code}` : rawType; +} + /** @@ -21,15 +36,22 @@ function extractNationalIdentifier(patient) { * * GET /fhir/DocumentReference?subject=:localId * GET /fhir/DocumentReference?patient.identifier=:localId + * GET /fhir/DocumentReference?subject=:localId&type=:type * * Flow: * 1. Fetch the Patient from the Bus by local ID to obtain the national identifier. - * 2. Search DocumentReferences in the Bus by that national identifier. + * 2. Search DocumentReferences in the Bus by that national identifier + * (opcionalmente filtrando por tipo de documento). * 3. Return the resulting Bundle. * * Required query parameter (one of): * subject — local Patient ID in the Bus. * patient.identifier — same semantics, alternate FHIR parameter name. + * + * Optional query parameter: + * type — tipo de documento a buscar. Acepta las etiquetas conocidas + * (IPS, MeOW, IT) o un token FHIR (`system|code`, ej: `http://loinc.org|60591-5`). + * Si se omite, devuelve documentos de cualquier tipo. */ async function listDocumentReference(req, res, next) { try { @@ -37,6 +59,7 @@ async function listDocumentReference(req, res, next) { if (!localPatientIdentifier) { throw createError(400, 'Missing required query parameter: subject or patient.identifier'); } + const documentType = resolveDocumentType(req.query.type); const token = await getBusToken( config.bus.url, config.bus.jwtSecret, @@ -46,14 +69,15 @@ async function listDocumentReference(req, res, next) { config.bus.documentRegistryScope ].join(',') ); - // 1. Obtengo el identificador nacional del paciente en forma de referencia + // 1. Obtengo el identificador nacional del paciente en forma de referencia const patientSearchset = await findPatient(token, { identifier: localPatientIdentifier }); if (!patientSearchset) { throw createError(422, 'Could not resolve national identifier for the given patient'); } const patientNationalId = patientSearchset.entry[0].fullUrl - // 2. Obtengo el listado de entradas del indice de atenciones asociadada al id de paciente. - const documentReferenceSearchset = await findDocumentReferenceByPatient(token, patientNationalId) + // 2. Obtengo el listado de entradas del indice de atenciones asociadada al id de paciente + // (y, si se pidió, al tipo de documento). + const documentReferenceSearchset = await findDocumentReferenceByPatient(token, patientNationalId, documentType) res.status(200).json(documentReferenceSearchset); } catch (err) { diff --git a/bus-gateway/docs/iti67.mmd b/bus-gateway/docs/iti67.mmd index f4298f8..e3889c3 100644 --- a/bus-gateway/docs/iti67.mmd +++ b/bus-gateway/docs/iti67.mmd @@ -8,15 +8,16 @@ sequenceDiagram participant IndiceNacion as Indice Documentos end participant NodoDominio2 as Nodo B + Note over HIS_A,FederadorNacion: Tipos soportados: IPS, MeOW, IT (parámetro opcional type) Note over HIS_A,FederadorNacion: 1. Busqueda y resolución de Identidad - HIS_A->>NodoDominio: ITI67: Solicita los IPS asociados al paciente por su identificador local
[GET /DocumentReference?patient.identifier=] + HIS_A->>NodoDominio: ITI67: Solicita los documentos asociados al paciente por su identificador local, opcionalmente filtrando por tipo
[GET /DocumentReference?patient.identifier=&type=] NodoDominio->>FederadorNacion: Busca el paciente por su identificador local
[GET /Patient?identifier=] FederadorNacion-->>NodoDominio: 200 OK (Patient Searchset) Note over NodoDominio,IndiceNacion: 2. Busqueda de Metadatos - Note right of NodoDominio: El Nodo obtiene el identificador nacional del paciente - NodoDominio->>IndiceNacion: Busca los IPS asociados al paciente por su identificador nacional
[GET /DocumentReference?patient=] + Note right of NodoDominio: El Nodo obtiene el identificador nacional del paciente + NodoDominio->>IndiceNacion: Busca los documentos asociados al paciente por su identificador nacional (y tipo, si se pidió)
[GET /DocumentReference?patient=&type=] IndiceNacion-->>NodoDominio: 200 OK (DocumentReference Searchset) NodoDominio-->>HIS_A: 200 OK (DocumentReference Searchset) Note over HIS_A,NodoDominio2: 3. Descarga del documento (ITI-68) - HIS_A->>NodoDominio2: Obtiene el documento IPS
[GET ] - NodoDominio2-->>HIS_A: 200 OK (IPS Bundle) + HIS_A->>NodoDominio2: Obtiene el documento
[GET ] + NodoDominio2-->>HIS_A: 200 OK (Bundle) diff --git a/bus-gateway/services/documentReference.js b/bus-gateway/services/documentReference.js index eb7f81b..d9b2988 100644 --- a/bus-gateway/services/documentReference.js +++ b/bus-gateway/services/documentReference.js @@ -69,20 +69,24 @@ async function findDocumentReferenceBySubject(token, subjectSystem, subjectValue } /** - * Searches DocumentReferences in the document registry by patient internal ID - * (GET /fhir/DocumentReference?patient=value). + * Searches DocumentReferences in the document registry by patient internal ID, + * opcionalmente filtrando por tipo de documento + * (GET /fhir/DocumentReference?patient=value[&type=system|code]). * @param {string} documentRegistryUrl - Base URL of the document registry service. * @param {string} token - Bearer access token. * @param {string} patientId - Internal patient ID in the document registry. + * @param {string} [type] - Token FHIR (`system|code` o `code`) de DocumentReference.type, ej: `http://loinc.org|60591-5`. * @returns {Promise} FHIR Bundle (searchset) with matching DocumentReferences. */ -async function findDocumentReferenceByPatient(token, patientId) { +async function findDocumentReferenceByPatient(token, patientId, type) { const request = createBusRequest(token); + const params = { subject: patientId }; + if (type) { + params.type = type; + } const response = await request.get( URL.parse(INDICE_ATENCION_URL), - { - params: { subject: patientId }, - } + { params } ); return response.data; }