diff --git a/package-lock.json b/package-lock.json index f866e2a..e33434f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mpi-mediator", - "version": "v2.1.0", + "version": "v2.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mpi-mediator", - "version": "v2.1.0", + "version": "v2.1.1", "license": "ISC", "dependencies": { "@types/sinon": "^10.0.13", diff --git a/package.json b/package.json index c72f237..7d7b701 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mpi-mediator", - "version": "v2.1.0", + "version": "v2.1.1", "description": "An OpenHIM mediator to handle all interactions with an MPI component", "main": "index.ts", "scripts": { diff --git a/src/middlewares/mpi-mdm-summary.ts b/src/middlewares/mpi-mdm-summary.ts index 859c530..447ace6 100644 --- a/src/middlewares/mpi-mdm-summary.ts +++ b/src/middlewares/mpi-mdm-summary.ts @@ -4,14 +4,14 @@ import { fetchMpiPatientLinks } from '../utils/mpi'; import { buildOpenhimResponseObject } from '../utils/utils'; import { fetchAllPatientSummariesByRefs } from '../routes/handlers/fetchPatientSummaries'; -const fetchAllLinkedPatientSummary = async (patientId: string) => { +const fetchAllLinkedPatientSummary = async (patientId: string, params: object) => { try { const patientRef = `Patient/${patientId}`; const patientRefs: string[] = []; await fetchMpiPatientLinks(patientRef, patientRefs); - const bundle = await fetchAllPatientSummariesByRefs(patientRefs); + const bundle = await fetchAllPatientSummariesByRefs(patientRefs, params); logger.debug(`Fetched all patient summaries from the MPI: ${bundle}`); @@ -40,7 +40,9 @@ export const mpiMdmSummaryMiddleware: RequestHandler = async (req, res, next) => return next(); } - const { status, body } = await fetchAllLinkedPatientSummary(req.params.patientId); + delete req.query._mdm; + + const { status, body } = await fetchAllLinkedPatientSummary(req.params.patientId, req.query); res.set('Content-Type', 'application/json+openhim'); res.status(status).send(body); diff --git a/src/routes/handlers/fetchPatientSummaries.ts b/src/routes/handlers/fetchPatientSummaries.ts index 170e05d..0c0aee6 100644 --- a/src/routes/handlers/fetchPatientSummaries.ts +++ b/src/routes/handlers/fetchPatientSummaries.ts @@ -16,13 +16,23 @@ const { } = getConfig(); export const fetchAllPatientSummariesByRefs = async ( - patientRefs: string[] + patientRefs: string[], + queryParams?: object ): Promise => { // remove duplicates patientRefs = Array.from(new Set(patientRefs.map(ref => ref?.split('/').pop() || ''))); const patientExternalRefs = patientRefs.map((ref) => { - const path = `/fhir/Patient/${ref}/$summary`; + const params = Object.entries(queryParams ?? {}); + let combinedParams = null; + + if (params.length > 0) { + combinedParams = params + .map(([key, value]) => `${key}=${encodeURIComponent(value)}`) + .join('&'); + } + + const path = `/fhir/Patient/${ref}/$summary${combinedParams ? `?${combinedParams}` : ''}`; return getData(protocol, host, port, path, { 'Content-Type': 'application/fhir+json', @@ -46,10 +56,11 @@ export const fetchAllPatientSummariesByRefs = async ( }; export const fetchPatientSummaryByRef = async ( - ref: string + ref: string, + queryParams: object ): Promise => { try { - const bundle = await fetchAllPatientSummariesByRefs([ref]); + const bundle = await fetchAllPatientSummariesByRefs([ref], queryParams); const responseBody = buildOpenhimResponseObject('Successful', 200, bundle); logger.info(`Successfully fetched patient summary with id ${ref}`); diff --git a/src/routes/index.ts b/src/routes/index.ts index d012d7c..d68e0e5 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -87,7 +87,7 @@ routes.get('/fhir/Patient/:patientId', async (req, res) => { {} ); - let upsteamId = requestedId; + let upstreamId = requestedId; if (fhirResponse.status === 200) { const patient = fhirResponse.body as Patient; @@ -95,12 +95,12 @@ routes.get('/fhir/Patient/:patientId', async (req, res) => { patient.link && patient.link[0]?.other.reference?.match(/Patient\/([^/]+)/)?.[1]; if (interactionId) { - upsteamId = interactionId; - logger.debug(`Swapping source ID ${requestedId} for interaction ID ${upsteamId}`); + upstreamId = interactionId; + logger.debug(`Swapping source ID ${requestedId} for interaction ID ${upstreamId}`); } } - logger.debug(`Fetching patient ${upsteamId} from MPI`); + logger.debug(`Fetching patient ${upstreamId} from MPI`); const headers: HeadersInit = { 'Content-Type': 'application/fhir+json', @@ -116,7 +116,7 @@ routes.get('/fhir/Patient/:patientId', async (req, res) => { mpiProtocol, mpiHost, mpiPort, - `/fhir/links/Patient/${upsteamId}`, + `/fhir/links/Patient/${upstreamId}`, {} ); @@ -129,7 +129,7 @@ routes.get('/fhir/Patient/:patientId', async (req, res) => { if (req.query.projection === 'partial') mpiResponse.body = patientProjector(patient); logger.debug( - `Mapped upstream ID ${upsteamId} to requested ID ${requestedId} in response body` + `Mapped upstream ID ${upstreamId} to requested ID ${requestedId} in response body` ); } @@ -151,7 +151,10 @@ routes.get( '/fhir/Patient/:patientId/\\$summary', mpiMdmSummaryMiddleware, asyncHandler(async (req, res) => { - const { status, body } = await fetchPatientSummaryByRef(`Patient/${req.params.patientId}`); + const { status, body } = await fetchPatientSummaryByRef( + `Patient/${req.params.patientId}`, + req.query + ); res.set('Content-Type', 'application/json+openhim'); res.status(status).send(body); diff --git a/src/utils/kafkaFhir.ts b/src/utils/kafkaFhir.ts index 47e147d..3181be1 100644 --- a/src/utils/kafkaFhir.ts +++ b/src/utils/kafkaFhir.ts @@ -76,14 +76,15 @@ export const sendToFhirAndKafka = async ( // Restore full patient resources to the bundle for sending to Kafka Object.keys(newPatientRef).forEach((fullUrl) => { const patientData = newPatientRef[fullUrl]; + const url = `Patient/${patientData.mpiResponsePatient?.id}`; if (patientData.restoredPatient && bundle.entry) { const patientEntry: BundleEntry = { - fullUrl: fullUrl, + fullUrl, resource: patientData.restoredPatient, request: { method: 'PUT', - url: `Patient/${patientData.mpiResponsePatient?.id}`, + url }, }; @@ -101,6 +102,13 @@ export const sendToFhirAndKafka = async ( ); bundle.entry.push(patientEntry); } + + // Replace the old patient reference in the resources + const oldId = fullUrl.split('/').pop(); + + if (oldId) { + bundle = JSON.parse(JSON.stringify(bundle).replace(RegExp(`Patient/${oldId}`, 'g'), url)); + } } }); diff --git a/tests/unit/fetchPatientSummaries.ts b/tests/unit/fetchPatientSummaries.ts index 79fa320..4733860 100644 --- a/tests/unit/fetchPatientSummaries.ts +++ b/tests/unit/fetchPatientSummaries.ts @@ -211,14 +211,13 @@ describe('FetchPatientSummaries handler', (): void => { describe('fetchPatientSummariesByRefs', async () => { it('should return an empty bundle', async () => { nock(fhirDatastoreUrl).get(`/fhir/${emptyPatientRef1}/$summary`).reply(200, {}); - - const result = await fetchPatientSummaryByRef(emptyPatientRef1); + const result = await fetchPatientSummaryByRef(emptyPatientRef1, {}); expect(JSON.parse(result.body.response.body)).to.deep.equal(emptyBundle); }); it('should return a bundle with 2 entries for 1 given patient', async () => { nock(fhirDatastoreUrl).get(`/fhir/${patientRef3}/$summary`).reply(200, patientSummary3); - const result = await fetchPatientSummaryByRef(patientRef3); + const result = await fetchPatientSummaryByRef(patientRef3, {}); expect(JSON.parse(result.body.response.body)).to.deep.equal(combinedBundle2); }); });