Skip to content

Commit

Permalink
Merge pull request #48 from jembi/add-full-patient-details-summary
Browse files Browse the repository at this point in the history
Add full patient's demographic details to patients summary
  • Loading branch information
rcrichton authored Sep 16, 2024
2 parents e00ae90 + 278db71 commit ef604d3
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 15 deletions.
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.3.0",
"version": "v2.3.1",
"description": "An OpenHIM mediator to handle all interactions with an MPI component",
"main": "index.ts",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/openhim/mediatorConfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"urn": "urn:mediator:mpi-mediator",
"version": "v2.3.0",
"version": "v2.3.1",
"name": "MPI mediator",
"description": "A mediator handling interactions between the OpenHIM Core service, Sante MPI, Hapi-FHIR, and Kafka",
"defaultChannelConfig": [
Expand Down
21 changes: 19 additions & 2 deletions src/routes/handlers/fetchPatientSummaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '../../utils/utils';
import logger from '../../logger';
import { MpiMediatorResponseObject, Orchestration } from '../../types/response';
import { fetchPatientById } from './fetchPatient';

const {
fhirDatastoreProtocol: protocol,
Expand All @@ -26,7 +27,7 @@ export const fetchAllPatientSummariesByRefs = async (
// remove duplicates
patientRefs = Array.from(new Set(patientRefs.map(ref => ref?.split('/').pop() || '')));

const patientExternalRefs = patientRefs.map((ref) => {
const patientExternalRefs = patientRefs.map(async (ref) => {
const params = Object.entries(queryParams ?? {});
let combinedParams = null;

Expand All @@ -36,6 +37,13 @@ export const fetchAllPatientSummariesByRefs = async (
.join('&');
}

const fullPatient: MpiMediatorResponseObject = await fetchPatientById(ref, '');
orchestrations.push(...fullPatient.body.orchestrations);

if (!isHttpStatusOk(fullPatient.status) && fullPatient.status != 404) {
throw fullPatient;
}

const path = `/fhir/Patient/${ref}/$summary${combinedParams ? `?${combinedParams}` : ''}`;

const headers: HeadersInit = {'Content-Type': 'application/fhir+json'};
Expand All @@ -58,7 +66,16 @@ export const fetchAllPatientSummariesByRefs = async (
throw response;
}

return response;
// Add patient's demographic data
const bundle = response?.body as Bundle;

const index = bundle.entry?.findIndex(resource => resource.resource?.resourceType?.match(/Patient/));

if (bundle.entry && index && index > -1) {
bundle.entry[index].resource = JSON.parse(fullPatient.body.response.body);
}

return {status: response.status, body: bundle};
});
});

Expand Down
115 changes: 114 additions & 1 deletion tests/unit/fetchPatientSummaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
} from '../../src/routes/handlers/fetchPatientSummaries';
import format from 'date-fns/format';
import { Orchestration } from '../../src/types/response';
import * as patientMethods from '../../src/routes/handlers/fetchPatient';
import sinon from 'sinon';

const config = getConfig();

Expand Down Expand Up @@ -188,8 +190,80 @@ const combinedBundle2: Bundle = {
};

describe('FetchPatientSummaries handler', (): void => {
const mpiPatient = {
id: 123,
identifier: [
{
system: 'http://cdr.aacahb.gov.et/SmartCareID',
value: '642b83d3-a43c-41ef-a578-2b730f276bfb',
},
{
system: 'http://cdr.aacahb.gov.et/NationalID',
value: 'MRN-642b83d3-a43c-41ef-a578-2b730f476bf9',
},
{
system: 'http://cdr.aacahb.gov.et/UAN',
value: 'UAN-642b83d3-a43c-41ef-a578-2b730f276bfb',
},
],
name: [
{
use: 'official',
family: 'Rodrigues',
given: ['Liniee'],
},
],
telecom: [
{
system: 'phone',
value: '+2519000000',
use: 'home',
},
],
gender: 'female',
birthDate: '1999-06-19',
address: [
{
type: 'physical',
text: 'Urban',
state: 'Addis Ababa',
city: 'Cherkos sub city',
district: '10',
line: ['17', '927/5'],
},
],
maritalStatus: {
coding: [
{
system: 'http://terminology.hl7.org/CodeSystem/v3-MaritalStatus',
code: 'M',
display: 'Married',
},
],
},
link: [
{
other: {
reference: `Patient/123`,
},
type: 'refer',
},
],
resourceType: 'Patient',
};

describe('fetchAllPatientSummariesByRefs', async () => {
it('should return an empty bundle', async () => {
const stub = sinon.stub(patientMethods, 'fetchPatientById');
stub.resolves({
status: 200,
body: {
'x-mediator-urn': 'urn',
status: 'Successful',
orchestrations: [],
response: { status: 200, timestamp: '102203002', body: JSON.stringify(mpiPatient) },
},
});
nock(fhirDatastoreUrl).get(`/fhir/${emptyPatientRef1}/$summary`).reply(200, {});
nock(fhirDatastoreUrl).get(`/fhir/${emptyPatientRef2}/$summary`).reply(200, {});

Expand All @@ -198,30 +272,69 @@ describe('FetchPatientSummaries handler', (): void => {
emptyPatientRef2,
]);
expect(result).to.deep.equal(emptyBundle);
stub.restore();
});

it('should return a bundle with 2 entries for 2 given patients', async () => {
const stub = sinon.stub(patientMethods, 'fetchPatientById');
stub.resolves({
status: 200,
body: {
'x-mediator-urn': 'urn',
status: 'Successful',
orchestrations: [],
response: { status: 200, timestamp: '102203002', body: JSON.stringify(mpiPatient) },
},
});
nock(fhirDatastoreUrl).get(`/fhir/${patientRef1}/$summary`).reply(200, patientSummary1);
nock(fhirDatastoreUrl).get(`/fhir/${patientRef2}/$summary`).reply(200, patientSummary2);

const orchestrations: Orchestration[] = [];
const result = await fetchAllPatientSummariesByRefs([patientRef1, patientRef2], {}, orchestrations);
const result = await fetchAllPatientSummariesByRefs(
[patientRef1, patientRef2],
{},
orchestrations
);
expect(result).to.deep.equal(combinedBundle1);
expect(orchestrations.length).to.be.greaterThan(0);
stub.restore();
});
});

describe('fetchPatientSummariesByRefs', async () => {
it('should return an empty bundle', async () => {
const stub = sinon.stub(patientMethods, 'fetchPatientById');
stub.resolves({
status: 200,
body: {
'x-mediator-urn': 'urn',
status: 'Successful',
orchestrations: [],
response: { status: 200, timestamp: '102203002', body: JSON.stringify(mpiPatient) },
},
});
nock(fhirDatastoreUrl).get(`/fhir/${emptyPatientRef1}/$summary`).reply(200, {});

const result = await fetchPatientSummaryByRef(emptyPatientRef1, {});
expect(JSON.parse(result.body.response.body)).to.deep.equal(emptyBundle);
stub.restore();
});
it('should return a bundle with 2 entries for 1 given patient', async () => {
const stub = sinon.stub(patientMethods, 'fetchPatientById');
stub.resolves({
status: 200,
body: {
'x-mediator-urn': 'urn',
status: 'Successful',
orchestrations: [],
response: { status: 200, timestamp: '102203002', body: JSON.stringify(mpiPatient) },
},
});
nock(fhirDatastoreUrl).get(`/fhir/${patientRef3}/$summary`).reply(200, patientSummary3);

const result = await fetchPatientSummaryByRef(patientRef3, {});
expect(JSON.parse(result.body.response.body)).to.deep.equal(combinedBundle2);
stub.restore();
});
});
});
Loading

0 comments on commit ef604d3

Please sign in to comment.