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.
Files changed (178) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +1 -0
  3. data/.eslintrc.json +26 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +32 -0
  5. data/.gitignore +21 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +42 -0
  8. data/.travis.yml +21 -0
  9. data/Gemfile +5 -0
  10. data/LICENSE.txt +201 -0
  11. data/README.md +26 -0
  12. data/Rakefile +12 -0
  13. data/app/assets/javascripts/AdverseEvent.js +27 -0
  14. data/app/assets/javascripts/AllDataElements.js +120 -0
  15. data/app/assets/javascripts/AllergyIntolerance.js +27 -0
  16. data/app/assets/javascripts/AssessmentPerformed.js +30 -0
  17. data/app/assets/javascripts/AssessmentRecommended.js +27 -0
  18. data/app/assets/javascripts/CareGoal.js +25 -0
  19. data/app/assets/javascripts/CommunicationFromPatientToProvider.js +26 -0
  20. data/app/assets/javascripts/CommunicationFromProviderToPatient.js +26 -0
  21. data/app/assets/javascripts/CommunicationFromProviderToProvider.js +26 -0
  22. data/app/assets/javascripts/Component.js +22 -0
  23. data/app/assets/javascripts/Concept.js +14 -0
  24. data/app/assets/javascripts/DeviceApplied.js +29 -0
  25. data/app/assets/javascripts/DeviceOrder.js +26 -0
  26. data/app/assets/javascripts/DeviceRecommended.js +26 -0
  27. data/app/assets/javascripts/Diagnosis.js +27 -0
  28. data/app/assets/javascripts/DiagnosticStudyOrder.js +27 -0
  29. data/app/assets/javascripts/DiagnosticStudyPerformed.js +33 -0
  30. data/app/assets/javascripts/DiagnosticStudyRecommended.js +27 -0
  31. data/app/assets/javascripts/EncounterOrder.js +27 -0
  32. data/app/assets/javascripts/EncounterPerformed.js +32 -0
  33. data/app/assets/javascripts/EncounterRecommended.js +27 -0
  34. data/app/assets/javascripts/FacilityLocation.js +22 -0
  35. data/app/assets/javascripts/FamilyHistory.js +25 -0
  36. data/app/assets/javascripts/Id.js +22 -0
  37. data/app/assets/javascripts/ImmunizationAdministered.js +30 -0
  38. data/app/assets/javascripts/ImmunizationOrder.js +30 -0
  39. data/app/assets/javascripts/InterventionOrder.js +26 -0
  40. data/app/assets/javascripts/InterventionPerformed.js +29 -0
  41. data/app/assets/javascripts/InterventionRecommended.js +26 -0
  42. data/app/assets/javascripts/LaboratoryTestOrder.js +27 -0
  43. data/app/assets/javascripts/LaboratoryTestPerformed.js +33 -0
  44. data/app/assets/javascripts/LaboratoryTestRecommended.js +27 -0
  45. data/app/assets/javascripts/Measure.js +76 -0
  46. data/app/assets/javascripts/MeasurePackage.js +20 -0
  47. data/app/assets/javascripts/MedicationActive.js +28 -0
  48. data/app/assets/javascripts/MedicationAdministered.js +31 -0
  49. data/app/assets/javascripts/MedicationDischarge.js +30 -0
  50. data/app/assets/javascripts/MedicationDispensed.js +31 -0
  51. data/app/assets/javascripts/MedicationOrder.js +34 -0
  52. data/app/assets/javascripts/Participation.js +21 -0
  53. data/app/assets/javascripts/Patient.js +248 -0
  54. data/app/assets/javascripts/PatientCareExperience.js +23 -0
  55. data/app/assets/javascripts/PatientCharacteristic.js +23 -0
  56. data/app/assets/javascripts/PatientCharacteristicBirthdate.js +24 -0
  57. data/app/assets/javascripts/PatientCharacteristicClinicalTrialParticipant.js +26 -0
  58. data/app/assets/javascripts/PatientCharacteristicEthnicity.js +23 -0
  59. data/app/assets/javascripts/PatientCharacteristicExpired.js +25 -0
  60. data/app/assets/javascripts/PatientCharacteristicPayer.js +24 -0
  61. data/app/assets/javascripts/PatientCharacteristicRace.js +23 -0
  62. data/app/assets/javascripts/PatientCharacteristicSex.js +23 -0
  63. data/app/assets/javascripts/PhysicalExamOrder.js +28 -0
  64. data/app/assets/javascripts/PhysicalExamPerformed.js +31 -0
  65. data/app/assets/javascripts/PhysicalExamRecommended.js +28 -0
  66. data/app/assets/javascripts/ProcedureOrder.js +30 -0
  67. data/app/assets/javascripts/ProcedurePerformed.js +35 -0
  68. data/app/assets/javascripts/ProcedureRecommended.js +30 -0
  69. data/app/assets/javascripts/ProviderCareExperience.js +23 -0
  70. data/app/assets/javascripts/ProviderCharacteristic.js +23 -0
  71. data/app/assets/javascripts/Ratio.js +22 -0
  72. data/app/assets/javascripts/Result.js +28 -0
  73. data/app/assets/javascripts/ResultComponent.js +21 -0
  74. data/app/assets/javascripts/SubstanceAdministered.js +30 -0
  75. data/app/assets/javascripts/SubstanceOrder.js +32 -0
  76. data/app/assets/javascripts/SubstanceRecommended.js +32 -0
  77. data/app/assets/javascripts/Symptom.js +25 -0
  78. data/app/assets/javascripts/ValueSet.js +30 -0
  79. data/app/assets/javascripts/basetypes/Code.js +25 -0
  80. data/app/assets/javascripts/basetypes/DataElement.js +36 -0
  81. data/app/assets/javascripts/basetypes/DateTime.js +18 -0
  82. data/app/assets/javascripts/basetypes/Interval.js +35 -0
  83. data/app/assets/javascripts/basetypes/Quantity.js +20 -0
  84. data/app/assets/javascripts/index.js +12 -0
  85. data/app/models/models.rb +78 -0
  86. data/app/models/qdm/adverse_event.rb +15 -0
  87. data/app/models/qdm/allergy_intolerance.rb +15 -0
  88. data/app/models/qdm/assessment_performed.rb +18 -0
  89. data/app/models/qdm/assessment_recommended.rb +15 -0
  90. data/app/models/qdm/basetypes/code.rb +56 -0
  91. data/app/models/qdm/basetypes/data_element.rb +42 -0
  92. data/app/models/qdm/basetypes/interval.rb +54 -0
  93. data/app/models/qdm/basetypes/quantity.rb +52 -0
  94. data/app/models/qdm/care_goal.rb +13 -0
  95. data/app/models/qdm/communication_from_patient_to_provider.rb +14 -0
  96. data/app/models/qdm/communication_from_provider_to_patient.rb +14 -0
  97. data/app/models/qdm/communication_from_provider_to_provider.rb +14 -0
  98. data/app/models/qdm/component.rb +10 -0
  99. data/app/models/qdm/device_applied.rb +17 -0
  100. data/app/models/qdm/device_order.rb +14 -0
  101. data/app/models/qdm/device_recommended.rb +14 -0
  102. data/app/models/qdm/diagnosis.rb +15 -0
  103. data/app/models/qdm/diagnostic_study_order.rb +15 -0
  104. data/app/models/qdm/diagnostic_study_performed.rb +21 -0
  105. data/app/models/qdm/diagnostic_study_recommended.rb +15 -0
  106. data/app/models/qdm/encounter_order.rb +15 -0
  107. data/app/models/qdm/encounter_performed.rb +20 -0
  108. data/app/models/qdm/encounter_recommended.rb +15 -0
  109. data/app/models/qdm/facility_location.rb +10 -0
  110. data/app/models/qdm/family_history.rb +13 -0
  111. data/app/models/qdm/id.rb +10 -0
  112. data/app/models/qdm/immunization_administered.rb +18 -0
  113. data/app/models/qdm/immunization_order.rb +18 -0
  114. data/app/models/qdm/intervention_order.rb +14 -0
  115. data/app/models/qdm/intervention_performed.rb +17 -0
  116. data/app/models/qdm/intervention_recommended.rb +14 -0
  117. data/app/models/qdm/laboratory_test_order.rb +15 -0
  118. data/app/models/qdm/laboratory_test_performed.rb +21 -0
  119. data/app/models/qdm/laboratory_test_recommended.rb +15 -0
  120. data/app/models/qdm/medication_active.rb +16 -0
  121. data/app/models/qdm/medication_administered.rb +19 -0
  122. data/app/models/qdm/medication_discharge.rb +18 -0
  123. data/app/models/qdm/medication_dispensed.rb +19 -0
  124. data/app/models/qdm/medication_order.rb +22 -0
  125. data/app/models/qdm/participation.rb +9 -0
  126. data/app/models/qdm/patient.rb +201 -0
  127. data/app/models/qdm/patient_care_experience.rb +11 -0
  128. data/app/models/qdm/patient_characteristic.rb +11 -0
  129. data/app/models/qdm/patient_characteristic_birthdate.rb +12 -0
  130. data/app/models/qdm/patient_characteristic_clinical_trial_participant.rb +14 -0
  131. data/app/models/qdm/patient_characteristic_ethnicity.rb +11 -0
  132. data/app/models/qdm/patient_characteristic_expired.rb +13 -0
  133. data/app/models/qdm/patient_characteristic_payer.rb +12 -0
  134. data/app/models/qdm/patient_characteristic_race.rb +11 -0
  135. data/app/models/qdm/patient_characteristic_sex.rb +11 -0
  136. data/app/models/qdm/physical_exam_order.rb +16 -0
  137. data/app/models/qdm/physical_exam_performed.rb +19 -0
  138. data/app/models/qdm/physical_exam_recommended.rb +16 -0
  139. data/app/models/qdm/procedure_order.rb +18 -0
  140. data/app/models/qdm/procedure_performed.rb +23 -0
  141. data/app/models/qdm/procedure_recommended.rb +18 -0
  142. data/app/models/qdm/provider_care_experience.rb +11 -0
  143. data/app/models/qdm/provider_characteristic.rb +11 -0
  144. data/app/models/qdm/ratio.rb +10 -0
  145. data/app/models/qdm/result_component.rb +9 -0
  146. data/app/models/qdm/substance_administered.rb +18 -0
  147. data/app/models/qdm/substance_order.rb +20 -0
  148. data/app/models/qdm/substance_recommended.rb +20 -0
  149. data/app/models/qdm/symptom.rb +13 -0
  150. data/app/models/qdm/tacoma/concept.rb +14 -0
  151. data/app/models/qdm/tacoma/measure.rb +172 -0
  152. data/app/models/qdm/tacoma/measure_package.rb +10 -0
  153. data/app/models/qdm/tacoma/valueset.rb +68 -0
  154. data/bin/console +14 -0
  155. data/bin/setup +8 -0
  156. data/bin/validate_dist.sh +17 -0
  157. data/config/mongoid.yml +6 -0
  158. data/cqm-models.gemspec +29 -0
  159. data/data/oids.json +584 -0
  160. data/dist/index.js +157647 -0
  161. data/lib/cqm/models.rb +1 -0
  162. data/lib/generate_models.rb +330 -0
  163. data/modelinfo/qdm-modelinfo-4.2.xml +515 -0
  164. data/modelinfo/qdm-modelinfo-4.3.xml +521 -0
  165. data/modelinfo/qdm-modelinfo-5.0.1.xml +436 -0
  166. data/modelinfo/qdm-modelinfo-5.0.2.xml +445 -0
  167. data/modelinfo/qdm-modelinfo-5.0.xml +429 -0
  168. data/modelinfo/qdm-modelinfo-5.3.xml +524 -0
  169. data/package.json +34 -0
  170. data/templates/all_data_elements_template.js.erb +4 -0
  171. data/templates/index_template.js.erb +12 -0
  172. data/templates/models_template.rb.erb +21 -0
  173. data/templates/mongoose_template.js.erb +20 -0
  174. data/templates/patient_extension.rb.erb +194 -0
  175. data/templates/patient_template.js.erb +247 -0
  176. data/tmp/.keep +0 -0
  177. data/yarn.lock +1901 -0
  178. 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,9 @@
1
+ module QDM
2
+ # app/models/qdm/result_component.rb
3
+ class ResultComponent < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :referenceRange, type: QDM::Interval
7
+ field :qdmVersion, type: String, default: '5.3'
8
+ end
9
+ 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,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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"
@@ -0,0 +1,6 @@
1
+ test:
2
+ clients:
3
+ default:
4
+ database: cqm_models_test
5
+ hosts:
6
+ - localhost:27017
@@ -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