diff --git a/mediator/src/middlewares/schemas/patient.ts b/mediator/src/middlewares/schemas/patient.ts index 385e76ae..4bffd3d4 100644 --- a/mediator/src/middlewares/schemas/patient.ts +++ b/mediator/src/middlewares/schemas/patient.ts @@ -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(), }); diff --git a/mediator/src/middlewares/schemas/tests/fhir-resource-factories.ts b/mediator/src/middlewares/schemas/tests/fhir-resource-factories.ts index d35f460b..fdc2f81e 100644 --- a/mediator/src/middlewares/schemas/tests/fhir-resource-factories.ts +++ b/mediator/src/middlewares/schemas/tests/fhir-resource-factories.ts @@ -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) diff --git a/mediator/src/routes/patient.ts b/mediator/src/routes/patient.ts index a65b07a8..76df1dfc 100644 --- a/mediator/src/routes/patient.ts +++ b/mediator/src/routes/patient.ts @@ -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'; @@ -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; diff --git a/mediator/src/routes/tests/patient.spec.ts b/mediator/src/routes/tests/patient.spec.ts index 25f2c8fd..4d509c83 100644 --- a/mediator/src/routes/tests/patient.spec.ts +++ b/mediator/src/routes/tests/patient.spec.ts @@ -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); diff --git a/mediator/src/utils/openmrs.ts b/mediator/src/utils/openmrs.ts new file mode 100644 index 00000000..f6a5e518 --- /dev/null +++ b/mediator/src/utils/openmrs.ts @@ -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): 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; +}