The project is divided into two apps:
- A React powered frontend, created using Create React App
- A backend, powered by AdonisJs and a MySQL database, exposing a REST API
Follow these instructions to get the project up and running:
- Install Node.js.
Make sure you have Node >= v8.10 installed on your machine.
- Install Yarn.
Make sure you have Yarn v1 installed on your machine.
-
Install dependencies.
This will install the Node dependencies for both projects at once.
cd jembi-fhir-server/ yarn
-
Run migrations
yarn workspace backend node ace migration:run
-
Start the two apps
yarn workspace backend cd backend/ yarn workspace frontend
You only need to start the backend application for this demo
- And, you're all set up!
yarn workspace backend test test/ObservationsEndpoint.ts
yarn lint
yarn lint:fix
curl -L -X POST "http://127.0.0.1:<port>/v1/Observations" \
-H "Content-Type: application/json" \
--data-raw '{ "resourceType" : "Observation", ... }'
Alternatively, you should use an API testing tool like Postman for convenience
NB: Remember to use adapted request body sample in the Assumptions about app section.
curl -L -X GET "http://127.0.0.1:<port>/v1/Observations?category=vital-signs&code=LOINC"
Where LOINC
is a string value for the code
NB: Multi code search i.e ...&code=[LOINC{,LOINC2...}]
is not implemented
curl -L -X GET "http://127.0.0.1:<port>/v1/Observations?category=vital-signs&date=[date]"
curl -L -X GET "http://127.0.0.1:<port>/v1/Observations?category=vital-signs&date=[date]{&date=[date]}"
The query parameter and value ?category=vital-signs
should be added otherwise an error will returned.
The database needs to populated with sufficient data for running queries against the API.
- The structure of the
POST
request body resembles theObservation
resource here
Here's the adapted structure of the request body
{
"resourceType" : "Observation",
// from Resource: id, meta, implicitRules, and language
// from DomainResource: See jembi-fhir-server/backend/app/Models/DomainResource
"identifier" : [{ Identifier }], // Business Identifier for observation
"status" : "<code>", // R! registered | preliminary | final | amended +
"code": { CodeableConcept }, // R! Type of observation (code / type)
"effectivePeriod" : { Period },
"issued" : "<instant>", // Date/Time this version was made available
"valueQuantity": { Quantity },
"interpretation": [
{
"low" : { Quantity(SimpleQuantity) }, // C? Low Range, if relevant
"high" : { Quantity(SimpleQuantity) }, // C? High Range, if relevant
...
"text" : "<string>" // Text based reference range in an observation
}
]
}
Here's a sample of the adapted request body
{
"identifier": [
{
"use": "official",
"system": "http://www.bmc.nl/zorgportal/identifiers/observations",
"value": "6325"
}
],
"status": "final",
"code": {
"text": "Negative for Chlamydia Trachomatis rRNA",
"coding": [
{
"system": "http://loinc.org",
"symbol": "11557-6",
"display": "Carbon dioxide in blood"
}
]
},
"effectivePeriod": {
"start": "2013-04-02T10:30:10+01:00",
"end": "2013-04-05T10:30:10+01:00"
},
"issued": "2013-04-03T15:30:10+01:00",
"valueQuantity": {
"value": 6.2,
"unit": "kPa",
"system": "http://unitsofmeasure.org",
"code": "kPa"
},
"interpretation": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
"code": "H",
"display": "High"
}
]
}
],
"referenceRange": [
{
"text": "Text based reference range in an observation",
"low": {
"value": 4.8,
"unit": "kPa",
"system": "http://unitsofmeasure.org",
"code": "kPa"
},
"high": {
"value": 6.0,
"unit": "kPa",
"system": "http://unitsofmeasure.org",
"code": "kPa"
}
}
]
}
-
Data to the
POST
endpoint has beeen validated on frontend and can be reasonably realied on. -
Several attributes were ommited from the
Observation
model underjembi-fhir-server/backend/app/Models/Observation
to make scope manageable. -
Observation
andDomainResource
have ahasOne
relationship. AnObservation
has oneDomainResource
associated with it at the time of its creation and that thisDomainResource
houses the logical ID and meta information which is populated by default. -
Resource
andDomainResource
have been merged into one representation to make scope manageable. You'll find some attributes fromResource
such asid
referenced inDomainResource
. -
In the interest of time, the exercise didn't focus developing extensive unit tests and generating seed values for extensive testing.
-
The response has been standardised under
jembi-fhir-server/backend/contracts/interfaces/ObservationsInterface
-
ReferenceRange
accepts a single instance of even though it has ahasMany
relationship with the parant modelObservation
. The first object will be read from the array passed to it only.