cqm-models 4.1.1 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +7 -8
- data/app/assets/javascripts/QDMPatient.js +25 -2
- data/app/assets/javascripts/attributes/Component.js +17 -0
- data/app/assets/javascripts/attributes/Entity.js +17 -0
- data/app/assets/javascripts/basetypes/AnyEntity.js +1 -1
- data/app/models/cqm/individual_result.rb +2 -2
- data/app/models/cqm/measure.rb +1 -1
- data/app/models/cqm/patient.rb +1 -1
- data/app/models/cqm/provider.rb +0 -2
- data/app/models/qdm/attributes/identifier.rb +2 -0
- data/app/models/qdm/basetypes/data_element.rb +3 -1
- data/cqm-models.gemspec +5 -5
- data/dist/browser.js +3436 -1167
- data/dist/index.js +3436 -1167
- data/jest.config.js +16 -0
- data/package-lock.json +9901 -1047
- data/package.json +14 -10
- data/templates/mongoose_template.js.erb +17 -0
- data/templates/patient_template.js.erb +25 -2
- data/yarn.lock +2635 -1374
- metadata +28 -28
- data/.github/workflows/gitleaks_github_actions.yml +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b776247323332ba61b8df7b85393f9cc69e8388d15dc3d55a4d7bfcfd3d2be2
|
4
|
+
data.tar.gz: 57d99f0316933ab3886aa50e25a65c791d0996ff8b7d9cd38766f056b22a9793
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b79ea33f45b11872d85be3c2f5765c2400c11b43e9004f8c7701508bf9b5565e7f8f961c09bb0337be1b6ab7b1cc0701ed72d3b8ccb506ccdc378a74bef77379
|
7
|
+
data.tar.gz: f4c50758a5342921502da3389e2410c05d1a0004e6f9072cf9216cbb5b987ad3960353dbc896b9b6dece71903e897000a59f29ac8c0ce1c8273a918a16da0e58
|
data/.github/workflows/ci.yml
CHANGED
@@ -12,21 +12,21 @@ jobs:
|
|
12
12
|
|
13
13
|
strategy:
|
14
14
|
matrix:
|
15
|
-
ruby-version: [
|
16
|
-
mongodb-version: [4.
|
17
|
-
node-version: [
|
15
|
+
ruby-version: [3.0]
|
16
|
+
mongodb-version: [4.2, 4.4]
|
17
|
+
node-version: [18.x]
|
18
18
|
|
19
19
|
steps:
|
20
|
-
- uses: actions/checkout@
|
20
|
+
- uses: actions/checkout@v3
|
21
21
|
- name: Use Ruby ${{ matrix.ruby-version }}
|
22
22
|
uses: ruby/setup-ruby@v1
|
23
23
|
with:
|
24
24
|
ruby-version: ${{ matrix.ruby-version }}
|
25
|
-
bundler: 2.
|
25
|
+
bundler: 2.3.17
|
26
26
|
- name: Install dependencies
|
27
27
|
run: bundle install
|
28
28
|
- name: Start MongoDB
|
29
|
-
uses: supercharge/mongodb-github-action@1.
|
29
|
+
uses: supercharge/mongodb-github-action@1.10.0
|
30
30
|
with:
|
31
31
|
mongodb-version: ${{ matrix.mongodb-version }}
|
32
32
|
- name: Run audit
|
@@ -38,7 +38,7 @@ jobs:
|
|
38
38
|
- name: Run rubocop
|
39
39
|
run: bundle exec rubocop
|
40
40
|
- name: Use Node.js ${{ matrix.node-version }}
|
41
|
-
uses: actions/setup-node@
|
41
|
+
uses: actions/setup-node@v3
|
42
42
|
with:
|
43
43
|
node-version: ${{ matrix.node-version }}
|
44
44
|
- name: Install Yarn
|
@@ -53,4 +53,3 @@ jobs:
|
|
53
53
|
run: |
|
54
54
|
./bin/validate_dist.sh
|
55
55
|
./bin/validate_browser.sh
|
56
|
-
./bin/validate_generator.sh
|
@@ -3,6 +3,7 @@ const Code = require('./basetypes/Code');
|
|
3
3
|
const Interval = require('./basetypes/Interval');
|
4
4
|
const Quantity = require('./basetypes/Quantity');
|
5
5
|
const DateTime = require('./basetypes/DateTime');
|
6
|
+
const AnyEntity = require('./basetypes/AnyEntity');
|
6
7
|
const AllDataElements = require('./AllDataElements');
|
7
8
|
|
8
9
|
const [Schema, Number, String, Mixed] = [
|
@@ -94,6 +95,12 @@ QDMPatientSchema.methods.getDataElements = function getDataElements(params) {
|
|
94
95
|
return this.dataElements;
|
95
96
|
};
|
96
97
|
|
98
|
+
QDMPatientSchema.methods.addMethodsTo = function addMethodsTo(obj, methods) {
|
99
|
+
Object.entries(methods).forEach(([method_name, method]) => {
|
100
|
+
obj[method_name] = method;
|
101
|
+
});
|
102
|
+
};
|
103
|
+
|
97
104
|
// Returns an array of dataElements that exist on the patient, queried by
|
98
105
|
// QDM profile
|
99
106
|
// @param {string} profile - the data criteria requested by the execution engine
|
@@ -105,10 +112,26 @@ QDMPatientSchema.methods.getByProfile = function getByProfile(profile, isNegated
|
|
105
112
|
// If isNegated == null, return all matching data elements by type, regardless of negationRationale.
|
106
113
|
const results = this.dataElements.filter(element => (element._type === `QDM::${profile}` || element._type === profile) && (isNegated === null || !!element.negationRationale === isNegated));
|
107
114
|
return results.map((result) => {
|
115
|
+
// we need to convert mongoose document to an object.
|
116
|
+
// This is required for comparing the two objects(in cql-execution) as we can't compare two mongoose documents.
|
108
117
|
const removedMongooseItems = new AllDataElements[profile](result).toObject({ virtuals: true });
|
109
118
|
// toObject() will remove all mongoose functions but also remove the schema methods, so we add them back
|
110
|
-
|
111
|
-
|
119
|
+
this.addMethodsTo(removedMongooseItems, result.schema.methods);
|
120
|
+
// add methods to entities
|
121
|
+
Object.entries(result).forEach(([key, values]) => {
|
122
|
+
// entities are always an array
|
123
|
+
if (Array.isArray(values)) {
|
124
|
+
try {
|
125
|
+
// check if the attribute is of Entity
|
126
|
+
if (AnyEntity.prototype.cast(values[0])) {
|
127
|
+
values.forEach((value, index) => {
|
128
|
+
const entity = removedMongooseItems[key][index];
|
129
|
+
this.addMethodsTo(entity, value.schema.methods);
|
130
|
+
});
|
131
|
+
}
|
132
|
+
// eslint-disable-next-line no-empty
|
133
|
+
} catch (e) {}
|
134
|
+
}
|
112
135
|
});
|
113
136
|
return removedMongooseItems;
|
114
137
|
});
|
@@ -44,6 +44,23 @@ function ComponentSchemaFunction(add, options) {
|
|
44
44
|
extended.add(add);
|
45
45
|
}
|
46
46
|
|
47
|
+
/* eslint no-underscore-dangle: 0 */
|
48
|
+
extended.methods._is = function _is(typeSpecifier) {
|
49
|
+
return this._typeHierarchy().some(
|
50
|
+
t => t.type === typeSpecifier.type && t.name === typeSpecifier.name
|
51
|
+
);
|
52
|
+
};
|
53
|
+
|
54
|
+
extended.methods._typeHierarchy = function _typeHierarchy() {
|
55
|
+
const typeName = this._type.replace(/QDM::/, '');
|
56
|
+
const ver = this.qdmVersion.replace('.', '_');
|
57
|
+
return [
|
58
|
+
{
|
59
|
+
name: `{urn:healthit-gov:qdm:v${ver}}${typeName}`,
|
60
|
+
type: 'NamedTypeSpecifier',
|
61
|
+
},
|
62
|
+
];
|
63
|
+
};
|
47
64
|
return extended;
|
48
65
|
}
|
49
66
|
|
@@ -51,6 +51,23 @@ function EntitySchemaFunction(add, options) {
|
|
51
51
|
extended.add(add);
|
52
52
|
}
|
53
53
|
|
54
|
+
/* eslint no-underscore-dangle: 0 */
|
55
|
+
extended.methods._is = function _is(typeSpecifier) {
|
56
|
+
return this._typeHierarchy().some(
|
57
|
+
t => t.type === typeSpecifier.type && t.name === typeSpecifier.name
|
58
|
+
);
|
59
|
+
};
|
60
|
+
|
61
|
+
extended.methods._typeHierarchy = function _typeHierarchy() {
|
62
|
+
const typeName = this._type.replace(/QDM::/, '');
|
63
|
+
const ver = this.qdmVersion.replace('.', '_');
|
64
|
+
return [
|
65
|
+
{
|
66
|
+
name: `{urn:healthit-gov:qdm:v${ver}}${typeName}`,
|
67
|
+
type: 'NamedTypeSpecifier',
|
68
|
+
},
|
69
|
+
];
|
70
|
+
};
|
54
71
|
return extended;
|
55
72
|
}
|
56
73
|
|
@@ -15,7 +15,7 @@ AnyEntity.prototype.cast = (entity) => {
|
|
15
15
|
return null;
|
16
16
|
}
|
17
17
|
|
18
|
-
if (entity instanceof PatientEntity || entity instanceof Practitioner || entity instanceof CarePartner || entity instanceof Organization) {
|
18
|
+
if (entity instanceof PatientEntity || entity instanceof Practitioner || entity instanceof CarePartner || entity instanceof Organization || entity instanceof Location) {
|
19
19
|
return entity;
|
20
20
|
}
|
21
21
|
|
@@ -35,8 +35,8 @@ module CQM
|
|
35
35
|
field :state, type: String, default: 'queued'
|
36
36
|
|
37
37
|
# Relations to other model classes
|
38
|
-
belongs_to :measure
|
39
|
-
belongs_to :patient
|
38
|
+
belongs_to :measure, class_name: 'CQM::Measure', inverse_of: :calculation_result
|
39
|
+
belongs_to :patient, class_name: 'CQM::Patient', inverse_of: :calculation_result
|
40
40
|
|
41
41
|
# Convert the stored array into a hash between clause and result
|
42
42
|
def clause_results_by_clause
|
data/app/models/cqm/measure.rb
CHANGED
@@ -73,7 +73,7 @@ module CQM
|
|
73
73
|
# hence the 'inverse_of: nil')
|
74
74
|
has_and_belongs_to_many :value_sets, inverse_of: nil
|
75
75
|
|
76
|
-
has_many :calculation_results, class_name: 'CQM::IndividualResult'
|
76
|
+
has_many :calculation_results, class_name: 'CQM::IndividualResult', inverse_of: :measure
|
77
77
|
|
78
78
|
def all_stratifications
|
79
79
|
population_sets.flat_map(&:stratifications)
|
data/app/models/cqm/patient.rb
CHANGED
@@ -11,7 +11,7 @@ module CQM
|
|
11
11
|
|
12
12
|
has_and_belongs_to_many :providers, class_name: 'CQM::Provider'
|
13
13
|
embeds_one :qdmPatient, class_name: 'QDM::Patient', autobuild: true
|
14
|
-
has_many :calculation_results, class_name: 'CQM::IndividualResult'
|
14
|
+
has_many :calculation_results, class_name: 'CQM::IndividualResult', inverse_of: :patient
|
15
15
|
|
16
16
|
# Include '_type' in any JSON output. This is necessary for deserialization.
|
17
17
|
def to_json(options = nil)
|
data/app/models/cqm/provider.rb
CHANGED
@@ -76,7 +76,9 @@ module QDM
|
|
76
76
|
elsif field == 'facilityLocation'
|
77
77
|
facility_location = send(field)
|
78
78
|
unless facility_location.nil?
|
79
|
-
|
79
|
+
# Guessing something changed in mongoid such that facility_location gets typed to an Object
|
80
|
+
# but this method (I think) expects a Hash.
|
81
|
+
shift_facility_location_dates(facility_location.attributes, seconds)
|
80
82
|
send(field + '=', facility_location)
|
81
83
|
end
|
82
84
|
end
|
data/cqm-models.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'cqm-models'
|
7
|
-
spec.version = '4.
|
7
|
+
spec.version = '4.2.0'
|
8
8
|
spec.authors = ['aholmes@mitre.org', 'mokeefe@mitre.org', 'lades@mitre.org']
|
9
9
|
|
10
10
|
spec.summary = 'Mongo models that correspond to the QDM specification.'
|
@@ -20,13 +20,13 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
22
|
spec.add_development_dependency 'bundle-audit'
|
23
|
-
spec.add_development_dependency 'bundler', '~> 2.1.4'
|
24
23
|
spec.add_development_dependency 'byebug', '~> 11.0.1'
|
25
24
|
spec.add_development_dependency 'codecov'
|
26
|
-
spec.add_development_dependency 'mongoid', '~>
|
27
|
-
spec.add_development_dependency '
|
25
|
+
spec.add_development_dependency 'mongoid', '~> 8'
|
26
|
+
spec.add_development_dependency 'nokogiri', '>= 1.16.2'
|
27
|
+
spec.add_development_dependency 'rails', '~> 7.1'
|
28
28
|
spec.add_development_dependency 'rake', '~> 12.3.3'
|
29
29
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
30
|
-
spec.add_development_dependency 'rubocop', '~> 0.
|
30
|
+
spec.add_development_dependency 'rubocop', '~> 0.63.0'
|
31
31
|
spec.add_development_dependency 'simplecov'
|
32
32
|
end
|