Test server for executing FHIR-based Electronic Clinical Quality Measures (eCQMs).
Clone the source code:
git clone https://github.com/projecttacoma/deqm-test-server.git
Install dependencies:
npm install
Unit tests can be running using the following npm
command:
npm run test
This test server makes use of MongoDB, a cross-platform document-oriented database program.
Follow the MongoDB Community Edition installation guide for your platform, and follow the commands for running MongoDB on your machine.
This server uses Redis in order to use the bee queue Node.js queue library. To install with Homebrew, run the following command:
brew install redis
To launch Redis, run:
brew services start redis
To verify the Redis server is running, ping it with:
redis-cli ping
You should receive the output PONG
.
This test server can be run with Docker by calling docker-compose up --build
.
Debugging with terminal input can be facilitated with stdin_open: true
and tty: true
added to the service specification for the service you want to debug. You can then attach to the image of interest using docker attach <imagename>
. If you're unsure of the image name, use docker ps
to find the image of interest.
Once MongoDB is running on your machine, run the npm start
command to start up the FHIR server at localhost:3000
. The server can also be run in "watch" mode with npm run start:watch
and in "debug" mode by running NODE_ENV=development npm start
.
DEQM test server offers optional FHIR resource validation using the Inferno FHIR Validator. The FHIR Validator acts as middleware on all PUT
and POST
requests that attempt to write data to the server. To set this up locally, pull and run the Inferno FHIR Validator docker image using docker run -p 4567:4567 infernocommunity/fhir-validator-service
. Then start up the test server using VALIDATE=true VALIDATOR_HOST=localhost VALIDATOR_PORT=4567 npm run start
. These environment variables can be changed in the .env file as well to prevent lengthy start-up commands.
For ease of testing, it is recommended to download Insomnia API Client and Design Tool for sending HTTP requests to the server and Robo 3T as a GUI for viewing the Mongo database.
When sending requests, ensure that the "Content-type": "application/json+fhir"
header is set. For sending POST/PUT requests, ensure that the "X-Provenance"
is populated with a valid JSON object with the resourceType
key set to "Provenance"
.
The following npm
commands can be used to set up the database:
npm run db:setup
creates collections for all the valid FHIR resource typesnpm run db:delete
deletes all existing collections in the databasenpm run db:reset
runs both of the above, deleting all current collections and then creating new, empty collections- To upload all the ecqm-content-r4-2021 measure bundles,
git clone
the ecqm-content-r4-2021 repo into the root directory of thedeqm-test-server
repository. Runnpm run upload-bundles
. This runs a script that uploads all the measure bundle resources to the appropriate Mongo collections. - The full CLI function signature of
upload-bundles
script isnpm run upload-bundles [dirPath] [searchPattern]
. The command can be run more dynamically by specifying adirPath
string which represents the path to a repository that contains the desired bundles for upload.searchPattern
is a string which is used as a regex to filter bundle files for upload by file name. Example:npm run upload-bundles connectathon/fhir401/bundles/measure "^EXM124.*-bundle.json"
The test server supports the following operations: create, read, update, and delete, search, and transaction. See the FHIR CRUD Operations documentation for more information.
The test server's Measure searching capabilities support searches by name, version, both, or neither.
GET http://localhost:3000/4_0_1/Measure/
returns all Measures currently in the databaseGET http://localhost:3000/4_0_1/Measure?name=NAME
returns all Measures in the database with nameNAME
GET http://localhost:3000/4_0_1/Measure?NAME&version=VERSION
returns all Measures in the database with nameNAME
and versionVERSION
The test server's resource searching capabilities support searches by identifier.
GET http://localhost:3000/4_0_1/RESOURCETYPE/?identifier=ID
returns bundle entries of resource typeRESOURCETYPE
that have the identifierID
. Errors are thrown when an identifier is not included. An empty searchset is returned if the identifier cannot be found in the database.
This operation calculates a measure for a given patient. Currently, individual and population measure reports are supported. Subject-list measure reports are not yet supported.
Required parameters include:
periodStart
: start of the measurement periodperiodEnd
: end of the measurement periodsubject
: subject for which the measure will be calculated (unless apopulation
reportType
is specified)
Optional parameters include:
practitioner
: practitioner for which the measure will be calculated
Currently, measure
and lastReceivedOn
parameters are not supported by the test server. The subject-list
reportType
is not supported by the test server - only subject
and population
reportTypes
are supported at this time,
which will generate individual
and summary
MeasureReport
s respectively.
To use, first POST a measure bundle into your database, then send a GET request to http://localhost:3000/4_0_1/Measure/<your-measure-id>/$evaluate-measure
with the required parameters.
This operation will execute in a multi-process manner by chunking up the patients to smaller groups and executing across 5 processes if there are more than 100 patients to execute. The settings for this multi-process "Scaled" calculation can be configured in the .env
file:
ENV Variable | Description | Default Value |
---|---|---|
EXEC_WORKERS |
Number of worker processes. 0 will disable multi-process calculation. | 5 |
SCALED_EXEC_THRESHOLD |
Patient count threshold to execute in worker processes. | 100 |
SCALED_EXEC_MAX_JOBSIZE |
Maximum patients to put in each worker job. | 15 |
SCALED_EXEC_STRATEGY |
Patient source strategy to use for scaled calculation (mongo or bundle ) |
bundle |
Check out the $evaluate-measure operation spec for more information.
This operation calculates gaps in care for a given patient against the given measure.
Required parameters include:
periodStart
: start of the measurement periodperiodEnd
: end of the measurement periodstatus
: status of the care gap
The user also SHALL include either
subject
: subject for which the measure will be calculated ORorganization
: Reference to an organization for which the gaps in care report will be created ORorganization
andpractitioner
: Reference to a generalPractitioner for which the gaps in care report should be created
The user MAY include
measureId
ORmeasureIdentifier
ORmeasureURL
: a measure identification field for which the gaps in care will be reported ORprogram
: programs that a provider participates in, for which only associated measures will be used to report gaps in care
Otherwise all available measures will be used.
Currently, topic
and using both a measure identification and 'program' at the same time is not yet supported by the test server.
To use, first POST a measure bundle into your database, then send a GET request to http://localhost:3000/4_0_1/Measure/$care-gaps
with the required parameters.
Check out the $care-gaps operation spec for more information.
This operation retrieves all the data requirements for a given measure as a FHIR library.
Optional parameters for this function include:
periodStart
: start of the measurement periodperiodEnd
: end of the measurement period
If either periodStart
or periodEnd
parameter is supplied without the other, a measurement period will be used with duration 1 year starting or ending at the provided date. If periodStart
and periodEnd
parameters are omitted entirely, the measurement period for the operation will default to the effectivePeriod
of the referenced FHIR Measure. If no effectivePeriod
property is present, dateFilters
will be excluded from the returned FHIR Library entirely.
To use, first POST a measure bundle into your database, then send a GET request to http://localhost:3000/4_0_1/Measure/<your-measure-id>/$data-requirements
.
Check out the $data-requirements operation spec for more information.
This operation takes a Measure Report and a set of required data with which to calculate the measure, and the server adds new documents to the database for each contained FHIR object. To use, send a valid FHIR parameters object in a POST request to http://localhost:3000/4_0_1/Measure/$submit-data
or http://localhost:3000/4_0_1/Measure/<your-measure-id>/$submit-data
.
Check out the $submit-data operation spec for more information.
This operation returns a searchset bundle containing all the information related to a patient. If no patient ID is specified, bundle will contain information for all patients.
To use, first POST a bundle into your database, then send a GET request to http://localhost:3000/4_0_1/Patient/<your-patient-id>/$everything
or http://localhost:3000/4_0_1/Patient/$everything
.
Check out the Patient-everything operation spec for more information.
The server contains functionality for the bulk $import operation as defined by the Data Exchange for Quality Measures Implementation Guide.
The first step in the bulk $import operation work flow is to gather data for submission and organize that data into a set of inputs that this server will retrieve. This is outlined in detail in the DEQM IG Data Exchange Using Bulk $import Section and by type inputs can be gathered using the bulk-export-server $export operation. by subject and hybrid by type and by subject inputs are not yet implemented in this server.
To kickoff a bulk data import operation, POST a valid Import Manifest object to http://localhost:3000/$import
.
The user can check the status of an $import or $bulk-submit-data request by copying the content-location header in the response, and sending a GET request to http://localhost:3000/<content-location-header>
.
Copyright 2021-2022 The MITRE Corporation
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.