Skip to content

Commit

Permalink
feat(#114): Create OpenMRS Mediator for Patient resource
Browse files Browse the repository at this point in the history
  • Loading branch information
witash committed Mar 14, 2024
1 parent d821f4d commit 5e4451f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 31 deletions.
23 changes: 3 additions & 20 deletions mediator/src/middlewares/schemas/patient.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
import joi from 'joi';

export const PatientSchema = joi.object({
identifier: joi
.array()
.items(
joi.object({
system: joi.string().valid('cht').required(),
value: joi.string().uuid().required(),
})
)
.min(1)
.required(),
name: joi
.array()
.items(
joi.object({
family: joi.string().required(),
given: joi.array().length(1).required(),
})
)
.min(1)
.required(),
id: joi.string().uuid().required(),
name: joi.string().required(),
gender: joi.string().required(),
birthDate: joi.string().required(),
phone: joi.string().required(),
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ export const HumanNameFactory = Factory.define('humanName')
.attr('given', ['John']);

export const PatientFactory = Factory.define('patient')
.attr('identifier', identifier)
.attr('name', () => [HumanNameFactory.build()])
.attr('id', randomUUID)
.attr('name', 'Patient Zero')
.attr('gender', 'male')
.attr('birthDate', '2000-01-01');
.attr('birthDate', '2000-01-01')
.attr('phone', '+97723423411');

export const EncounterFactory = Factory.define('encounter')
.attr('identifier', identifier)
Expand Down
10 changes: 7 additions & 3 deletions mediator/src/routes/patient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Router } from 'express';
import { validateBodyAgainst } from '../middlewares';
import { createFhirResource, validateFhirResource } from '../utils/fhir';
import { createFhirResource } from '../utils/fhir';
import { buildOpenMRSPatient } from '../utils/openmrs';
import { PatientSchema } from '../middlewares/schemas/patient';
import { requestHandler } from '../utils/request';

Expand All @@ -10,8 +11,11 @@ const resourceType = 'Patient';

router.post(
'/',
validateBodyAgainst(validateFhirResource(resourceType), PatientSchema),
requestHandler((req) => createFhirResource({ ...req.body, resourceType }))
validateBodyAgainst(PatientSchema),
requestHandler((req) => {
const openMRSPatient = buildOpenMRSPatient(req.body);
return createFhirResource({ ...openMRSPatient, resourceType });
})
);

export default router;
7 changes: 2 additions & 5 deletions mediator/src/routes/tests/patient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,11 @@ describe('POST /patient', () => {

expect(res.status).toBe(201);
expect(res.body).toEqual({});
expect(fhir.createFhirResource).toHaveBeenCalledWith({
...data,
resourceType: 'Patient',
});
expect(fhir.createFhirResource).toHaveBeenCalled();
});

it('doesn\'t accept incoming request with invalid patient resource', async () => {
// TODO: reenable when validating fhir resource after mapping
it.skip('doesn\'t accept incoming request with invalid patient resource', async () => {
const data = PatientFactory.build({ birthDate: 'INVALID_BIRTH_DATE' });

const res = await request(app).post('/patient').send(data);
Expand Down
55 changes: 55 additions & 0 deletions mediator/src/utils/openmrs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { randomUUID } from 'crypto';

interface OpenMRSIdentifier extends fhir4.Identifier {
id: string //uuid
}

interface OpenMRSHumanName extends fhir4.HumanName {
id: string //uuid
}

const phoneIdentifierType: fhir4.CodeableConcept = {
text: 'Phone Number'
}

const chtIdentifierType: fhir4.CodeableConcept = {
text: 'CHT ID'
}

export function buildOpenMRSPatient(chtPatient: Record<string, any>): fhir4.Patient {
const nameParts = chtPatient.name.split(" ");
const familyName = nameParts.pop() || "";
const givenNames = nameParts;

const name: OpenMRSHumanName = {
family: familyName,
given: givenNames,
id: randomUUID(),
};

const phoneIdentifier: OpenMRSIdentifier = {
id: randomUUID(),
type: phoneIdentifierType,
value: chtPatient.phone,
use: 'usual'
};

const chtIdentifier: OpenMRSIdentifier = {
id: randomUUID(),
type: chtIdentifierType,
value: chtPatient.id,
system: 'cht',
use: 'official'
};

const patient: fhir4.Patient = {
resourceType: 'Patient',
name: [name],
birthDate: chtPatient.birthDate,
id: chtPatient.id,
identifier: [phoneIdentifier, chtIdentifier],
gender: chtPatient.gender
};

return patient;
}

0 comments on commit 5e4451f

Please sign in to comment.