Agregadas variantes de ITI-65 para MeOW e IT ademas de IPS
Se generaliza el controller para recibir el tipo de documento (LOINC) en vez de hardcodear el de IPS, y se agregan las rutas y mapeos de nginx para /fhir/MeOWTransaction, /fhir/MeOWDocument, /fhir/ITTransaction y /fhir/ITDocument, siguiendo la misma logica que las rutas IPS existentes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
1fbc308d66
commit
df87fc5ee7
@ -14,7 +14,12 @@ El componente actúa exclusivamente como gateway: no contiene lógica de negocio
|
||||
|
||||
| Transacción | Método | Ruta | Descripción |
|
||||
|---|---|---|---|
|
||||
| ITI-65 | `POST` | `/fhir/Bundle` | Provide Document Bundle: almacena el Bundle en HAPI FHIR, resuelve el ID nacional del paciente vía `$match` en el Bus y registra el DocumentReference en el Document Registry. |
|
||||
| ITI-65 | `POST` | `/fhir/IPSTransaction` | Provide Document Bundle (IPS): variante transacción — el cliente envía el Bundle transaction completo (Patient, Bundle document, DocumentReference, List). |
|
||||
| ITI-65 | `POST` | `/fhir/IPSDocument` | Provide Document Bundle (IPS): variante document — el cliente envía solo el Bundle IPS (`type: document`); el gateway arma la transacción internamente. |
|
||||
| ITI-65 | `POST` | `/fhir/MeOWTransaction` | Provide Document Bundle (MeOW - Medication Overview): variante transacción. |
|
||||
| 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-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. |
|
||||
@ -136,7 +141,7 @@ docker compose logs -f
|
||||
|
||||
## Headers requeridos por transacción
|
||||
|
||||
### ITI-65 `POST /fhir/Bundle`
|
||||
### ITI-65 `POST /fhir/IPSTransaction`, `/fhir/IPSDocument`, `/fhir/MeOWTransaction`, `/fhir/MeOWDocument`, `/fhir/ITTransaction`, `/fhir/ITDocument`
|
||||
|
||||
| Header | Descripción |
|
||||
|---|---|
|
||||
|
||||
@ -20,6 +20,32 @@ 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];
|
||||
@ -31,7 +57,7 @@ function extractLocalIdentifier(patient) {
|
||||
})[0];
|
||||
}
|
||||
|
||||
function generateDocumentReferenceResource(subjectReference, bundleUrl) {
|
||||
function generateDocumentReferenceResource(subjectReference, bundleUrl, docType) {
|
||||
const documentRefernece = {
|
||||
resourceType: 'DocumentReference',
|
||||
status: 'current',
|
||||
@ -43,9 +69,9 @@ function generateDocumentReferenceResource(subjectReference, bundleUrl) {
|
||||
type: {
|
||||
coding: [
|
||||
{
|
||||
system: 'http://loinc.org',
|
||||
code: '60591-5',
|
||||
display: 'Patient Summary Document',
|
||||
system: docType.system,
|
||||
code: docType.code,
|
||||
display: docType.display,
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -77,19 +103,20 @@ async function getResourcesFromTransactionResponse(transactionResponse) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construye un Bundle de tipo transaction a partir de un Bundle de tipo document (IPS).
|
||||
* Genera Patient, Bundle (IPS), DocumentReference y List (SubmissionSet MHD).
|
||||
* Construye un Bundle de tipo transaction a partir de un Bundle de tipo document
|
||||
* (IPS, MeOW, IT, ...). Genera Patient, Bundle (documento), DocumentReference y
|
||||
* List (SubmissionSet MHD).
|
||||
* Usa urn:uuid: como fullUrl para que HAPI FHIR resuelva las referencias internas.
|
||||
*/
|
||||
function buildTransactionFromIPSDocument(ipsBundle) {
|
||||
if (ipsBundle.type !== 'document') {
|
||||
function buildTransactionFromDocumentBundle(documentBundle, docType) {
|
||||
if (documentBundle.type !== 'document') {
|
||||
throw createError(400, 'Bundle must be of type document');
|
||||
}
|
||||
const patientEntry = (ipsBundle.entry || []).find(
|
||||
const patientEntry = (documentBundle.entry || []).find(
|
||||
e => e.resource && e.resource.resourceType === 'Patient'
|
||||
);
|
||||
if (!patientEntry) {
|
||||
throw createError(400, 'IPS Bundle must contain a Patient resource');
|
||||
throw createError(400, `${docType.label} Bundle must contain a Patient resource`);
|
||||
}
|
||||
|
||||
const patientFullUrl = `urn:uuid:${uuidv4()}`;
|
||||
@ -108,9 +135,9 @@ function buildTransactionFromIPSDocument(ipsBundle) {
|
||||
},
|
||||
type: {
|
||||
coding: [{
|
||||
system: 'http://loinc.org',
|
||||
code: '60591-5',
|
||||
display: 'Patient Summary Document',
|
||||
system: docType.system,
|
||||
code: docType.code,
|
||||
display: docType.display,
|
||||
}]
|
||||
},
|
||||
date: now,
|
||||
@ -158,7 +185,7 @@ function buildTransactionFromIPSDocument(ipsBundle) {
|
||||
},
|
||||
{
|
||||
fullUrl: bundleFullUrl,
|
||||
resource: ipsBundle,
|
||||
resource: documentBundle,
|
||||
request: { method: 'POST', url: 'Bundle' }
|
||||
},
|
||||
{
|
||||
@ -178,7 +205,7 @@ function buildTransactionFromIPSDocument(ipsBundle) {
|
||||
* Lógica central de ITI-65: persiste la transacción en HAPI FHIR, resuelve el
|
||||
* paciente en el Bus y registra un DocumentReference apuntando al Bundle guardado.
|
||||
*/
|
||||
async function executeITI65(transaction, token) {
|
||||
async function executeITI65(transaction, token, docType) {
|
||||
const transactionResponse = await processDocumentBundleTransaction(transaction);
|
||||
const resources = await getResourcesFromTransactionResponse(transactionResponse);
|
||||
|
||||
@ -193,59 +220,73 @@ async function executeITI65(transaction, token) {
|
||||
const nationalPatientId = patientSearchset.entry[0].fullUrl;
|
||||
const bundleReference = `${config.baseURL}/fhir/Bundle/${localIPSDocument.id}`;
|
||||
|
||||
const documentReference = generateDocumentReferenceResource(nationalPatientId, bundleReference);
|
||||
const documentReference = generateDocumentReferenceResource(nationalPatientId, bundleReference, docType);
|
||||
return createDocumentReference(token, documentReference);
|
||||
}
|
||||
|
||||
async function acquireToken() {
|
||||
return getBusToken(
|
||||
config.bus.url,
|
||||
config.bus.jwtSecret,
|
||||
config.bus.issuer,
|
||||
[config.bus.mpiScope, config.bus.documentRegistryScope].join(',')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ITI-65: Provide Document Bundle (MHD) — variante transacción
|
||||
*
|
||||
* POST /fhir/iti65
|
||||
*
|
||||
* Espera un Bundle de tipo transaction construido por el cliente.
|
||||
*/
|
||||
async function provideIPSTransaction(req, res, next) {
|
||||
function provideTransaction(docType) {
|
||||
return async function (req, res, next) {
|
||||
try {
|
||||
const transaction = req.body;
|
||||
const token = await getBusToken(
|
||||
config.bus.url,
|
||||
config.bus.jwtSecret,
|
||||
config.bus.issuer,
|
||||
[config.bus.mpiScope, config.bus.documentRegistryScope].join(',')
|
||||
);
|
||||
const result = await executeITI65(transaction, token);
|
||||
const token = await acquireToken();
|
||||
const result = await executeITI65(transaction, token, docType);
|
||||
return res.status(200).json(result);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* ITI-65: Provide Document Bundle (MHD) — variante IPS document
|
||||
* ITI-65: Provide Document Bundle (MHD) — variante document
|
||||
*
|
||||
* POST /fhir/Bundle
|
||||
*
|
||||
* Espera un Bundle de tipo document (IPS). Genera internamente el Bundle
|
||||
* transaction y ejecuta el mismo flujo que provideDocumentBundle.
|
||||
* Espera un Bundle de tipo document. Genera internamente el Bundle transaction
|
||||
* (Patient, Bundle, DocumentReference, List) y ejecuta el mismo flujo que
|
||||
* provideTransaction.
|
||||
*/
|
||||
async function provideIPSDocumentBundle(req, res, next) {
|
||||
function provideDocumentBundle(docType) {
|
||||
return async function (req, res, next) {
|
||||
try {
|
||||
const ipsBundle = req.body;
|
||||
if (!ipsBundle || ipsBundle.resourceType !== 'Bundle') {
|
||||
const documentBundle = req.body;
|
||||
if (!documentBundle || documentBundle.resourceType !== 'Bundle') {
|
||||
throw createError(400, 'Request body must be a FHIR Bundle resource');
|
||||
}
|
||||
const transaction = buildTransactionFromIPSDocument(ipsBundle);
|
||||
const token = await getBusToken(
|
||||
config.bus.url,
|
||||
config.bus.jwtSecret,
|
||||
config.bus.issuer,
|
||||
[config.bus.mpiScope, config.bus.documentRegistryScope].join(',')
|
||||
);
|
||||
const result = await executeITI65(transaction, token);
|
||||
const transaction = buildTransactionFromDocumentBundle(documentBundle, docType);
|
||||
const token = await acquireToken();
|
||||
const result = await executeITI65(transaction, token, docType);
|
||||
return res.status(200).json(result);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { provideIPSTransaction, provideIPSDocumentBundle };
|
||||
const provideIPSTransaction = provideTransaction(DOCUMENT_TYPES.IPS);
|
||||
const provideIPSDocumentBundle = provideDocumentBundle(DOCUMENT_TYPES.IPS);
|
||||
const provideMeOWTransaction = provideTransaction(DOCUMENT_TYPES.MEOW);
|
||||
const provideMeOWDocumentBundle = provideDocumentBundle(DOCUMENT_TYPES.MEOW);
|
||||
const provideITTransaction = provideTransaction(DOCUMENT_TYPES.IT);
|
||||
const provideITDocumentBundle = provideDocumentBundle(DOCUMENT_TYPES.IT);
|
||||
|
||||
module.exports = {
|
||||
provideIPSTransaction,
|
||||
provideIPSDocumentBundle,
|
||||
provideMeOWTransaction,
|
||||
provideMeOWDocumentBundle,
|
||||
provideITTransaction,
|
||||
provideITDocumentBundle,
|
||||
};
|
||||
|
||||
@ -7,14 +7,15 @@ sequenceDiagram
|
||||
participant FederadorNacion as Federador
|
||||
participant IndiceNacion as Indice Documentos
|
||||
end
|
||||
Note over HIS_A,IndiceNacion: 1. Recepcion Local del Documento Bundle (POST /Bundle)
|
||||
HIS_A->>NodoDominio: ITI65: Provee un nuevo documento IPS (bundle)
|
||||
Note over HIS_A,IndiceNacion: Variantes: /IPSTransaction, /IPSDocument, /MeOWTransaction, /MeOWDocument, /ITTransaction, /ITDocument
|
||||
Note over HIS_A,IndiceNacion: 1. Recepcion Local del Documento Bundle
|
||||
HIS_A->>NodoDominio: ITI65: Provee un nuevo documento (bundle)
|
||||
Note right of NodoDominio: El Nodo almacena físicamente el documento y extrae la metadata.
|
||||
Note over NodoDominio,FederadorNacion: 2. Resolución de Identidad
|
||||
NodoDominio->>FederadorNacion: Busca al paciente por el su identificador local [GET /Patient?identifier=<ID_Local>]
|
||||
FederadorNacion-->>NodoDominio: 200 OK (Patient Searchset)
|
||||
Note over NodoDominio,IndiceNacion: 3. Enrutamiento de la Petición
|
||||
Note right of NodoDominio: El Nodo genera la referencia al IPS y la asocia al identificador nacional del paciente.
|
||||
NodoDominio->>IndiceNacion: Guarda la referencia al IPS en el índice de documentos [POST /DocumentReference]
|
||||
Note right of NodoDominio: El Nodo genera la referencia al documento y la asocia al identificador nacional del paciente.
|
||||
NodoDominio->>IndiceNacion: Guarda la referencia al documento en el índice de documentos [POST /DocumentReference]
|
||||
IndiceNacion-->>NodoDominio: 201 (Created)
|
||||
NodoDominio-->>HIS_A: 200 OK (DocumentReference)
|
||||
|
||||
@ -1,11 +1,24 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { provideIPSTransaction, provideIPSDocumentBundle } = require('../controllers/iti65');
|
||||
const {
|
||||
provideIPSTransaction,
|
||||
provideIPSDocumentBundle,
|
||||
provideMeOWTransaction,
|
||||
provideMeOWDocumentBundle,
|
||||
provideITTransaction,
|
||||
provideITDocumentBundle,
|
||||
} = require('../controllers/iti65');
|
||||
|
||||
// ITI-65: Provide Document Bundle — variante transaction Bundle
|
||||
// ITI-65: Provide Document Bundle — IPS
|
||||
router.post('/IPSTransaction', provideIPSTransaction);
|
||||
|
||||
// ITI-65: Provide Document Bundle — variante IPS document Bundle (type: document)
|
||||
router.post('/IPSDocument', provideIPSDocumentBundle);
|
||||
|
||||
// ITI-65: Provide Document Bundle — MeOW (Medication Overview)
|
||||
router.post('/MeOWTransaction', provideMeOWTransaction);
|
||||
router.post('/MeOWDocument', provideMeOWDocumentBundle);
|
||||
|
||||
// ITI-65: Provide Document Bundle — IT (Consultation Note / respuesta de interconsulta)
|
||||
router.post('/ITTransaction', provideITTransaction);
|
||||
router.post('/ITDocument', provideITDocumentBundle);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@ -35,6 +35,46 @@ http {
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — MeOW (Medication Overview) transaction Bundle
|
||||
location /fhir/MeOWTransaction {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — MeOW (Medication Overview) document Bundle
|
||||
location /fhir/MeOWDocument {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — IT (Consultation Note) transaction Bundle
|
||||
location /fhir/ITTransaction {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — IT (Consultation Note) document Bundle
|
||||
location /fhir/ITDocument {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-67: Find Document References
|
||||
location /fhir/DocumentReference {
|
||||
proxy_pass http://bus_gateway;
|
||||
|
||||
@ -51,6 +51,46 @@ http {
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — MeOW (Medication Overview) transaction Bundle
|
||||
location /fhir/MeOWTransaction {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — MeOW (Medication Overview) document Bundle
|
||||
location /fhir/MeOWDocument {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — IT (Consultation Note) transaction Bundle
|
||||
location /fhir/ITTransaction {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-65: Provide Document Bundle — IT (Consultation Note) document Bundle
|
||||
location /fhir/ITDocument {
|
||||
proxy_pass http://bus_gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# ITI-67: Find Document References
|
||||
location /fhir/DocumentReference {
|
||||
proxy_pass http://bus_gateway;
|
||||
|
||||
121
tests/fixtures/iti65/bundle-document-it.json
vendored
Normal file
121
tests/fixtures/iti65/bundle-document-it.json
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
{
|
||||
"resourceType": "Bundle",
|
||||
"type": "document",
|
||||
"timestamp": "2026-04-23T07:50:00-03:00",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "urn:uuid:5ca8da35-efb1-498a-93bc-ed34524a360f",
|
||||
"resource": {
|
||||
"resourceType": "Patient",
|
||||
"identifier": [
|
||||
{
|
||||
"system": "urn:oid:2.16.858.1.858.1.1.1",
|
||||
"value": "123456789"
|
||||
}
|
||||
],
|
||||
"active": true,
|
||||
"name": [
|
||||
{
|
||||
"use": "official",
|
||||
"family": "Pérez",
|
||||
"given": [
|
||||
"Juan"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:4d58cb4f-1f8b-4f94-9877-bb5a0de47955",
|
||||
"resource": {
|
||||
"resourceType": "Composition",
|
||||
"status": "final",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "11488-4",
|
||||
"display": "Consultation note"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:5ca8da35-efb1-498a-93bc-ed34524a360f"
|
||||
},
|
||||
"date": "2026-04-23T07:50:00-03:00",
|
||||
"author": [
|
||||
{
|
||||
"display": "Dra. Especialista - Nodo Panamá"
|
||||
}
|
||||
],
|
||||
"title": "Informe de Contra-referencia Dermatológica",
|
||||
"section": [
|
||||
{
|
||||
"title": "Motivo de Interconsulta",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "42349-1",
|
||||
"display": "Reason for referral"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Se solicita segunda opinión para evaluación de lesión pigmentada en región escapular, con el fin de descartar malignidad tras hallazgos clínicos iniciales en Uruguay.</p></div>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Revisión de Evidencia",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "30954-2",
|
||||
"display": "Relevant diagnostic tests"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Se re-evaluaron los resultados del IPS (Bundle/2313), específicamente el DiagnosticReport/biopsia-001 y las imágenes dermatoscópicas adjuntas.</p></div>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Juicio Clínico",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "51848-0",
|
||||
"display": "Assessment note"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Tras el análisis de la evidencia, se concluye que la morfología de la lesión es compatible con un Nevus Displásico. No se identifican criterios histológicos de melanoma.</p></div>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Recomendaciones",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "18776-5",
|
||||
"display": "Plan of care"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><ul><li>Control dermatoscópico cada 6 meses.</li><li>Uso de fotoprotección (FPS 50+).</li><li>No se requiere intervención quirúrgica inmediata.</li></ul></div>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
177
tests/fixtures/iti65/bundle-document-meow.json
vendored
Normal file
177
tests/fixtures/iti65/bundle-document-meow.json
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
{
|
||||
"resourceType": "Bundle",
|
||||
"id": "medication-overview-example",
|
||||
"meta": {
|
||||
"profile": [
|
||||
"http://profiles.ihe.net/PHARM/MEOW/StructureDefinition/MedicationOverview"
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"system": "urn:ietf:rfc:3986",
|
||||
"value": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a71"
|
||||
},
|
||||
"type": "document",
|
||||
"timestamp": "2025-06-17T18:36:18+00:00",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a72",
|
||||
"resource": {
|
||||
"resourceType": "Composition",
|
||||
"id": "composition-example",
|
||||
"meta": {
|
||||
"profile": [
|
||||
"http://profiles.ihe.net/PHARM/MEOW/StructureDefinition/MedicationOverviewComposition"
|
||||
]
|
||||
},
|
||||
"status": "final",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "56445-0",
|
||||
"display": "Medication summary"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
},
|
||||
"date": "2025-06-17T18:36:18+00:00",
|
||||
"author": [
|
||||
{
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
}
|
||||
],
|
||||
"title": "Medication Overview",
|
||||
"section": [
|
||||
{
|
||||
"title": "Medicamentos",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "55112-7",
|
||||
"display": "Document summary"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Resumen de medicamentos</p></div>"
|
||||
},
|
||||
"entry": [
|
||||
{
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a74"
|
||||
},
|
||||
{
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a75"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73",
|
||||
"resource": {
|
||||
"resourceType": "Patient",
|
||||
"id": "patient-example",
|
||||
"identifier": [
|
||||
{
|
||||
"system": "http://hospital.example.org",
|
||||
"value": "12345"
|
||||
}
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"family": "Doe",
|
||||
"given": [
|
||||
"John"
|
||||
]
|
||||
}
|
||||
],
|
||||
"gender": "male",
|
||||
"birthDate": "1970-01-01"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a74",
|
||||
"resource": {
|
||||
"resourceType": "MedicationStatement",
|
||||
"id": "medication-statement-1",
|
||||
"status": "active",
|
||||
"medicationCodeableConcept": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://snomed.info/sct",
|
||||
"code": "1222004",
|
||||
"display": "Metronidazole-containing product"
|
||||
}
|
||||
],
|
||||
"text": "Metronidazole-containing product"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
},
|
||||
"effectiveDateTime": "2025-01-01",
|
||||
"effectivePeriod": {
|
||||
"start": "2025-01-01",
|
||||
"end": "2025-12-31"
|
||||
},
|
||||
"dateAsserted": "2025-06-17T18:36:18+00:00",
|
||||
"dosage": [
|
||||
{
|
||||
"text": "500 mg daily",
|
||||
"route": {
|
||||
"text": "Oral"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reasonCode": [
|
||||
{
|
||||
"text": "Infection"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a75",
|
||||
"resource": {
|
||||
"resourceType": "MedicationStatement",
|
||||
"id": "medication-statement-2",
|
||||
"status": "active",
|
||||
"medicationCodeableConcept": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://snomed.info/sct",
|
||||
"code": "796001",
|
||||
"display": "Digoxin-containing product"
|
||||
}
|
||||
],
|
||||
"text": "Digoxin-containing product"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
},
|
||||
"effectiveDateTime": "2025-01-01",
|
||||
"effectivePeriod": {
|
||||
"start": "2025-01-01"
|
||||
},
|
||||
"dateAsserted": "2025-06-17T18:36:18+00:00",
|
||||
"dosage": [
|
||||
{
|
||||
"text": "0.125 mg daily",
|
||||
"route": {
|
||||
"text": "Oral"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reasonCode": [
|
||||
{
|
||||
"text": "Heart failure"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
188
tests/fixtures/iti65/bundle-transaction-it.json
vendored
Normal file
188
tests/fixtures/iti65/bundle-transaction-it.json
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
{
|
||||
"resourceType": "Bundle",
|
||||
"type": "transaction",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "urn:uuid:5ca8da35-efb1-498a-93bc-ed34524a360f",
|
||||
"resource": {
|
||||
"resourceType": "Patient",
|
||||
"identifier": [
|
||||
{
|
||||
"system": "urn:oid:2.16.858.1.858.1.1.1",
|
||||
"value": "123456789"
|
||||
}
|
||||
],
|
||||
"active": true,
|
||||
"name": [
|
||||
{
|
||||
"use": "official",
|
||||
"family": "Pérez",
|
||||
"given": [
|
||||
"Juan"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "Patient"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:15f62e6b-f4d9-43d8-91f5-ee963a34339c",
|
||||
"resource": {
|
||||
"resourceType": "DocumentReference",
|
||||
"status": "current",
|
||||
"docStatus": "final",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "57133-1",
|
||||
"display": "Referral note"
|
||||
}
|
||||
],
|
||||
"text": "Informe de Contra-referencia Dermatológica"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:5ca8da35-efb1-498a-93bc-ed34524a360f"
|
||||
},
|
||||
"date": "2026-04-23T07:50:00-03:00",
|
||||
"author": [
|
||||
{
|
||||
"display": "Dra. Especialista - Nodo Panamá"
|
||||
}
|
||||
],
|
||||
"description": "Respuesta a interconsulta - Caso Dermatología",
|
||||
"content": [
|
||||
{
|
||||
"attachment": {
|
||||
"contentType": "application/fhir+json",
|
||||
"url": "urn:uuid:03e4a890-b152-481a-9ca5-685e03550a08"
|
||||
}
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"related": [
|
||||
{
|
||||
"identifier": {
|
||||
"system": "https://salud.gub.uy/interconsultas",
|
||||
"value": "UY-PA-2026-998877"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "DocumentReference"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:03e4a890-b152-481a-9ca5-685e03550a08",
|
||||
"resource": {
|
||||
"resourceType": "Bundle",
|
||||
"type": "document",
|
||||
"timestamp": "2026-04-23T07:50:00-03:00",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "urn:uuid:4d58cb4f-1f8b-4f94-9877-bb5a0de47955",
|
||||
"resource": {
|
||||
"resourceType": "Composition",
|
||||
"status": "final",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "11488-4",
|
||||
"display": "Consultation note"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:5ca8da35-efb1-498a-93bc-ed34524a360f"
|
||||
},
|
||||
"date": "2026-04-23T07:50:00-03:00",
|
||||
"author": [
|
||||
{
|
||||
"display": "Dra. Especialista - Nodo Panamá"
|
||||
}
|
||||
],
|
||||
"title": "Informe de Contra-referencia Dermatológica",
|
||||
"section": [
|
||||
{
|
||||
"title": "Motivo de Interconsulta",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "42349-1",
|
||||
"display": "Reason for referral"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Se solicita segunda opinión para evaluación de lesión pigmentada en región escapular, con el fin de descartar malignidad tras hallazgos clínicos iniciales en Uruguay.</p></div>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Revisión de Evidencia",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "30954-2",
|
||||
"display": "Relevant diagnostic tests"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Se re-evaluaron los resultados del IPS (Bundle/2313), específicamente el DiagnosticReport/biopsia-001 y las imágenes dermatoscópicas adjuntas.</p></div>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Juicio Clínico",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "51848-0",
|
||||
"display": "Assessment note"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Tras el análisis de la evidencia, se concluye que la morfología de la lesión es compatible con un Nevus Displásico. No se identifican criterios histológicos de melanoma.</p></div>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Recomendaciones",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "18776-5",
|
||||
"display": "Plan of care"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><ul><li>Control dermatoscópico cada 6 meses.</li><li>Uso de fotoprotección (FPS 50+).</li><li>No se requiere intervención quirúrgica inmediata.</li></ul></div>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "Bundle"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
258
tests/fixtures/iti65/bundle-transaction-meow.json
vendored
Normal file
258
tests/fixtures/iti65/bundle-transaction-meow.json
vendored
Normal file
@ -0,0 +1,258 @@
|
||||
{
|
||||
"resourceType": "Bundle",
|
||||
"id": "iti65-transaction-medication",
|
||||
"type": "transaction",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73",
|
||||
"resource": {
|
||||
"resourceType": "Patient",
|
||||
"id": "patient-example",
|
||||
"identifier": [
|
||||
{
|
||||
"system": "http://hospital.example.org",
|
||||
"value": "12345"
|
||||
}
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"family": "Doe",
|
||||
"given": [
|
||||
"John"
|
||||
]
|
||||
}
|
||||
],
|
||||
"gender": "male",
|
||||
"birthDate": "1970-01-01"
|
||||
},
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "Patient"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a80",
|
||||
"resource": {
|
||||
"resourceType": "DocumentReference",
|
||||
"status": "current",
|
||||
"docStatus": "final",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "56445-0",
|
||||
"display": "Medication summary"
|
||||
}
|
||||
],
|
||||
"text": "Medication Overview"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
},
|
||||
"date": "2025-06-17T18:36:18+00:00",
|
||||
"author": [
|
||||
{
|
||||
"display": "Dra. Especialista"
|
||||
}
|
||||
],
|
||||
"description": "Medication Overview - Patient Medication Summary",
|
||||
"content": [
|
||||
{
|
||||
"attachment": {
|
||||
"contentType": "application/fhir+json",
|
||||
"url": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a71"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "DocumentReference"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a71",
|
||||
"resource": {
|
||||
"resourceType": "Bundle",
|
||||
"id": "medication-overview-example",
|
||||
"meta": {
|
||||
"profile": [
|
||||
"http://profiles.ihe.net/PHARM/MEOW/StructureDefinition/MedicationOverview"
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"system": "urn:ietf:rfc:3986",
|
||||
"value": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a71"
|
||||
},
|
||||
"type": "document",
|
||||
"timestamp": "2025-06-17T18:36:18+00:00",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a72",
|
||||
"resource": {
|
||||
"resourceType": "Composition",
|
||||
"id": "composition-example",
|
||||
"meta": {
|
||||
"profile": [
|
||||
"http://profiles.ihe.net/PHARM/MEOW/StructureDefinition/MedicationOverviewComposition"
|
||||
]
|
||||
},
|
||||
"status": "final",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "56445-0",
|
||||
"display": "Medication summary"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
},
|
||||
"date": "2025-06-17T18:36:18+00:00",
|
||||
"author": [
|
||||
{
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
}
|
||||
],
|
||||
"title": "Medication Overview",
|
||||
"section": [
|
||||
{
|
||||
"title": "Medicamentos",
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "55112-7",
|
||||
"display": "Document summary"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Resumen de medicamentos</p></div>"
|
||||
},
|
||||
"entry": [
|
||||
{
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a74"
|
||||
},
|
||||
{
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a75"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73",
|
||||
"resource": {
|
||||
"resourceType": "Patient",
|
||||
"id": "patient-example",
|
||||
"identifier": [
|
||||
{
|
||||
"system": "http://hospital.example.org",
|
||||
"value": "12345"
|
||||
}
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"family": "Doe",
|
||||
"given": [
|
||||
"John"
|
||||
]
|
||||
}
|
||||
],
|
||||
"gender": "male",
|
||||
"birthDate": "1970-01-01"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a74",
|
||||
"resource": {
|
||||
"resourceType": "MedicationStatement",
|
||||
"id": "medication-statement-1",
|
||||
"status": "active",
|
||||
"medicationCodeableConcept": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://snomed.info/sct",
|
||||
"code": "1222004",
|
||||
"display": "Metronidazole-containing product"
|
||||
}
|
||||
],
|
||||
"text": "Metronidazole-containing product"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
},
|
||||
"effectiveDateTime": "2025-01-01",
|
||||
"effectivePeriod": {
|
||||
"start": "2025-01-01",
|
||||
"end": "2025-12-31"
|
||||
},
|
||||
"dateAsserted": "2025-06-17T18:36:18+00:00",
|
||||
"dosage": [
|
||||
{
|
||||
"text": "500 mg daily",
|
||||
"route": {
|
||||
"text": "Oral"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reasonCode": [
|
||||
{
|
||||
"text": "Infection"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a75",
|
||||
"resource": {
|
||||
"resourceType": "MedicationStatement",
|
||||
"id": "medication-statement-2",
|
||||
"status": "active",
|
||||
"medicationCodeableConcept": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://snomed.info/sct",
|
||||
"code": "796001",
|
||||
"display": "Digoxin-containing product"
|
||||
}
|
||||
],
|
||||
"text": "Digoxin-containing product"
|
||||
},
|
||||
"subject": {
|
||||
"reference": "urn:uuid:68c15694-52f1-4171-bc01-e63d666d2a73"
|
||||
},
|
||||
"effectiveDateTime": "2025-01-01",
|
||||
"effectivePeriod": {
|
||||
"start": "2025-01-01"
|
||||
},
|
||||
"dateAsserted": "2025-06-17T18:36:18+00:00",
|
||||
"dosage": [
|
||||
{
|
||||
"text": "0.125 mg daily",
|
||||
"route": {
|
||||
"text": "Oral"
|
||||
}
|
||||
}
|
||||
],
|
||||
"reasonCode": [
|
||||
{
|
||||
"text": "Heart failure"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "Bundle"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user