cqm-models 0.7.2
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 +7 -0
- data/.eslintignore +1 -0
- data/.eslintrc.json +26 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +32 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.rubocop.yml +42 -0
- data/.travis.yml +21 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +201 -0
- data/README.md +26 -0
- data/Rakefile +12 -0
- data/app/assets/javascripts/AdverseEvent.js +27 -0
- data/app/assets/javascripts/AllDataElements.js +120 -0
- data/app/assets/javascripts/AllergyIntolerance.js +27 -0
- data/app/assets/javascripts/AssessmentPerformed.js +30 -0
- data/app/assets/javascripts/AssessmentRecommended.js +27 -0
- data/app/assets/javascripts/CareGoal.js +25 -0
- data/app/assets/javascripts/CommunicationFromPatientToProvider.js +26 -0
- data/app/assets/javascripts/CommunicationFromProviderToPatient.js +26 -0
- data/app/assets/javascripts/CommunicationFromProviderToProvider.js +26 -0
- data/app/assets/javascripts/Component.js +22 -0
- data/app/assets/javascripts/Concept.js +14 -0
- data/app/assets/javascripts/DeviceApplied.js +29 -0
- data/app/assets/javascripts/DeviceOrder.js +26 -0
- data/app/assets/javascripts/DeviceRecommended.js +26 -0
- data/app/assets/javascripts/Diagnosis.js +27 -0
- data/app/assets/javascripts/DiagnosticStudyOrder.js +27 -0
- data/app/assets/javascripts/DiagnosticStudyPerformed.js +33 -0
- data/app/assets/javascripts/DiagnosticStudyRecommended.js +27 -0
- data/app/assets/javascripts/EncounterOrder.js +27 -0
- data/app/assets/javascripts/EncounterPerformed.js +32 -0
- data/app/assets/javascripts/EncounterRecommended.js +27 -0
- data/app/assets/javascripts/FacilityLocation.js +22 -0
- data/app/assets/javascripts/FamilyHistory.js +25 -0
- data/app/assets/javascripts/Id.js +22 -0
- data/app/assets/javascripts/ImmunizationAdministered.js +30 -0
- data/app/assets/javascripts/ImmunizationOrder.js +30 -0
- data/app/assets/javascripts/InterventionOrder.js +26 -0
- data/app/assets/javascripts/InterventionPerformed.js +29 -0
- data/app/assets/javascripts/InterventionRecommended.js +26 -0
- data/app/assets/javascripts/LaboratoryTestOrder.js +27 -0
- data/app/assets/javascripts/LaboratoryTestPerformed.js +33 -0
- data/app/assets/javascripts/LaboratoryTestRecommended.js +27 -0
- data/app/assets/javascripts/Measure.js +76 -0
- data/app/assets/javascripts/MeasurePackage.js +20 -0
- data/app/assets/javascripts/MedicationActive.js +28 -0
- data/app/assets/javascripts/MedicationAdministered.js +31 -0
- data/app/assets/javascripts/MedicationDischarge.js +30 -0
- data/app/assets/javascripts/MedicationDispensed.js +31 -0
- data/app/assets/javascripts/MedicationOrder.js +34 -0
- data/app/assets/javascripts/Participation.js +21 -0
- data/app/assets/javascripts/Patient.js +248 -0
- data/app/assets/javascripts/PatientCareExperience.js +23 -0
- data/app/assets/javascripts/PatientCharacteristic.js +23 -0
- data/app/assets/javascripts/PatientCharacteristicBirthdate.js +24 -0
- data/app/assets/javascripts/PatientCharacteristicClinicalTrialParticipant.js +26 -0
- data/app/assets/javascripts/PatientCharacteristicEthnicity.js +23 -0
- data/app/assets/javascripts/PatientCharacteristicExpired.js +25 -0
- data/app/assets/javascripts/PatientCharacteristicPayer.js +24 -0
- data/app/assets/javascripts/PatientCharacteristicRace.js +23 -0
- data/app/assets/javascripts/PatientCharacteristicSex.js +23 -0
- data/app/assets/javascripts/PhysicalExamOrder.js +28 -0
- data/app/assets/javascripts/PhysicalExamPerformed.js +31 -0
- data/app/assets/javascripts/PhysicalExamRecommended.js +28 -0
- data/app/assets/javascripts/ProcedureOrder.js +30 -0
- data/app/assets/javascripts/ProcedurePerformed.js +35 -0
- data/app/assets/javascripts/ProcedureRecommended.js +30 -0
- data/app/assets/javascripts/ProviderCareExperience.js +23 -0
- data/app/assets/javascripts/ProviderCharacteristic.js +23 -0
- data/app/assets/javascripts/Ratio.js +22 -0
- data/app/assets/javascripts/Result.js +28 -0
- data/app/assets/javascripts/ResultComponent.js +21 -0
- data/app/assets/javascripts/SubstanceAdministered.js +30 -0
- data/app/assets/javascripts/SubstanceOrder.js +32 -0
- data/app/assets/javascripts/SubstanceRecommended.js +32 -0
- data/app/assets/javascripts/Symptom.js +25 -0
- data/app/assets/javascripts/ValueSet.js +30 -0
- data/app/assets/javascripts/basetypes/Code.js +25 -0
- data/app/assets/javascripts/basetypes/DataElement.js +36 -0
- data/app/assets/javascripts/basetypes/DateTime.js +18 -0
- data/app/assets/javascripts/basetypes/Interval.js +35 -0
- data/app/assets/javascripts/basetypes/Quantity.js +20 -0
- data/app/assets/javascripts/index.js +12 -0
- data/app/models/models.rb +78 -0
- data/app/models/qdm/adverse_event.rb +15 -0
- data/app/models/qdm/allergy_intolerance.rb +15 -0
- data/app/models/qdm/assessment_performed.rb +18 -0
- data/app/models/qdm/assessment_recommended.rb +15 -0
- data/app/models/qdm/basetypes/code.rb +56 -0
- data/app/models/qdm/basetypes/data_element.rb +42 -0
- data/app/models/qdm/basetypes/interval.rb +54 -0
- data/app/models/qdm/basetypes/quantity.rb +52 -0
- data/app/models/qdm/care_goal.rb +13 -0
- data/app/models/qdm/communication_from_patient_to_provider.rb +14 -0
- data/app/models/qdm/communication_from_provider_to_patient.rb +14 -0
- data/app/models/qdm/communication_from_provider_to_provider.rb +14 -0
- data/app/models/qdm/component.rb +10 -0
- data/app/models/qdm/device_applied.rb +17 -0
- data/app/models/qdm/device_order.rb +14 -0
- data/app/models/qdm/device_recommended.rb +14 -0
- data/app/models/qdm/diagnosis.rb +15 -0
- data/app/models/qdm/diagnostic_study_order.rb +15 -0
- data/app/models/qdm/diagnostic_study_performed.rb +21 -0
- data/app/models/qdm/diagnostic_study_recommended.rb +15 -0
- data/app/models/qdm/encounter_order.rb +15 -0
- data/app/models/qdm/encounter_performed.rb +20 -0
- data/app/models/qdm/encounter_recommended.rb +15 -0
- data/app/models/qdm/facility_location.rb +10 -0
- data/app/models/qdm/family_history.rb +13 -0
- data/app/models/qdm/id.rb +10 -0
- data/app/models/qdm/immunization_administered.rb +18 -0
- data/app/models/qdm/immunization_order.rb +18 -0
- data/app/models/qdm/intervention_order.rb +14 -0
- data/app/models/qdm/intervention_performed.rb +17 -0
- data/app/models/qdm/intervention_recommended.rb +14 -0
- data/app/models/qdm/laboratory_test_order.rb +15 -0
- data/app/models/qdm/laboratory_test_performed.rb +21 -0
- data/app/models/qdm/laboratory_test_recommended.rb +15 -0
- data/app/models/qdm/medication_active.rb +16 -0
- data/app/models/qdm/medication_administered.rb +19 -0
- data/app/models/qdm/medication_discharge.rb +18 -0
- data/app/models/qdm/medication_dispensed.rb +19 -0
- data/app/models/qdm/medication_order.rb +22 -0
- data/app/models/qdm/participation.rb +9 -0
- data/app/models/qdm/patient.rb +201 -0
- data/app/models/qdm/patient_care_experience.rb +11 -0
- data/app/models/qdm/patient_characteristic.rb +11 -0
- data/app/models/qdm/patient_characteristic_birthdate.rb +12 -0
- data/app/models/qdm/patient_characteristic_clinical_trial_participant.rb +14 -0
- data/app/models/qdm/patient_characteristic_ethnicity.rb +11 -0
- data/app/models/qdm/patient_characteristic_expired.rb +13 -0
- data/app/models/qdm/patient_characteristic_payer.rb +12 -0
- data/app/models/qdm/patient_characteristic_race.rb +11 -0
- data/app/models/qdm/patient_characteristic_sex.rb +11 -0
- data/app/models/qdm/physical_exam_order.rb +16 -0
- data/app/models/qdm/physical_exam_performed.rb +19 -0
- data/app/models/qdm/physical_exam_recommended.rb +16 -0
- data/app/models/qdm/procedure_order.rb +18 -0
- data/app/models/qdm/procedure_performed.rb +23 -0
- data/app/models/qdm/procedure_recommended.rb +18 -0
- data/app/models/qdm/provider_care_experience.rb +11 -0
- data/app/models/qdm/provider_characteristic.rb +11 -0
- data/app/models/qdm/ratio.rb +10 -0
- data/app/models/qdm/result_component.rb +9 -0
- data/app/models/qdm/substance_administered.rb +18 -0
- data/app/models/qdm/substance_order.rb +20 -0
- data/app/models/qdm/substance_recommended.rb +20 -0
- data/app/models/qdm/symptom.rb +13 -0
- data/app/models/qdm/tacoma/concept.rb +14 -0
- data/app/models/qdm/tacoma/measure.rb +172 -0
- data/app/models/qdm/tacoma/measure_package.rb +10 -0
- data/app/models/qdm/tacoma/valueset.rb +68 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/validate_dist.sh +17 -0
- data/config/mongoid.yml +6 -0
- data/cqm-models.gemspec +29 -0
- data/data/oids.json +584 -0
- data/dist/index.js +157647 -0
- data/lib/cqm/models.rb +1 -0
- data/lib/generate_models.rb +330 -0
- data/modelinfo/qdm-modelinfo-4.2.xml +515 -0
- data/modelinfo/qdm-modelinfo-4.3.xml +521 -0
- data/modelinfo/qdm-modelinfo-5.0.1.xml +436 -0
- data/modelinfo/qdm-modelinfo-5.0.2.xml +445 -0
- data/modelinfo/qdm-modelinfo-5.0.xml +429 -0
- data/modelinfo/qdm-modelinfo-5.3.xml +524 -0
- data/package.json +34 -0
- data/templates/all_data_elements_template.js.erb +4 -0
- data/templates/index_template.js.erb +12 -0
- data/templates/models_template.rb.erb +21 -0
- data/templates/mongoose_template.js.erb +20 -0
- data/templates/patient_extension.rb.erb +194 -0
- data/templates/patient_template.js.erb +247 -0
- data/tmp/.keep +0 -0
- data/yarn.lock +1901 -0
- metadata +320 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/patient_characteristic_expired.rb
|
|
3
|
+
class PatientCharacteristicExpired < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :expiredDatetime, type: DateTime
|
|
7
|
+
field :cause, type: QDM::Code
|
|
8
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.57'
|
|
9
|
+
field :category, type: String, default: 'patient_characteristic'
|
|
10
|
+
field :qdmStatus, type: String, default: 'expired'
|
|
11
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/patient_characteristic_payer.rb
|
|
3
|
+
class PatientCharacteristicPayer < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :relevantPeriod, type: QDM::Interval
|
|
7
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.58'
|
|
8
|
+
field :category, type: String, default: 'patient_characteristic'
|
|
9
|
+
field :qdmStatus, type: String, default: 'payer'
|
|
10
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/patient_characteristic_race.rb
|
|
3
|
+
class PatientCharacteristicRace < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.59'
|
|
7
|
+
field :category, type: String, default: 'patient_characteristic'
|
|
8
|
+
field :qdmStatus, type: String, default: 'race'
|
|
9
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/patient_characteristic_sex.rb
|
|
3
|
+
class PatientCharacteristicSex < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.55'
|
|
7
|
+
field :category, type: String, default: 'patient_characteristic'
|
|
8
|
+
field :qdmStatus, type: String, default: 'gender'
|
|
9
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/physical_exam_order.rb
|
|
3
|
+
class PhysicalExamOrder < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :reason, type: QDM::Code
|
|
8
|
+
field :method, type: QDM::Code
|
|
9
|
+
field :anatomicalLocationSite, type: QDM::Code
|
|
10
|
+
field :negationRationale, type: QDM::Code
|
|
11
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.61'
|
|
12
|
+
field :category, type: String, default: 'physical_exam'
|
|
13
|
+
field :qdmStatus, type: String, default: 'order'
|
|
14
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/physical_exam_performed.rb
|
|
3
|
+
class PhysicalExamPerformed < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :relevantPeriod, type: QDM::Interval
|
|
8
|
+
field :reason, type: QDM::Code
|
|
9
|
+
field :method, type: QDM::Code
|
|
10
|
+
field :result
|
|
11
|
+
field :anatomicalLocationSite, type: QDM::Code
|
|
12
|
+
field :negationRationale, type: QDM::Code
|
|
13
|
+
field :components, type: Array
|
|
14
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.62'
|
|
15
|
+
field :category, type: String, default: 'physical_exam'
|
|
16
|
+
field :qdmStatus, type: String, default: 'performed'
|
|
17
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/physical_exam_recommended.rb
|
|
3
|
+
class PhysicalExamRecommended < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :reason, type: QDM::Code
|
|
8
|
+
field :method, type: QDM::Code
|
|
9
|
+
field :anatomicalLocationSite, type: QDM::Code
|
|
10
|
+
field :negationRationale, type: QDM::Code
|
|
11
|
+
field :hqmfOid, type: String, default: '22.16.840.1.113883.10.20.28.3.63'
|
|
12
|
+
field :category, type: String, default: 'physical_exam'
|
|
13
|
+
field :qdmStatus, type: String, default: 'recommended'
|
|
14
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/procedure_order.rb
|
|
3
|
+
class ProcedureOrder < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :reason, type: QDM::Code
|
|
8
|
+
field :method, type: QDM::Code
|
|
9
|
+
field :anatomicalApproachSite, type: QDM::Code
|
|
10
|
+
field :anatomicalLocationSite, type: QDM::Code
|
|
11
|
+
field :ordinality, type: QDM::Code
|
|
12
|
+
field :negationRationale, type: QDM::Code
|
|
13
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.66'
|
|
14
|
+
field :category, type: String, default: 'procedure'
|
|
15
|
+
field :qdmStatus, type: String, default: 'order'
|
|
16
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/procedure_performed.rb
|
|
3
|
+
class ProcedurePerformed < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :relevantPeriod, type: QDM::Interval
|
|
8
|
+
field :reason, type: QDM::Code
|
|
9
|
+
field :method, type: QDM::Code
|
|
10
|
+
field :result
|
|
11
|
+
field :status, type: QDM::Code
|
|
12
|
+
field :anatomicalApproachSite, type: QDM::Code
|
|
13
|
+
field :anatomicalLocationSite, type: QDM::Code
|
|
14
|
+
field :ordinality, type: QDM::Code
|
|
15
|
+
field :incisionDatetime, type: DateTime
|
|
16
|
+
field :negationRationale, type: QDM::Code
|
|
17
|
+
field :components, type: Array
|
|
18
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.67'
|
|
19
|
+
field :category, type: String, default: 'procedure'
|
|
20
|
+
field :qdmStatus, type: String, default: 'performed'
|
|
21
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/procedure_recommended.rb
|
|
3
|
+
class ProcedureRecommended < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :reason, type: QDM::Code
|
|
8
|
+
field :method, type: QDM::Code
|
|
9
|
+
field :anatomicalApproachSite, type: QDM::Code
|
|
10
|
+
field :anatomicalLocationSite, type: QDM::Code
|
|
11
|
+
field :ordinality, type: QDM::Code
|
|
12
|
+
field :negationRationale, type: QDM::Code
|
|
13
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.68'
|
|
14
|
+
field :category, type: String, default: 'procedure'
|
|
15
|
+
field :qdmStatus, type: String, default: 'recommended'
|
|
16
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/provider_care_experience.rb
|
|
3
|
+
class ProviderCareExperience < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.70'
|
|
8
|
+
field :category, type: String, default: 'care_experience'
|
|
9
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/provider_characteristic.rb
|
|
3
|
+
class ProviderCharacteristic < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.71'
|
|
8
|
+
field :category, type: String, default: 'provider_characteristic'
|
|
9
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/ratio.rb
|
|
3
|
+
class Ratio < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :numerator, type: QDM::Quantity
|
|
7
|
+
field :denominator, type: QDM::Quantity
|
|
8
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/substance_administered.rb
|
|
3
|
+
class SubstanceAdministered < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :relevantPeriod, type: QDM::Interval
|
|
8
|
+
field :dosage, type: QDM::Quantity
|
|
9
|
+
field :supply, type: QDM::Quantity
|
|
10
|
+
field :frequency, type: QDM::Code
|
|
11
|
+
field :route, type: QDM::Code
|
|
12
|
+
field :negationRationale, type: QDM::Code
|
|
13
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.73'
|
|
14
|
+
field :category, type: String, default: 'substance'
|
|
15
|
+
field :qdmStatus, type: String, default: 'administered'
|
|
16
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/substance_order.rb
|
|
3
|
+
class SubstanceOrder < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :reason, type: QDM::Code
|
|
8
|
+
field :dosage, type: QDM::Quantity
|
|
9
|
+
field :supply, type: QDM::Quantity
|
|
10
|
+
field :frequency, type: QDM::Code
|
|
11
|
+
field :method, type: QDM::Code
|
|
12
|
+
field :refills, type: Integer
|
|
13
|
+
field :route, type: QDM::Code
|
|
14
|
+
field :negationRationale, type: QDM::Code
|
|
15
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.77'
|
|
16
|
+
field :category, type: String, default: 'substance'
|
|
17
|
+
field :qdmStatus, type: String, default: 'order'
|
|
18
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/substance_recommended.rb
|
|
3
|
+
class SubstanceRecommended < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :authorDatetime, type: DateTime
|
|
7
|
+
field :reason, type: QDM::Code
|
|
8
|
+
field :dosage, type: QDM::Quantity
|
|
9
|
+
field :supply, type: QDM::Quantity
|
|
10
|
+
field :frequency, type: QDM::Code
|
|
11
|
+
field :method, type: QDM::Code
|
|
12
|
+
field :refills, type: Integer
|
|
13
|
+
field :route, type: QDM::Code
|
|
14
|
+
field :negationRationale, type: QDM::Code
|
|
15
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.78'
|
|
16
|
+
field :category, type: String, default: 'substance'
|
|
17
|
+
field :qdmStatus, type: String, default: 'recommended'
|
|
18
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# app/models/qdm/symptom.rb
|
|
3
|
+
class Symptom < DataElement
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
embedded_in :patient
|
|
6
|
+
field :prevalencePeriod, type: QDM::Interval
|
|
7
|
+
field :severity, type: QDM::Code
|
|
8
|
+
field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.116'
|
|
9
|
+
field :qrdaOid, type: String, default: '2.16.840.1.113883.10.20.24.3.136'
|
|
10
|
+
field :category, type: String, default: 'symptom'
|
|
11
|
+
field :qdmVersion, type: String, default: '5.3'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# Concept is an individual code within a ValueSet, including all of the associated metadata
|
|
3
|
+
# such as code system, version, and display name
|
|
4
|
+
class Concept
|
|
5
|
+
include Mongoid::Document
|
|
6
|
+
field :code, type: String
|
|
7
|
+
field :code_system_name, type: String
|
|
8
|
+
field :code_system_version, type: String
|
|
9
|
+
field :display_name, type: String
|
|
10
|
+
field :code_system, type: String
|
|
11
|
+
scope :by_code_system_name, ->(cs) { where(code_system_name: cs) }
|
|
12
|
+
scope :by_code_system, ->(cs) { where(code_system: cs) }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# Measure contains the information necessary to represent the CQL version of a Clinical Quality Measure,
|
|
3
|
+
# As needed by the Bonnie & Cypress applications
|
|
4
|
+
class Measure
|
|
5
|
+
include Mongoid::Document
|
|
6
|
+
include Mongoid::Timestamps
|
|
7
|
+
|
|
8
|
+
DEFAULT_EFFECTIVE_DATE = Time.gm(2012, 12, 31, 23, 59).to_i
|
|
9
|
+
MP_START_DATE = Time.gm(2012, 1, 1, 0, 0).to_i
|
|
10
|
+
TYPES = %w[ep eh].freeze
|
|
11
|
+
|
|
12
|
+
IPP = 'IPP'.freeze
|
|
13
|
+
DENOM = 'DENOM'.freeze
|
|
14
|
+
NUMER = 'NUMER'.freeze
|
|
15
|
+
NUMEX = 'NUMEX'.freeze
|
|
16
|
+
DENEXCEP = 'DENEXCEP'.freeze
|
|
17
|
+
DENEX = 'DENEX'.freeze
|
|
18
|
+
MSRPOPL = 'MSRPOPL'.freeze
|
|
19
|
+
OBSERV = 'OBSERV'.freeze
|
|
20
|
+
MSRPOPLEX = 'MSRPOPLEX'.freeze
|
|
21
|
+
|
|
22
|
+
STRAT = 'STRAT'.freeze
|
|
23
|
+
|
|
24
|
+
ALL_POPULATION_CODES = [STRAT, IPP, DENOM, DENEX, NUMER, NUMEX, DENEXCEP, MSRPOPL, OBSERV, MSRPOPLEX].freeze
|
|
25
|
+
|
|
26
|
+
CQL_SKIP_STATEMENTS = ['SDE Ethnicity', 'SDE Payer', 'SDE Race', 'SDE Sex'].freeze
|
|
27
|
+
|
|
28
|
+
# ID/other measure information
|
|
29
|
+
field :id, type: String
|
|
30
|
+
field :measure_id, type: String
|
|
31
|
+
field :hqmf_id, type: String
|
|
32
|
+
field :hqmf_set_id, type: String
|
|
33
|
+
field :hqmf_version_number, type: Integer
|
|
34
|
+
field :cms_id, type: String
|
|
35
|
+
field :title, type: String, default: ''
|
|
36
|
+
field :description, type: String, default: ''
|
|
37
|
+
field :type, type: String
|
|
38
|
+
field :category, type: String, default: 'uncategorized'
|
|
39
|
+
|
|
40
|
+
# Measure type variables
|
|
41
|
+
field :episode_of_care, type: Boolean
|
|
42
|
+
field :continuous_variable, type: Boolean
|
|
43
|
+
field :episode_ids, type: Array
|
|
44
|
+
|
|
45
|
+
# Publishing data (used by Bonnie)
|
|
46
|
+
field :published, type: Boolean
|
|
47
|
+
field :publish_date, type: Date
|
|
48
|
+
field :version, type: Integer
|
|
49
|
+
|
|
50
|
+
# ELM/CQL Measure-logic related data
|
|
51
|
+
field :elm_annotations, type: Hash
|
|
52
|
+
field :cql, type: Array
|
|
53
|
+
field :elm, type: Array
|
|
54
|
+
field :main_cql_library, type: String
|
|
55
|
+
field :cql_statement_dependencies, type: Hash
|
|
56
|
+
|
|
57
|
+
# HQMF/Tacoma-specific Measure-logic related data
|
|
58
|
+
field :population_criteria, type: Hash
|
|
59
|
+
field :data_criteria, type: Hash
|
|
60
|
+
field :source_data_criteria, type: Hash
|
|
61
|
+
field :measure_period, type: Hash
|
|
62
|
+
field :measure_attributes, type: Array
|
|
63
|
+
field :populations, type: Array
|
|
64
|
+
field :populations_cql_map, type: Hash
|
|
65
|
+
field :observations, type: Array
|
|
66
|
+
|
|
67
|
+
field :value_set_oids, type: Array, default: []
|
|
68
|
+
field :value_set_oid_version_objects, type: Array, default: []
|
|
69
|
+
|
|
70
|
+
field :complexity, type: Hash
|
|
71
|
+
|
|
72
|
+
# Relations to other model classes
|
|
73
|
+
belongs_to :user
|
|
74
|
+
belongs_to :bundle, class_name: 'HealthDataStandards::CQM::Bundle'
|
|
75
|
+
has_and_belongs_to_many :records, inverse_of: nil
|
|
76
|
+
has_one :package, class_name: 'CqlMeasurePackage', inverse_of: :measure, dependent: :destroy
|
|
77
|
+
|
|
78
|
+
scope :by_measure_id, ->(id) { where('measure_id' => id) }
|
|
79
|
+
scope :by_type, ->(type) { where('type' => type) }
|
|
80
|
+
scope :by_user, ->(user) { where user_id: user.id }
|
|
81
|
+
|
|
82
|
+
index 'user_id' => 1
|
|
83
|
+
# Find the measures matching a patient
|
|
84
|
+
def self.for_patient(record)
|
|
85
|
+
where user_id: record.user_id, hqmf_set_id: { '$in' => record.measure_ids }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def value_sets
|
|
89
|
+
options = { oid: value_set_oids }
|
|
90
|
+
options[:user_id] = user.id if user?
|
|
91
|
+
@value_sets ||= HealthDataStandards::SVS::ValueSet.in(options)
|
|
92
|
+
@value_sets
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Returns the hqmf-parser's ruby implementation of an HQMF document.
|
|
96
|
+
# Rebuild from population_criteria, data_criteria, and measure_period JSON
|
|
97
|
+
def as_hqmf_model
|
|
98
|
+
json = {
|
|
99
|
+
'id' => measure_id,
|
|
100
|
+
'title' => title,
|
|
101
|
+
'description' => description,
|
|
102
|
+
'population_criteria' => population_criteria,
|
|
103
|
+
'data_criteria' => data_criteria,
|
|
104
|
+
'source_data_criteria' => source_data_criteria,
|
|
105
|
+
'measure_period' => measure_period,
|
|
106
|
+
'attributes' => measure_attributes,
|
|
107
|
+
'populations' => populations,
|
|
108
|
+
'hqmf_id' => hqmf_id,
|
|
109
|
+
'hqmf_set_id' => hqmf_set_id,
|
|
110
|
+
'hqmf_version_number' => hqmf_version_number,
|
|
111
|
+
'cms_id' => cms_id
|
|
112
|
+
}
|
|
113
|
+
HQMF::Document.from_json(json)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def all_data_criteria
|
|
117
|
+
as_hqmf_model.all_data_criteria
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Note whether or not the measure is a continuous variable measure.
|
|
121
|
+
before_save :set_continuous_variable
|
|
122
|
+
def set_continuous_variable
|
|
123
|
+
# The return value of this function is not related to whether or not this
|
|
124
|
+
# measure is a CV measure. The true return value ensures false is not
|
|
125
|
+
# accidentally returned here, which would cause the chain of 'before_*' to
|
|
126
|
+
# stop executing.
|
|
127
|
+
self.continuous_variable = populations.map(&:keys).flatten.uniq.include? HQMF::PopulationCriteria::MSRPOPL
|
|
128
|
+
true
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# When saving calculate the cyclomatic complexity of the measure
|
|
132
|
+
# TODO: Do we want to consider a measure other than "cyclomatic complexity" for CQL?
|
|
133
|
+
# TODO: THIS IS NOT CYCLOMATIC COMPLEXITY, ALL MULTIPLE ELEMENT EXPRESSIONS GET COUNTED AS HIGHER COMPLEXITY, NOT JUST LOGICAL
|
|
134
|
+
before_save :calculate_complexity
|
|
135
|
+
def calculate_complexity
|
|
136
|
+
# We calculate the complexity for each statement, and (at least for now) store the result in the same way
|
|
137
|
+
# we store the complexity for QDM variables
|
|
138
|
+
# TODO: consider whether this is too much of a force fit
|
|
139
|
+
self.complexity = { variables: [] }
|
|
140
|
+
# Recursively look through an expression to count the logical branches
|
|
141
|
+
def count_expression_logical_branches(expression)
|
|
142
|
+
case expression
|
|
143
|
+
when nil
|
|
144
|
+
0
|
|
145
|
+
when Array
|
|
146
|
+
expression.map { |exp| count_expression_logical_branches(exp) }.sum
|
|
147
|
+
when Hash
|
|
148
|
+
case expression['type']
|
|
149
|
+
when 'And', 'Or', 'Not'
|
|
150
|
+
count_expression_logical_branches(expression['operand'])
|
|
151
|
+
when 'Query'
|
|
152
|
+
# TODO: Do we need to look into the source side of the query? Can there be logical operators there?
|
|
153
|
+
count_expression_logical_branches(expression['where']) + count_expression_logical_branches(expression['relationship'])
|
|
154
|
+
else
|
|
155
|
+
1
|
|
156
|
+
end
|
|
157
|
+
else
|
|
158
|
+
0
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Determine the complexity of each statement
|
|
163
|
+
elm.each do |elm|
|
|
164
|
+
next unless (statements = elm.try(:[], 'library').try(:[], 'statements').try(:[], 'def'))
|
|
165
|
+
statements.each do |statement|
|
|
166
|
+
complexity[:variables] << { name: statement['name'], complexity: count_expression_logical_branches(statement['expression']) }
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
complexity
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# MeasurePackage stores the uploaded file for a given Measure, so it can be recreated if need be
|
|
3
|
+
class MeasurePackage
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
include Mongoid::Timestamps
|
|
6
|
+
|
|
7
|
+
field :file, type: BSON::Binary
|
|
8
|
+
belongs_to :measure, class_name: 'Measure', inverse_of: :package
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module QDM
|
|
2
|
+
# ValueSet represents a collection of Concepts, used by the Measures to specify a set of codes for a particular topic
|
|
3
|
+
class ValueSet
|
|
4
|
+
include Mongoid::Document
|
|
5
|
+
field :oid, type: String
|
|
6
|
+
field :display_name, type: String
|
|
7
|
+
field :version, type: String
|
|
8
|
+
field :user_id, type: String # Eventually we need to delete this from bundles when exporting
|
|
9
|
+
field :categories, type: Hash
|
|
10
|
+
|
|
11
|
+
index(oid: 1)
|
|
12
|
+
embeds_many :concepts
|
|
13
|
+
index 'concepts.code' => 1
|
|
14
|
+
index 'concepts.code_system' => 1
|
|
15
|
+
index 'concepts.code_system_name' => 1
|
|
16
|
+
index 'bundle_id' => 1
|
|
17
|
+
scope :by_oid, ->(oid) { where(oid: oid) }
|
|
18
|
+
|
|
19
|
+
# Provides an Array of Hashes. Each code system gets its own Hash
|
|
20
|
+
# The hash has a key of "set" for the code system name and "values"
|
|
21
|
+
# for the actual code list
|
|
22
|
+
def code_set_map
|
|
23
|
+
codes = []
|
|
24
|
+
concept_pairs = concepts.each_with_object({}) do |concept, memo|
|
|
25
|
+
memo[concept.code_system_name] ||= []
|
|
26
|
+
memo[concept.code_system_name] << concept.code
|
|
27
|
+
end
|
|
28
|
+
concept_pairs.each_pair do |code_set, code_list|
|
|
29
|
+
codes << { 'set' => code_set, 'values' => code_list }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
codes
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.load_from_xml(doc)
|
|
36
|
+
doc.root.add_namespace_definition('vs', 'urn:ihe:iti:svs:2008')
|
|
37
|
+
vs_element = doc.at_xpath('/vs:RetrieveValueSetResponse/vs:ValueSet|/vs:RetrieveMultipleValueSetsResponse/vs:DescribedValueSet')
|
|
38
|
+
return unless vs_element
|
|
39
|
+
vs = ValueSet.new(oid: vs_element['ID'], display_name: vs_element['displayName'], version: vs_element['version'])
|
|
40
|
+
vs.concepts = extract_concepts(vs_element)
|
|
41
|
+
vs.categories = extract_categories(vs_element)
|
|
42
|
+
vs
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.extract_concepts(vs_element)
|
|
46
|
+
vs_element.xpath('//vs:Concept').collect do |con|
|
|
47
|
+
code_system_name = HealthDataStandards::Util::CodeSystemHelper::CODE_SYSTEMS[con['codeSystem']] || con['codeSystemName']
|
|
48
|
+
Concept.new(code: con['code'],
|
|
49
|
+
code_system_name: code_system_name,
|
|
50
|
+
code_system_version: con['codeSystemVersion'],
|
|
51
|
+
display_name: con['displayName'], code_system: con['codeSystem'])
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.extract_categories(vs_element)
|
|
56
|
+
category_hash = Hash.new { |h, k| h[k] = [] }
|
|
57
|
+
groups_with_categories = vs_element.xpath("//vs:Group/@ID[../@displayName='CATEGORY']")
|
|
58
|
+
groups_with_categories.each do |group_number|
|
|
59
|
+
measure = vs_element.xpath("//vs:Group[@displayName='CMS eMeasure ID' and @ID='#{group_number}']/vs:Keyword").text
|
|
60
|
+
categories_for_group = vs_element.xpath("//vs:Group[@displayName='CATEGORY' and @ID='#{group_number}']/vs:Keyword")
|
|
61
|
+
categories_for_group.each do |category|
|
|
62
|
+
category_hash[measure] << category.text
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
!category_hash.empty? ? category_hash : nil
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "cqm/models"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
mkdir -p tmp/dist/
|
|
4
|
+
|
|
5
|
+
# dist_test browserifies index.js to tmp/dist
|
|
6
|
+
yarn run dist_test
|
|
7
|
+
|
|
8
|
+
# comm -3 only returns lines that differ between the two files. If none are different, diff will be empty
|
|
9
|
+
diff=`diff dist/index.js tmp/dist/index.js`
|
|
10
|
+
|
|
11
|
+
# Exit with a non-zero code if the diff isn't empty
|
|
12
|
+
if [ "$diff" != "" ]; then
|
|
13
|
+
echo "dist/index.js is out of date. Please run 'yarn run dist' locally and commit/push the result"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
echo "dist/index.js is up to date"
|
data/config/mongoid.yml
ADDED
data/cqm-models.gemspec
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'cqm-models'
|
|
7
|
+
spec.version = '0.7.2'
|
|
8
|
+
spec.authors = ['aholmes@mitre.org', 'mokeefe@mitre.org', 'lades@mitre.org']
|
|
9
|
+
|
|
10
|
+
spec.summary = 'Mongo models that correspond to the QDM specification.'
|
|
11
|
+
spec.description = 'This library contains auto generated Mongoid (Ruby) and Mongoose (JavaScript) models that correspond to the QDM (Quality Data Model) specification.'
|
|
12
|
+
spec.homepage = 'https://github.com/projecttacoma/cqm-models'
|
|
13
|
+
spec.license = 'Apache-2.0'
|
|
14
|
+
|
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
|
17
|
+
end
|
|
18
|
+
spec.bindir = 'exe'
|
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
|
+
spec.require_paths = ['lib']
|
|
21
|
+
|
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
|
23
|
+
spec.add_development_dependency 'byebug', '~> 10.0.0'
|
|
24
|
+
spec.add_development_dependency 'mongoid', '~> 6.3.0'
|
|
25
|
+
spec.add_development_dependency 'rails', '~> 5.1'
|
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
28
|
+
spec.add_development_dependency 'rubocop', '~> 0.54.0'
|
|
29
|
+
end
|