Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fqm-execution bump to 1.3.1 and update Docker setup #141

Closed
wants to merge 10 commits into from
Closed
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
connectathon
ecqm-content-r4-2021
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
node-version: [16.x]
mongodb-version: ['5.0']
mongodb-version: ['6.0']

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -48,7 +48,7 @@ jobs:
strategy:
matrix:
node-version: [16.x]
mongodb-version: ['5.0']
mongodb-version: ['6.0']
steps:
- uses: actions/checkout@v2

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:14
FROM node:16

# Create app directory
WORKDIR /usr/src/app
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Test server for executing FHIR-based Electronic Clinical Quality Measures (eCQMs
### Prerequisites

- [Node.js >=16.0.0](https://nodejs.org/en/)
- [MongoDB >= 5.0](https://www.mongodb.com)
- [MongoDB >= 6.0](https://www.mongodb.com)
- [Git](https://git-scm.com/)
- [Docker](https://docs.docker.com/get-docker/)
- [Redis](https://redis.com/break-the-data-matrix/)
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ services:
NDJSON_WORKERS: 2
REDIS_HOST: redis
REDIS_PORT: 6379
VALIDATE: "false"
VALIDATE: 'false'
VALIDATOR_HOST: validator
VALIDATOR_PORT: 4567
ports:
Expand All @@ -31,7 +31,7 @@ services:
tty: true

mongo:
image: mongo:4.4.4
image: mongo:6.0
ports:
- '27017'
volumes:
Expand Down
6,390 changes: 3,488 additions & 2,902 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"cql-exec-fhir-mongo": "git+https://[email protected]/projecttacoma/cql-exec-fhir-mongo",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"fqm-execution": "^1.0.5",
"fqm-execution": "^1.3.1",
"lodash": "^4.17.21",
"mongodb": "^4.1.3",
"uuid": "^8.3.2",
Expand All @@ -54,4 +54,4 @@
"./test/globalSetup.js"
]
}
}
}
8 changes: 7 additions & 1 deletion src/queue/execQueue.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,18 @@ class ScaledCalculation {
}

this._measureBundle = measureBundle;
const measureEntry = measureBundle.entry.find(e => e.resource.resourceType === 'Measure');
if (measureEntry) {
this._measure = measureEntry.resource;
} else {
throw new Error('Measure resource was not found in bundle.');
}
this._periodStart = periodStart;
this._periodEnd = periodEnd;

// Prepare the fqm-execution measure report builder
try {
this._mrBuilder = new MeasureReportBuilder(this._measureBundle, {
this._mrBuilder = new MeasureReportBuilder(this._measure, {
measurementPeriodStart: this._periodStart,
measurementPeriodEnd: this._periodEnd,
reportType: 'summary'
Expand Down
18 changes: 16 additions & 2 deletions src/scripts/uploadPremadeBundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require('fs');
const path = require('path');
const mongoUtil = require('../database/connection');
const { createResource } = require('../database/dbOperations');
const { v4: uuidv4 } = require('uuid');

const ecqmContentR4Path = path.resolve(path.join(__dirname, '../../ecqm-content-r4-2021/bundles/measure/'));

Expand Down Expand Up @@ -97,14 +98,27 @@ async function main() {
let filesUploaded = 0;
let resourcesUploaded = 0;
for (const filePath of bundleFiles) {
// read each EXM bundle file
// read each bundle file
const data = fs.readFileSync(filePath, 'utf8');
if (data) {
console.log(`Uploading ${filePath.split('/').slice(-1)}...`);
const bundle = JSON.parse(data);
if (bundle.resourceType !== 'Bundle') {
console.log(`Skipping ${filePath.split('/').slice(-1)} NOT A BUNDLE`);
continue;
}

// uncomment if you want to see every bundle found that this script is processing
//console.log(`Uploading ${filePath.split('/').slice(-1)}...`);

// retrieve each resource and insert into database
const uploads = bundle.entry.map(async res => {
try {
// If there is no ID... make one. This probably is a MADiE Export Measure resource. Try to grab the first
// chunk from the filename looking for the `-` to hopefully get `CMSXXXFHIR` otherwise use a random ID
if (!res.resource.id) {
res.resource.id = filePath.split('/').slice(-1)[0].split('-')[0] || uuidv4();
console.log(`Gave ${res.resource.resourceType} an ID of ${res.resource.id}`);
}
await createResource(res.resource, res.resource.resourceType);
resourcesUploaded += 1;
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion src/services/measure.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ const evaluateMeasure = async (args, { req }) => {
const { reportType, subject } = req.query;

// If reportType is not specified, default to 'subject', but
// only if the 'subject' parameter is also specificed
// only if the 'subject' parameter is also specified
if (reportType === 'subject' || (reportType == null && subject != null)) {
logger.debug('Evaluating measure for individual');
return evaluateMeasureForIndividual(args, { req });
Expand Down
4 changes: 2 additions & 2 deletions src/util/bundleUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ async function getDependentValueSets(lib) {
}

const depValueSetUrls = lib.relatedArtifact
.filter(ra => ra.type === 'depends-on' && ra.resource.includes('ValueSet'))
.filter(ra => ra.type === 'depends-on' && ra.resource?.includes('ValueSet'))
.map(ra => ra.resource);

const valueSetGets = depValueSetUrls.map(async url => {
Expand Down Expand Up @@ -180,7 +180,7 @@ async function getAllDependentLibraries(lib) {
.filter(
ra =>
ra.type === 'depends-on' &&
ra.resource.includes('Library') &&
ra.resource?.includes('Library') &&
ra.resource !== 'http://fhir.org/guides/cqf/common/Library/FHIR-ModelInfo|4.0.1'
) // exclude modelinfo dependency
.map(ra => ra.resource);
Expand Down
2 changes: 1 addition & 1 deletion test/queue/execQueue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ describe('execQueue', () => {
'2019-01-01',
'2019-12-31'
);
}).toThrow('Could not prepare report builder:');
}).toThrow('Measure resource was not found in bundle.');
});

test('Throws an error if scaled calculation is disabled', () => {
Expand Down
5 changes: 3 additions & 2 deletions test/services/base.service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ describe('base.service', () => {
url: expect.stringMatching(/\/4_0_1\/Patient\?page=1$/)
}
]);
expect(response.body.entry[0].resource.id).toEqual(testPatient.id);
expect(response.body.entry[0].resource.resourceType).toEqual('Patient');
const testPatientEntry = response.body.entry.find(e => e.resource.id === testPatient.id);
expect(testPatientEntry).toBeDefined();
expect(testPatientEntry.resource.resourceType).toEqual('Patient');
});
});

Expand Down
Loading