From e3ed9c88b6ccabcc60fb78916063f96669beabd6 Mon Sep 17 00:00:00 2001 From: Alejandro Gomez Auad Date: Thu, 30 Apr 2026 12:00:38 +0000 Subject: [PATCH] Ajustados los servicios --- bus-gateway/controllers/iti104.js | 9 +-- bus-gateway/controllers/iti65.js | 92 ++++++----------------- bus-gateway/controllers/iti67.js | 8 +- bus-gateway/controllers/iti68.js | 11 +-- bus-gateway/controllers/iti78.js | 8 +- bus-gateway/services/documentReference.js | 17 ++--- bus-gateway/services/fhir.js | 50 ++++++++++++ bus-gateway/services/patient.js | 16 ++-- 8 files changed, 104 insertions(+), 107 deletions(-) create mode 100644 bus-gateway/services/fhir.js diff --git a/bus-gateway/controllers/iti104.js b/bus-gateway/controllers/iti104.js index 8615e98..f397ca0 100644 --- a/bus-gateway/controllers/iti104.js +++ b/bus-gateway/controllers/iti104.js @@ -11,9 +11,8 @@ const { getBusToken } = require('../utils/busAuth'); async function createPatient(req, res, next) { try { const token = await getBusToken(config.bus.url, config.bus.jwtSecret, config.bus.issuer, config.bus.mpiScope); - const response = await busCreatePatient(token, req.body) - const patientResponse = await findPatientByUrl(token, response.headers['location']); - res.status(200).json(patientResponse.data); + const patient = await busCreatePatient(token, req.body) + res.status(200).json(patient); } catch (err) { next(err); } @@ -26,8 +25,8 @@ async function createPatient(req, res, next) { async function updatePatient(req, res, next) { try { const token = await getBusToken(config.bus.url, config.bus.jwtSecret, config.bus.issuer, config.bus.mpiScope); - const response = await busUpdatePatient(token, req.body) - res.status(200).json(response.data); + const patient = await busUpdatePatient(token, req.body) + res.status(200).json(patient); } catch (err) { next(err); } diff --git a/bus-gateway/controllers/iti65.js b/bus-gateway/controllers/iti65.js index c792107..d9e85ab 100644 --- a/bus-gateway/controllers/iti65.js +++ b/bus-gateway/controllers/iti65.js @@ -6,6 +6,7 @@ const { findPatient } = require('../services/patient'); const { createDocumentReference, findDocumentReferenceById, findDocumentReferenceByUrl } = require('../services/documentReference'); const { logger } = require('../utils/logger'); const { v4: uuidv4 } = require('uuid'); +const { getResourceByUrl } = require('../services/fhir'); const DOCUMENT_REFERENCE_RESOURCE_TYPE = "DocumentReference"; @@ -19,27 +20,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' -/** - * Procesa una transacción y devuelve los recursos persistidos en el servidor HAPI FHIR - * @param {*} transactionBundle - * @returns - */ -async function processTransaction(transactionBundle) { - const response = await axios.post(`${config.fhir.url}`, transactionBundle, { - headers: { 'Content-Type': 'application/fhir+json' }, - }); - if (response.status !== 200) { - throw createError(response.status, response.data.issue.diagnostics); - } - const processed = response.data; - const resources = []; - const responses = processed.entry.map(e => e.response); - for (i = 0; i < responses.length; i++) { - const resource = await axios.get(`${config.fhir.url}/${responses[i].location}`) - resources.push(resource); - } - return Promise.resolve(resources); -} function extractResource(resources, resourceType) { return resources.map(r => r.data).filter(r => r.resourceType === resourceType)[0]; @@ -51,43 +31,8 @@ function extractLocalIdentifier(patient) { })[0]; } -/** - * - * @param {*} documentReference - * @returns - */ -async function getBusCustodianIdentifier() { - return Promise.resolve({ system: CUSTODIAN_ID_SYSTEM, value: config.bus.issuer }); -} - -async function getBusPatientReference(patient, token) { - const localIdentifier = extractLocalIdentifier(patient); - const nationalPatientResponse = await findPatient(token, { identifier: `${localIdentifier.system}|${localIdentifier.value}` }); - const nationalPatientBundle = nationalPatientResponse.data; - if (nationalPatientBundle.total == 0) { - throw createError(404, 'Patient does not exists'); - } - // NOTE:La siguiente consulta no debería traer mas de un resultado. - return Promise.resolve(nationalPatientBundle.entry[0].fullUrl); -} - -async function getLocalIPSDocumentReference(localIPSDocument) { - return Promise.resolve(`${config.baseURL}/fhir/Bundle/${localIPSDocument.id}`); -} - -/** - * Crea un nuevo document refrence en el bus - * @param {*} token - * @param {*} localIPSDocument - * @param {*} localPatient - * @param {*} localDocumentReference - * @returns - */ -async function createBusDocumentReference(token, localIPSDocument, localPatient) { - const busCustodianIdentifier = await getBusCustodianIdentifier(); - const busPatientReference = await getBusPatientReference(localPatient, token); - const localIPSDocumentReference = await getLocalIPSDocumentReference(localIPSDocument); - const busDocumentReference = { +function generateDocumentReferenceResource(subjectReference, bundleUrl) { + const documentRefernece = { resourceType: 'DocumentReference', status: 'current', masterIdentifier: { @@ -106,7 +51,7 @@ async function createBusDocumentReference(token, localIPSDocument, localPatient) }, date: new Date().toISOString(), subject: { - reference: busPatientReference + reference: subjectReference }, custodian: { identifier: busCustodianIdentifier, @@ -114,17 +59,16 @@ async function createBusDocumentReference(token, localIPSDocument, localPatient) content: [ { attachment: { - url: localIPSDocumentReference, + url: bundleUrl, contentType: 'application/fhir+json' }, }, ], }; - const response = await createDocumentReference(token, busDocumentReference); - const created = await findDocumentReferenceByUrl(token, response.headers['location']); - return created.data; + return documentRefernece; } + /** * ITI-65: Provide Document Bundle (MHD) * @@ -149,15 +93,29 @@ async function provideDocumentBundle(req, res, next) { ); // Paso 1: Ejecuto la transcción en el servidor hapi subyacente - const resources = await processTransaction(transaction); + const transactionResponse = await processTransaction(transaction); + const resources = []; + transactionResponse.entry.map(e => e.response); + transactionResponse.entry.map(e => e.response).foreEach(r => { + const resource = getResourceByUr(r.location); + resources.push(resource); + + }); // Paso 2: Obtengo el paciente local (tal como se guardo en la trasnaccion) const localPatient = extractResource(resources, PATIENT_RESOURCE_TYPE); // Paso 3: Obtengo el documento IPS local (tal como se guardo en la transacción) const localIPSDocument = extractResource(resources, IPS_DOCUMENT_RESOURCE_TYPE) - // Paso 4: Creo el document reference en el indice de atenciones - const busDocumentReference = await createBusDocumentReference(token, localIPSDocument, localPatient); - return res.status(200).json(busDocumentReference); + const localPatientIdentifier = extractLocalIdentifier(localPatient); + const patientSearchset = await findPatient(token, { identifier: `${localIdentifier.system}|${localIdentifier.value}` }); + if (patientSearchset.total == 0) { + throw createError(404, 'Patient does not exists'); + } + const nationalPatientId = patientSearchset.entry[0].fullUrl; + const bundleReference = `${config.baseURL}/fhir/Bundle/${localIPSDocument.id}`; + + const createdDocumentReference = await createDocumentReference(token, createdDocumentReference); + return res.status(200).json(createdDocumentReference); } catch (err) { next(err); diff --git a/bus-gateway/controllers/iti67.js b/bus-gateway/controllers/iti67.js index 49c49c4..6f5e626 100644 --- a/bus-gateway/controllers/iti67.js +++ b/bus-gateway/controllers/iti67.js @@ -20,8 +20,8 @@ async function getPatient(token, identifier) { } async function getDocumentReferencesForPatient(token, patient) { - const response = await findDocumentReferenceByPatient(token, patient) - return Promise.resolve(response.data); + const searchset = await findDocumentReferenceByPatient(token, patient) + return Promise.resolve(searchset); } /** * ITI-67: Find Document References (MHD) @@ -57,9 +57,9 @@ async function listDocumentReference(req, res, next) { throw createError(422, 'Could not resolve national identifier for the given patient'); } // 2. Obtengo el listado de entradas del indice de atenciones asociadada al id de paciente. - const bundle = await getDocumentReferencesForPatient(token, patientId); + const searchset = await getDocumentReferencesForPatient(token, patientId); - res.status(200).json(bundle); + res.status(200).json(searchset); } catch (err) { next(err); } diff --git a/bus-gateway/controllers/iti68.js b/bus-gateway/controllers/iti68.js index 50351eb..eb872cf 100644 --- a/bus-gateway/controllers/iti68.js +++ b/bus-gateway/controllers/iti68.js @@ -2,15 +2,6 @@ const createError = require('http-errors'); const axios = require('axios'); -async function getRemoteDocument(url) { - const response = await axios.get(parsedUrl.toString(), { - responseType: 'arraybuffer', - headers: { - Accept: req.headers['accept'] || '*/*', - }, - }); - return response -} /** @@ -35,7 +26,7 @@ async function getBundleById(req, res, next) { } catch { throw createError(400, 'Invalid document URL'); } - const response = await getRemoteDocument(url); + const response = await getDocumentBundleByUrl(url); const contentType = response.headers['content-type']; if (contentType) res.setHeader('Content-Type', contentType); diff --git a/bus-gateway/controllers/iti78.js b/bus-gateway/controllers/iti78.js index 4ba5aa4..19d487b 100644 --- a/bus-gateway/controllers/iti78.js +++ b/bus-gateway/controllers/iti78.js @@ -11,8 +11,8 @@ const { findPatient, findPatientById } = require('../services/patient'); async function listPatient(req, res, next) { try { const token = await getBusToken(config.bus.url, config.bus.jwtSecret, config.bus.issuer, config.bus.mpiScope); - const response = await findPatient(token, req.query); - res.status(200).json(response.data); + const searchset = await findPatient(token, req.query); + res.status(200).json(searchset); } catch (err) { next(err); } @@ -26,8 +26,8 @@ async function getPatientById(req, res, next) { try { const { id } = req.params; const token = await getBusToken(config.bus.url, config.bus.jwtSecret, config.bus.issuer, config.bus.mpiScope); - const response = await findPatientById(token, id) - res.status(200).json(response.data); + const patient = await findPatientById(token, id) + res.status(200).json(patient); } catch (err) { next(err); } diff --git a/bus-gateway/services/documentReference.js b/bus-gateway/services/documentReference.js index c50609a..eb7f81b 100644 --- a/bus-gateway/services/documentReference.js +++ b/bus-gateway/services/documentReference.js @@ -18,7 +18,7 @@ async function findDocumentReferenceById(token, id) { const response = await request.get( URL.parse(`${INDICE_ATENCION_URL}/${id}`) ); - return response; + return response.data; } @@ -27,7 +27,7 @@ async function findDocumentReferenceByUrl(token, id) { const response = await request.get( URL.parse(id, INDICE_ATENCION_URL) ); - return response; + return response.data; } /** @@ -45,8 +45,8 @@ async function createDocumentReference(token, documentReference) { URL.parse(INDICE_ATENCION_URL), documentReference ); - response.headers['location'] = maskPrivateURL(response.headers['location']); - return response; + const location = maskPrivateURL(response.headers['location']); + return findDocumentReferenceByUrl(token, location); } /** * Searches DocumentReferences in the document registry by patient subject identifier @@ -65,7 +65,7 @@ async function findDocumentReferenceBySubject(token, subjectSystem, subjectValue params: { subject: `${subjectSystem}|${subjectValue}` }, } ); - return response; + return response.data; } /** @@ -84,7 +84,7 @@ async function findDocumentReferenceByPatient(token, patientId) { params: { subject: patientId }, } ); - return response; + return response.data; } /** @@ -108,7 +108,7 @@ async function searchDocumentReference(token, subject, custodian, type) { type: `${type.system}|${type.value}`, }, }); - return response; + return response.data; } module.exports = { @@ -116,6 +116,5 @@ module.exports = { createDocumentReference, findDocumentReferenceBySubject, findDocumentReferenceByPatient, - searchDocumentReference, - findDocumentReferenceByUrl + searchDocumentReference }; diff --git a/bus-gateway/services/fhir.js b/bus-gateway/services/fhir.js new file mode 100644 index 0000000..cd6e63c --- /dev/null +++ b/bus-gateway/services/fhir.js @@ -0,0 +1,50 @@ +const config = require("../config"); +const axios = require('axios'); + + +const HAPI_FHIR_SERVER_URL = config.fhir.url; + + +/** + * Procesa una transacción y devuelve los recursos persistidos en el servidor HAPI FHIR + * @param {*} transactionBundle + * @returns + */ +async function processDocumentBundleTransaction(transactionBundle) { + const response = await axios.post(HAPI_FHIR_SERVER_URL, transactionBundle, { + headers: { 'Content-Type': 'application/fhir+json' }, + }); + const processed = response.data; + const resources = []; + const responses = processed.entry.map(e => e.response); + for (i = 0; i < responses.length; i++) { + const resource = await axios.get(`${config.fhir.url}/${responses[i].location}`) + resources.push(resource); + } + return Promise.resolve(resources); +} + + +async function getResourceByUrl(url) { + const response = await axios.get( + URL.parse(url, HAPI_FHIR_SERVER_URL) + ); + return response.data; +} + + +async function getDocumentBundleByUrl(url) { + const response = await axios.get(parsedUrl.toString(), { + responseType: 'arraybuffer', + headers: { + Accept: req.headers['accept'] || '*/*', + }, + }); + return response.data +} + + +module.exports = { + processDocumentBundleTransaction, + getResourceByUrl +} \ No newline at end of file diff --git a/bus-gateway/services/patient.js b/bus-gateway/services/patient.js index b3d7755..2b6b549 100644 --- a/bus-gateway/services/patient.js +++ b/bus-gateway/services/patient.js @@ -24,8 +24,8 @@ async function createPatient(token, patient) { URL.parse(MPI_URL), patient ); - response.headers['location'] = maskPrivateURL(response.headers['location']); - return response; + const location = maskPrivateURL(response.headers['location']); + return findPatientByUrl(token, location); } @@ -35,7 +35,7 @@ async function updatePatient(token, patient, id) { URL.parse(`${MPI_URL}/${id}`), patient ); - return response; + return response.data; } /** @@ -83,7 +83,7 @@ async function findPatient(token, criteria = {}) { return l; }); } - return response; + return response.data; } async function findPatientByUrl(token, url) { @@ -91,7 +91,7 @@ async function findPatientByUrl(token, url) { const response = await request.get( URL.parse(url, MPI_URL) ); - return response; + return response.data; } /** @@ -106,7 +106,7 @@ async function findPatientById(token, id) { const response = await request.get( URL.parse(`${MPI_URL}/${id}`) ); - return response; + return response.data; } /** @@ -140,7 +140,7 @@ async function findPatientByMatch(token, patient, count) { URL.parse('$match', MPI_URL), parameters ); - return response; + return response.data; } -module.exports = { createPatient, findPatientById, findPatientByMatch, findPatientByUrl, updatePatient, findPatient }; +module.exports = { createPatient, findPatientById, findPatientByMatch, updatePatient, findPatient };