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 <noreply@anthropic.com>
This commit is contained in:
parent
df87fc5ee7
commit
7e1b0585e7
@ -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/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/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-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` | 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-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. |
|
| ITI-104 | `POST` | `/fhir/Patient` | Patient Identity Feed: alta de paciente en el MPI. |
|
||||||
|
|||||||
27
bus-gateway/constants/documentTypes.js
Normal file
27
bus-gateway/constants/documentTypes.js
Normal file
@ -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 };
|
||||||
@ -7,6 +7,7 @@ const { createDocumentReference, findDocumentReferenceById } = require('../servi
|
|||||||
const { logger } = require('../utils/logger');
|
const { logger } = require('../utils/logger');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
const { getResourceByUrl, processDocumentBundleTransaction } = require('../services/fhir');
|
const { getResourceByUrl, processDocumentBundleTransaction } = require('../services/fhir');
|
||||||
|
const { DOCUMENT_TYPES } = require('../constants/documentTypes');
|
||||||
|
|
||||||
|
|
||||||
const DOCUMENT_REFERENCE_RESOURCE_TYPE = "DocumentReference";
|
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 CUSTODIAN_ID_SYSTEM = 'http://federador.msal.gob.ar/uri';
|
||||||
const MASTER_ID_SYSTEM = 'urn:ietf:rfc:3986'
|
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) {
|
function extractResource(resources, resourceType) {
|
||||||
return resources.filter(r => r.resourceType === resourceType)[0];
|
return resources.filter(r => r.resourceType === resourceType)[0];
|
||||||
|
|||||||
@ -3,6 +3,7 @@ const config = require('../config');
|
|||||||
const { getBusToken } = require('../utils/busAuth');
|
const { getBusToken } = require('../utils/busAuth');
|
||||||
const { findPatient } = require('../services/patient');
|
const { findPatient } = require('../services/patient');
|
||||||
const { findDocumentReferenceByPatient } = require('../services/documentReference');
|
const { findDocumentReferenceByPatient } = require('../services/documentReference');
|
||||||
|
const { DOCUMENT_TYPES } = require('../constants/documentTypes');
|
||||||
|
|
||||||
const NATIONAL_ID_SYSTEM = 'https://federador.msal.gob.ar/patient-id';
|
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;
|
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?subject=:localId
|
||||||
* GET /fhir/DocumentReference?patient.identifier=:localId
|
* GET /fhir/DocumentReference?patient.identifier=:localId
|
||||||
|
* GET /fhir/DocumentReference?subject=:localId&type=:type
|
||||||
*
|
*
|
||||||
* Flow:
|
* Flow:
|
||||||
* 1. Fetch the Patient from the Bus by local ID to obtain the national identifier.
|
* 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.
|
* 3. Return the resulting Bundle.
|
||||||
*
|
*
|
||||||
* Required query parameter (one of):
|
* Required query parameter (one of):
|
||||||
* subject — local Patient ID in the Bus.
|
* subject — local Patient ID in the Bus.
|
||||||
* patient.identifier — same semantics, alternate FHIR parameter name.
|
* 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) {
|
async function listDocumentReference(req, res, next) {
|
||||||
try {
|
try {
|
||||||
@ -37,6 +59,7 @@ async function listDocumentReference(req, res, next) {
|
|||||||
if (!localPatientIdentifier) {
|
if (!localPatientIdentifier) {
|
||||||
throw createError(400, 'Missing required query parameter: subject or patient.identifier');
|
throw createError(400, 'Missing required query parameter: subject or patient.identifier');
|
||||||
}
|
}
|
||||||
|
const documentType = resolveDocumentType(req.query.type);
|
||||||
const token = await getBusToken(
|
const token = await getBusToken(
|
||||||
config.bus.url,
|
config.bus.url,
|
||||||
config.bus.jwtSecret,
|
config.bus.jwtSecret,
|
||||||
@ -46,14 +69,15 @@ async function listDocumentReference(req, res, next) {
|
|||||||
config.bus.documentRegistryScope
|
config.bus.documentRegistryScope
|
||||||
].join(',')
|
].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 });
|
const patientSearchset = await findPatient(token, { identifier: localPatientIdentifier });
|
||||||
if (!patientSearchset) {
|
if (!patientSearchset) {
|
||||||
throw createError(422, 'Could not resolve national identifier for the given patient');
|
throw createError(422, 'Could not resolve national identifier for the given patient');
|
||||||
}
|
}
|
||||||
const patientNationalId = patientSearchset.entry[0].fullUrl
|
const patientNationalId = patientSearchset.entry[0].fullUrl
|
||||||
// 2. Obtengo el listado de entradas del indice de atenciones asociadada al id de paciente.
|
// 2. Obtengo el listado de entradas del indice de atenciones asociadada al id de paciente
|
||||||
const documentReferenceSearchset = await findDocumentReferenceByPatient(token, patientNationalId)
|
// (y, si se pidió, al tipo de documento).
|
||||||
|
const documentReferenceSearchset = await findDocumentReferenceByPatient(token, patientNationalId, documentType)
|
||||||
|
|
||||||
res.status(200).json(documentReferenceSearchset);
|
res.status(200).json(documentReferenceSearchset);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@ -8,15 +8,16 @@ sequenceDiagram
|
|||||||
participant IndiceNacion as Indice Documentos
|
participant IndiceNacion as Indice Documentos
|
||||||
end
|
end
|
||||||
participant NodoDominio2 as Nodo B
|
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
|
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 <br /> [GET /DocumentReference?patient.identifier=<ID_Local>]
|
HIS_A->>NodoDominio: ITI67: Solicita los documentos asociados al paciente por su identificador local, opcionalmente filtrando por tipo <br /> [GET /DocumentReference?patient.identifier=<ID_Local>&type=<IPS|MeOW|IT>]
|
||||||
NodoDominio->>FederadorNacion: Busca el paciente por su identificador local <br /> [GET /Patient?identifier=<ID_Local>]
|
NodoDominio->>FederadorNacion: Busca el paciente por su identificador local <br /> [GET /Patient?identifier=<ID_Local>]
|
||||||
FederadorNacion-->>NodoDominio: 200 OK (Patient Searchset)
|
FederadorNacion-->>NodoDominio: 200 OK (Patient Searchset)
|
||||||
Note over NodoDominio,IndiceNacion: 2. Busqueda de Metadatos
|
Note over NodoDominio,IndiceNacion: 2. Busqueda de Metadatos
|
||||||
Note right of NodoDominio: El Nodo obtiene el identificador nacional del paciente
|
Note right of NodoDominio: El Nodo obtiene el identificador nacional del paciente
|
||||||
NodoDominio->>IndiceNacion: Busca los IPS asociados al paciente por su identificador nacional <br /> [GET /DocumentReference?patient=<ID_Nacional>]
|
NodoDominio->>IndiceNacion: Busca los documentos asociados al paciente por su identificador nacional (y tipo, si se pidió) <br /> [GET /DocumentReference?patient=<ID_Nacional>&type=<system|code>]
|
||||||
IndiceNacion-->>NodoDominio: 200 OK (DocumentReference Searchset)
|
IndiceNacion-->>NodoDominio: 200 OK (DocumentReference Searchset)
|
||||||
NodoDominio-->>HIS_A: 200 OK (DocumentReference Searchset)
|
NodoDominio-->>HIS_A: 200 OK (DocumentReference Searchset)
|
||||||
Note over HIS_A,NodoDominio2: 3. Descarga del documento (ITI-68)
|
Note over HIS_A,NodoDominio2: 3. Descarga del documento (ITI-68)
|
||||||
HIS_A->>NodoDominio2: Obtiene el documento IPS <br /> [GET <URL_IPSBundle>]
|
HIS_A->>NodoDominio2: Obtiene el documento <br /> [GET <URL_Bundle>]
|
||||||
NodoDominio2-->>HIS_A: 200 OK (IPS Bundle)
|
NodoDominio2-->>HIS_A: 200 OK (Bundle)
|
||||||
|
|||||||
@ -69,20 +69,24 @@ async function findDocumentReferenceBySubject(token, subjectSystem, subjectValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches DocumentReferences in the document registry by patient internal ID
|
* Searches DocumentReferences in the document registry by patient internal ID,
|
||||||
* (GET /fhir/DocumentReference?patient=value).
|
* 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} documentRegistryUrl - Base URL of the document registry service.
|
||||||
* @param {string} token - Bearer access token.
|
* @param {string} token - Bearer access token.
|
||||||
* @param {string} patientId - Internal patient ID in the document registry.
|
* @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<object>} FHIR Bundle (searchset) with matching DocumentReferences.
|
* @returns {Promise<object>} FHIR Bundle (searchset) with matching DocumentReferences.
|
||||||
*/
|
*/
|
||||||
async function findDocumentReferenceByPatient(token, patientId) {
|
async function findDocumentReferenceByPatient(token, patientId, type) {
|
||||||
const request = createBusRequest(token);
|
const request = createBusRequest(token);
|
||||||
|
const params = { subject: patientId };
|
||||||
|
if (type) {
|
||||||
|
params.type = type;
|
||||||
|
}
|
||||||
const response = await request.get(
|
const response = await request.get(
|
||||||
URL.parse(INDICE_ATENCION_URL),
|
URL.parse(INDICE_ATENCION_URL),
|
||||||
{
|
{ params }
|
||||||
params: { subject: patientId },
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user