Alejandro Gomez Auad b2bc5549ff Fix ITI-67 patient national ID resolution to use the Federador identifier
listDocumentReference was using the Patient entry's fullUrl as the
national ID passed to the document registry search. It now extracts
the Patient identifier whose system is the Federador national-id
system and builds a system|value token, wiring in the previously
unused extractNationalIdentifier helper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 22:28:22 +00:00

79 lines
3.4 KiB
JavaScript

const createError = require('http-errors');
const config = require('../config');
const { getBusToken } = require('../utils/busAuth');
const { findPatient } = require('../services/patient');
const { findDocumentReferenceByPatient } = require('../services/documentReference');
const NATIONAL_ID_SYSTEM = 'https://federador.msal.gob.ar/patient-id';
/**
* Extracts the Federador national identifier from a Patient resource.
*/
function extractNationalIdentifier(patient) {
const identifiers = Array.isArray(patient.identifier) ? patient.identifier : [];
return identifiers.find(id => id.system === NATIONAL_ID_SYSTEM) || null;
}
/**
* ITI-67: Find Document References (MHD)
*
* 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
* (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 — token FHIR de DocumentReference.type (`system|code`, `|code` o `code`),
* ej: `http://loinc.org|60591-5` (IPS), `http://loinc.org|56445-0` (MeOW),
* `http://loinc.org|57133-1` (IT). Se pasa tal cual al Bus, sin traducir
* alias propios, para no apartarse de la semántica estándar de búsqueda
* por token de FHIR. Si se omite, devuelve documentos de cualquier tipo.
*/
async function listDocumentReference(req, res, next) {
try {
const localPatientIdentifier = req.query.subject ?? req.query['patient.identifier'];
if (!localPatientIdentifier) {
throw createError(400, 'Missing required query parameter: subject or patient.identifier');
}
const documentType = req.query.type;
const token = await getBusToken(
config.bus.url,
config.bus.jwtSecret,
config.bus.issuer,
[
config.bus.mpiScope,
config.bus.documentRegistryScope
].join(',')
);
// 1. Obtengo el identificador nacional del paciente (identifier con system
// NATIONAL_ID_SYSTEM), como token FHIR `system|value`.
const patientSearchset = await findPatient(token, { identifier: localPatientIdentifier });
const patientResource = patientSearchset?.entry?.[0]?.resource;
const nationalIdentifier = patientResource && extractNationalIdentifier(patientResource);
if (!nationalIdentifier) {
throw createError(422, 'Could not resolve national identifier for the given patient');
}
const patientNationalId = `${nationalIdentifier.system}|${nationalIdentifier.value}`;
// 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) {
next(err);
}
}
module.exports = { listDocumentReference };