Skip to content

Commit

Permalink
Merge branch 'main' of github.com:jembi/mpi-mediator into Enable-pati…
Browse files Browse the repository at this point in the history
…ent-update
  • Loading branch information
bradsawadye committed May 9, 2024
2 parents 74dfb6f + 9cc1e01 commit d13ed92
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 22 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
8 changes: 5 additions & 3 deletions src/middlewares/mpi-mdm-summary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);

Expand Down Expand Up @@ -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);
Expand Down
19 changes: 15 additions & 4 deletions src/routes/handlers/fetchPatientSummaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,23 @@ const {
} = getConfig();

export const fetchAllPatientSummariesByRefs = async (
patientRefs: string[]
patientRefs: string[],
queryParams?: object
): Promise<Bundle> => {
// 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',
Expand All @@ -46,10 +56,11 @@ export const fetchAllPatientSummariesByRefs = async (
};

export const fetchPatientSummaryByRef = async (
ref: string
ref: string,
queryParams: object
): Promise<MpiMediatorResponseObject> => {
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}`);
Expand Down
17 changes: 10 additions & 7 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,20 @@ routes.get('/fhir/Patient/:patientId', async (req, res) => {
{}
);

let upsteamId = requestedId;
let upstreamId = requestedId;

if (fhirResponse.status === 200) {
const patient = fhirResponse.body as Patient;
const interactionId =
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',
Expand All @@ -116,7 +116,7 @@ routes.get('/fhir/Patient/:patientId', async (req, res) => {
mpiProtocol,
mpiHost,
mpiPort,
`/fhir/links/Patient/${upsteamId}`,
`/fhir/links/Patient/${upstreamId}`,
{}
);

Expand All @@ -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`
);
}

Expand All @@ -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);
Expand Down
12 changes: 10 additions & 2 deletions src/utils/kafkaFhir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
};

Expand All @@ -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));
}
}
});

Expand Down
5 changes: 2 additions & 3 deletions tests/unit/fetchPatientSummaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
Expand Down

0 comments on commit d13ed92

Please sign in to comment.