cancer_registry_reporting_test_kit 0.9.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.
Files changed (262) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/config/presets/hdea_report_preset.json +14 -0
  4. data/config/presets/inferno_reference_server_preset.json.erb +84 -0
  5. data/lib/cancer_registry_reporting_test_kit/bundle_parse.rb +161 -0
  6. data/lib/cancer_registry_reporting_test_kit/docs/ehr_suite_description.md +134 -0
  7. data/lib/cancer_registry_reporting_test_kit/docs/hdea_suite_description.md +108 -0
  8. data/lib/cancer_registry_reporting_test_kit/ehr_suite/ehr_capability_statement/mcode_capability_statement_profile_support.rb +40 -0
  9. data/lib/cancer_registry_reporting_test_kit/ehr_suite/ehr_data_access_group.rb +131 -0
  10. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_administration/medication_administration_must_support_test.rb +43 -0
  11. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_administration/medication_administration_search_test.rb +51 -0
  12. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_administration/medication_administration_validation_test.rb +41 -0
  13. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_administration/metadata.yml +72 -0
  14. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_administration_group.rb +72 -0
  15. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_request/medication_request_must_support_test.rb +55 -0
  16. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_request/medication_request_search_test.rb +55 -0
  17. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_request/medication_request_validation_test.rb +38 -0
  18. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_request/metadata.yml +94 -0
  19. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/medication_request_group.rb +73 -0
  20. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/primary_cancer_condition_group.rb +73 -0
  21. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/primary_condition/metadata.yml +100 -0
  22. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/primary_condition/primary_cancer_condition_must_support_test.rb +50 -0
  23. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/primary_condition/primary_cancer_condition_search_test.rb +70 -0
  24. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/primary_condition/primary_cancer_condition_validation_test.rb +39 -0
  25. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/radiotherapy_procedure/metadata.yml +99 -0
  26. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/radiotherapy_procedure/radiotherapy_procedure_must_support_test.rb +46 -0
  27. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/radiotherapy_procedure/radiotherapy_procedure_search_test.rb +51 -0
  28. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/radiotherapy_procedure/radiotherapy_procedure_validation_test.rb +37 -0
  29. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/radiotherapy_procedure_group.rb +83 -0
  30. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/secondary_cancer_condition_group.rb +68 -0
  31. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/secondary_condition/metadata.yml +102 -0
  32. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/secondary_condition/secondary_cancer_condition_must_support_test.rb +50 -0
  33. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/secondary_condition/secondary_cancer_condition_search_test.rb +70 -0
  34. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/secondary_condition/secondary_cancer_condition_validation_test.rb +39 -0
  35. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_distant_metastases_category/metadata.yml +65 -0
  36. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_distant_metastases_category/tnm_distant_metastases_category_must_support_test.rb +44 -0
  37. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_distant_metastases_category/tnm_distant_metastases_category_search_test.rb +69 -0
  38. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_distant_metastases_category/tnm_distant_metastases_category_validation_test.rb +39 -0
  39. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_distant_metastases_category_group.rb +74 -0
  40. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_primary_tumor_category/metadata.yml +64 -0
  41. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_primary_tumor_category/tnm_primary_tumor_category_must_support_test.rb +44 -0
  42. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_primary_tumor_category/tnm_primary_tumor_category_search_test.rb +69 -0
  43. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_primary_tumor_category/tnm_primary_tumor_category_validation_test.rb +39 -0
  44. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_primary_tumor_category_group.rb +73 -0
  45. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_regional_nodes_category/metadata.yml +64 -0
  46. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_regional_nodes_category/tnm_regional_nodes_category_must_support_test.rb +44 -0
  47. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_regional_nodes_category/tnm_regional_nodes_category_search_test.rb +69 -0
  48. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_regional_nodes_category/tnm_regional_nodes_category_validation_test.rb +39 -0
  49. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_regional_nodes_category_group.rb +73 -0
  50. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_stage_group/metadata.yml +68 -0
  51. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_stage_group/tnm_stage_group_must_support_test.rb +45 -0
  52. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_stage_group/tnm_stage_group_search_test.rb +69 -0
  53. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_stage_group/tnm_stage_group_validation_test.rb +39 -0
  54. data/lib/cancer_registry_reporting_test_kit/ehr_suite/mcode_data_access_resources/tnm_stage_group_group.rb +72 -0
  55. data/lib/cancer_registry_reporting_test_kit/ehr_suite.rb +69 -0
  56. data/lib/cancer_registry_reporting_test_kit/fhir_resource_navigation.rb +174 -0
  57. data/lib/cancer_registry_reporting_test_kit/hdea_generator/group_generator.rb +47 -0
  58. data/lib/cancer_registry_reporting_test_kit/hdea_generator/group_metadata.rb +86 -0
  59. data/lib/cancer_registry_reporting_test_kit/hdea_generator/group_metadata_extractor.rb +205 -0
  60. data/lib/cancer_registry_reporting_test_kit/hdea_generator/ig_loader.rb +78 -0
  61. data/lib/cancer_registry_reporting_test_kit/hdea_generator/ig_metadata.rb +26 -0
  62. data/lib/cancer_registry_reporting_test_kit/hdea_generator/ig_metadata_extractor.rb +78 -0
  63. data/lib/cancer_registry_reporting_test_kit/hdea_generator/ig_resources.rb +56 -0
  64. data/lib/cancer_registry_reporting_test_kit/hdea_generator/must_support_metadata_extractor.rb +399 -0
  65. data/lib/cancer_registry_reporting_test_kit/hdea_generator/must_support_test_generator.rb +134 -0
  66. data/lib/cancer_registry_reporting_test_kit/hdea_generator/naming.rb +168 -0
  67. data/lib/cancer_registry_reporting_test_kit/hdea_generator/special_cases.rb +43 -0
  68. data/lib/cancer_registry_reporting_test_kit/hdea_generator/templates/must_support.rb.erb +41 -0
  69. data/lib/cancer_registry_reporting_test_kit/hdea_generator/templates/validation.rb.erb +35 -0
  70. data/lib/cancer_registry_reporting_test_kit/hdea_generator/terminology_binding_metadata_extractor.rb +118 -0
  71. data/lib/cancer_registry_reporting_test_kit/hdea_generator/validation_test_generator.rb +125 -0
  72. data/lib/cancer_registry_reporting_test_kit/hdea_generator/value_extractor.rb +134 -0
  73. data/lib/cancer_registry_reporting_test_kit/hdea_generator.rb +66 -0
  74. data/lib/cancer_registry_reporting_test_kit/hdea_suite/author/author_validation_test.rb +61 -0
  75. data/lib/cancer_registry_reporting_test_kit/hdea_suite/author/organization_metadata.yml +47 -0
  76. data/lib/cancer_registry_reporting_test_kit/hdea_suite/author/organization_must_support_test.rb +73 -0
  77. data/lib/cancer_registry_reporting_test_kit/hdea_suite/author/practitioner_metadata.yml +51 -0
  78. data/lib/cancer_registry_reporting_test_kit/hdea_suite/author/practitioner_must_support_test.rb +73 -0
  79. data/lib/cancer_registry_reporting_test_kit/hdea_suite/author/practitioner_role_metadata.yml +48 -0
  80. data/lib/cancer_registry_reporting_test_kit/hdea_suite/author/practitioner_role_must_support_test.rb +66 -0
  81. data/lib/cancer_registry_reporting_test_kit/hdea_suite/bundle_resources_group.rb +213 -0
  82. data/lib/cancer_registry_reporting_test_kit/hdea_suite/ccrr_content_bundle_parse_and_validation_test.rb +67 -0
  83. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/allergy_intolerance/allergy_intolerance_must_support_test.rb +46 -0
  84. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/allergy_intolerance/allergy_intolerance_validation_test.rb +35 -0
  85. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/allergy_intolerance/metadata.yml +36 -0
  86. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/care_plan/care_plan_must_support_test.rb +48 -0
  87. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/care_plan/care_plan_validation_test.rb +35 -0
  88. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/care_plan/metadata.yml +50 -0
  89. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/ccrr_content_bundle/ccrr_content_bundle_must_support_test.rb +43 -0
  90. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/ccrr_content_bundle/metadata.yml +36 -0
  91. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/central_cancer_registry_primary_cancer_condition/central_cancer_registry_primary_cancer_condition_must_support_test.rb +59 -0
  92. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/central_cancer_registry_primary_cancer_condition/central_cancer_registry_primary_cancer_condition_validation_test.rb +35 -0
  93. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/central_cancer_registry_primary_cancer_condition/metadata.yml +86 -0
  94. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/composition/composition_must_support_test.rb +109 -0
  95. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/composition/composition_validation_test.rb +35 -0
  96. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/composition/metadata.yml +272 -0
  97. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/condition/condition_must_support_test.rb +45 -0
  98. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/condition/condition_validation_test.rb +35 -0
  99. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/condition/metadata.yml +33 -0
  100. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/diagnostic_report_lab/diagnostic_report_lab_must_support_test.rb +49 -0
  101. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/diagnostic_report_lab/diagnostic_report_lab_validation_test.rb +35 -0
  102. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/diagnostic_report_lab/metadata.yml +57 -0
  103. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/diagnostic_report_note/diagnostic_report_note_must_support_test.rb +53 -0
  104. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/diagnostic_report_note/diagnostic_report_note_validation_test.rb +35 -0
  105. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/diagnostic_report_note/metadata.yml +75 -0
  106. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/document_reference/document_reference_must_support_test.rb +57 -0
  107. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/document_reference/document_reference_validation_test.rb +35 -0
  108. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/document_reference/metadata.yml +68 -0
  109. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/encounter/encounter_must_support_test.rb +59 -0
  110. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/encounter/encounter_validation_test.rb +35 -0
  111. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/encounter/metadata.yml +73 -0
  112. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_radiotherapy_course_summary/mcode_radiotherapy_course_summary_must_support_test.rb +52 -0
  113. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_radiotherapy_course_summary/mcode_radiotherapy_course_summary_validation_test.rb +35 -0
  114. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_radiotherapy_course_summary/metadata.yml +59 -0
  115. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_secondary_cancer_condition/mcode_secondary_cancer_condition_must_support_test.rb +56 -0
  116. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_secondary_cancer_condition/mcode_secondary_cancer_condition_validation_test.rb +35 -0
  117. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_secondary_cancer_condition/metadata.yml +77 -0
  118. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_tnm_stage_group/mcode_tnm_stage_group_must_support_test.rb +48 -0
  119. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_tnm_stage_group/mcode_tnm_stage_group_validation_test.rb +35 -0
  120. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/mcode_tnm_stage_group/metadata.yml +46 -0
  121. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication/medication_must_support_test.rb +41 -0
  122. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication/medication_validation_test.rb +35 -0
  123. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication/metadata.yml +26 -0
  124. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_administration/medication_administration_must_support_test.rb +48 -0
  125. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_administration/medication_administration_validation_test.rb +35 -0
  126. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_administration/metadata.yml +48 -0
  127. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_request/medication_request_must_support_test.rb +57 -0
  128. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_request/medication_request_validation_test.rb +35 -0
  129. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_request/metadata.yml +86 -0
  130. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_statement/medication_statement_must_support_test.rb +41 -0
  131. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_statement/medication_statement_validation_test.rb +35 -0
  132. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/medication_statement/metadata.yml +26 -0
  133. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/observation/metadata.yml +26 -0
  134. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/observation/observation_must_support_test.rb +41 -0
  135. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/observation/observation_validation_test.rb +35 -0
  136. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/observation_lab/metadata.yml +53 -0
  137. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/observation_lab/observation_lab_must_support_test.rb +50 -0
  138. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/observation_lab/observation_lab_validation_test.rb +35 -0
  139. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/odh_usual_work/metadata.yml +81 -0
  140. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/odh_usual_work/odh_usual_work_must_support_test.rb +49 -0
  141. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/odh_usual_work/odh_usual_work_validation_test.rb +35 -0
  142. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/organization/metadata.yml +46 -0
  143. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/organization/organization_must_support_test.rb +55 -0
  144. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/organization/organization_validation_test.rb +35 -0
  145. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/patient/metadata.yml +51 -0
  146. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/patient/patient_must_support_test.rb +58 -0
  147. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/patient/patient_validation_test.rb +35 -0
  148. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/practitioner/metadata.yml +50 -0
  149. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/practitioner/practitioner_must_support_test.rb +55 -0
  150. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/practitioner/practitioner_validation_test.rb +35 -0
  151. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/practitioner_role/metadata.yml +47 -0
  152. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/practitioner_role/practitioner_role_must_support_test.rb +49 -0
  153. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/practitioner_role/practitioner_role_validation_test.rb +35 -0
  154. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/procedure/metadata.yml +37 -0
  155. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/procedure/procedure_must_support_test.rb +44 -0
  156. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/procedure/procedure_validation_test.rb +35 -0
  157. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/service_request/metadata.yml +26 -0
  158. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/service_request/service_request_must_support_test.rb +41 -0
  159. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/service_request/service_request_validation_test.rb +35 -0
  160. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/smokingstatus/metadata.yml +58 -0
  161. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/smokingstatus/smokingstatus_must_support_test.rb +47 -0
  162. data/lib/cancer_registry_reporting_test_kit/hdea_suite/generated/v1.0.0/smokingstatus/smokingstatus_validation_test.rb +35 -0
  163. data/lib/cancer_registry_reporting_test_kit/hdea_suite.rb +80 -0
  164. data/lib/cancer_registry_reporting_test_kit/igs/README.md +21 -0
  165. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-cancer-related-medication-administration.json +1905 -0
  166. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-cancer-related-medication-request.json +3611 -0
  167. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-primary-cancer-condition.json +2246 -0
  168. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-radiotherapy-course-summary.json +2700 -0
  169. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-secondary-cancer-condition.json +2419 -0
  170. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-tnm-distant-metastases-category.json +2320 -0
  171. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-tnm-primary-tumor-category.json +2320 -0
  172. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-tnm-regional-nodes-category.json +2320 -0
  173. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-mcode-tnm-stage-group.json +2414 -0
  174. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-medicationstatement.profile.json +1578 -0
  175. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-observation.profile.json +3510 -0
  176. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-odh-UsualWork.json +7248 -0
  177. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-servicerequest.profile.json +3048 -0
  178. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-allergyintolerance.json +1842 -0
  179. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-careplan.json +1 -0
  180. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-condition.json +2154 -0
  181. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-diagnosticreport-lab.json +2002 -0
  182. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-diagnosticreport-note.json +2049 -0
  183. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-documentreference.json +1 -0
  184. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-encounter.json +1 -0
  185. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-medication.json +1 -0
  186. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-observation-lab.json +3153 -0
  187. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-organization.json +1 -0
  188. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-patient.json +1 -0
  189. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-practitioner.json +1 -0
  190. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-practitionerrole.json +1 -0
  191. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-procedure.json +1 -0
  192. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100/StructureDefinition-us-core-smokingstatus.json +1 -0
  193. data/lib/cancer_registry_reporting_test_kit/igs/ccrr_v100.tgz +0 -0
  194. data/lib/cancer_registry_reporting_test_kit/igs/package/.index.db +0 -0
  195. data/lib/cancer_registry_reporting_test_kit/igs/package/.index.json +4 -0
  196. data/lib/cancer_registry_reporting_test_kit/igs/package/CapabilityStatement-central-cancer-registry-reporting-ehr.json +1 -0
  197. data/lib/cancer_registry_reporting_test_kit/igs/package/ImplementationGuide-hl7.fhir.us.central-cancer-registry-reporting.json +1 -0
  198. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-cancer-encounter.json +1 -0
  199. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-cancer-patient.json +1 -0
  200. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-ccrr-composition.json +1 -0
  201. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-ccrr-content-bundle.json +1 -0
  202. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-ccrr-plandefinition.json +1 -0
  203. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-ccrr-reporting-bundle.json +1 -0
  204. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-central-cancer-registry-primary-cancer-condition.json +1 -0
  205. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-central-cancer-registry-reporting-messageheader.json +1 -0
  206. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-us-ph-patient.json +1 -0
  207. data/lib/cancer_registry_reporting_test_kit/igs/package/StructureDefinition-us-ph-tribal-affiliation-extension.json +1 -0
  208. data/lib/cancer_registry_reporting_test_kit/igs/package/ValueSet-cancer-core-reportability-codes.json +1 -0
  209. data/lib/cancer_registry_reporting_test_kit/igs/package/example/AllergyIntolerance-example.json +1 -0
  210. data/lib/cancer_registry_reporting_test_kit/igs/package/example/BodyStructure-jenny-m-chest-wall-lymph-nodes-treatment-volume.json +1 -0
  211. data/lib/cancer_registry_reporting_test_kit/igs/package/example/BodyStructure-jenny-m-chest-wall-treatment-volume.json +1 -0
  212. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Bundle-ccrr-content-bundle-example.json +1 -0
  213. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Bundle-central-cancer-registry-reporting-specification-bundle-example.json +1 -0
  214. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Bundle-reporting-bundle-example.json +1 -0
  215. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Composition-ccrr-composition-example.json +1 -0
  216. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Condition-primary-cancer-condition-breast.json +1 -0
  217. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Encounter-encounter-cancer-example.json +1 -0
  218. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Endpoint-example-healthcare-endpoint.json +1 -0
  219. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Endpoint-example-ph-endpoint.json +1 -0
  220. data/lib/cancer_registry_reporting_test_kit/igs/package/example/MedicationAdministration-cancer-related-medication-administration-example.json +1 -0
  221. data/lib/cancer_registry_reporting_test_kit/igs/package/example/MessageHeader-messageheader-example-reportheader.json +1 -0
  222. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Observation-cancer-stage-group-example.json +1 -0
  223. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Observation-tnm-clinical-distant-metastases-category-cM0.json +1 -0
  224. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Observation-tnm-clinical-primary-tumor-category-cT3.json +1 -0
  225. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Observation-tnm-clinical-regional-nodes-category-cN3.json +1 -0
  226. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Organization-example-healthcare-org.json +1 -0
  227. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Organization-example-pha-org.json +1 -0
  228. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Patient-example.json +1 -0
  229. data/lib/cancer_registry_reporting_test_kit/igs/package/example/PlanDefinition-plandefinition-central-cancer-registry-reporting-example.json +1 -0
  230. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Practitioner-1.json +1 -0
  231. data/lib/cancer_registry_reporting_test_kit/igs/package/example/Procedure-radiotherapy-example.json +1 -0
  232. data/lib/cancer_registry_reporting_test_kit/igs/package/openapi/central-cancer-registry-reporting-ehr.openapi.json +364 -0
  233. data/lib/cancer_registry_reporting_test_kit/igs/package/other/ig-r4.jsonX +1 -0
  234. data/lib/cancer_registry_reporting_test_kit/igs/package/other/spec.internals +293 -0
  235. data/lib/cancer_registry_reporting_test_kit/igs/package/other/validation-oo.json +1 -0
  236. data/lib/cancer_registry_reporting_test_kit/igs/package/other/validation-summary.json +1 -0
  237. data/lib/cancer_registry_reporting_test_kit/igs/package/package.json +30 -0
  238. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-cancer-encounter.sch +19 -0
  239. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-cancer-patient.sch +175 -0
  240. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-ccrr-composition.sch +61 -0
  241. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-ccrr-content-bundle.sch +12 -0
  242. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-ccrr-plandefinition.sch +331 -0
  243. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-ccrr-reporting-bundle.sch +12 -0
  244. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-central-cancer-registry-primary-cancer-condition.sch +31 -0
  245. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-central-cancer-registry-reporting-messageheader.sch +27 -0
  246. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-us-ph-patient.sch +217 -0
  247. data/lib/cancer_registry_reporting_test_kit/igs/package/xml/StructureDefinition-us-ph-tribal-affiliation-extension.sch +36 -0
  248. data/lib/cancer_registry_reporting_test_kit/metadata.rb +71 -0
  249. data/lib/cancer_registry_reporting_test_kit/must_support_test.rb +263 -0
  250. data/lib/cancer_registry_reporting_test_kit/primitive_type.rb +7 -0
  251. data/lib/cancer_registry_reporting_test_kit/requirements/cancer-registry-reporting-test-kit_out_of_scope_requirements.csv +77 -0
  252. data/lib/cancer_registry_reporting_test_kit/requirements/cancer-registry-reporting-test-kit_requirements.csv +162 -0
  253. data/lib/cancer_registry_reporting_test_kit/requirements/generated/cancer-registry-reporting-test-kit_requirements_coverage.csv +161 -0
  254. data/lib/cancer_registry_reporting_test_kit/search_test.rb +897 -0
  255. data/lib/cancer_registry_reporting_test_kit/search_test_properties.rb +58 -0
  256. data/lib/cancer_registry_reporting_test_kit/validation_test.rb +68 -0
  257. data/lib/cancer_registry_reporting_test_kit/version.rb +6 -0
  258. data/lib/cancer_registry_reporting_test_kit.rb +6 -0
  259. data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +22 -0
  260. data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +284 -0
  261. data/lib/requirements_config.yaml +22 -0
  262. metadata +341 -0
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/all'
4
+ require 'fhir_models'
5
+ require 'pathname'
6
+ require 'rubygems/package'
7
+ require 'zlib'
8
+ require_relative 'ig_resources'
9
+
10
+ module CancerRegistryReportingTestKit
11
+ class HdeaGenerator
12
+ class IGLoader
13
+ attr_accessor :ig_file_name
14
+
15
+ def initialize(ig_file_name)
16
+ self.ig_file_name = ig_file_name
17
+ end
18
+
19
+ def ig_resources
20
+ @ig_resources ||= IGResources.new
21
+ end
22
+
23
+ def load
24
+ load_ig
25
+ load_standalone_resources
26
+ end
27
+
28
+ def load_ig
29
+ tar = Gem::Package::TarReader.new(
30
+ Zlib::GzipReader.open(ig_file_name)
31
+ )
32
+
33
+ tar.each do |entry|
34
+ next if entry.directory?
35
+
36
+ file_name = entry.full_name.split('/').last
37
+
38
+ next if file_name.end_with? 'package.json'
39
+
40
+ next unless file_name.end_with? '.json'
41
+ next unless entry.full_name.start_with? 'package/'
42
+
43
+ begin
44
+ resource = FHIR.from_contents(entry.read)
45
+ next if resource.nil?
46
+ rescue StandardError
47
+ puts "#{file_name} does not appear to be a FHIR resource."
48
+ next
49
+ end
50
+
51
+ ig_resources.add(resource)
52
+ end
53
+
54
+ ig_resources
55
+ end
56
+
57
+ def load_standalone_resources
58
+ ig_directory = ig_file_name.chomp('.tgz')
59
+
60
+ return ig_resources unless File.exist? ig_directory
61
+
62
+ Dir.glob(File.join(ig_directory, '*.json')).each do |file_path|
63
+ begin
64
+ resource = FHIR.from_contents(File.read(file_path))
65
+ next if resource.nil?
66
+ rescue StandardError
67
+ file_name = file_path.split('/').last
68
+ puts "#{file_name} does not appear to be a FHIR resource (standalone)."
69
+ next
70
+ end
71
+ ig_resources.add(resource)
72
+ end
73
+
74
+ ig_resources
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'special_cases'
4
+ require 'pry'
5
+ module CancerRegistryReportingTestKit
6
+ class HdeaGenerator
7
+ class IGMetadata
8
+ attr_accessor :ig_version, :groups
9
+
10
+ def reformatted_version
11
+ @reformatted_version ||= ig_version.delete('.').gsub('-', '_')
12
+ end
13
+
14
+ def ordered_groups
15
+ @ordered_groups ||= groups
16
+ end
17
+
18
+ def to_hash
19
+ {
20
+ ig_version: ig_version,
21
+ groups: groups.map(&:to_hash)
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ig_metadata'
4
+ require_relative 'group_metadata_extractor'
5
+
6
+ module CancerRegistryReportingTestKit
7
+ class HdeaGenerator
8
+ class IGMetadataExtractor
9
+ attr_accessor :ig_resources, :metadata
10
+
11
+ def initialize(ig_resources)
12
+ self.ig_resources = ig_resources
13
+ add_missing_supported_profiles
14
+ remove_version_from_supported_profiles
15
+ self.metadata = IGMetadata.new
16
+ end
17
+
18
+ def extract
19
+ add_metadata_from_ig
20
+ add_metadata_from_resources
21
+ metadata
22
+ end
23
+
24
+ def add_metadata_from_ig
25
+ metadata.ig_version = "v#{ig_resources.ig.version}"
26
+ end
27
+
28
+ def resources_in_capability_statement
29
+ ig_resources.capability_statement.rest.first.resource
30
+ end
31
+
32
+ def resources_in_structure_definitions
33
+ ig_resources.resources_by_type['StructureDefinition'].map
34
+ end
35
+
36
+ def add_missing_supported_profiles
37
+ case ig_resources.ig.version
38
+ when '3.1.1'
39
+ # The US Core v3.1.1 Server Capability Statement does not list support for the
40
+ # required vital signs profiles, so they need to be added
41
+ ig_resources.capability_statement.rest.first.resource
42
+ .find { |resource| resource.type == 'Observation' }
43
+ .supportedProfile.concat [
44
+ 'http://hl7.org/fhir/StructureDefinition/bodyheight',
45
+ 'http://hl7.org/fhir/StructureDefinition/bodytemp',
46
+ 'http://hl7.org/fhir/StructureDefinition/bp',
47
+ 'http://hl7.org/fhir/StructureDefinition/bodyweight',
48
+ 'http://hl7.org/fhir/StructureDefinition/heartrate',
49
+ 'http://hl7.org/fhir/StructureDefinition/resprate'
50
+ ]
51
+
52
+ when '5.0.1'
53
+ # The US Core v5.0.1 Server Capability Statement does not have supported-profile for Encounter
54
+ ig_resources.capability_statement.rest.first.resource
55
+ .find { |resource| resource.type == 'Encounter' }
56
+ .supportedProfile.concat [
57
+ 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter'
58
+ ]
59
+
60
+ end
61
+ end
62
+
63
+ def remove_version_from_supported_profiles
64
+ resources_in_capability_statement.each do |resource|
65
+ resource.supportedProfile.map! { |profile_url| profile_url.split('|').first }
66
+ end
67
+ end
68
+
69
+ def add_metadata_from_resources
70
+ metadata.groups =
71
+ resources_in_structure_definitions.flat_map do |resource|
72
+ supported_profile = resource.url
73
+ GroupMetadataExtractor.new(resource, supported_profile, metadata, ig_resources).group_metadata
74
+ end.compact
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CancerRegistryReportingTestKit
4
+ class HdeaGenerator
5
+ class IGResources
6
+ def add(resource)
7
+ resources_by_type[resource.resourceType] << resource
8
+ end
9
+
10
+ def capability_statement(mode = 'server')
11
+ resources_by_type['CapabilityStatement'].find do |capability_statement_resource|
12
+ capability_statement_resource.rest.any? { |r| r.mode == mode }
13
+ end
14
+ end
15
+
16
+ def ig
17
+ resources_by_type['ImplementationGuide'].first
18
+ end
19
+
20
+ def inspect
21
+ 'IGResources'
22
+ end
23
+
24
+ def profile_by_url(url)
25
+ resources_by_type['StructureDefinition'].find { |profile| profile.url == url }
26
+ end
27
+
28
+ def resource_for_profile(url)
29
+ resources_by_type['StructureDefinition'].find { |profile| profile.url == url }.type
30
+ end
31
+
32
+ def value_set_by_url(url)
33
+ resources_by_type['ValueSet'].find { |profile| profile.url == url }
34
+ end
35
+
36
+ def code_system_by_url(url)
37
+ resources_by_type['CodeSystem'].find { |system| system.url == url }
38
+ end
39
+
40
+ def search_param_by_resource_and_name(resource, name)
41
+ # remove '_' from search parameter name, such as _id or _tag
42
+ normalized_name = name.to_s.delete_prefix('_')
43
+
44
+ resources_by_type['SearchParameter'].find do |param|
45
+ param.id == "us-core-#{resource.downcase}-#{normalized_name}" || param.name == name
46
+ end
47
+ end
48
+
49
+ # private
50
+
51
+ def resources_by_type
52
+ @resources_by_type ||= Hash.new { |hash, key| hash[key] = [] }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,399 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'value_extractor'
4
+
5
+ module CancerRegistryReportingTestKit
6
+ class HdeaGenerator
7
+ class MustSupportMetadataExtractor
8
+ attr_accessor :profile_elements, :profile, :resource, :ig_resources
9
+
10
+ def initialize(profile_elements, profile, resource, ig_resources)
11
+ self.profile_elements = profile_elements
12
+ self.profile = profile
13
+ self.resource = resource
14
+ self.ig_resources = ig_resources
15
+ end
16
+
17
+ def must_supports
18
+ @must_supports = {
19
+ extensions: must_support_extensions,
20
+ slices: must_support_slices,
21
+ elements: must_support_elements
22
+ }
23
+
24
+ @must_supports
25
+ end
26
+
27
+ def is_uscdi_requirement_element?(element)
28
+ element.extension.any? do |extension|
29
+ extension.url == 'http://hl7.org/fhir/us/core/StructureDefinition/uscdi-requirement' &&
30
+ extension.valueBoolean
31
+ end && !element.mustSupport
32
+ end
33
+
34
+ def all_must_support_elements
35
+ profile_elements.select do |element|
36
+ element.path != resource && (element.mustSupport || is_uscdi_requirement_element?(element))
37
+ end
38
+ end
39
+
40
+ def must_support_extension_elements
41
+ all_must_support_elements.select { |element| element.path.end_with? 'extension' }
42
+ end
43
+
44
+ def must_support_extensions
45
+ must_support_extension_elements.map do |element|
46
+ next unless element.type.first.profile.present?
47
+ {
48
+ id: element.id,
49
+ path: element.path.gsub("#{resource}.", ''),
50
+ url: element.type.first.profile.first
51
+ }.tap do |metadata|
52
+ metadata[:uscdi_only] = true if is_uscdi_requirement_element?(element)
53
+ end
54
+ end.compact
55
+ end
56
+
57
+ def must_support_slice_elements
58
+ all_must_support_elements.select do |element|
59
+ !element.path.end_with?('extension') && element.sliceName.present?
60
+ end
61
+ end
62
+
63
+ def sliced_element(slice)
64
+ profile_elements.find do |element|
65
+ element.id == slice.path || element.id == slice.id.sub(":#{slice.sliceName}", '')
66
+ end
67
+ end
68
+
69
+ def discriminators(slice)
70
+ slice&.slicing&.discriminator
71
+ end
72
+
73
+ def must_support_pattern_slice_elements
74
+ must_support_slice_elements.select do |element|
75
+ discriminators(sliced_element(element))&.first&.type == 'pattern'
76
+ end
77
+ end
78
+
79
+ def pattern_slices
80
+ must_support_pattern_slice_elements.map do |current_element|
81
+ {
82
+ slice_id: current_element.id,
83
+ slice_name: current_element.sliceName,
84
+ path: current_element.path.gsub("#{resource}.", '')
85
+ }.tap do |metadata|
86
+ discriminator = discriminators(sliced_element(current_element)).first
87
+ discriminator_path = discriminator.path
88
+ discriminator_path = '' if discriminator_path == '$this'
89
+ pattern_element =
90
+ if discriminator_path.present?
91
+ profile_elements.find { |element| element.id == "#{current_element.id}.#{discriminator_path}" }
92
+ else
93
+ current_element
94
+ end
95
+ metadata[:discriminator] =
96
+ if pattern_element.patternCodeableConcept.present?
97
+ {
98
+ type: 'patternCodeableConcept',
99
+ path: discriminator_path,
100
+ code: pattern_element.patternCodeableConcept.coding.first.code,
101
+ system: pattern_element.patternCodeableConcept.coding.first.system
102
+ }
103
+ elsif pattern_element.patternCoding.present?
104
+ {
105
+ type: 'patternCoding',
106
+ path: discriminator_path,
107
+ code: pattern_element.patternCoding.code,
108
+ system: pattern_element.patternCoding.system
109
+ }
110
+ elsif pattern_element.patternIdentifier.present?
111
+ {
112
+ type: 'patternIdentifier',
113
+ path: discriminator_path,
114
+ system: pattern_element.patternIdentifier.system
115
+ }
116
+ elsif pattern_element.binding&.strength == 'required' &&
117
+ pattern_element.binding&.valueSet.present?
118
+
119
+ value_extractor = ValueExactor.new(ig_resources, resource, profile_elements)
120
+
121
+ values = value_extractor.codings_from_value_set_binding(pattern_element).presence ||
122
+ value_extractor.values_from_resource_metadata([metadata[:path]]).presence || []
123
+
124
+ {
125
+ type: 'requiredBinding',
126
+ path: discriminator_path,
127
+ values: values
128
+ }
129
+ else
130
+ raise StandardError, 'Unsupported discriminator pattern type'
131
+ end
132
+
133
+ metadata[:uscdi_only] = true if is_uscdi_requirement_element?(current_element)
134
+ end
135
+ end
136
+ end
137
+
138
+ def must_support_type_slice_elements
139
+ must_support_slice_elements.select do |element|
140
+ discriminators(sliced_element(element))&.first&.type == 'type'
141
+ end
142
+ end
143
+
144
+ def type_slices
145
+ must_support_type_slice_elements.map do |current_element|
146
+ discriminator = discriminators(sliced_element(current_element)).first
147
+ type_path = discriminator.path
148
+ type_path = '' if type_path == '$this'
149
+ type_element =
150
+ if type_path.present?
151
+ profile_elements.find { |element| element.id == "#{current_element.id}.#{type_path}" }
152
+ else
153
+ current_element
154
+ end
155
+
156
+ type_code = type_element.type.first.code
157
+
158
+ {
159
+ slice_id: current_element.id,
160
+ slice_name: current_element.sliceName,
161
+ path: current_element.path.gsub("#{resource}.", ''),
162
+ discriminator: {
163
+ type: 'type',
164
+ code: type_code.upcase_first
165
+ }
166
+ }.tap do |metadata|
167
+ metadata[:uscdi_only] = true if is_uscdi_requirement_element?(current_element)
168
+ end
169
+ end
170
+ end
171
+
172
+ def must_support_value_slice_elements
173
+ must_support_slice_elements.select do |element|
174
+ discriminators(sliced_element(element))&.first&.type == 'value'
175
+ end
176
+ end
177
+
178
+ def value_slices
179
+ must_support_value_slice_elements.map do |current_element|
180
+ {
181
+ slice_id: current_element.id,
182
+ slice_name: current_element.sliceName,
183
+ path: current_element.path.gsub("#{resource}.", ''),
184
+ discriminator: {
185
+ type: 'value'
186
+ }
187
+ }.tap do |metadata|
188
+ metadata[:discriminator][:values] = discriminators(sliced_element(current_element)).map do |discriminator|
189
+ fixed_element = profile_elements.find do |element|
190
+ element.id.starts_with?(current_element.id) &&
191
+ element.path == "#{current_element.path}.#{discriminator.path}"
192
+ end
193
+
194
+ if fixed_element.patternCodeableConcept.present?
195
+ code_value = fixed_element.patternCodeableConcept.coding.first.code
196
+ {
197
+ path: "#{discriminator.path}.coding.code",
198
+ value: code_value !~ /\D/ ? code_value.to_i : code_value
199
+ }
200
+ else
201
+ {
202
+ path: discriminator.path,
203
+ value: fixed_element.fixedUri || fixed_element.fixedCode
204
+ }
205
+ end
206
+
207
+ end
208
+
209
+ metadata[:uscdi_only] = true if is_uscdi_requirement_element?(current_element)
210
+ end
211
+ end
212
+ end
213
+
214
+ def must_support_slices
215
+ pattern_slices + type_slices + value_slices
216
+ end
217
+
218
+ def plain_must_support_elements
219
+ all_must_support_elements - must_support_extension_elements - must_support_slice_elements
220
+ end
221
+
222
+ def element_part_of_slice_discrimination?(element)
223
+ must_support_slice_elements.any? { |ms_slice| element.id.include?(ms_slice.id) }
224
+ end
225
+
226
+ def handle_fixed_values(metadata, element)
227
+ if element.fixedUri.present?
228
+ metadata[:fixed_value] = element.fixedUri
229
+ elsif element.patternCodeableConcept.present? && !element_part_of_slice_discrimination?(element)
230
+ metadata[:fixed_value] = element.patternCodeableConcept.coding.first.code
231
+ metadata[:path] += '.coding.code'
232
+ elsif element.fixedCode.present?
233
+ metadata[:fixed_value] = element.fixedCode
234
+ elsif element.patternIdentifier.present? && !element_part_of_slice_discrimination?(element)
235
+ metadata[:fixed_value] = element.patternIdentifier.system
236
+ metadata[:path] += '.system'
237
+ end
238
+ end
239
+
240
+ def type_must_support_extension?(extensions)
241
+ extensions&.any? do |extension|
242
+ extension.url == 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support' &&
243
+ extension.valueBoolean
244
+ end
245
+ end
246
+
247
+ def save_type_code?(type)
248
+ type.code == 'Reference'
249
+ end
250
+
251
+ def get_type_must_support_metadata(current_metadata, current_element)
252
+ current_element.type.map do |type|
253
+ next unless type_must_support_extension?(type.extension)
254
+
255
+ metadata =
256
+ {
257
+ path: "#{current_metadata[:path].delete_suffix('[x]')}#{type.code.upcase_first}",
258
+ original_path: current_metadata[:path]
259
+ }
260
+ metadata[:types] = [type.code] if save_type_code?(type)
261
+ handle_type_must_support_target_profiles(type, metadata) if type.code == 'Reference'
262
+
263
+ metadata
264
+ end.compact
265
+ end
266
+
267
+ def handle_type_must_support_target_profiles(type, metadata)
268
+ # US Core 3.1.1 profiles do not have US Core target profiles.
269
+ # Vital Sign proifles from FHIR R4 (version 4.0.1) do not have US Core target profiles either.
270
+ return if ['3.1.1', '4.0.1'].include?(profile.version)
271
+
272
+ target_profiles = []
273
+
274
+ if type.targetProfile&.length == 1
275
+ target_profiles << type.targetProfile.first
276
+ else
277
+ type.source_hash['_targetProfile']&.each_with_index do |hash, index|
278
+ if hash.present?
279
+ element = FHIR::Element.new(hash)
280
+ target_profiles << type.targetProfile[index] if type_must_support_extension?(element.extension)
281
+ end
282
+ end
283
+ end
284
+
285
+ # remove target_profile for FHIR Base resource type.
286
+ target_profiles.delete_if { |reference| reference.start_with?('http://hl7.org/fhir/StructureDefinition') }
287
+ metadata[:target_profiles] = target_profiles if target_profiles.present?
288
+ end
289
+
290
+ def handle_choice_type_in_sliced_element(current_metadata, must_support_elements_metadata)
291
+ choice_element_metadata = must_support_elements_metadata.find do |metadata|
292
+ metadata[:original_path].present? &&
293
+ current_metadata[:path].include?(metadata[:original_path])
294
+ end
295
+
296
+ return unless choice_element_metadata.present?
297
+
298
+ current_metadata[:original_path] = current_metadata[:path]
299
+ current_metadata[:path] =
300
+ current_metadata[:path].sub(choice_element_metadata[:original_path], choice_element_metadata[:path])
301
+ end
302
+
303
+ def must_support_elements
304
+ plain_must_support_elements.each_with_object([]) do |current_element, must_support_elements_metadata|
305
+ {
306
+ path: current_element.id.gsub("#{resource}.", '')
307
+ }.tap do |current_metadata|
308
+ current_metadata[:uscdi_only] = true if is_uscdi_requirement_element?(current_element)
309
+
310
+ type_must_support_metadata = get_type_must_support_metadata(current_metadata, current_element)
311
+
312
+ if type_must_support_metadata.any?
313
+ must_support_elements_metadata.concat(type_must_support_metadata)
314
+ else
315
+ handle_choice_type_in_sliced_element(current_metadata, must_support_elements_metadata)
316
+
317
+ supported_types = current_element.type.select { |type| save_type_code?(type) }.map(&:code)
318
+ current_metadata[:types] = supported_types if supported_types.present?
319
+
320
+ if current_element.type.first&.code == 'Reference'
321
+ handle_type_must_support_target_profiles(current_element.type.first,
322
+ current_metadata)
323
+ end
324
+
325
+ handle_fixed_values(current_metadata, current_element)
326
+
327
+ must_support_elements_metadata.delete_if do |metadata|
328
+ metadata[:path] == current_metadata[:path] && metadata[:fixed_value].blank?
329
+ end
330
+
331
+ must_support_elements_metadata << current_metadata
332
+ end
333
+ end
334
+ end.uniq
335
+ end
336
+
337
+ #### SPECIAL CASE ####
338
+
339
+ def is_vital_sign?
340
+ [
341
+ 'http://hl7.org/fhir/StructureDefinition/vitalsigns',
342
+ 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-vital-signs'
343
+ ].include?(profile.baseDefinition)
344
+ end
345
+
346
+ def is_blood_pressure?
347
+ %w[bp us-core-blood-pressure us-core-average-blood-pressure].include?(profile.id)
348
+ end
349
+
350
+ # Exclude Observation.component from vital sign profiles except observation-bp and observation-pulse-ox
351
+ def remove_vital_sign_component
352
+ return if is_blood_pressure? || profile.name == 'USCorePulseOximetryProfile'
353
+
354
+ return unless is_vital_sign?
355
+
356
+ @must_supports[:elements].delete_if do |element|
357
+ element[:path].start_with?('component')
358
+ end
359
+ end
360
+
361
+ # Exclude Observation.value[x] from observation-bp
362
+ def remove_blood_pressure_value_data_absent_reason
363
+ return unless is_blood_pressure?
364
+
365
+ pattern = /component(:[^.]+)?\.dataAbsentReason/
366
+
367
+ @must_supports[:elements].delete_if do |element|
368
+ element[:path].start_with?('value[x]') ||
369
+ element[:original_path]&.start_with?('value[x]') ||
370
+ element[:path] == ('dataAbsentReason') ||
371
+ (
372
+ pattern.match?(element[:path]) && ['3.1.1', '4.0.0'].include?(ig_resources.ig.version)
373
+ )
374
+ end
375
+
376
+ @must_supports[:slices].delete_if do |slice|
377
+ slice[:path].start_with?('value[x]')
378
+ end
379
+ end
380
+
381
+ # ONC and US Core 4.0.0 both clarified that health IT developers that always provide HL7 FHIR "observation" values
382
+ # are not required to demonstrate Health IT Module support for "dataAbsentReason" elements.
383
+ # Remove MS check for dataAbsentReason and component.dataAbsentReason from vital sign profiles and observation lab profile
384
+ # Smoking status profile does not have MS on dataAbsentReason. It is safe to use profile.type == 'Observation'
385
+ # Since US Core 5.0.1, Blood Pressure profile restores component.dataAbsentReason as MustSupport.
386
+ def remove_observation_data_absent_reason
387
+ return if is_blood_pressure?
388
+
389
+ pattern = /(component(:[^.]+)?\.)?dataAbsentReason/
390
+
391
+ return unless profile.type == 'Observation'
392
+
393
+ @must_supports[:elements].delete_if do |element|
394
+ pattern.match?(element[:path])
395
+ end
396
+ end
397
+ end
398
+ end
399
+ end