endoreg-db 0.8.9.32__py3-none-any.whl

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.

Potentially problematic release.


This version of endoreg-db might be problematic. Click here for more details.

Files changed (787) hide show
  1. endoreg_db/__init__.py +0 -0
  2. endoreg_db/_version.py +34 -0
  3. endoreg_db/admin.py +97 -0
  4. endoreg_db/api/serializers/finding_descriptions.py +0 -0
  5. endoreg_db/api/views/finding_descriptions.py +0 -0
  6. endoreg_db/api_urls.py +4 -0
  7. endoreg_db/apps.py +17 -0
  8. endoreg_db/assets/dummy_model.ckpt +1 -0
  9. endoreg_db/authz/auth.py +78 -0
  10. endoreg_db/authz/backends.py +168 -0
  11. endoreg_db/authz/management/commands/list_routes.py +20 -0
  12. endoreg_db/authz/middleware.py +84 -0
  13. endoreg_db/authz/permissions.py +138 -0
  14. endoreg_db/authz/policy.py +224 -0
  15. endoreg_db/authz/settings.py +64 -0
  16. endoreg_db/authz/views_auth.py +70 -0
  17. endoreg_db/codemods/readme.md +88 -0
  18. endoreg_db/codemods/rename_datetime_fields.py +99 -0
  19. endoreg_db/config/__init__.py +0 -0
  20. endoreg_db/config/env.py +106 -0
  21. endoreg_db/config/settings/__init__.py +6 -0
  22. endoreg_db/config/settings/base.py +148 -0
  23. endoreg_db/config/settings/case_gen.py +32 -0
  24. endoreg_db/config/settings/dev.py +108 -0
  25. endoreg_db/config/settings/keycloak.py +177 -0
  26. endoreg_db/config/settings/prod.py +66 -0
  27. endoreg_db/config/settings/test.py +72 -0
  28. endoreg_db/data/__init__.py +135 -0
  29. endoreg_db/data/ai_model/data.yaml +7 -0
  30. endoreg_db/data/ai_model_label/label/data.yaml +88 -0
  31. endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
  32. endoreg_db/data/ai_model_label/label-set/data.yaml +40 -0
  33. endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
  34. endoreg_db/data/ai_model_label/label-type/data.yaml +7 -0
  35. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +27 -0
  36. endoreg_db/data/ai_model_type/data.yaml +7 -0
  37. endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
  38. endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
  39. endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
  40. endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
  41. endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
  42. endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
  43. endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
  44. endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
  45. endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
  46. endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
  47. endoreg_db/data/case_template/rule_value/.init +0 -0
  48. endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
  49. endoreg_db/data/case_template/template/base.yaml +8 -0
  50. endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
  51. endoreg_db/data/case_template/tmp/_rule_value +13 -0
  52. endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
  53. endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
  54. endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
  55. endoreg_db/data/center/data.yaml +99 -0
  56. endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
  57. endoreg_db/data/center_shift/ukw.yaml +9 -0
  58. endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
  59. endoreg_db/data/contraindication/bleeding.yaml +11 -0
  60. endoreg_db/data/db_summary.csv +58 -0
  61. endoreg_db/data/db_summary.xlsx +0 -0
  62. endoreg_db/data/disease/cardiovascular.yaml +37 -0
  63. endoreg_db/data/disease/hepatology.yaml +5 -0
  64. endoreg_db/data/disease/misc.yaml +5 -0
  65. endoreg_db/data/disease/renal.yaml +5 -0
  66. endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
  67. endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
  68. endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
  69. endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
  70. endoreg_db/data/distribution/date/patient.yaml +7 -0
  71. endoreg_db/data/distribution/multiple_categorical/.init +0 -0
  72. endoreg_db/data/distribution/numeric/data.yaml +14 -0
  73. endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
  74. endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
  75. endoreg_db/data/endoscope/data.yaml +93 -0
  76. endoreg_db/data/endoscope_type/data.yaml +11 -0
  77. endoreg_db/data/endoscopy_processor/data.yaml +50 -0
  78. endoreg_db/data/event/cardiology.yaml +15 -0
  79. endoreg_db/data/event/neurology.yaml +14 -0
  80. endoreg_db/data/event/surgery.yaml +13 -0
  81. endoreg_db/data/event/thrombembolism.yaml +20 -0
  82. endoreg_db/data/event_classification/data.yaml +4 -0
  83. endoreg_db/data/event_classification_choice/data.yaml +9 -0
  84. endoreg_db/data/examination/examinations/data.yaml +172 -0
  85. endoreg_db/data/examination/time/data.yaml +48 -0
  86. endoreg_db/data/examination/time-type/data.yaml +5 -0
  87. endoreg_db/data/examination/type/data.yaml +17 -0
  88. endoreg_db/data/examination_indication/endoscopy.yaml +359 -0
  89. endoreg_db/data/examination_indication_classification/endoscopy.yaml +90 -0
  90. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +97 -0
  91. endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
  92. endoreg_db/data/finding/00_generic.yaml +35 -0
  93. endoreg_db/data/finding/00_generic_complication.yaml +9 -0
  94. endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
  95. endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
  96. endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
  97. endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
  98. endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
  99. endoreg_db/data/finding_classification/00_generic.yaml +44 -0
  100. endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
  101. endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
  102. endoreg_db/data/finding_classification/02_colonoscopy_baseline.yaml +83 -0
  103. endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
  104. endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
  105. endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
  106. endoreg_db/data/finding_classification_choice/00_generic.yaml +15 -0
  107. endoreg_db/data/finding_classification_choice/00_generic_baseline.yaml +23 -0
  108. endoreg_db/data/finding_classification_choice/00_generic_complication.yaml +15 -0
  109. endoreg_db/data/finding_classification_choice/00_generic_histology.yaml +21 -0
  110. endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
  111. endoreg_db/data/finding_classification_choice/02_colonoscopy_bowel_preparation.yaml +49 -0
  112. endoreg_db/data/finding_classification_choice/02_colonoscopy_generic.yaml +19 -0
  113. endoreg_db/data/finding_classification_choice/02_colonoscopy_histology.yaml +20 -0
  114. endoreg_db/data/finding_classification_choice/02_colonoscopy_location.yaml +248 -0
  115. endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
  116. endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
  117. endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_morphology.yaml +75 -0
  118. endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
  119. endoreg_db/data/finding_classification_type/00_generic.yaml +53 -0
  120. endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
  121. endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
  122. endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
  123. endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
  124. endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
  125. endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
  126. endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
  127. endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
  128. endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
  129. endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
  130. endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
  131. endoreg_db/data/finding_type/data.yaml +39 -0
  132. endoreg_db/data/gender/data.yaml +42 -0
  133. endoreg_db/data/information_source/annotation.yaml +6 -0
  134. endoreg_db/data/information_source/data.yaml +30 -0
  135. endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
  136. endoreg_db/data/information_source/medication.yaml +6 -0
  137. endoreg_db/data/information_source/prediction.yaml +7 -0
  138. endoreg_db/data/information_source_type/data.yaml +8 -0
  139. endoreg_db/data/lab_value/cardiac_enzymes.yaml +37 -0
  140. endoreg_db/data/lab_value/coagulation.yaml +54 -0
  141. endoreg_db/data/lab_value/electrolytes.yaml +228 -0
  142. endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -0
  143. endoreg_db/data/lab_value/hematology.yaml +184 -0
  144. endoreg_db/data/lab_value/hormones.yaml +59 -0
  145. endoreg_db/data/lab_value/lipids.yaml +53 -0
  146. endoreg_db/data/lab_value/misc.yaml +76 -0
  147. endoreg_db/data/lab_value/renal_function.yaml +12 -0
  148. endoreg_db/data/log_type/data.yaml +57 -0
  149. endoreg_db/data/lx_client_tag/base.yaml +54 -0
  150. endoreg_db/data/lx_client_type/base.yaml +30 -0
  151. endoreg_db/data/lx_permission/base.yaml +24 -0
  152. endoreg_db/data/lx_permission/endoreg.yaml +52 -0
  153. endoreg_db/data/material/material.yaml +91 -0
  154. endoreg_db/data/medication/anticoagulation.yaml +65 -0
  155. endoreg_db/data/medication/tah.yaml +70 -0
  156. endoreg_db/data/medication_indication/anticoagulation.yaml +115 -0
  157. endoreg_db/data/medication_indication_type/data.yaml +11 -0
  158. endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
  159. endoreg_db/data/medication_intake_time/base.yaml +31 -0
  160. endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
  161. endoreg_db/data/medication_schedule/ass.yaml +12 -0
  162. endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
  163. endoreg_db/data/names_first/first_names.yaml +54 -0
  164. endoreg_db/data/names_last/last_names.yaml +51 -0
  165. endoreg_db/data/network_device/data.yaml +59 -0
  166. endoreg_db/data/network_device_type/data.yaml +12 -0
  167. endoreg_db/data/organ/data.yaml +29 -0
  168. endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
  169. endoreg_db/data/pdf_type/data.yaml +46 -0
  170. endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
  171. endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
  172. endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
  173. endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
  174. endoreg_db/data/profession/data.yaml +70 -0
  175. endoreg_db/data/qualification/endoscopy.yaml +36 -0
  176. endoreg_db/data/qualification/m2.yaml +39 -0
  177. endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
  178. endoreg_db/data/qualification/sonography.yaml +36 -0
  179. endoreg_db/data/qualification_type/base.yaml +29 -0
  180. endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
  181. endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
  182. endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -0
  183. endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +24 -0
  184. endoreg_db/data/requirement/01_patient_data.yaml +93 -0
  185. endoreg_db/data/requirement/old/colon_polyp_intervention.yaml +49 -0
  186. endoreg_db/data/requirement/old/colonoscopy_baseline_austria.yaml +45 -0
  187. endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
  188. endoreg_db/data/requirement/old/disease_cardiovascular.yaml +79 -0
  189. endoreg_db/data/requirement/old/disease_classification_choice_cardiovascular.yaml +41 -0
  190. endoreg_db/data/requirement/old/disease_hepatology.yaml +12 -0
  191. endoreg_db/data/requirement/old/disease_misc.yaml +12 -0
  192. endoreg_db/data/requirement/old/disease_renal.yaml +96 -0
  193. endoreg_db/data/requirement/old/endoscopy_bleeding_risk.yaml +59 -0
  194. endoreg_db/data/requirement/old/event_cardiology.yaml +251 -0
  195. endoreg_db/data/requirement/old/event_requirements.yaml +145 -0
  196. endoreg_db/data/requirement/old/finding_colon_polyp.yaml +50 -0
  197. endoreg_db/data/requirement/old/gender.yaml +0 -0
  198. endoreg_db/data/requirement/old/lab_value.yaml +441 -0
  199. endoreg_db/data/requirement/old/medication.yaml +93 -0
  200. endoreg_db/data/requirement_operator/_old/age.yaml +13 -0
  201. endoreg_db/data/requirement_operator/_old/lab_operators.yaml +129 -0
  202. endoreg_db/data/requirement_operator/_old/model_operators.yaml +96 -0
  203. endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
  204. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +65 -0
  205. endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
  206. endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
  207. endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
  208. endoreg_db/data/requirement_set/_old_ +109 -0
  209. endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
  210. endoreg_db/data/requirement_set_type/data.yaml +41 -0
  211. endoreg_db/data/requirement_type/requirement_types.yaml +165 -0
  212. endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
  213. endoreg_db/data/risk/bleeding.yaml +26 -0
  214. endoreg_db/data/risk/thrombosis.yaml +37 -0
  215. endoreg_db/data/risk_type/data.yaml +27 -0
  216. endoreg_db/data/setup_config.yaml +38 -0
  217. endoreg_db/data/shift/endoscopy.yaml +21 -0
  218. endoreg_db/data/shift/m2.yaml +0 -0
  219. endoreg_db/data/shift_type/base.yaml +35 -0
  220. endoreg_db/data/tag/requirement_set_tags.yaml +32 -0
  221. endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
  222. endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
  223. endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
  224. endoreg_db/data/unit/concentration.yaml +115 -0
  225. endoreg_db/data/unit/data.yaml +17 -0
  226. endoreg_db/data/unit/length.yaml +31 -0
  227. endoreg_db/data/unit/misc.yaml +20 -0
  228. endoreg_db/data/unit/rate.yaml +6 -0
  229. endoreg_db/data/unit/time.yaml +48 -0
  230. endoreg_db/data/unit/volume.yaml +35 -0
  231. endoreg_db/data/unit/weight.yaml +38 -0
  232. endoreg_db/data/waste/data.yaml +12 -0
  233. endoreg_db/exceptions.py +24 -0
  234. endoreg_db/export/frames/export.py +6 -0
  235. endoreg_db/export/frames/export_frames_with_labels.py +616 -0
  236. endoreg_db/factories/__init__.py +0 -0
  237. endoreg_db/forms/__init__.py +4 -0
  238. endoreg_db/forms/examination_form.py +12 -0
  239. endoreg_db/forms/patient_finding_intervention_form.py +40 -0
  240. endoreg_db/forms/patient_form.py +23 -0
  241. endoreg_db/forms/questionnaires/__init__.py +1 -0
  242. endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
  243. endoreg_db/forms/settings/__init__.py +11 -0
  244. endoreg_db/forms/unit.py +7 -0
  245. endoreg_db/helpers/__init__.py +0 -0
  246. endoreg_db/helpers/count_db.py +48 -0
  247. endoreg_db/helpers/data_loader.py +280 -0
  248. endoreg_db/helpers/default_objects.py +414 -0
  249. endoreg_db/helpers/download_segmentation_model.py +32 -0
  250. endoreg_db/helpers/interact.py +1 -0
  251. endoreg_db/helpers/test_video_helper.py +127 -0
  252. endoreg_db/import_files/__init__.py +27 -0
  253. endoreg_db/import_files/context/__init__.py +7 -0
  254. endoreg_db/import_files/context/default_sensitive_meta.py +83 -0
  255. endoreg_db/import_files/context/ensure_center.py +17 -0
  256. endoreg_db/import_files/context/file_lock.py +66 -0
  257. endoreg_db/import_files/context/import_context.py +42 -0
  258. endoreg_db/import_files/context/validate_directories.py +57 -0
  259. endoreg_db/import_files/file_storage/__init__.py +15 -0
  260. endoreg_db/import_files/file_storage/create_report_file.py +99 -0
  261. endoreg_db/import_files/file_storage/create_video_file.py +104 -0
  262. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +42 -0
  263. endoreg_db/import_files/file_storage/state_management.py +463 -0
  264. endoreg_db/import_files/file_storage/storage.py +42 -0
  265. endoreg_db/import_files/import_service.md +26 -0
  266. endoreg_db/import_files/processing/__init__.py +11 -0
  267. endoreg_db/import_files/processing/report_processing/report_anonymization.py +99 -0
  268. endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
  269. endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
  270. endoreg_db/import_files/pseudonymization/__init__.py +0 -0
  271. endoreg_db/import_files/pseudonymization/fake.py +52 -0
  272. endoreg_db/import_files/pseudonymization/k_anonymity.py +181 -0
  273. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +139 -0
  274. endoreg_db/import_files/pseudonymization/pseudonymize.py +0 -0
  275. endoreg_db/import_files/report_import_service.py +147 -0
  276. endoreg_db/import_files/video_import_service.py +154 -0
  277. endoreg_db/logger_conf.py +156 -0
  278. endoreg_db/management/__init__.py +1 -0
  279. endoreg_db/management/commands/__init__.py +1 -0
  280. endoreg_db/management/commands/anonymize_video.py +0 -0
  281. endoreg_db/management/commands/check_auth.py +132 -0
  282. endoreg_db/management/commands/create_model_meta_from_huggingface.py +177 -0
  283. endoreg_db/management/commands/create_multilabel_model_meta.py +419 -0
  284. endoreg_db/management/commands/export_frame_annot.py +196 -0
  285. endoreg_db/management/commands/fix_missing_patient_data.py +206 -0
  286. endoreg_db/management/commands/fix_video_paths.py +186 -0
  287. endoreg_db/management/commands/import_report.py +361 -0
  288. endoreg_db/management/commands/list_routes.py +20 -0
  289. endoreg_db/management/commands/load_ai_model_data.py +83 -0
  290. endoreg_db/management/commands/load_ai_model_label_data.py +60 -0
  291. endoreg_db/management/commands/load_base_db_data.py +63 -0
  292. endoreg_db/management/commands/load_center_data.py +68 -0
  293. endoreg_db/management/commands/load_contraindication_data.py +39 -0
  294. endoreg_db/management/commands/load_disease_classification_choices_data.py +38 -0
  295. endoreg_db/management/commands/load_disease_classification_data.py +38 -0
  296. endoreg_db/management/commands/load_disease_data.py +59 -0
  297. endoreg_db/management/commands/load_distribution_data.py +63 -0
  298. endoreg_db/management/commands/load_endoscope_data.py +58 -0
  299. endoreg_db/management/commands/load_event_data.py +39 -0
  300. endoreg_db/management/commands/load_examination_data.py +78 -0
  301. endoreg_db/management/commands/load_examination_indication_data.py +85 -0
  302. endoreg_db/management/commands/load_finding_data.py +115 -0
  303. endoreg_db/management/commands/load_gender_data.py +37 -0
  304. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +142 -0
  305. endoreg_db/management/commands/load_information_source.py +46 -0
  306. endoreg_db/management/commands/load_lab_value_data.py +52 -0
  307. endoreg_db/management/commands/load_legacy_data.py +303 -0
  308. endoreg_db/management/commands/load_medication_data.py +104 -0
  309. endoreg_db/management/commands/load_name_data.py +36 -0
  310. endoreg_db/management/commands/load_organ_data.py +39 -0
  311. endoreg_db/management/commands/load_pdf_type_data.py +58 -0
  312. endoreg_db/management/commands/load_profession_data.py +40 -0
  313. endoreg_db/management/commands/load_qualification_data.py +56 -0
  314. endoreg_db/management/commands/load_report_reader_flag_data.py +40 -0
  315. endoreg_db/management/commands/load_requirement_data.py +207 -0
  316. endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
  317. endoreg_db/management/commands/load_risk_data.py +57 -0
  318. endoreg_db/management/commands/load_shift_data.py +57 -0
  319. endoreg_db/management/commands/load_tag_data.py +54 -0
  320. endoreg_db/management/commands/load_unit_data.py +40 -0
  321. endoreg_db/management/commands/load_user_groups.py +26 -0
  322. endoreg_db/management/commands/model_input.py +169 -0
  323. endoreg_db/management/commands/register_ai_model.py +70 -0
  324. endoreg_db/management/commands/setup_endoreg_db.py +459 -0
  325. endoreg_db/management/commands/start_filewatcher.py +115 -0
  326. endoreg_db/management/commands/storage_management.py +622 -0
  327. endoreg_db/management/commands/summarize_db_content.py +280 -0
  328. endoreg_db/management/commands/train_image_multilabel_model.py +144 -0
  329. endoreg_db/management/commands/validate_video_files.py +189 -0
  330. endoreg_db/management/commands/video_validation.py +20 -0
  331. endoreg_db/mermaid/Overall_flow_patient_finding_intervention.md +10 -0
  332. endoreg_db/mermaid/anonymized_image_annotation.md +20 -0
  333. endoreg_db/mermaid/binary_classification_annotation.md +50 -0
  334. endoreg_db/mermaid/classification.md +8 -0
  335. endoreg_db/mermaid/examination.md +8 -0
  336. endoreg_db/mermaid/findings.md +7 -0
  337. endoreg_db/mermaid/image_classification.md +28 -0
  338. endoreg_db/mermaid/interventions.md +8 -0
  339. endoreg_db/mermaid/morphology.md +8 -0
  340. endoreg_db/mermaid/patient_creation.md +14 -0
  341. endoreg_db/mermaid/video_segmentation_annotation.md +17 -0
  342. endoreg_db/migrations/0001_initial.py +1953 -0
  343. endoreg_db/migrations/__init__.py +0 -0
  344. endoreg_db/models/__init__.py +322 -0
  345. endoreg_db/models/administration/__init__.py +95 -0
  346. endoreg_db/models/administration/ai/__init__.py +9 -0
  347. endoreg_db/models/administration/ai/active_model.py +35 -0
  348. endoreg_db/models/administration/ai/ai_model.py +180 -0
  349. endoreg_db/models/administration/ai/model_type.py +42 -0
  350. endoreg_db/models/administration/case/__init__.py +5 -0
  351. endoreg_db/models/administration/case/case.py +114 -0
  352. endoreg_db/models/administration/case/case_template/__init__.py +3 -0
  353. endoreg_db/models/administration/case/case_template/case_template.py +3 -0
  354. endoreg_db/models/administration/case/case_template/case_template_rule.py +3 -0
  355. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +3 -0
  356. endoreg_db/models/administration/case/case_template/case_template_type.py +3 -0
  357. endoreg_db/models/administration/center/__init__.py +13 -0
  358. endoreg_db/models/administration/center/center.py +85 -0
  359. endoreg_db/models/administration/center/center_product.py +67 -0
  360. endoreg_db/models/administration/center/center_resource.py +69 -0
  361. endoreg_db/models/administration/center/center_shift.py +94 -0
  362. endoreg_db/models/administration/center/center_waste.py +42 -0
  363. endoreg_db/models/administration/person/__init__.py +26 -0
  364. endoreg_db/models/administration/person/employee/__init__.py +3 -0
  365. endoreg_db/models/administration/person/employee/employee.py +40 -0
  366. endoreg_db/models/administration/person/employee/employee_qualification.py +44 -0
  367. endoreg_db/models/administration/person/employee/employee_type.py +50 -0
  368. endoreg_db/models/administration/person/examiner/__init__.py +4 -0
  369. endoreg_db/models/administration/person/examiner/examiner.py +64 -0
  370. endoreg_db/models/administration/person/names/__init__.py +0 -0
  371. endoreg_db/models/administration/person/names/first_name.py +20 -0
  372. endoreg_db/models/administration/person/names/last_name.py +20 -0
  373. endoreg_db/models/administration/person/patient/__init__.py +7 -0
  374. endoreg_db/models/administration/person/patient/patient.py +488 -0
  375. endoreg_db/models/administration/person/patient/patient_external_id.py +36 -0
  376. endoreg_db/models/administration/person/person.py +35 -0
  377. endoreg_db/models/administration/person/profession/__init__.py +28 -0
  378. endoreg_db/models/administration/person/user/__init__.py +5 -0
  379. endoreg_db/models/administration/person/user/portal_user_information.py +41 -0
  380. endoreg_db/models/administration/product/__init__.py +15 -0
  381. endoreg_db/models/administration/product/product.py +106 -0
  382. endoreg_db/models/administration/product/product_group.py +41 -0
  383. endoreg_db/models/administration/product/product_material.py +60 -0
  384. endoreg_db/models/administration/product/product_weight.py +51 -0
  385. endoreg_db/models/administration/product/reference_product.py +147 -0
  386. endoreg_db/models/administration/qualification/__init__.py +7 -0
  387. endoreg_db/models/administration/qualification/qualification.py +43 -0
  388. endoreg_db/models/administration/qualification/qualification_type.py +39 -0
  389. endoreg_db/models/administration/shift/__init__.py +9 -0
  390. endoreg_db/models/administration/shift/scheduled_days.py +72 -0
  391. endoreg_db/models/administration/shift/shift.py +57 -0
  392. endoreg_db/models/administration/shift/shift_type.py +108 -0
  393. endoreg_db/models/aidataset/__init__.py +5 -0
  394. endoreg_db/models/aidataset/aidataset.py +193 -0
  395. endoreg_db/models/label/__init__.py +23 -0
  396. endoreg_db/models/label/annotation/__init__.py +12 -0
  397. endoreg_db/models/label/annotation/image_classification.py +85 -0
  398. endoreg_db/models/label/annotation/video_segmentation_annotation.py +61 -0
  399. endoreg_db/models/label/label.py +91 -0
  400. endoreg_db/models/label/label_set.py +68 -0
  401. endoreg_db/models/label/label_type.py +29 -0
  402. endoreg_db/models/label/label_video_segment/__init__.py +3 -0
  403. endoreg_db/models/label/label_video_segment/_create_from_video.py +42 -0
  404. endoreg_db/models/label/label_video_segment/label_video_segment.py +611 -0
  405. endoreg_db/models/label/video_segmentation_label.py +35 -0
  406. endoreg_db/models/label/video_segmentation_labelset.py +28 -0
  407. endoreg_db/models/media/__init__.py +23 -0
  408. endoreg_db/models/media/frame/__init__.py +3 -0
  409. endoreg_db/models/media/frame/frame.py +137 -0
  410. endoreg_db/models/media/pdf/__init__.py +12 -0
  411. endoreg_db/models/media/pdf/raw_pdf.py +764 -0
  412. endoreg_db/models/media/pdf/report_file.py +162 -0
  413. endoreg_db/models/media/pdf/report_reader/__init__.py +7 -0
  414. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +85 -0
  415. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +46 -0
  416. endoreg_db/models/media/video/__init__.py +9 -0
  417. endoreg_db/models/media/video/create_from_file.py +402 -0
  418. endoreg_db/models/media/video/pipe_1.py +258 -0
  419. endoreg_db/models/media/video/pipe_2.py +129 -0
  420. endoreg_db/models/media/video/video_file.py +907 -0
  421. endoreg_db/models/media/video/video_file_ai.py +828 -0
  422. endoreg_db/models/media/video/video_file_anonymize.py +524 -0
  423. endoreg_db/models/media/video/video_file_frames/__init__.py +49 -0
  424. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +25 -0
  425. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
  426. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +126 -0
  427. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +233 -0
  428. endoreg_db/models/media/video/video_file_frames/_get_frame.py +36 -0
  429. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +13 -0
  430. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +24 -0
  431. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +40 -0
  432. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +44 -0
  433. endoreg_db/models/media/video/video_file_frames/_get_frames.py +30 -0
  434. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +205 -0
  435. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +228 -0
  436. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +107 -0
  437. endoreg_db/models/media/video/video_file_io.py +272 -0
  438. endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
  439. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +58 -0
  440. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +62 -0
  441. endoreg_db/models/media/video/video_file_meta/get_fps.py +183 -0
  442. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +198 -0
  443. endoreg_db/models/media/video/video_file_meta/text_meta.py +178 -0
  444. endoreg_db/models/media/video/video_file_meta/video_meta.py +105 -0
  445. endoreg_db/models/media/video/video_file_segments.py +317 -0
  446. endoreg_db/models/media/video/video_metadata.py +67 -0
  447. endoreg_db/models/media/video/video_processing.py +192 -0
  448. endoreg_db/models/medical/__init__.py +136 -0
  449. endoreg_db/models/medical/contraindication/README.md +1 -0
  450. endoreg_db/models/medical/contraindication/__init__.py +29 -0
  451. endoreg_db/models/medical/disease.py +174 -0
  452. endoreg_db/models/medical/event.py +154 -0
  453. endoreg_db/models/medical/examination/__init__.py +20 -0
  454. endoreg_db/models/medical/examination/examination.py +183 -0
  455. endoreg_db/models/medical/examination/examination_indication.py +229 -0
  456. endoreg_db/models/medical/examination/examination_time.py +68 -0
  457. endoreg_db/models/medical/examination/examination_time_type.py +44 -0
  458. endoreg_db/models/medical/examination/examination_type.py +47 -0
  459. endoreg_db/models/medical/finding/__init__.py +20 -0
  460. endoreg_db/models/medical/finding/finding.py +113 -0
  461. endoreg_db/models/medical/finding/finding_classification.py +131 -0
  462. endoreg_db/models/medical/finding/finding_intervention.py +68 -0
  463. endoreg_db/models/medical/finding/finding_type.py +38 -0
  464. endoreg_db/models/medical/hardware/__init__.py +8 -0
  465. endoreg_db/models/medical/hardware/endoscope.py +77 -0
  466. endoreg_db/models/medical/hardware/endoscopy_processor.py +182 -0
  467. endoreg_db/models/medical/laboratory/__init__.py +5 -0
  468. endoreg_db/models/medical/laboratory/lab_value.py +490 -0
  469. endoreg_db/models/medical/medication/__init__.py +23 -0
  470. endoreg_db/models/medical/medication/medication.py +45 -0
  471. endoreg_db/models/medical/medication/medication_indication.py +78 -0
  472. endoreg_db/models/medical/medication/medication_indication_type.py +58 -0
  473. endoreg_db/models/medical/medication/medication_intake_time.py +58 -0
  474. endoreg_db/models/medical/medication/medication_schedule.py +58 -0
  475. endoreg_db/models/medical/organ/__init__.py +38 -0
  476. endoreg_db/models/medical/patient/__init__.py +48 -0
  477. endoreg_db/models/medical/patient/medication_examples.py +56 -0
  478. endoreg_db/models/medical/patient/patient_disease.py +72 -0
  479. endoreg_db/models/medical/patient/patient_event.py +80 -0
  480. endoreg_db/models/medical/patient/patient_examination.py +280 -0
  481. endoreg_db/models/medical/patient/patient_examination_indication.py +57 -0
  482. endoreg_db/models/medical/patient/patient_finding.py +416 -0
  483. endoreg_db/models/medical/patient/patient_finding_classification.py +231 -0
  484. endoreg_db/models/medical/patient/patient_finding_intervention.py +37 -0
  485. endoreg_db/models/medical/patient/patient_lab_sample.py +157 -0
  486. endoreg_db/models/medical/patient/patient_lab_value.py +247 -0
  487. endoreg_db/models/medical/patient/patient_medication.py +111 -0
  488. endoreg_db/models/medical/patient/patient_medication_schedule.py +152 -0
  489. endoreg_db/models/medical/risk/__init__.py +7 -0
  490. endoreg_db/models/medical/risk/risk.py +73 -0
  491. endoreg_db/models/medical/risk/risk_type.py +54 -0
  492. endoreg_db/models/metadata/__init__.py +19 -0
  493. endoreg_db/models/metadata/model_meta.py +266 -0
  494. endoreg_db/models/metadata/model_meta_logic.py +485 -0
  495. endoreg_db/models/metadata/pdf_meta.py +96 -0
  496. endoreg_db/models/metadata/sensitive_meta.py +345 -0
  497. endoreg_db/models/metadata/sensitive_meta_logic.py +1161 -0
  498. endoreg_db/models/metadata/video_meta.py +459 -0
  499. endoreg_db/models/metadata/video_prediction_logic.py +232 -0
  500. endoreg_db/models/metadata/video_prediction_meta.py +319 -0
  501. endoreg_db/models/operation_log.py +63 -0
  502. endoreg_db/models/other/__init__.py +40 -0
  503. endoreg_db/models/other/distribution/__init__.py +46 -0
  504. endoreg_db/models/other/distribution/base_value_distribution.py +22 -0
  505. endoreg_db/models/other/distribution/date_value_distribution.py +163 -0
  506. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +50 -0
  507. endoreg_db/models/other/distribution/numeric_value_distribution.py +211 -0
  508. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +23 -0
  509. endoreg_db/models/other/emission/__init__.py +5 -0
  510. endoreg_db/models/other/emission/emission_factor.py +110 -0
  511. endoreg_db/models/other/gender.py +32 -0
  512. endoreg_db/models/other/information_source.py +190 -0
  513. endoreg_db/models/other/material.py +34 -0
  514. endoreg_db/models/other/resource.py +24 -0
  515. endoreg_db/models/other/tag.py +32 -0
  516. endoreg_db/models/other/transport_route.py +40 -0
  517. endoreg_db/models/other/unit.py +40 -0
  518. endoreg_db/models/other/waste.py +28 -0
  519. endoreg_db/models/report/__init__.py +0 -0
  520. endoreg_db/models/report/images.py +0 -0
  521. endoreg_db/models/report/report.py +5 -0
  522. endoreg_db/models/requirement/__init__.py +11 -0
  523. endoreg_db/models/requirement/requirement.py +792 -0
  524. endoreg_db/models/requirement/requirement_error.py +84 -0
  525. endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
  526. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
  527. endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
  528. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +6 -0
  529. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +137 -0
  530. endoreg_db/models/requirement/requirement_operator.py +187 -0
  531. endoreg_db/models/requirement/requirement_set.py +327 -0
  532. endoreg_db/models/state/__init__.py +13 -0
  533. endoreg_db/models/state/abstract.py +11 -0
  534. endoreg_db/models/state/anonymization.py +30 -0
  535. endoreg_db/models/state/audit_ledger.py +155 -0
  536. endoreg_db/models/state/label_video_segment.py +31 -0
  537. endoreg_db/models/state/processing_history/__init__.py +3 -0
  538. endoreg_db/models/state/processing_history/processing_history.py +136 -0
  539. endoreg_db/models/state/raw_pdf.py +219 -0
  540. endoreg_db/models/state/sensitive_meta.py +50 -0
  541. endoreg_db/models/state/video.py +251 -0
  542. endoreg_db/models/upload_job.py +100 -0
  543. endoreg_db/models/utils.py +138 -0
  544. endoreg_db/queries/__init__.py +3 -0
  545. endoreg_db/queries/annotations/__init__.py +1 -0
  546. endoreg_db/queries/annotations/legacy.py +169 -0
  547. endoreg_db/queries/sanity/__init_.py +0 -0
  548. endoreg_db/root_urls.py +27 -0
  549. endoreg_db/schemas/__init__.py +0 -0
  550. endoreg_db/schemas/examination_evaluation.py +30 -0
  551. endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +861 -0
  552. endoreg_db/serializers/__init__.py +104 -0
  553. endoreg_db/serializers/administration/__init__.py +13 -0
  554. endoreg_db/serializers/administration/ai/__init__.py +9 -0
  555. endoreg_db/serializers/administration/ai/active_model.py +12 -0
  556. endoreg_db/serializers/administration/ai/ai_model.py +20 -0
  557. endoreg_db/serializers/administration/ai/model_type.py +12 -0
  558. endoreg_db/serializers/administration/center.py +14 -0
  559. endoreg_db/serializers/administration/gender.py +11 -0
  560. endoreg_db/serializers/anonymization.py +77 -0
  561. endoreg_db/serializers/evaluation/examination_evaluation.py +0 -0
  562. endoreg_db/serializers/examination/__init__.py +10 -0
  563. endoreg_db/serializers/examination/base.py +45 -0
  564. endoreg_db/serializers/examination/dropdown.py +20 -0
  565. endoreg_db/serializers/examination_serializer.py +9 -0
  566. endoreg_db/serializers/finding/__init__.py +5 -0
  567. endoreg_db/serializers/finding/finding.py +61 -0
  568. endoreg_db/serializers/finding_classification/__init__.py +7 -0
  569. endoreg_db/serializers/finding_classification/choice.py +19 -0
  570. endoreg_db/serializers/finding_classification/classification.py +11 -0
  571. endoreg_db/serializers/label_video_segment/__init__.py +9 -0
  572. endoreg_db/serializers/label_video_segment/image_classification_annotation.py +62 -0
  573. endoreg_db/serializers/label_video_segment/label/__init__.py +6 -0
  574. endoreg_db/serializers/label_video_segment/label/label.py +15 -0
  575. endoreg_db/serializers/label_video_segment/label_video_segment.py +427 -0
  576. endoreg_db/serializers/meta/__init__.py +13 -0
  577. endoreg_db/serializers/meta/sensitive_meta_detail.py +122 -0
  578. endoreg_db/serializers/meta/sensitive_meta_update.py +153 -0
  579. endoreg_db/serializers/meta/sensitive_meta_verification.py +62 -0
  580. endoreg_db/serializers/meta/video_meta.py +39 -0
  581. endoreg_db/serializers/misc/__init__.py +14 -0
  582. endoreg_db/serializers/misc/file_overview.py +72 -0
  583. endoreg_db/serializers/misc/sensitive_patient_data.py +144 -0
  584. endoreg_db/serializers/misc/stats.py +35 -0
  585. endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
  586. endoreg_db/serializers/misc/upload_job.py +74 -0
  587. endoreg_db/serializers/patient/__init__.py +12 -0
  588. endoreg_db/serializers/patient/patient.py +103 -0
  589. endoreg_db/serializers/patient/patient_dropdown.py +35 -0
  590. endoreg_db/serializers/patient_examination/__init__.py +7 -0
  591. endoreg_db/serializers/patient_examination/patient_examination.py +168 -0
  592. endoreg_db/serializers/patient_finding/__init__.py +15 -0
  593. endoreg_db/serializers/patient_finding/patient_finding.py +32 -0
  594. endoreg_db/serializers/patient_finding/patient_finding_classification.py +47 -0
  595. endoreg_db/serializers/patient_finding/patient_finding_detail.py +62 -0
  596. endoreg_db/serializers/patient_finding/patient_finding_intervention.py +28 -0
  597. endoreg_db/serializers/patient_finding/patient_finding_list.py +40 -0
  598. endoreg_db/serializers/patient_finding/patient_finding_write.py +135 -0
  599. endoreg_db/serializers/pdf/__init__.py +3 -0
  600. endoreg_db/serializers/pdf/anony_text_validation.py +101 -0
  601. endoreg_db/serializers/requirements/requirement_schema.py +20 -0
  602. endoreg_db/serializers/requirements/requirement_sets.py +99 -0
  603. endoreg_db/serializers/sensitive_meta_serializer.py +301 -0
  604. endoreg_db/serializers/video/__init__.py +7 -0
  605. endoreg_db/serializers/video/video_file.py +283 -0
  606. endoreg_db/serializers/video/video_file_brief.py +14 -0
  607. endoreg_db/serializers/video/video_file_detail.py +96 -0
  608. endoreg_db/serializers/video/video_file_list.py +100 -0
  609. endoreg_db/serializers/video/video_processing_history.py +172 -0
  610. endoreg_db/serializers/video_examination.py +198 -0
  611. endoreg_db/services/__init__.py +5 -0
  612. endoreg_db/services/anonymization.py +274 -0
  613. endoreg_db/services/examination_evaluation.py +172 -0
  614. endoreg_db/services/finding_description_service.py +0 -0
  615. endoreg_db/services/lookup_service.py +424 -0
  616. endoreg_db/services/lookup_store.py +266 -0
  617. endoreg_db/services/model_meta_from_hf.py +76 -0
  618. endoreg_db/services/pdf_import.py +0 -0
  619. endoreg_db/services/polling_coordinator.py +319 -0
  620. endoreg_db/services/pseudonym_service.py +94 -0
  621. endoreg_db/services/report_import.py +13 -0
  622. endoreg_db/services/segment_sync.py +171 -0
  623. endoreg_db/services/video_import.py +9 -0
  624. endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
  625. endoreg_db/templates/admin/start_examination.html +12 -0
  626. endoreg_db/templates/timeline.html +176 -0
  627. endoreg_db/urls/__init__.py +56 -0
  628. endoreg_db/urls/ai.py +14 -0
  629. endoreg_db/urls/anonymization.py +78 -0
  630. endoreg_db/urls/auth.py +16 -0
  631. endoreg_db/urls/classification.py +34 -0
  632. endoreg_db/urls/examination.py +63 -0
  633. endoreg_db/urls/media.py +251 -0
  634. endoreg_db/urls/patient.py +23 -0
  635. endoreg_db/urls/requirements.py +15 -0
  636. endoreg_db/urls/root_urls.py +28 -0
  637. endoreg_db/urls/stats.py +54 -0
  638. endoreg_db/urls/upload.py +12 -0
  639. endoreg_db/urls.py +9 -0
  640. endoreg_db/utils/__init__.py +97 -0
  641. endoreg_db/utils/ai/__init__.py +9 -0
  642. endoreg_db/utils/ai/data_loader_for_model_input.py +262 -0
  643. endoreg_db/utils/ai/data_loader_for_model_training.py +262 -0
  644. endoreg_db/utils/ai/get.py +6 -0
  645. endoreg_db/utils/ai/inference_dataset.py +51 -0
  646. endoreg_db/utils/ai/model_training/config.py +117 -0
  647. endoreg_db/utils/ai/model_training/dataset.py +74 -0
  648. endoreg_db/utils/ai/model_training/losses.py +68 -0
  649. endoreg_db/utils/ai/model_training/metrics.py +78 -0
  650. endoreg_db/utils/ai/model_training/model_backbones.py +155 -0
  651. endoreg_db/utils/ai/model_training/model_gastronet_resnet.py +118 -0
  652. endoreg_db/utils/ai/model_training/trainer_gastronet_multilabel.py +771 -0
  653. endoreg_db/utils/ai/multilabel_classification_net.py +270 -0
  654. endoreg_db/utils/ai/postprocess.py +63 -0
  655. endoreg_db/utils/ai/predict.py +293 -0
  656. endoreg_db/utils/ai/preprocess.py +76 -0
  657. endoreg_db/utils/calc_duration_seconds.py +24 -0
  658. endoreg_db/utils/case_generator/__init__.py +3 -0
  659. endoreg_db/utils/case_generator/lab_sample_factory.py +32 -0
  660. endoreg_db/utils/check_video_files.py +175 -0
  661. endoreg_db/utils/cropping.py +30 -0
  662. endoreg_db/utils/dataloader.py +285 -0
  663. endoreg_db/utils/dates.py +59 -0
  664. endoreg_db/utils/defaults/set_default_center.py +33 -0
  665. endoreg_db/utils/env.py +37 -0
  666. endoreg_db/utils/extract_specific_frames.py +87 -0
  667. endoreg_db/utils/file_operations.py +70 -0
  668. endoreg_db/utils/fix_video_path_direct.py +157 -0
  669. endoreg_db/utils/frame_anonymization_utils.py +463 -0
  670. endoreg_db/utils/hashs.py +138 -0
  671. endoreg_db/utils/links/__init__.py +0 -0
  672. endoreg_db/utils/links/requirement_link.py +237 -0
  673. endoreg_db/utils/mime_types.py +0 -0
  674. endoreg_db/utils/names.py +82 -0
  675. endoreg_db/utils/ocr.py +195 -0
  676. endoreg_db/utils/operation_log.py +87 -0
  677. endoreg_db/utils/parse_and_generate_yaml.py +45 -0
  678. endoreg_db/utils/paths.py +159 -0
  679. endoreg_db/utils/permissions.py +160 -0
  680. endoreg_db/utils/pipelines/Readme.md +235 -0
  681. endoreg_db/utils/pipelines/__init__.py +0 -0
  682. endoreg_db/utils/pipelines/process_video_dir.py +144 -0
  683. endoreg_db/utils/product/__init__.py +0 -0
  684. endoreg_db/utils/product/sum_emissions.py +22 -0
  685. endoreg_db/utils/product/sum_weights.py +20 -0
  686. endoreg_db/utils/pydantic_models/__init__.py +5 -0
  687. endoreg_db/utils/pydantic_models/db_config.py +57 -0
  688. endoreg_db/utils/requirement_helpers.py +0 -0
  689. endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
  690. endoreg_db/utils/requirement_operator_logic/_old/lab_value_operators.py +678 -0
  691. endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +842 -0
  692. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +114 -0
  693. endoreg_db/utils/setup_config.py +196 -0
  694. endoreg_db/utils/storage.py +117 -0
  695. endoreg_db/utils/translation.py +31 -0
  696. endoreg_db/utils/uuid.py +5 -0
  697. endoreg_db/utils/validate_endo_roi.py +33 -0
  698. endoreg_db/utils/validate_subcategory_dict.py +93 -0
  699. endoreg_db/utils/validate_video_detailed.py +415 -0
  700. endoreg_db/utils/video/__init__.py +30 -0
  701. endoreg_db/utils/video/extract_frames.py +100 -0
  702. endoreg_db/utils/video/ffmpeg_wrapper.py +996 -0
  703. endoreg_db/utils/video/names.py +47 -0
  704. endoreg_db/utils/video/streaming_processor.py +386 -0
  705. endoreg_db/utils/video/video_splitter.py +105 -0
  706. endoreg_db/versioning.md +79 -0
  707. endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +247 -0
  708. endoreg_db/views/__init__.py +157 -0
  709. endoreg_db/views/anonymization/__init__.py +31 -0
  710. endoreg_db/views/anonymization/media_management.py +486 -0
  711. endoreg_db/views/anonymization/overview.py +307 -0
  712. endoreg_db/views/anonymization/validate.py +310 -0
  713. endoreg_db/views/auth/__init__.py +13 -0
  714. endoreg_db/views/auth/keycloak.py +146 -0
  715. endoreg_db/views/examination/__init__.py +30 -0
  716. endoreg_db/views/examination/examination.py +37 -0
  717. endoreg_db/views/examination/examination_manifest_cache.py +26 -0
  718. endoreg_db/views/examination/get_finding_classification_choices.py +62 -0
  719. endoreg_db/views/examination/get_finding_classifications.py +38 -0
  720. endoreg_db/views/examination/get_findings.py +39 -0
  721. endoreg_db/views/examination/get_instruments.py +19 -0
  722. endoreg_db/views/examination/get_interventions.py +14 -0
  723. endoreg_db/views/finding/__init__.py +9 -0
  724. endoreg_db/views/finding/finding.py +116 -0
  725. endoreg_db/views/finding/get_classifications.py +14 -0
  726. endoreg_db/views/finding/get_interventions.py +17 -0
  727. endoreg_db/views/finding_classification/__init__.py +13 -0
  728. endoreg_db/views/finding_classification/base.py +0 -0
  729. endoreg_db/views/finding_classification/finding_classification.py +41 -0
  730. endoreg_db/views/finding_classification/get_classification_choices.py +54 -0
  731. endoreg_db/views/media/__init__.py +32 -0
  732. endoreg_db/views/media/pdf_media.py +411 -0
  733. endoreg_db/views/media/sensitive_metadata.py +372 -0
  734. endoreg_db/views/media/video_media.py +275 -0
  735. endoreg_db/views/meta/__init__.py +7 -0
  736. endoreg_db/views/meta/sensitive_meta_list.py +102 -0
  737. endoreg_db/views/meta/sensitive_meta_verification.py +74 -0
  738. endoreg_db/views/misc/__init__.py +29 -0
  739. endoreg_db/views/misc/center.py +14 -0
  740. endoreg_db/views/misc/csrf.py +8 -0
  741. endoreg_db/views/misc/gender.py +15 -0
  742. endoreg_db/views/misc/stats.py +255 -0
  743. endoreg_db/views/misc/upload_views.py +241 -0
  744. endoreg_db/views/patient/__init__.py +3 -0
  745. endoreg_db/views/patient/patient.py +253 -0
  746. endoreg_db/views/patient_examination/__init__.py +11 -0
  747. endoreg_db/views/patient_examination/patient_examination.py +141 -0
  748. endoreg_db/views/patient_examination/patient_examination_create.py +58 -0
  749. endoreg_db/views/patient_examination/patient_examination_detail.py +63 -0
  750. endoreg_db/views/patient_examination/patient_examination_list.py +72 -0
  751. endoreg_db/views/patient_examination/video.py +228 -0
  752. endoreg_db/views/patient_finding/__init__.py +7 -0
  753. endoreg_db/views/patient_finding/base.py +0 -0
  754. endoreg_db/views/patient_finding/patient_finding.py +71 -0
  755. endoreg_db/views/patient_finding/patient_finding_optimized.py +291 -0
  756. endoreg_db/views/patient_finding_classification/__init__.py +5 -0
  757. endoreg_db/views/patient_finding_classification/pfc_create.py +75 -0
  758. endoreg_db/views/report/__init__.py +7 -0
  759. endoreg_db/views/report/reimport.py +177 -0
  760. endoreg_db/views/report/report_stream.py +191 -0
  761. endoreg_db/views/requirement/__init__.py +11 -0
  762. endoreg_db/views/requirement/evaluate.py +278 -0
  763. endoreg_db/views/requirement/lookup.py +380 -0
  764. endoreg_db/views/requirement/lookup_store.py +183 -0
  765. endoreg_db/views/requirement/requirement_utils.py +87 -0
  766. endoreg_db/views/requirement_lookup/lookup.py +0 -0
  767. endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
  768. endoreg_db/views/stats/__init__.py +13 -0
  769. endoreg_db/views/stats/stats_views.py +266 -0
  770. endoreg_db/views/video/__init__.py +49 -0
  771. endoreg_db/views/video/ai/__init__.py +8 -0
  772. endoreg_db/views/video/ai/label.py +159 -0
  773. endoreg_db/views/video/correction.py +529 -0
  774. endoreg_db/views/video/reimport.py +230 -0
  775. endoreg_db/views/video/segments_crud.py +709 -0
  776. endoreg_db/views/video/video_apply_mask.py +49 -0
  777. endoreg_db/views/video/video_correction.py +22 -0
  778. endoreg_db/views/video/video_download_processed.py +58 -0
  779. endoreg_db/views/video/video_examination_viewset.py +242 -0
  780. endoreg_db/views/video/video_metadata.py +101 -0
  781. endoreg_db/views/video/video_processing_history.py +25 -0
  782. endoreg_db/views/video/video_remove_frames.py +49 -0
  783. endoreg_db/views/video/video_stream.py +334 -0
  784. endoreg_db-0.8.9.32.dist-info/METADATA +404 -0
  785. endoreg_db-0.8.9.32.dist-info/RECORD +787 -0
  786. endoreg_db-0.8.9.32.dist-info/WHEEL +4 -0
  787. endoreg_db-0.8.9.32.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,1953 @@
1
+ # Generated by Django 6.0 on 2025-12-20 13:34
2
+
3
+ import django.core.validators
4
+ import django.db.models.deletion
5
+ import uuid
6
+ from decimal import Decimal
7
+ from django.conf import settings
8
+ from django.db import migrations, models
9
+
10
+
11
+ class Migration(migrations.Migration):
12
+
13
+ initial = True
14
+
15
+ dependencies = [
16
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
17
+ ]
18
+
19
+ operations = [
20
+ migrations.CreateModel(
21
+ name='AiModel',
22
+ fields=[
23
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24
+ ('name', models.CharField(max_length=255, unique=True)),
25
+ ('description', models.TextField(blank=True, null=True)),
26
+ ('model_subtype', models.CharField(blank=True, max_length=255, null=True)),
27
+ ],
28
+ ),
29
+ migrations.CreateModel(
30
+ name='Center',
31
+ fields=[
32
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
33
+ ('name', models.CharField(max_length=255)),
34
+ ('display_name', models.CharField(blank=True, default='', max_length=255)),
35
+ ],
36
+ ),
37
+ migrations.CreateModel(
38
+ name='Contraindication',
39
+ fields=[
40
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
41
+ ('name', models.CharField(max_length=100, unique=True)),
42
+ ('description', models.TextField(blank=True, null=True)),
43
+ ],
44
+ ),
45
+ migrations.CreateModel(
46
+ name='DateValueDistribution',
47
+ fields=[
48
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
49
+ ('name', models.CharField(max_length=100)),
50
+ ('description', models.TextField(blank=True, null=True)),
51
+ ('distribution_type', models.CharField(choices=[('uniform', 'Uniform'), ('normal', 'Normal')], max_length=20)),
52
+ ('mode', models.CharField(choices=[('date', 'Date'), ('timedelta', 'Timedelta')], max_length=20)),
53
+ ('date_min', models.DateField(blank=True, null=True)),
54
+ ('date_max', models.DateField(blank=True, null=True)),
55
+ ('date_mean', models.DateField(blank=True, null=True)),
56
+ ('date_std_dev', models.IntegerField(blank=True, null=True)),
57
+ ('timedelta_days_min', models.IntegerField(blank=True, null=True)),
58
+ ('timedelta_days_max', models.IntegerField(blank=True, null=True)),
59
+ ('timedelta_days_mean', models.IntegerField(blank=True, null=True)),
60
+ ('timedelta_days_std_dev', models.IntegerField(blank=True, null=True)),
61
+ ],
62
+ options={
63
+ 'abstract': False,
64
+ },
65
+ ),
66
+ migrations.CreateModel(
67
+ name='Disease',
68
+ fields=[
69
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
70
+ ('name', models.CharField(max_length=255, unique=True)),
71
+ ('subcategories', models.JSONField(default=dict)),
72
+ ('numerical_descriptors', models.JSONField(default=dict)),
73
+ ],
74
+ ),
75
+ migrations.CreateModel(
76
+ name='DocumentType',
77
+ fields=[
78
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
79
+ ('name', models.CharField(max_length=255, unique=True)),
80
+ ('description', models.TextField(blank=True, null=True)),
81
+ ],
82
+ options={
83
+ 'verbose_name': 'Document Type',
84
+ 'verbose_name_plural': 'Document Types',
85
+ },
86
+ ),
87
+ migrations.CreateModel(
88
+ name='EmissionFactor',
89
+ fields=[
90
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
91
+ ('name', models.CharField(max_length=255)),
92
+ ('value', models.FloatField()),
93
+ ],
94
+ ),
95
+ migrations.CreateModel(
96
+ name='EmployeeType',
97
+ fields=[
98
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
99
+ ('name', models.CharField(max_length=255, unique=True)),
100
+ ('description', models.TextField(blank=True, null=True)),
101
+ ('is_active', models.BooleanField(default=True)),
102
+ ],
103
+ ),
104
+ migrations.CreateModel(
105
+ name='EndoscopeType',
106
+ fields=[
107
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
108
+ ('name', models.CharField(max_length=255, unique=True)),
109
+ ],
110
+ options={
111
+ 'verbose_name': 'Endoscope Type',
112
+ 'verbose_name_plural': 'Endoscope Types',
113
+ 'ordering': ['name'],
114
+ },
115
+ ),
116
+ migrations.CreateModel(
117
+ name='Event',
118
+ fields=[
119
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
120
+ ('name', models.CharField(max_length=100, unique=True)),
121
+ ('description', models.TextField(blank=True, null=True)),
122
+ ],
123
+ ),
124
+ migrations.CreateModel(
125
+ name='ExaminationIndication',
126
+ fields=[
127
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
128
+ ('name', models.CharField(max_length=255, unique=True)),
129
+ ('description', models.TextField(blank=True, null=True)),
130
+ ],
131
+ ),
132
+ migrations.CreateModel(
133
+ name='ExaminationIndicationClassification',
134
+ fields=[
135
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
136
+ ('name', models.CharField(max_length=255, unique=True)),
137
+ ('description', models.TextField(blank=True, null=True)),
138
+ ],
139
+ ),
140
+ migrations.CreateModel(
141
+ name='ExaminationIndicationClassificationChoice',
142
+ fields=[
143
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
144
+ ('name', models.CharField(max_length=255, unique=True)),
145
+ ('subcategories', models.JSONField(default=dict)),
146
+ ('numerical_descriptors', models.JSONField(default=dict)),
147
+ ],
148
+ ),
149
+ migrations.CreateModel(
150
+ name='ExaminationTime',
151
+ fields=[
152
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
153
+ ('name', models.CharField(max_length=100, unique=True)),
154
+ ],
155
+ options={
156
+ 'verbose_name': 'Examination Time',
157
+ 'verbose_name_plural': 'Examination Times',
158
+ 'ordering': ['name'],
159
+ },
160
+ ),
161
+ migrations.CreateModel(
162
+ name='ExaminationType',
163
+ fields=[
164
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
165
+ ('name', models.CharField(max_length=100, unique=True)),
166
+ ],
167
+ ),
168
+ migrations.CreateModel(
169
+ name='FFMpegMeta',
170
+ fields=[
171
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
172
+ ('width', models.IntegerField(blank=True, null=True)),
173
+ ('height', models.IntegerField(blank=True, null=True)),
174
+ ('duration', models.FloatField(blank=True, null=True)),
175
+ ('frame_rate_num', models.IntegerField(blank=True, null=True)),
176
+ ('frame_rate_den', models.IntegerField(blank=True, null=True)),
177
+ ('codec_name', models.CharField(blank=True, max_length=50, null=True)),
178
+ ('pixel_format', models.CharField(blank=True, max_length=50, null=True)),
179
+ ('bit_rate', models.BigIntegerField(blank=True, null=True)),
180
+ ('raw_probe_data', models.JSONField(blank=True, null=True)),
181
+ ],
182
+ ),
183
+ migrations.CreateModel(
184
+ name='Finding',
185
+ fields=[
186
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
187
+ ('name', models.CharField(max_length=100, unique=True)),
188
+ ('description', models.TextField(blank=True, null=True)),
189
+ ],
190
+ ),
191
+ migrations.CreateModel(
192
+ name='FindingClassification',
193
+ fields=[
194
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
195
+ ('name', models.CharField(max_length=255, unique=True)),
196
+ ('description', models.TextField(blank=True)),
197
+ ],
198
+ ),
199
+ migrations.CreateModel(
200
+ name='FindingClassificationChoice',
201
+ fields=[
202
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
203
+ ('name', models.CharField(max_length=255, unique=True)),
204
+ ('description', models.TextField(blank=True)),
205
+ ('subcategories', models.JSONField(default=dict)),
206
+ ('numerical_descriptors', models.JSONField(default=dict)),
207
+ ],
208
+ ),
209
+ migrations.CreateModel(
210
+ name='FindingClassificationType',
211
+ fields=[
212
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
213
+ ('name', models.CharField(max_length=255, unique=True)),
214
+ ('description', models.TextField(blank=True)),
215
+ ],
216
+ ),
217
+ migrations.CreateModel(
218
+ name='FindingIntervention',
219
+ fields=[
220
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
221
+ ('name', models.CharField(max_length=100, unique=True)),
222
+ ('description', models.TextField(blank=True, null=True)),
223
+ ],
224
+ ),
225
+ migrations.CreateModel(
226
+ name='FindingInterventionType',
227
+ fields=[
228
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
229
+ ('name', models.CharField(max_length=100, unique=True)),
230
+ ('description', models.TextField(blank=True, null=True)),
231
+ ],
232
+ ),
233
+ migrations.CreateModel(
234
+ name='FindingType',
235
+ fields=[
236
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
237
+ ('name', models.CharField(max_length=100, unique=True)),
238
+ ('description', models.TextField(blank=True, null=True)),
239
+ ],
240
+ ),
241
+ migrations.CreateModel(
242
+ name='FirstName',
243
+ fields=[
244
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
245
+ ('name', models.CharField(max_length=255, unique=True)),
246
+ ],
247
+ ),
248
+ migrations.CreateModel(
249
+ name='Frame',
250
+ fields=[
251
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
252
+ ('frame_number', models.PositiveIntegerField()),
253
+ ('relative_path', models.CharField(max_length=512)),
254
+ ('timestamp', models.FloatField(blank=True, null=True)),
255
+ ('is_extracted', models.BooleanField(default=False)),
256
+ ],
257
+ options={
258
+ 'ordering': ['video', 'frame_number'],
259
+ },
260
+ ),
261
+ migrations.CreateModel(
262
+ name='Gender',
263
+ fields=[
264
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
265
+ ('name', models.CharField(max_length=255)),
266
+ ('abbreviation', models.CharField(max_length=255, null=True)),
267
+ ('description', models.TextField(blank=True, null=True)),
268
+ ],
269
+ ),
270
+ migrations.CreateModel(
271
+ name='Label',
272
+ fields=[
273
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
274
+ ('name', models.CharField(max_length=255)),
275
+ ('description', models.TextField(blank=True, null=True)),
276
+ ],
277
+ ),
278
+ migrations.CreateModel(
279
+ name='LabelType',
280
+ fields=[
281
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
282
+ ('name', models.CharField(max_length=255)),
283
+ ('description', models.TextField(blank=True, null=True)),
284
+ ],
285
+ ),
286
+ migrations.CreateModel(
287
+ name='LastName',
288
+ fields=[
289
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
290
+ ('name', models.CharField(max_length=255, unique=True)),
291
+ ],
292
+ ),
293
+ migrations.CreateModel(
294
+ name='Medication',
295
+ fields=[
296
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
297
+ ('name', models.CharField(max_length=255, unique=True)),
298
+ ('adapt_to_renal_function', models.BooleanField(default=False)),
299
+ ('adapt_to_hepatic_function', models.BooleanField(default=False)),
300
+ ('adapt_to_indication', models.BooleanField(default=False)),
301
+ ('adapt_to_age', models.BooleanField(default=False)),
302
+ ('adapt_to_weight', models.BooleanField(default=False)),
303
+ ('adapt_to_risk', models.BooleanField(default=False)),
304
+ ],
305
+ ),
306
+ migrations.CreateModel(
307
+ name='MedicationIndicationType',
308
+ fields=[
309
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
310
+ ('name', models.CharField(max_length=255, unique=True)),
311
+ ],
312
+ ),
313
+ migrations.CreateModel(
314
+ name='MedicationIntakeTime',
315
+ fields=[
316
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
317
+ ('name', models.CharField(max_length=255, unique=True)),
318
+ ('repeats', models.CharField(default='daily', max_length=20)),
319
+ ('time', models.TimeField()),
320
+ ],
321
+ ),
322
+ migrations.CreateModel(
323
+ name='ModelType',
324
+ fields=[
325
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
326
+ ('name', models.CharField(max_length=255)),
327
+ ('description', models.TextField(blank=True, null=True)),
328
+ ],
329
+ ),
330
+ migrations.CreateModel(
331
+ name='MultipleCategoricalValueDistribution',
332
+ fields=[
333
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
334
+ ('name', models.CharField(max_length=100)),
335
+ ('categories', models.JSONField()),
336
+ ('min_count', models.IntegerField()),
337
+ ('max_count', models.IntegerField()),
338
+ ('count_distribution_type', models.CharField(choices=[('uniform', 'Uniform'), ('normal', 'Normal')], max_length=20)),
339
+ ('count_mean', models.FloatField(blank=True, null=True)),
340
+ ('count_std_dev', models.FloatField(blank=True, null=True)),
341
+ ],
342
+ options={
343
+ 'abstract': False,
344
+ },
345
+ ),
346
+ migrations.CreateModel(
347
+ name='NumericValueDistribution',
348
+ fields=[
349
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
350
+ ('name', models.CharField(max_length=100)),
351
+ ('distribution_type', models.CharField(choices=[('uniform', 'Uniform'), ('normal', 'Normal'), ('skewed_normal', 'Skewed Normal')], max_length=20)),
352
+ ('min_descriptor', models.CharField(max_length=20)),
353
+ ('max_descriptor', models.CharField(max_length=20)),
354
+ ('min_value', models.FloatField(blank=True, help_text='Lower hard limit for generated values', null=True)),
355
+ ('max_value', models.FloatField(blank=True, help_text='Upper hard limit for generated values', null=True)),
356
+ ('mean', models.FloatField(blank=True, help_text='Mean used for normal or skewed normal distributions', null=True)),
357
+ ('std_dev', models.FloatField(blank=True, help_text='Standard deviation for bell-shaped distributions', null=True)),
358
+ ('skewness', models.FloatField(blank=True, help_text='Shape parameter for skewed normal distributions', null=True)),
359
+ ],
360
+ options={
361
+ 'abstract': False,
362
+ },
363
+ ),
364
+ migrations.CreateModel(
365
+ name='Organ',
366
+ fields=[
367
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
368
+ ('name', models.CharField(max_length=100, unique=True)),
369
+ ('description', models.TextField(blank=True, null=True)),
370
+ ],
371
+ ),
372
+ migrations.CreateModel(
373
+ name='PatientLabSampleType',
374
+ fields=[
375
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
376
+ ('name', models.CharField(max_length=255)),
377
+ ('description', models.TextField(blank=True, null=True)),
378
+ ],
379
+ ),
380
+ migrations.CreateModel(
381
+ name='PdfType',
382
+ fields=[
383
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
384
+ ('name', models.CharField(max_length=255)),
385
+ ],
386
+ ),
387
+ migrations.CreateModel(
388
+ name='ProcessingHistory',
389
+ fields=[
390
+ ('file_hash', models.CharField(blank=True, help_text='Content hash of the original file (e.g. video_hash/pdf_hash).', max_length=64, primary_key=True, serialize=False)),
391
+ ('created_at', models.DateTimeField(auto_now_add=True)),
392
+ ('success', models.BooleanField(blank=True, default=False)),
393
+ ('object_id', models.PositiveBigIntegerField(blank=True, null=True)),
394
+ ],
395
+ options={
396
+ 'ordering': ['-created_at'],
397
+ },
398
+ ),
399
+ migrations.CreateModel(
400
+ name='Product',
401
+ fields=[
402
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
403
+ ('name', models.CharField(max_length=255)),
404
+ ],
405
+ ),
406
+ migrations.CreateModel(
407
+ name='ProductGroup',
408
+ fields=[
409
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
410
+ ('name', models.CharField(max_length=255)),
411
+ ],
412
+ ),
413
+ migrations.CreateModel(
414
+ name='Profession',
415
+ fields=[
416
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
417
+ ('name', models.CharField(max_length=100)),
418
+ ('description', models.TextField(blank=True, null=True)),
419
+ ],
420
+ ),
421
+ migrations.CreateModel(
422
+ name='Qualification',
423
+ fields=[
424
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
425
+ ('name', models.CharField(max_length=255, unique=True)),
426
+ ('description', models.TextField(blank=True, null=True)),
427
+ ('is_active', models.BooleanField(default=True)),
428
+ ],
429
+ ),
430
+ migrations.CreateModel(
431
+ name='QualificationType',
432
+ fields=[
433
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
434
+ ('name', models.CharField(max_length=255, unique=True)),
435
+ ('description', models.TextField(blank=True, null=True)),
436
+ ('is_active', models.BooleanField(default=True)),
437
+ ],
438
+ ),
439
+ migrations.CreateModel(
440
+ name='RawPdfState',
441
+ fields=[
442
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
443
+ ('text_meta_extracted', models.BooleanField(default=False, help_text='True if text metadata (OCR) has been extracted.')),
444
+ ('initial_prediction_completed', models.BooleanField(default=False, help_text='True if initial AI prediction has run.')),
445
+ ('sensitive_meta_processed', models.BooleanField(default=False, help_text='True if the video has been fully processed, meaning a anonymized person was created.')),
446
+ ('anonymized', models.BooleanField(default=False, help_text='True if the anonymized video file has been created.')),
447
+ ('anonymization_validated', models.BooleanField(default=False, help_text='True if the anonymization process has been validated and confirmed.')),
448
+ ('processing_started', models.BooleanField(default=False, help_text='True if the processing has started, but not yet completed.')),
449
+ ('processing_error', models.BooleanField(default=False, help_text='True if an error occurred during processing.')),
450
+ ('date_created', models.DateTimeField(auto_now_add=True)),
451
+ ('date_modified', models.DateTimeField(auto_now=True)),
452
+ ('was_created', models.BooleanField(default=True, help_text='True if this state was created for the first time.')),
453
+ ('pdf_meta_extracted', models.BooleanField(default=False, help_text='True if report metadata has been extracted.')),
454
+ ],
455
+ options={
456
+ 'verbose_name': 'Raw report Processing State',
457
+ 'verbose_name_plural': 'Raw report Processing States',
458
+ },
459
+ ),
460
+ migrations.CreateModel(
461
+ name='ReportReaderFlag',
462
+ fields=[
463
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
464
+ ('name', models.CharField(max_length=255, unique=True)),
465
+ ('value', models.CharField(max_length=255)),
466
+ ],
467
+ ),
468
+ migrations.CreateModel(
469
+ name='RequirementOperator',
470
+ fields=[
471
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
472
+ ('name', models.CharField(max_length=100, unique=True)),
473
+ ('description', models.TextField(blank=True, null=True)),
474
+ ('evaluation_function_name', models.CharField(blank=True, max_length=255, null=True)),
475
+ ],
476
+ ),
477
+ migrations.CreateModel(
478
+ name='RequirementSetType',
479
+ fields=[
480
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
481
+ ('name', models.CharField(max_length=100, unique=True)),
482
+ ('description', models.TextField(blank=True, null=True)),
483
+ ],
484
+ ),
485
+ migrations.CreateModel(
486
+ name='RequirementType',
487
+ fields=[
488
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
489
+ ('name', models.CharField(max_length=100, unique=True)),
490
+ ('description', models.TextField(blank=True, null=True)),
491
+ ],
492
+ ),
493
+ migrations.CreateModel(
494
+ name='Resource',
495
+ fields=[
496
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
497
+ ('name', models.CharField(max_length=255)),
498
+ ],
499
+ ),
500
+ migrations.CreateModel(
501
+ name='RiskType',
502
+ fields=[
503
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
504
+ ('name', models.CharField(max_length=100, unique=True)),
505
+ ('description', models.TextField(blank=True, null=True)),
506
+ ],
507
+ ),
508
+ migrations.CreateModel(
509
+ name='ScheduledDays',
510
+ fields=[
511
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
512
+ ('name', models.CharField(help_text='Name of the scheduled days.', max_length=255, unique=True)),
513
+ ('working_days', models.BooleanField(blank=True, default=True, null=True)),
514
+ ('non_working_days', models.BooleanField(blank=True, default=False, null=True)),
515
+ ('limited_time', models.BooleanField(blank=True, default=False, null=True)),
516
+ ('start_date', models.DateField(blank=True, null=True)),
517
+ ('end_date', models.DateField(blank=True, null=True)),
518
+ ],
519
+ ),
520
+ migrations.CreateModel(
521
+ name='ShiftType',
522
+ fields=[
523
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
524
+ ('name', models.CharField(max_length=255, unique=True)),
525
+ ('description', models.TextField(blank=True, null=True)),
526
+ ('is_active', models.BooleanField(default=True)),
527
+ ],
528
+ ),
529
+ migrations.CreateModel(
530
+ name='SingleCategoricalValueDistribution',
531
+ fields=[
532
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
533
+ ('name', models.CharField(max_length=100)),
534
+ ('categories', models.JSONField()),
535
+ ],
536
+ options={
537
+ 'abstract': False,
538
+ },
539
+ ),
540
+ migrations.CreateModel(
541
+ name='Tag',
542
+ fields=[
543
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
544
+ ('name', models.CharField(max_length=100, unique=True)),
545
+ ],
546
+ options={
547
+ 'verbose_name': 'Tag',
548
+ 'verbose_name_plural': 'Tags',
549
+ },
550
+ ),
551
+ migrations.CreateModel(
552
+ name='Unit',
553
+ fields=[
554
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
555
+ ('name', models.CharField(max_length=100)),
556
+ ('description', models.CharField(blank=True, max_length=100, null=True)),
557
+ ('abbreviation', models.CharField(blank=True, max_length=25, null=True)),
558
+ ],
559
+ ),
560
+ migrations.CreateModel(
561
+ name='VideoImportMeta',
562
+ fields=[
563
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
564
+ ('file_name', models.CharField(blank=True, max_length=255, null=True)),
565
+ ('video_anonymized', models.BooleanField(default=False)),
566
+ ('video_patient_data_detected', models.BooleanField(default=False)),
567
+ ('outside_detected', models.BooleanField(default=False)),
568
+ ('patient_data_removed', models.BooleanField(default=False)),
569
+ ('outside_removed', models.BooleanField(default=False)),
570
+ ],
571
+ ),
572
+ migrations.CreateModel(
573
+ name='VideoSegmentationLabel',
574
+ fields=[
575
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
576
+ ('name', models.CharField(max_length=255)),
577
+ ('description', models.TextField(blank=True, null=True)),
578
+ ('color', models.CharField(blank=True, max_length=255, null=True)),
579
+ ('order_priority', models.IntegerField(default=0)),
580
+ ],
581
+ ),
582
+ migrations.CreateModel(
583
+ name='VideoState',
584
+ fields=[
585
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
586
+ ('frames_extracted', models.BooleanField(default=False, help_text='True if raw frames have been extracted to files.')),
587
+ ('frames_initialized', models.BooleanField(default=False, help_text='True if Frame DB objects have been created.')),
588
+ ('frame_count', models.PositiveIntegerField(blank=True, help_text='Number of frames extracted/initialized.', null=True)),
589
+ ('video_meta_extracted', models.BooleanField(default=False, help_text='True if VideoMeta (technical specs) has been extracted.')),
590
+ ('text_meta_extracted', models.BooleanField(default=False, help_text='True if text metadata (OCR) has been extracted.')),
591
+ ('initial_prediction_completed', models.BooleanField(default=False, help_text='True if initial AI prediction has run.')),
592
+ ('lvs_created', models.BooleanField(default=False, help_text='True if LabelVideoSegments have been created from predictions.')),
593
+ ('frame_annotations_generated', models.BooleanField(default=False, help_text='True if frame-level annotations have been generated from segments.')),
594
+ ('sensitive_meta_processed', models.BooleanField(default=False, help_text='True if the video has been fully processed, meaning a anonymized person was created.')),
595
+ ('anonymized', models.BooleanField(default=False, help_text='True if the anonymized video file has been created.')),
596
+ ('anonymization_validated', models.BooleanField(default=False, help_text='True if the anonymization process has been validated and confirmed.')),
597
+ ('processing_started', models.BooleanField(default=False, help_text='True if the processing has started, but not yet completed.')),
598
+ ('date_created', models.DateTimeField(auto_now_add=True)),
599
+ ('date_modified', models.DateTimeField(auto_now=True)),
600
+ ('segment_annotations_created', models.BooleanField(default=False, help_text='True if segment annotations have been created from LabelVideoSegments.')),
601
+ ('segment_annotations_validated', models.BooleanField(default=False, help_text='True if segment annotations have been validated.')),
602
+ ('was_created', models.BooleanField(default=True, help_text='True if this state was created for the first time.')),
603
+ ],
604
+ options={
605
+ 'verbose_name': 'Video Processing State',
606
+ 'verbose_name_plural': 'Video Processing States',
607
+ },
608
+ ),
609
+ migrations.CreateModel(
610
+ name='Waste',
611
+ fields=[
612
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
613
+ ('name', models.CharField(max_length=255)),
614
+ ],
615
+ ),
616
+ migrations.CreateModel(
617
+ name='DiseaseClassification',
618
+ fields=[
619
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
620
+ ('name', models.CharField(max_length=255, unique=True)),
621
+ ('disease', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='disease_classifications', to='endoreg_db.disease')),
622
+ ],
623
+ ),
624
+ migrations.CreateModel(
625
+ name='DiseaseClassificationChoice',
626
+ fields=[
627
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
628
+ ('name', models.CharField(max_length=255, unique=True)),
629
+ ('disease_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='disease_classification_choices', to='endoreg_db.diseaseclassification')),
630
+ ],
631
+ ),
632
+ migrations.CreateModel(
633
+ name='Endoscope',
634
+ fields=[
635
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
636
+ ('name', models.CharField(max_length=255)),
637
+ ('sn', models.CharField(max_length=255)),
638
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='endoscopes', to='endoreg_db.center')),
639
+ ('endoscope_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='endoscopes', to='endoreg_db.endoscopetype')),
640
+ ],
641
+ options={
642
+ 'verbose_name': 'Endoscope',
643
+ 'verbose_name_plural': 'Endoscopes',
644
+ 'ordering': ['name'],
645
+ },
646
+ ),
647
+ migrations.CreateModel(
648
+ name='EndoscopyProcessor',
649
+ fields=[
650
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
651
+ ('name', models.CharField(max_length=255)),
652
+ ('image_width', models.IntegerField()),
653
+ ('image_height', models.IntegerField()),
654
+ ('endoscope_image_x', models.IntegerField()),
655
+ ('endoscope_image_y', models.IntegerField()),
656
+ ('endoscope_image_width', models.IntegerField()),
657
+ ('endoscope_image_height', models.IntegerField()),
658
+ ('examination_date_x', models.IntegerField()),
659
+ ('examination_date_y', models.IntegerField()),
660
+ ('examination_date_width', models.IntegerField()),
661
+ ('examination_date_height', models.IntegerField()),
662
+ ('examination_time_x', models.IntegerField(blank=True, null=True)),
663
+ ('examination_time_y', models.IntegerField(blank=True, null=True)),
664
+ ('examination_time_width', models.IntegerField(blank=True, null=True)),
665
+ ('examination_time_height', models.IntegerField(blank=True, null=True)),
666
+ ('patient_first_name_x', models.IntegerField()),
667
+ ('patient_first_name_y', models.IntegerField()),
668
+ ('patient_first_name_width', models.IntegerField()),
669
+ ('patient_first_name_height', models.IntegerField()),
670
+ ('patient_last_name_x', models.IntegerField()),
671
+ ('patient_last_name_y', models.IntegerField()),
672
+ ('patient_last_name_width', models.IntegerField()),
673
+ ('patient_last_name_height', models.IntegerField()),
674
+ ('patient_dob_x', models.IntegerField()),
675
+ ('patient_dob_y', models.IntegerField()),
676
+ ('patient_dob_width', models.IntegerField()),
677
+ ('patient_dob_height', models.IntegerField()),
678
+ ('endoscope_type_x', models.IntegerField(blank=True, null=True)),
679
+ ('endoscope_type_y', models.IntegerField(blank=True, null=True)),
680
+ ('endoscope_type_width', models.IntegerField(blank=True, null=True)),
681
+ ('endoscope_type_height', models.IntegerField(blank=True, null=True)),
682
+ ('endoscope_sn_x', models.IntegerField(blank=True, null=True)),
683
+ ('endoscope_sn_y', models.IntegerField(blank=True, null=True)),
684
+ ('endoscope_sn_width', models.IntegerField(blank=True, null=True)),
685
+ ('endoscope_sn_height', models.IntegerField(blank=True, null=True)),
686
+ ('centers', models.ManyToManyField(blank=True, related_name='endoscopy_processors', to='endoreg_db.center')),
687
+ ],
688
+ ),
689
+ migrations.CreateModel(
690
+ name='EventClassification',
691
+ fields=[
692
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
693
+ ('name', models.CharField(max_length=255, unique=True)),
694
+ ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='event_classifications', to='endoreg_db.event')),
695
+ ],
696
+ ),
697
+ migrations.CreateModel(
698
+ name='EventClassificationChoice',
699
+ fields=[
700
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
701
+ ('name', models.CharField(max_length=255, unique=True)),
702
+ ('subcategories', models.JSONField(default=dict)),
703
+ ('numerical_descriptors', models.JSONField(default=dict)),
704
+ ('event_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='event_classification_choices', to='endoreg_db.eventclassification')),
705
+ ],
706
+ ),
707
+ migrations.CreateModel(
708
+ name='Examination',
709
+ fields=[
710
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
711
+ ('name', models.CharField(max_length=100, unique=True)),
712
+ ('description', models.TextField(blank=True, null=True)),
713
+ ('indications', models.ManyToManyField(blank=True, related_name='examinations', to='endoreg_db.examinationindication')),
714
+ ('examination_times', models.ManyToManyField(blank=True, related_name='examinations', to='endoreg_db.examinationtime')),
715
+ ('examination_types', models.ManyToManyField(blank=True, to='endoreg_db.examinationtype')),
716
+ ('findings', models.ManyToManyField(blank=True, related_name='examinations', to='endoreg_db.finding')),
717
+ ],
718
+ options={
719
+ 'verbose_name': 'Examination',
720
+ 'verbose_name_plural': 'Examinations',
721
+ 'ordering': ['name'],
722
+ },
723
+ ),
724
+ migrations.AddField(
725
+ model_name='examinationindication',
726
+ name='classifications',
727
+ field=models.ManyToManyField(blank=True, related_name='indications', to='endoreg_db.examinationindicationclassification'),
728
+ ),
729
+ migrations.AddField(
730
+ model_name='examinationindicationclassification',
731
+ name='choices',
732
+ field=models.ManyToManyField(blank=True, related_name='classifications', to='endoreg_db.examinationindicationclassificationchoice'),
733
+ ),
734
+ migrations.CreateModel(
735
+ name='ExaminationRequirementSet',
736
+ fields=[
737
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
738
+ ('enabled_by_default', models.BooleanField(default=False)),
739
+ ('name', models.CharField(max_length=100, unique=True)),
740
+ ('examinations', models.ManyToManyField(blank=True, related_name='exam_reqset_links', to='endoreg_db.examination')),
741
+ ],
742
+ ),
743
+ migrations.CreateModel(
744
+ name='ExaminationTimeType',
745
+ fields=[
746
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
747
+ ('name', models.CharField(max_length=100, unique=True)),
748
+ ('examinations', models.ManyToManyField(blank=True, to='endoreg_db.examination')),
749
+ ],
750
+ options={
751
+ 'verbose_name': 'Examination Time Type',
752
+ 'verbose_name_plural': 'Examination Time Types',
753
+ 'ordering': ['name'],
754
+ },
755
+ ),
756
+ migrations.AddField(
757
+ model_name='examinationtime',
758
+ name='time_types',
759
+ field=models.ManyToManyField(blank=True, to='endoreg_db.examinationtimetype'),
760
+ ),
761
+ migrations.CreateModel(
762
+ name='Examiner',
763
+ fields=[
764
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
765
+ ('first_name', models.CharField(max_length=255)),
766
+ ('last_name', models.CharField(max_length=255)),
767
+ ('dob', models.DateField(blank=True, null=True, verbose_name='Date of Birth')),
768
+ ('email', models.EmailField(blank=True, max_length=255, null=True)),
769
+ ('phone', models.CharField(blank=True, max_length=255, null=True)),
770
+ ('is_real_person', models.BooleanField(default=True)),
771
+ ('post_code', models.CharField(blank=True, max_length=20, null=True)),
772
+ ('city', models.CharField(blank=True, max_length=255, null=True)),
773
+ ('street', models.CharField(blank=True, max_length=255, null=True)),
774
+ ('hash', models.CharField(max_length=255, unique=True)),
775
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
776
+ ('gender', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.gender')),
777
+ ],
778
+ options={
779
+ 'abstract': False,
780
+ },
781
+ ),
782
+ migrations.AddField(
783
+ model_name='finding',
784
+ name='finding_classifications',
785
+ field=models.ManyToManyField(blank=True, related_name='findings', to='endoreg_db.findingclassification'),
786
+ ),
787
+ migrations.AddField(
788
+ model_name='findingclassification',
789
+ name='choices',
790
+ field=models.ManyToManyField(blank=True, related_name='classifications', to='endoreg_db.findingclassificationchoice'),
791
+ ),
792
+ migrations.AddField(
793
+ model_name='findingclassification',
794
+ name='classification_types',
795
+ field=models.ManyToManyField(to='endoreg_db.findingclassificationtype'),
796
+ ),
797
+ migrations.AddField(
798
+ model_name='finding',
799
+ name='caused_by_interventions',
800
+ field=models.ManyToManyField(blank=True, related_name='causes_findings', to='endoreg_db.findingintervention'),
801
+ ),
802
+ migrations.AddField(
803
+ model_name='finding',
804
+ name='finding_interventions',
805
+ field=models.ManyToManyField(blank=True, related_name='findings', to='endoreg_db.findingintervention'),
806
+ ),
807
+ migrations.AddField(
808
+ model_name='examinationindication',
809
+ name='expected_interventions',
810
+ field=models.ManyToManyField(blank=True, related_name='indications', to='endoreg_db.findingintervention'),
811
+ ),
812
+ migrations.AddField(
813
+ model_name='findingintervention',
814
+ name='intervention_types',
815
+ field=models.ManyToManyField(blank=True, related_name='interventions', to='endoreg_db.findinginterventiontype'),
816
+ ),
817
+ migrations.AddField(
818
+ model_name='findingclassification',
819
+ name='finding_types',
820
+ field=models.ManyToManyField(blank=True, related_name='finding_classifications', to='endoreg_db.findingtype'),
821
+ ),
822
+ migrations.AddField(
823
+ model_name='finding',
824
+ name='finding_types',
825
+ field=models.ManyToManyField(blank=True, related_name='findings', to='endoreg_db.findingtype'),
826
+ ),
827
+ migrations.AddField(
828
+ model_name='center',
829
+ name='first_names',
830
+ field=models.ManyToManyField(related_name='centers', to='endoreg_db.firstname'),
831
+ ),
832
+ migrations.CreateModel(
833
+ name='Employee',
834
+ fields=[
835
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
836
+ ('first_name', models.CharField(max_length=255)),
837
+ ('last_name', models.CharField(max_length=255)),
838
+ ('dob', models.DateField(blank=True, null=True, verbose_name='Date of Birth')),
839
+ ('email', models.EmailField(blank=True, max_length=255, null=True)),
840
+ ('phone', models.CharField(blank=True, max_length=255, null=True)),
841
+ ('is_real_person', models.BooleanField(default=True)),
842
+ ('post_code', models.CharField(blank=True, max_length=20, null=True)),
843
+ ('city', models.CharField(blank=True, max_length=255, null=True)),
844
+ ('street', models.CharField(blank=True, max_length=255, null=True)),
845
+ ('employee_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='employees', to='endoreg_db.employeetype')),
846
+ ('gender', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.gender')),
847
+ ],
848
+ options={
849
+ 'abstract': False,
850
+ },
851
+ ),
852
+ migrations.CreateModel(
853
+ name='ImageClassificationAnnotation',
854
+ fields=[
855
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
856
+ ('value', models.BooleanField()),
857
+ ('float_value', models.FloatField(blank=True, null=True)),
858
+ ('annotator', models.CharField(blank=True, max_length=255, null=True)),
859
+ ('date_created', models.DateTimeField(auto_now_add=True)),
860
+ ('date_modified', models.DateTimeField(auto_now=True)),
861
+ ('frame', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_annotations', to='endoreg_db.frame')),
862
+ ],
863
+ ),
864
+ migrations.CreateModel(
865
+ name='AIDataSet',
866
+ fields=[
867
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
868
+ ('name', models.CharField(blank=True, help_text='Human-readable identifier, e.g. "Legacy multilabel dataset v1".', max_length=255, null=True)),
869
+ ('description', models.TextField(blank=True, help_text='Optional notes / explanation about this dataset.', null=True)),
870
+ ('ai_model_type', models.CharField(default='image_multilabel_classification', help_text='AI model family this dataset is for, e.g. "image_multilabel_classification". Used to pick the correct architecture and output dimension logic.', max_length=255)),
871
+ ('dataset_type', models.CharField(choices=[('image', 'Image')], default='image', help_text='Controls which annotation table will be used. Currently only "image" is implemented; later "video", "text", etc.', max_length=32)),
872
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='When this AIDataSet was created.')),
873
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='When this AIDataSet was last modified.')),
874
+ ('is_active', models.BooleanField(default=True, help_text='Soft toggle to enable/disable this dataset for training.')),
875
+ ('image_annotations', models.ManyToManyField(blank=True, help_text="For dataset_type='image', this is the set of ImageClassificationAnnotation rows that define this AIDataSet. Each annotation has frame_id and label_id.", related_name='image_ai_datasets', to='endoreg_db.imageclassificationannotation')),
876
+ ],
877
+ ),
878
+ migrations.CreateModel(
879
+ name='InformationSource',
880
+ fields=[
881
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
882
+ ('name', models.CharField(max_length=100)),
883
+ ('url', models.URLField(blank=True, null=True)),
884
+ ('description', models.TextField(blank=True, null=True)),
885
+ ('date', models.DateField(blank=True, null=True)),
886
+ ('date_created', models.DateField(auto_now_add=True)),
887
+ ('date_modified', models.DateField(auto_now=True)),
888
+ ('abbreviation', models.CharField(blank=True, max_length=100, null=True, unique=True)),
889
+ ],
890
+ options={
891
+ 'verbose_name': 'Information Source',
892
+ 'verbose_name_plural': 'Information Sources',
893
+ 'indexes': [models.Index(fields=['name'], name='endoreg_db__name_febac5_idx'), models.Index(fields=['abbreviation'], name='endoreg_db__abbrevi_5a07c4_idx')],
894
+ },
895
+ ),
896
+ migrations.AddField(
897
+ model_name='imageclassificationannotation',
898
+ name='information_source',
899
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='image_classification_annotations', to='endoreg_db.informationsource'),
900
+ ),
901
+ migrations.AddField(
902
+ model_name='findingintervention',
903
+ name='information_sources',
904
+ field=models.ManyToManyField(blank=True, related_name='finding_interventions', to='endoreg_db.informationsource'),
905
+ ),
906
+ migrations.AddField(
907
+ model_name='findingclassification',
908
+ name='information_sources',
909
+ field=models.ManyToManyField(blank=True, related_name='finding_classifications', to='endoreg_db.informationsource'),
910
+ ),
911
+ migrations.AddField(
912
+ model_name='finding',
913
+ name='information_sources',
914
+ field=models.ManyToManyField(blank=True, related_name='findings', to='endoreg_db.informationsource'),
915
+ ),
916
+ migrations.AddField(
917
+ model_name='examinationtime',
918
+ name='information_sources',
919
+ field=models.ManyToManyField(blank=True, related_name='examination_times', to='endoreg_db.informationsource'),
920
+ ),
921
+ migrations.AddField(
922
+ model_name='examinationindication',
923
+ name='information_sources',
924
+ field=models.ManyToManyField(blank=True, related_name='examination_indications', to='endoreg_db.informationsource'),
925
+ ),
926
+ migrations.AddField(
927
+ model_name='examination',
928
+ name='information_sources',
929
+ field=models.ManyToManyField(blank=True, related_name='examinations', to='endoreg_db.informationsource'),
930
+ ),
931
+ migrations.CreateModel(
932
+ name='InformationSourceType',
933
+ fields=[
934
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
935
+ ('name', models.CharField(max_length=100, unique=True)),
936
+ ('description', models.TextField(blank=True, null=True)),
937
+ ('information_sources', models.ManyToManyField(blank=True, related_name='information_source_types', to='endoreg_db.informationsource')),
938
+ ],
939
+ options={
940
+ 'verbose_name': 'Information Source Type',
941
+ 'verbose_name_plural': 'Information Source Types',
942
+ },
943
+ ),
944
+ migrations.AddField(
945
+ model_name='imageclassificationannotation',
946
+ name='label',
947
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_annotations', to='endoreg_db.label'),
948
+ ),
949
+ migrations.CreateModel(
950
+ name='LabelSet',
951
+ fields=[
952
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
953
+ ('name', models.CharField(max_length=255)),
954
+ ('description', models.TextField(blank=True, null=True)),
955
+ ('version', models.IntegerField()),
956
+ ('labels', models.ManyToManyField(related_name='label_sets', to='endoreg_db.label')),
957
+ ],
958
+ ),
959
+ migrations.AddField(
960
+ model_name='label',
961
+ name='label_type',
962
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='labels', to='endoreg_db.labeltype'),
963
+ ),
964
+ migrations.CreateModel(
965
+ name='LabelVideoSegment',
966
+ fields=[
967
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
968
+ ('start_frame_number', models.IntegerField()),
969
+ ('end_frame_number', models.IntegerField()),
970
+ ('label', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.label')),
971
+ ('source', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.informationsource')),
972
+ ],
973
+ ),
974
+ migrations.CreateModel(
975
+ name='LabelVideoSegmentState',
976
+ fields=[
977
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
978
+ ('created_at', models.DateTimeField(auto_now_add=True)),
979
+ ('updated_at', models.DateTimeField(auto_now=True)),
980
+ ('prediction', models.BooleanField(default=False)),
981
+ ('annotation', models.BooleanField(default=False)),
982
+ ('frames_extracted', models.BooleanField(default=False)),
983
+ ('is_validated', models.BooleanField(default=False)),
984
+ ('origin', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='state', to='endoreg_db.labelvideosegment')),
985
+ ],
986
+ options={
987
+ 'verbose_name': 'Label Video Segment State',
988
+ 'verbose_name_plural': 'Label Video Segment States',
989
+ },
990
+ ),
991
+ migrations.AddField(
992
+ model_name='center',
993
+ name='last_names',
994
+ field=models.ManyToManyField(related_name='centers', to='endoreg_db.lastname'),
995
+ ),
996
+ migrations.CreateModel(
997
+ name='Material',
998
+ fields=[
999
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1000
+ ('name', models.CharField(max_length=255)),
1001
+ ('emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.emissionfactor')),
1002
+ ],
1003
+ ),
1004
+ migrations.CreateModel(
1005
+ name='MedicationSchedule',
1006
+ fields=[
1007
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1008
+ ('name', models.CharField(max_length=255, unique=True)),
1009
+ ('description', models.TextField(blank=True, null=True)),
1010
+ ('therapy_duration_d', models.FloatField(blank=True, null=True)),
1011
+ ('dose', models.FloatField()),
1012
+ ('intake_times', models.ManyToManyField(to='endoreg_db.medicationintaketime')),
1013
+ ('medication', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.medication')),
1014
+ ('unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.unit')),
1015
+ ],
1016
+ ),
1017
+ migrations.CreateModel(
1018
+ name='MedicationIndication',
1019
+ fields=[
1020
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1021
+ ('name', models.CharField(max_length=255, unique=True)),
1022
+ ('disease_classification_choices', models.ManyToManyField(to='endoreg_db.diseaseclassificationchoice')),
1023
+ ('diseases', models.ManyToManyField(to='endoreg_db.disease')),
1024
+ ('events', models.ManyToManyField(to='endoreg_db.event')),
1025
+ ('sources', models.ManyToManyField(to='endoreg_db.informationsource')),
1026
+ ('indication_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='medication_indications', to='endoreg_db.medicationindicationtype')),
1027
+ ('medication_schedules', models.ManyToManyField(to='endoreg_db.medicationschedule')),
1028
+ ],
1029
+ ),
1030
+ migrations.CreateModel(
1031
+ name='ModelMeta',
1032
+ fields=[
1033
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1034
+ ('name', models.CharField(help_text="User-defined name for this specific model metadata set (e.g., 'segmentation_base').", max_length=255)),
1035
+ ('version', models.CharField(help_text="Version identifier for this metadata set (e.g., '1', '2a').", max_length=255)),
1036
+ ('activation', models.CharField(default='sigmoid', help_text="Output activation function (e.g., 'sigmoid', 'softmax', 'none').", max_length=50)),
1037
+ ('weights', models.FileField(blank=True, help_text='Path to the model weights file (.safetensors), relative to MEDIA_ROOT.', null=True, upload_to='model_weights', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['safetensors', 'pth', 'pt'])])),
1038
+ ('mean', models.CharField(default='0.45211223,0.27139644,0.19264949', help_text='Comma-separated mean values for input normalization.', max_length=255)),
1039
+ ('std', models.CharField(default='0.31418097,0.21088019,0.16059452', help_text='Comma-separated standard deviation values for input normalization.', max_length=255)),
1040
+ ('size_x', models.IntegerField(default=716, help_text='Expected input image width.')),
1041
+ ('size_y', models.IntegerField(default=716, help_text='Expected input image height.')),
1042
+ ('axes', models.CharField(default='2,0,1', help_text="Comma-separated target axis order (e.g., '2,0,1' for CHW).", max_length=10)),
1043
+ ('batchsize', models.IntegerField(default=16, help_text='Default batch size for inference.')),
1044
+ ('num_workers', models.IntegerField(default=0, help_text='Default number of workers for data loading.')),
1045
+ ('description', models.TextField(blank=True, help_text='Optional description.', null=True)),
1046
+ ('date_created', models.DateTimeField(auto_now_add=True)),
1047
+ ('labelset', models.ForeignKey(help_text='The set of labels this model version predicts.', on_delete=django.db.models.deletion.CASCADE, related_name='model_metadata', to='endoreg_db.labelset')),
1048
+ ('model', models.ForeignKey(help_text='The base AI model architecture this metadata belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='metadata_versions', to='endoreg_db.aimodel')),
1049
+ ],
1050
+ options={
1051
+ 'verbose_name': 'Model Metadata',
1052
+ 'verbose_name_plural': 'Model Metadata',
1053
+ 'ordering': ['-date_created'],
1054
+ 'unique_together': {('name', 'version', 'model')},
1055
+ },
1056
+ ),
1057
+ migrations.AddField(
1058
+ model_name='imageclassificationannotation',
1059
+ name='model_meta',
1060
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='image_classification_annotations', to='endoreg_db.modelmeta'),
1061
+ ),
1062
+ migrations.AddField(
1063
+ model_name='aimodel',
1064
+ name='active_meta',
1065
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='active_model', to='endoreg_db.modelmeta'),
1066
+ ),
1067
+ migrations.CreateModel(
1068
+ name='ActiveModel',
1069
+ fields=[
1070
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1071
+ ('name', models.CharField(max_length=255, unique=True)),
1072
+ ('model_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.modelmeta')),
1073
+ ],
1074
+ ),
1075
+ migrations.AddField(
1076
+ model_name='aimodel',
1077
+ name='model_type',
1078
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ai_models', to='endoreg_db.modeltype'),
1079
+ ),
1080
+ migrations.CreateModel(
1081
+ name='LabValue',
1082
+ fields=[
1083
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1084
+ ('name', models.CharField(max_length=255, unique=True)),
1085
+ ('abbreviation', models.CharField(blank=True, max_length=10, null=True)),
1086
+ ('numeric_precision', models.IntegerField(default=3)),
1087
+ ('default_normal_range', models.JSONField(blank=True, null=True)),
1088
+ ('normal_range_age_dependent', models.BooleanField(default=False)),
1089
+ ('normal_range_gender_dependent', models.BooleanField(default=False)),
1090
+ ('normal_range_special_case', models.BooleanField(default=False)),
1091
+ ('bound_adjustment_factor', models.FloatField(default=0.1, help_text='Factor for adjusting bounds when generating increased/decreased values, e.g., 0.1 for 10%.')),
1092
+ ('default_date_value_distribution', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='default_date_value_distribution', to='endoreg_db.datevaluedistribution')),
1093
+ ('default_multiple_categorical_value_distribution', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='default_multiple_categorical_value_distribution', to='endoreg_db.multiplecategoricalvaluedistribution')),
1094
+ ('default_numerical_value_distribution', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='default_numerical_value_distribution', to='endoreg_db.numericvaluedistribution')),
1095
+ ('default_single_categorical_value_distribution', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='default_single_categorical_value_distribution', to='endoreg_db.singlecategoricalvaluedistribution')),
1096
+ ('default_unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.unit')),
1097
+ ],
1098
+ ),
1099
+ migrations.CreateModel(
1100
+ name='OperationLog',
1101
+ fields=[
1102
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1103
+ ('actor_username', models.CharField(blank=True, max_length=150)),
1104
+ ('actor_email', models.EmailField(blank=True, max_length=254)),
1105
+ ('actor_keycloak_id', models.CharField(blank=True, help_text='Keycloak subject/ID if you later want to store it.', max_length=255)),
1106
+ ('action', models.CharField(help_text="e.g. 'anonymization.start', 'anonymization.validate'", max_length=100)),
1107
+ ('http_method', models.CharField(blank=True, max_length=10)),
1108
+ ('path', models.CharField(blank=True, max_length=512)),
1109
+ ('resource_type', models.CharField(blank=True, help_text="e.g. 'video', 'pdf'", max_length=50)),
1110
+ ('resource_id', models.IntegerField(blank=True, help_text='ID of VideoFile / RawPdfFile etc.', null=True)),
1111
+ ('status_before', models.CharField(blank=True, max_length=50)),
1112
+ ('status_after', models.CharField(blank=True, max_length=50)),
1113
+ ('meta', models.JSONField(blank=True, null=True)),
1114
+ ('created_at', models.DateTimeField(auto_now_add=True)),
1115
+ ('actor_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operation_logs', to=settings.AUTH_USER_MODEL)),
1116
+ ],
1117
+ options={
1118
+ 'verbose_name': 'Operation Log',
1119
+ 'verbose_name_plural': 'Operation Logs',
1120
+ 'ordering': ['-created_at'],
1121
+ },
1122
+ ),
1123
+ migrations.CreateModel(
1124
+ name='Patient',
1125
+ fields=[
1126
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1127
+ ('email', models.EmailField(blank=True, max_length=255, null=True)),
1128
+ ('phone', models.CharField(blank=True, max_length=255, null=True)),
1129
+ ('is_real_person', models.BooleanField(default=True)),
1130
+ ('post_code', models.CharField(blank=True, max_length=20, null=True)),
1131
+ ('city', models.CharField(blank=True, max_length=255, null=True)),
1132
+ ('street', models.CharField(blank=True, max_length=255, null=True)),
1133
+ ('first_name', models.CharField(max_length=100)),
1134
+ ('last_name', models.CharField(max_length=100)),
1135
+ ('dob', models.DateField(blank=True, null=True)),
1136
+ ('patient_hash', models.CharField(blank=True, max_length=255, null=True)),
1137
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1138
+ ('gender', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.gender')),
1139
+ ],
1140
+ options={
1141
+ 'abstract': False,
1142
+ },
1143
+ ),
1144
+ migrations.CreateModel(
1145
+ name='PatientDisease',
1146
+ fields=[
1147
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1148
+ ('start_date', models.DateField(blank=True, null=True)),
1149
+ ('end_date', models.DateField(blank=True, null=True)),
1150
+ ('numerical_descriptors', models.JSONField(default=dict)),
1151
+ ('subcategories', models.JSONField(default=dict)),
1152
+ ('last_update', models.DateTimeField(auto_now=True)),
1153
+ ('classification_choices', models.ManyToManyField(to='endoreg_db.diseaseclassificationchoice')),
1154
+ ('disease', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_diseases', to='endoreg_db.disease')),
1155
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='diseases', to='endoreg_db.patient')),
1156
+ ],
1157
+ options={
1158
+ 'verbose_name': 'Patient Disease',
1159
+ 'verbose_name_plural': 'Patient Diseases',
1160
+ },
1161
+ ),
1162
+ migrations.CreateModel(
1163
+ name='PatientEvent',
1164
+ fields=[
1165
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1166
+ ('date_start', models.DateField()),
1167
+ ('date_end', models.DateField(blank=True, null=True)),
1168
+ ('description', models.TextField(blank=True, null=True)),
1169
+ ('subcategories', models.JSONField(default=dict)),
1170
+ ('numerical_descriptors', models.JSONField(default=dict)),
1171
+ ('last_update', models.DateTimeField(auto_now=True)),
1172
+ ('classification_choice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.eventclassificationchoice')),
1173
+ ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_events', to='endoreg_db.event')),
1174
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='endoreg_db.patient')),
1175
+ ],
1176
+ ),
1177
+ migrations.CreateModel(
1178
+ name='PatientExamination',
1179
+ fields=[
1180
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1181
+ ('date_start', models.DateField(blank=True, null=True)),
1182
+ ('date_end', models.DateField(blank=True, null=True)),
1183
+ ('hash', models.CharField(max_length=255, unique=True)),
1184
+ ('examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.examination')),
1185
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_examinations', to='endoreg_db.patient')),
1186
+ ],
1187
+ options={
1188
+ 'verbose_name': 'Patient Examination',
1189
+ 'verbose_name_plural': 'Patient Examinations',
1190
+ 'ordering': ['patient', 'examination', 'date_start'],
1191
+ },
1192
+ ),
1193
+ migrations.CreateModel(
1194
+ name='Case',
1195
+ fields=[
1196
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1197
+ ('hash', models.CharField(blank=True, help_text='An optional hash value associated with the case.', max_length=255, null=True)),
1198
+ ('start_date', models.DateTimeField(db_index=True, help_text='The start date and time of the case.')),
1199
+ ('end_date', models.DateTimeField(blank=True, help_text='The end date and time of the case (optional).', null=True)),
1200
+ ('is_active', models.BooleanField(db_index=True, default=True, help_text='Flag indicating if the case is currently active.')),
1201
+ ('is_closed', models.BooleanField(db_index=True, default=False, help_text='Flag indicating if the case has been closed.')),
1202
+ ('is_deleted', models.BooleanField(db_index=True, default=False, help_text='Flag indicating if the case is marked as deleted.')),
1203
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='The date and time the case was created.')),
1204
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='The date and time the case was last updated.')),
1205
+ ('patient', models.ForeignKey(help_text='The patient associated with this case.', on_delete=django.db.models.deletion.CASCADE, related_name='cases', to='endoreg_db.patient')),
1206
+ ('patient_examinations', models.ManyToManyField(help_text='The examinations included in this case.', related_name='cases', to='endoreg_db.patientexamination')),
1207
+ ],
1208
+ options={
1209
+ 'verbose_name': 'Case',
1210
+ 'verbose_name_plural': 'Cases',
1211
+ 'ordering': ['-start_date', 'patient'],
1212
+ },
1213
+ ),
1214
+ migrations.CreateModel(
1215
+ name='AnonymExaminationReport',
1216
+ fields=[
1217
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1218
+ ('meta', models.JSONField(blank=True, null=True)),
1219
+ ('text', models.TextField(blank=True, null=True)),
1220
+ ('date', models.DateField(blank=True, null=True)),
1221
+ ('time', models.TimeField(blank=True, null=True)),
1222
+ ('file', models.FileField(blank=True, null=True, upload_to='documents')),
1223
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1224
+ ('type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.documenttype')),
1225
+ ('examiners', models.ManyToManyField(blank=True, to='endoreg_db.examiner')),
1226
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='endoreg_db.patient')),
1227
+ ('patient_examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.patientexamination')),
1228
+ ],
1229
+ options={
1230
+ 'abstract': False,
1231
+ },
1232
+ ),
1233
+ migrations.CreateModel(
1234
+ name='PatientExaminationIndication',
1235
+ fields=[
1236
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1237
+ ('examination_indication', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.examinationindication')),
1238
+ ('indication_choice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.examinationindicationclassificationchoice')),
1239
+ ('patient_examination', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='indications', to='endoreg_db.patientexamination')),
1240
+ ],
1241
+ ),
1242
+ migrations.CreateModel(
1243
+ name='PatientExternalID',
1244
+ fields=[
1245
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1246
+ ('external_id', models.CharField(max_length=255)),
1247
+ ('origin', models.CharField(max_length=255)),
1248
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_ids', to='endoreg_db.patient')),
1249
+ ],
1250
+ ),
1251
+ migrations.CreateModel(
1252
+ name='PatientFinding',
1253
+ fields=[
1254
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1255
+ ('created_at', models.DateTimeField(auto_now_add=True)),
1256
+ ('updated_at', models.DateTimeField(auto_now=True)),
1257
+ ('is_active', models.BooleanField(default=True, help_text='Deaktiviert statt gelöscht für Audit-Trail')),
1258
+ ('deactivated_at', models.DateTimeField(blank=True, null=True)),
1259
+ ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='created_findings', to=settings.AUTH_USER_MODEL)),
1260
+ ('deactivated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deactivated_findings', to=settings.AUTH_USER_MODEL)),
1261
+ ('finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='finding_patient_findings', to='endoreg_db.finding')),
1262
+ ('patient_examination', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_findings', to='endoreg_db.patientexamination')),
1263
+ ('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='updated_findings', to=settings.AUTH_USER_MODEL)),
1264
+ ],
1265
+ options={
1266
+ 'verbose_name': 'Patient Finding',
1267
+ 'verbose_name_plural': 'Patient Findings',
1268
+ 'ordering': ['patient_examination', 'finding'],
1269
+ },
1270
+ ),
1271
+ migrations.AddField(
1272
+ model_name='labelvideosegment',
1273
+ name='patient_findings',
1274
+ field=models.ManyToManyField(blank=True, related_name='video_segments', to='endoreg_db.patientfinding'),
1275
+ ),
1276
+ migrations.CreateModel(
1277
+ name='PatientFindingClassification',
1278
+ fields=[
1279
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1280
+ ('is_active', models.BooleanField(default=True, help_text='Indicates if the classification is currently active.')),
1281
+ ('subcategories', models.JSONField(blank=True, null=True)),
1282
+ ('numerical_descriptors', models.JSONField(blank=True, null=True)),
1283
+ ('classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_classifications', to='endoreg_db.findingclassification')),
1284
+ ('classification_choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_classifications', to='endoreg_db.findingclassificationchoice')),
1285
+ ('finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='classifications', to='endoreg_db.patientfinding')),
1286
+ ],
1287
+ options={
1288
+ 'verbose_name': 'Patient Finding Classification',
1289
+ 'verbose_name_plural': 'Patient Finding Classifications',
1290
+ 'ordering': ['finding', 'classification', 'classification_choice'],
1291
+ },
1292
+ ),
1293
+ migrations.CreateModel(
1294
+ name='PatientFindingIntervention',
1295
+ fields=[
1296
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1297
+ ('is_active', models.BooleanField(default=True, help_text='Indicates if the intervention is currently active.')),
1298
+ ('state', models.CharField(blank=True, max_length=100, null=True)),
1299
+ ('time_start', models.DateTimeField(blank=True, null=True)),
1300
+ ('time_end', models.DateTimeField(blank=True, null=True)),
1301
+ ('date', models.DateField(blank=True, null=True)),
1302
+ ('finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interventions', to='endoreg_db.patientfinding')),
1303
+ ('intervention', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_interventions', to='endoreg_db.findingintervention')),
1304
+ ],
1305
+ ),
1306
+ migrations.CreateModel(
1307
+ name='PatientLabSample',
1308
+ fields=[
1309
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1310
+ ('date', models.DateTimeField()),
1311
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lab_samples', to='endoreg_db.patient')),
1312
+ ('sample_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patientlabsampletype')),
1313
+ ],
1314
+ ),
1315
+ migrations.CreateModel(
1316
+ name='PatientMedication',
1317
+ fields=[
1318
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1319
+ ('dosage', models.JSONField(blank=True, null=True)),
1320
+ ('active', models.BooleanField(default=True)),
1321
+ ('intake_times', models.ManyToManyField(blank=True, related_name='intake_time_patient_medications', to='endoreg_db.medicationintaketime')),
1322
+ ('medication', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='medication_patient_medications', to='endoreg_db.medication')),
1323
+ ('medication_indication', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='indication_patient_medications', to='endoreg_db.medicationindication')),
1324
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patient')),
1325
+ ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.unit')),
1326
+ ],
1327
+ options={
1328
+ 'verbose_name': 'Patient Medication',
1329
+ 'verbose_name_plural': 'Patient Medications',
1330
+ },
1331
+ ),
1332
+ migrations.CreateModel(
1333
+ name='PatientMedicationSchedule',
1334
+ fields=[
1335
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1336
+ ('created_at', models.DateTimeField(auto_now_add=True)),
1337
+ ('updated_at', models.DateTimeField(auto_now=True)),
1338
+ ('medication', models.ManyToManyField(blank=True, related_name='patient_medication_schedules', to='endoreg_db.patientmedication')),
1339
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patient')),
1340
+ ],
1341
+ ),
1342
+ migrations.CreateModel(
1343
+ name='PdfMeta',
1344
+ fields=[
1345
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1346
+ ('date', models.DateField()),
1347
+ ('time', models.TimeField()),
1348
+ ('pdf_hash', models.CharField(max_length=255, unique=True)),
1349
+ ('pdf_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.pdftype')),
1350
+ ],
1351
+ ),
1352
+ migrations.CreateModel(
1353
+ name='CenterProduct',
1354
+ fields=[
1355
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1356
+ ('date_used', models.DateField()),
1357
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_products', to='endoreg_db.center')),
1358
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_products', to='endoreg_db.product')),
1359
+ ],
1360
+ options={
1361
+ 'verbose_name': 'Center Product Usage',
1362
+ 'verbose_name_plural': 'Center Product Usages',
1363
+ 'ordering': ['center', '-date_used', 'product'],
1364
+ },
1365
+ ),
1366
+ migrations.AddField(
1367
+ model_name='product',
1368
+ name='product_group',
1369
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='products', to='endoreg_db.productgroup'),
1370
+ ),
1371
+ migrations.CreateModel(
1372
+ name='PortalUserInfo',
1373
+ fields=[
1374
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1375
+ ('works_in_endoscopy', models.BooleanField(blank=True, null=True)),
1376
+ ('examiner', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portal_user_info', to='endoreg_db.examiner')),
1377
+ ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
1378
+ ('profession', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portal_user_infos', to='endoreg_db.profession')),
1379
+ ],
1380
+ ),
1381
+ migrations.AddField(
1382
+ model_name='employeetype',
1383
+ name='qualifications',
1384
+ field=models.ManyToManyField(related_name='employee_types', to='endoreg_db.qualification'),
1385
+ ),
1386
+ migrations.CreateModel(
1387
+ name='EmployeeQualification',
1388
+ fields=[
1389
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1390
+ ('employee', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='qualification', to='endoreg_db.employee')),
1391
+ ('qualifications', models.ManyToManyField(related_name='employee_qualifications', to='endoreg_db.qualification')),
1392
+ ],
1393
+ ),
1394
+ migrations.AddField(
1395
+ model_name='qualification',
1396
+ name='qualification_types',
1397
+ field=models.ManyToManyField(related_name='qualifications', to='endoreg_db.qualificationtype'),
1398
+ ),
1399
+ migrations.CreateModel(
1400
+ name='ReferenceProduct',
1401
+ fields=[
1402
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1403
+ ('name', models.CharField(max_length=255)),
1404
+ ('emission_factor_package', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reference_product_package', to='endoreg_db.emissionfactor')),
1405
+ ('emission_factor_product', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reference_product_product', to='endoreg_db.emissionfactor')),
1406
+ ('emission_factor_total', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reference_products', to='endoreg_db.emissionfactor')),
1407
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reference_products', to='endoreg_db.product')),
1408
+ ('product_group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='reference_product', to='endoreg_db.productgroup')),
1409
+ ],
1410
+ ),
1411
+ migrations.CreateModel(
1412
+ name='ReportReaderConfig',
1413
+ fields=[
1414
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1415
+ ('locale', models.CharField(default='de_DE', max_length=10)),
1416
+ ('text_date_format', models.CharField(default='%d.%m.%Y', max_length=10)),
1417
+ ('first_names', models.ManyToManyField(related_name='report_reader_configs', to='endoreg_db.firstname')),
1418
+ ('last_names', models.ManyToManyField(related_name='report_reader_configs', to='endoreg_db.lastname')),
1419
+ ('cut_off_above', models.ManyToManyField(related_name='report_reader_configs_cut_off_above', to='endoreg_db.reportreaderflag')),
1420
+ ('cut_off_below', models.ManyToManyField(related_name='report_reader_configs_cut_off_below', to='endoreg_db.reportreaderflag')),
1421
+ ('endoscope_info_line_flag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='report_reader_configs_endoscope_info_line', to='endoreg_db.reportreaderflag')),
1422
+ ('examiner_info_line_flag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='report_reader_configs_examiner_info_line', to='endoreg_db.reportreaderflag')),
1423
+ ('patient_info_line_flag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='report_reader_configs_patient_info_line', to='endoreg_db.reportreaderflag')),
1424
+ ],
1425
+ ),
1426
+ migrations.AddField(
1427
+ model_name='pdftype',
1428
+ name='cut_off_above_lines',
1429
+ field=models.ManyToManyField(related_name='pdf_type_cut_off_above_lines', to='endoreg_db.reportreaderflag'),
1430
+ ),
1431
+ migrations.AddField(
1432
+ model_name='pdftype',
1433
+ name='cut_off_below_lines',
1434
+ field=models.ManyToManyField(related_name='pdf_type_cut_off_below_lines', to='endoreg_db.reportreaderflag'),
1435
+ ),
1436
+ migrations.AddField(
1437
+ model_name='pdftype',
1438
+ name='endoscope_info_line',
1439
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pdf_type_endoscopy_info_line', to='endoreg_db.reportreaderflag'),
1440
+ ),
1441
+ migrations.AddField(
1442
+ model_name='pdftype',
1443
+ name='examiner_info_line',
1444
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pdf_type_examiner_info_line', to='endoreg_db.reportreaderflag'),
1445
+ ),
1446
+ migrations.AddField(
1447
+ model_name='pdftype',
1448
+ name='patient_info_line',
1449
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pdf_type_patient_info_line', to='endoreg_db.reportreaderflag'),
1450
+ ),
1451
+ migrations.CreateModel(
1452
+ name='Requirement',
1453
+ fields=[
1454
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1455
+ ('name', models.CharField(max_length=100, unique=True)),
1456
+ ('description', models.TextField(blank=True, null=True)),
1457
+ ('operator_instructions', models.TextField(help_text='semicolon-separated list of target attributes for the requirement')),
1458
+ ('numeric_value', models.FloatField(blank=True, help_text='Numeric value for the requirement. ons.', null=True)),
1459
+ ('numeric_value_min', models.FloatField(blank=True, help_text='Minimum numeric value for the requirement. ons.', null=True)),
1460
+ ('numeric_value_max', models.FloatField(blank=True, help_text='Maximum numeric value for the requirement. ons.', null=True)),
1461
+ ('string_value', models.CharField(blank=True, help_text='String value for the requirement. ons.', max_length=100, null=True)),
1462
+ ('string_values', models.TextField(blank=True, help_text=" ','-separated list of string values for the requirement.ons.", null=True)),
1463
+ ('disease_classification_choices', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.diseaseclassificationchoice')),
1464
+ ('diseases', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.disease')),
1465
+ ('events', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.event')),
1466
+ ('examination_indications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.examinationindication')),
1467
+ ('examinations', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.examination')),
1468
+ ('finding_classification_choices', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.findingclassificationchoice')),
1469
+ ('finding_classifications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.findingclassification')),
1470
+ ('finding_interventions', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.findingintervention')),
1471
+ ('findings', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.finding')),
1472
+ ('genders', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.gender')),
1473
+ ('lab_values', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.labvalue')),
1474
+ ('medication_indications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medicationindication')),
1475
+ ('medication_intake_times', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medicationintaketime')),
1476
+ ('medication_schedules', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medicationschedule')),
1477
+ ('medications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medication')),
1478
+ ('operator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='required_in', to='endoreg_db.requirementoperator')),
1479
+ ('requirement_types', models.ManyToManyField(blank=True, related_name='linked_requirements', to='endoreg_db.requirementtype')),
1480
+ ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='required_in', to='endoreg_db.unit')),
1481
+ ],
1482
+ ),
1483
+ migrations.CreateModel(
1484
+ name='Risk',
1485
+ fields=[
1486
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1487
+ ('name', models.CharField(max_length=100, unique=True)),
1488
+ ('name_de', models.CharField(blank=True, max_length=100, null=True)),
1489
+ ('name_en', models.CharField(blank=True, max_length=100, null=True)),
1490
+ ('description', models.TextField(blank=True, null=True)),
1491
+ ('risk_value', models.FloatField(blank=True, help_text='Risk value for the risk. If not set, the risk is not used in calculations.', null=True)),
1492
+ ('risk_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='risks', to='endoreg_db.risktype')),
1493
+ ],
1494
+ ),
1495
+ migrations.CreateModel(
1496
+ name='SensitiveMeta',
1497
+ fields=[
1498
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1499
+ ('examination_date', models.DateField(blank=True, null=True)),
1500
+ ('examination_time', models.TimeField(blank=True, null=True)),
1501
+ ('casenumber', models.CharField(blank=True, max_length=255, null=True)),
1502
+ ('file_path', models.CharField(blank=True, max_length=1024, null=True)),
1503
+ ('patient_first_name', models.CharField(blank=True, max_length=255, null=True)),
1504
+ ('patient_last_name', models.CharField(blank=True, max_length=255, null=True)),
1505
+ ('patient_dob', models.DateTimeField(blank=True, help_text='Date of birth (can be auto-generated).', null=True)),
1506
+ ('examiner_first_name', models.CharField(blank=True, editable=False, max_length=255, null=True)),
1507
+ ('examiner_last_name', models.CharField(blank=True, editable=False, max_length=255, null=True)),
1508
+ ('patient_hash', models.CharField(blank=True, db_index=True, editable=False, max_length=64, null=True)),
1509
+ ('examination_hash', models.CharField(blank=True, db_index=True, editable=False, max_length=64, null=True)),
1510
+ ('endoscope_type', models.CharField(blank=True, max_length=255, null=True)),
1511
+ ('endoscope_sn', models.CharField(blank=True, max_length=255, null=True)),
1512
+ ('text', models.TextField(blank=True, null=True)),
1513
+ ('anonymized_text', models.TextField(blank=True, null=True)),
1514
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1515
+ ('examiners', models.ManyToManyField(blank=True, help_text='Pseudo-anonymized examiner(s)', to='endoreg_db.examiner')),
1516
+ ('external_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patientexternalid')),
1517
+ ('patient_gender', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.gender')),
1518
+ ('pseudo_examination', models.ForeignKey(blank=True, help_text='FK to the pseudo-anonymized PatientExamination record.', null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patientexamination')),
1519
+ ('pseudo_patient', models.ForeignKey(blank=True, help_text='FK to the pseudo-anonymized Patient record.', null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patient')),
1520
+ ],
1521
+ ),
1522
+ migrations.CreateModel(
1523
+ name='RawPdfFile',
1524
+ fields=[
1525
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1526
+ ('pdf_hash', models.CharField(max_length=255, unique=True)),
1527
+ ('text', models.TextField(blank=True, null=True)),
1528
+ ('date_created', models.DateTimeField(auto_now_add=True)),
1529
+ ('date_modified', models.DateTimeField(auto_now=True)),
1530
+ ('file', models.FileField(upload_to='sensitive_reports', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])])),
1531
+ ('processed_file', models.FileField(blank=True, null=True, upload_to='processed_reports_final', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])])),
1532
+ ('state_report_processing_required', models.BooleanField(default=True)),
1533
+ ('state_report_processed', models.BooleanField(default=False)),
1534
+ ('raw_meta', models.JSONField(blank=True, null=True)),
1535
+ ('anonymized_text', models.TextField(blank=True, null=True)),
1536
+ ('anonym_examination_report', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_file', to='endoreg_db.anonymexaminationreport')),
1537
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1538
+ ('examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_files', to='endoreg_db.patientexamination')),
1539
+ ('examiner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.examiner')),
1540
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_files', to='endoreg_db.patient')),
1541
+ ('pdf_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.pdftype')),
1542
+ ('state', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_file', to='endoreg_db.rawpdfstate')),
1543
+ ('sensitive_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_files', to='endoreg_db.sensitivemeta')),
1544
+ ],
1545
+ ),
1546
+ migrations.CreateModel(
1547
+ name='AnonymHistologyReport',
1548
+ fields=[
1549
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1550
+ ('meta', models.JSONField(blank=True, null=True)),
1551
+ ('text', models.TextField(blank=True, null=True)),
1552
+ ('date', models.DateField(blank=True, null=True)),
1553
+ ('time', models.TimeField(blank=True, null=True)),
1554
+ ('file', models.FileField(blank=True, null=True, upload_to='documents')),
1555
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1556
+ ('type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.documenttype')),
1557
+ ('examiners', models.ManyToManyField(blank=True, to='endoreg_db.examiner')),
1558
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='endoreg_db.patient')),
1559
+ ('patient_examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.patientexamination')),
1560
+ ('sensitive_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.sensitivemeta')),
1561
+ ],
1562
+ options={
1563
+ 'abstract': False,
1564
+ },
1565
+ ),
1566
+ migrations.AddField(
1567
+ model_name='anonymexaminationreport',
1568
+ name='sensitive_meta',
1569
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.sensitivemeta'),
1570
+ ),
1571
+ migrations.CreateModel(
1572
+ name='SensitiveMetaState',
1573
+ fields=[
1574
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1575
+ ('created_at', models.DateTimeField(auto_now_add=True)),
1576
+ ('updated_at', models.DateTimeField(auto_now=True)),
1577
+ ('dob_verified', models.BooleanField(default=False)),
1578
+ ('names_verified', models.BooleanField(default=False)),
1579
+ ('origin', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='state', to='endoreg_db.sensitivemeta')),
1580
+ ],
1581
+ options={
1582
+ 'verbose_name': 'Sensitive Meta State',
1583
+ 'verbose_name_plural': 'Sensitive Meta States',
1584
+ },
1585
+ ),
1586
+ migrations.CreateModel(
1587
+ name='Shift',
1588
+ fields=[
1589
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1590
+ ('name', models.CharField(max_length=255, unique=True)),
1591
+ ('description', models.TextField(blank=True, null=True)),
1592
+ ('is_active', models.BooleanField(default=True)),
1593
+ ('required_qualifications', models.ManyToManyField(related_name='shifts', to='endoreg_db.qualification')),
1594
+ ('shift_types', models.ManyToManyField(related_name='shifts', to='endoreg_db.shifttype')),
1595
+ ],
1596
+ ),
1597
+ migrations.CreateModel(
1598
+ name='CenterShift',
1599
+ fields=[
1600
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1601
+ ('name', models.CharField(max_length=255, unique=True)),
1602
+ ('description', models.TextField(blank=True, null=True)),
1603
+ ('start_time', models.TimeField()),
1604
+ ('end_time', models.TimeField()),
1605
+ ('estimated_presence_fraction', models.DecimalField(decimal_places=4, default=Decimal('0'), max_digits=5)),
1606
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_shifts', to='endoreg_db.center')),
1607
+ ('scheduled_days', models.ManyToManyField(related_name='center_shifts', to='endoreg_db.scheduleddays')),
1608
+ ('shift', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_shifts', to='endoreg_db.shift')),
1609
+ ],
1610
+ ),
1611
+ migrations.CreateModel(
1612
+ name='RequirementSet',
1613
+ fields=[
1614
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1615
+ ('name', models.CharField(max_length=100, unique=True)),
1616
+ ('description', models.TextField(blank=True, null=True)),
1617
+ ('depends_on', models.ManyToManyField(blank=True, help_text="Andere RequirementSets, die zuerst erfüllt sein müssen, bevor dieses Set geprüft wird ('after').", related_name='dependents', to='endoreg_db.requirementset')),
1618
+ ('information_sources', models.ManyToManyField(blank=True, related_name='requirement_sets', to='endoreg_db.informationsource')),
1619
+ ('links_to_sets', models.ManyToManyField(blank=True, related_name='links_from_sets', to='endoreg_db.requirementset')),
1620
+ ('reqset_exam_links', models.ManyToManyField(blank=True, related_name='requirement_set', to='endoreg_db.examinationrequirementset')),
1621
+ ('requirements', models.ManyToManyField(blank=True, related_name='requirement_sets', to='endoreg_db.requirement')),
1622
+ ('requirement_set_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='requirement_sets', to='endoreg_db.requirementsettype')),
1623
+ ('tags', models.ManyToManyField(blank=True, related_name='requirement_sets', to='endoreg_db.tag')),
1624
+ ],
1625
+ ),
1626
+ migrations.CreateModel(
1627
+ name='TransportRoute',
1628
+ fields=[
1629
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1630
+ ('distance', models.FloatField()),
1631
+ ('name', models.CharField(max_length=255)),
1632
+ ('emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.emissionfactor')),
1633
+ ('unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.unit')),
1634
+ ],
1635
+ ),
1636
+ migrations.AddField(
1637
+ model_name='product',
1638
+ name='transport_route',
1639
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.transportroute'),
1640
+ ),
1641
+ migrations.CreateModel(
1642
+ name='ProductWeight',
1643
+ fields=[
1644
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1645
+ ('name', models.CharField(max_length=255, null=True)),
1646
+ ('measured', models.FloatField(null=True)),
1647
+ ('verified', models.FloatField(null=True)),
1648
+ ('manufacturer', models.FloatField(null=True)),
1649
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.product')),
1650
+ ('unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.unit')),
1651
+ ],
1652
+ ),
1653
+ migrations.CreateModel(
1654
+ name='ProductMaterial',
1655
+ fields=[
1656
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1657
+ ('component', models.CharField(max_length=255)),
1658
+ ('quantity', models.FloatField()),
1659
+ ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_product_materials', to='endoreg_db.material')),
1660
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='product_product_materials', to='endoreg_db.product')),
1661
+ ('unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_product_materials', to='endoreg_db.unit')),
1662
+ ],
1663
+ ),
1664
+ migrations.CreateModel(
1665
+ name='PatientLabValue',
1666
+ fields=[
1667
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1668
+ ('value', models.FloatField(blank=True, null=True)),
1669
+ ('value_str', models.CharField(blank=True, max_length=255, null=True)),
1670
+ ('datetime', models.DateTimeField(auto_now_add=True)),
1671
+ ('normal_range', models.JSONField(default=dict)),
1672
+ ('lab_value', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.labvalue')),
1673
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='lab_values', to='endoreg_db.patient')),
1674
+ ('sample', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='values', to='endoreg_db.patientlabsample')),
1675
+ ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.unit')),
1676
+ ],
1677
+ ),
1678
+ migrations.AddField(
1679
+ model_name='medication',
1680
+ name='default_unit',
1681
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.unit'),
1682
+ ),
1683
+ migrations.AddField(
1684
+ model_name='emissionfactor',
1685
+ name='unit',
1686
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.unit'),
1687
+ ),
1688
+ migrations.CreateModel(
1689
+ name='CenterResource',
1690
+ fields=[
1691
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1692
+ ('name', models.CharField(max_length=255, null=True)),
1693
+ ('quantity', models.FloatField()),
1694
+ ('year', models.IntegerField()),
1695
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_resources', to='endoreg_db.center')),
1696
+ ('transport_emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='center_resource_transport_emission_factor', to='endoreg_db.emissionfactor')),
1697
+ ('use_emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='center_resource_use_emission_factor', to='endoreg_db.emissionfactor')),
1698
+ ('resource', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.resource')),
1699
+ ('unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.unit')),
1700
+ ],
1701
+ ),
1702
+ migrations.CreateModel(
1703
+ name='UploadJob',
1704
+ fields=[
1705
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='Unique identifier for the upload job', primary_key=True, serialize=False)),
1706
+ ('file', models.FileField(help_text='Uploaded file (report or video)', upload_to='uploads/%Y/%m/%d/')),
1707
+ ('status', models.CharField(choices=[('pending', 'Pending'), ('processing', 'Processing'), ('anonymized', 'Anonymized'), ('error', 'Error')], default='pending', help_text='Current processing status of the upload', max_length=20)),
1708
+ ('content_type', models.CharField(blank=True, help_text='MIME type of the uploaded file', max_length=100)),
1709
+ ('error_detail', models.TextField(blank=True, help_text='Error message if processing failed')),
1710
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='When the upload job was created')),
1711
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='When the upload job was last updated')),
1712
+ ('sensitive_meta', models.ForeignKey(blank=True, help_text='Link to the created SensitiveMeta record after processing', null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.sensitivemeta')),
1713
+ ],
1714
+ options={
1715
+ 'verbose_name': 'Upload Job',
1716
+ 'verbose_name_plural': 'Upload Jobs',
1717
+ 'ordering': ['-created_at'],
1718
+ },
1719
+ ),
1720
+ migrations.CreateModel(
1721
+ name='VideoFile',
1722
+ fields=[
1723
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1724
+ ('raw_file', models.FileField(blank=True, null=True, upload_to='sensitive_videos', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['mp4'])])),
1725
+ ('processed_file', models.FileField(blank=True, null=True, upload_to='processed_videos_final', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['mp4'])])),
1726
+ ('video_hash', models.CharField(help_text='Hash of the raw video file.', max_length=255, unique=True)),
1727
+ ('processed_video_hash', models.CharField(blank=True, help_text='Hash of the processed video file, unique if not null.', max_length=255, null=True, unique=True)),
1728
+ ('original_file_name', models.CharField(blank=True, max_length=255, null=True)),
1729
+ ('uploaded_at', models.DateTimeField(auto_now_add=True)),
1730
+ ('frame_dir', models.CharField(blank=True, help_text='Path to frames extracted from the raw video.', max_length=512)),
1731
+ ('fps', models.FloatField(blank=True, null=True)),
1732
+ ('duration', models.FloatField(blank=True, null=True)),
1733
+ ('frame_count', models.IntegerField(blank=True, null=True)),
1734
+ ('width', models.IntegerField(blank=True, null=True)),
1735
+ ('height', models.IntegerField(blank=True, null=True)),
1736
+ ('suffix', models.CharField(blank=True, max_length=10, null=True)),
1737
+ ('sequences', models.JSONField(blank=True, default=dict, help_text='AI prediction sequences based on raw frames.')),
1738
+ ('date', models.DateField(blank=True, null=True)),
1739
+ ('meta', models.JSONField(blank=True, null=True)),
1740
+ ('date_created', models.DateTimeField(auto_now_add=True)),
1741
+ ('date_modified', models.DateTimeField(auto_now=True)),
1742
+ ('ai_model_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.modelmeta')),
1743
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='endoreg_db.center')),
1744
+ ('examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_files', to='endoreg_db.patientexamination')),
1745
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_files', to='endoreg_db.patient')),
1746
+ ('processor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='endoreg_db.endoscopyprocessor')),
1747
+ ('sensitive_meta', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_file', to='endoreg_db.sensitivemeta')),
1748
+ ('import_meta', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.videoimportmeta')),
1749
+ ],
1750
+ ),
1751
+ migrations.AddField(
1752
+ model_name='patientexamination',
1753
+ name='video',
1754
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='patient_examination', to='endoreg_db.videofile'),
1755
+ ),
1756
+ migrations.AddField(
1757
+ model_name='labelvideosegment',
1758
+ name='video_file',
1759
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='label_video_segments', to='endoreg_db.videofile'),
1760
+ ),
1761
+ migrations.AddField(
1762
+ model_name='frame',
1763
+ name='video',
1764
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frames', to='endoreg_db.videofile'),
1765
+ ),
1766
+ migrations.CreateModel(
1767
+ name='VideoMeta',
1768
+ fields=[
1769
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1770
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1771
+ ('endoscope', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.endoscope')),
1772
+ ('ffmpeg_meta', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.ffmpegmeta')),
1773
+ ('import_meta', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.videoimportmeta')),
1774
+ ('processor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.endoscopyprocessor')),
1775
+ ],
1776
+ ),
1777
+ migrations.AddField(
1778
+ model_name='videofile',
1779
+ name='video_meta',
1780
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_file', to='endoreg_db.videometa'),
1781
+ ),
1782
+ migrations.CreateModel(
1783
+ name='VideoMetadata',
1784
+ fields=[
1785
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1786
+ ('sensitive_frame_count', models.IntegerField(blank=True, help_text='Number of frames detected as containing sensitive information', null=True)),
1787
+ ('sensitive_ratio', models.FloatField(blank=True, help_text='Ratio of sensitive frames to total frames (0.0-1.0)', null=True)),
1788
+ ('sensitive_frame_ids', models.TextField(blank=True, help_text='JSON array of sensitive frame indices (0-based)', null=True)),
1789
+ ('analyzed_at', models.DateTimeField(auto_now=True, help_text='Timestamp of last analysis')),
1790
+ ('video', models.OneToOneField(help_text='Video file this metadata belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='metadata', to='endoreg_db.videofile')),
1791
+ ],
1792
+ options={
1793
+ 'verbose_name': 'Video Metadata',
1794
+ 'verbose_name_plural': 'Video Metadata',
1795
+ 'db_table': 'video_metadata',
1796
+ },
1797
+ ),
1798
+ migrations.CreateModel(
1799
+ name='VideoPredictionMeta',
1800
+ fields=[
1801
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1802
+ ('date_created', models.DateTimeField(auto_now_add=True)),
1803
+ ('date_modified', models.DateTimeField(auto_now=True)),
1804
+ ('prediction_array', models.BinaryField(blank=True, null=True)),
1805
+ ('model_meta', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.modelmeta')),
1806
+ ('video_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='video_prediction_meta', to='endoreg_db.videofile')),
1807
+ ],
1808
+ ),
1809
+ migrations.AddField(
1810
+ model_name='labelvideosegment',
1811
+ name='prediction_meta',
1812
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='label_video_segments', to='endoreg_db.videopredictionmeta'),
1813
+ ),
1814
+ migrations.CreateModel(
1815
+ name='VideoProcessingHistory',
1816
+ fields=[
1817
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1818
+ ('operation', models.CharField(choices=[('mask_overlay', 'Mask Overlay'), ('frame_removal', 'Frame Removal'), ('analysis', 'Sensitivity Analysis'), ('reprocessing', 'Full Reprocessing')], help_text='Type of processing operation', max_length=50)),
1819
+ ('status', models.CharField(choices=[('pending', 'Pending'), ('running', 'Running'), ('success', 'Success'), ('failure', 'Failure'), ('cancelled', 'Cancelled')], default='pending', help_text='Current status of the operation', max_length=20)),
1820
+ ('config', models.JSONField(default=dict, help_text='Operation configuration (mask settings, frame list, etc.)')),
1821
+ ('output_file', models.CharField(blank=True, help_text='Path to output file (relative to MEDIA_ROOT)', max_length=500)),
1822
+ ('details', models.TextField(blank=True, help_text='Additional details or error messages')),
1823
+ ('task_id', models.CharField(blank=True, help_text='Celery task ID for progress tracking', max_length=100)),
1824
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='When the operation was started')),
1825
+ ('completed_at', models.DateTimeField(blank=True, help_text='When the operation completed (success or failure)', null=True)),
1826
+ ('video', models.ForeignKey(help_text='Video file this operation was performed on', on_delete=django.db.models.deletion.CASCADE, related_name='processing_history', to='endoreg_db.videofile')),
1827
+ ],
1828
+ options={
1829
+ 'verbose_name': 'Video Processing History',
1830
+ 'verbose_name_plural': 'Video Processing Histories',
1831
+ 'db_table': 'video_processing_history',
1832
+ 'ordering': ['-created_at'],
1833
+ },
1834
+ ),
1835
+ migrations.CreateModel(
1836
+ name='VideoSegmentationAnnotation',
1837
+ fields=[
1838
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1839
+ ('start_time', models.FloatField()),
1840
+ ('stop_time', models.FloatField()),
1841
+ ('is_true', models.BooleanField(default=True)),
1842
+ ('video_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='video_segmentation_annotations', to='endoreg_db.videofile')),
1843
+ ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.videosegmentationlabel')),
1844
+ ],
1845
+ ),
1846
+ migrations.CreateModel(
1847
+ name='VideoSegmentationLabelSet',
1848
+ fields=[
1849
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1850
+ ('name', models.CharField(max_length=255)),
1851
+ ('description', models.TextField(blank=True, null=True)),
1852
+ ('labels', models.ManyToManyField(related_name='labelsets', to='endoreg_db.videosegmentationlabel')),
1853
+ ],
1854
+ ),
1855
+ migrations.AddField(
1856
+ model_name='aimodel',
1857
+ name='video_segmentation_labelset',
1858
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ai_models', to='endoreg_db.videosegmentationlabelset'),
1859
+ ),
1860
+ migrations.AddField(
1861
+ model_name='videofile',
1862
+ name='state',
1863
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_file', to='endoreg_db.videostate'),
1864
+ ),
1865
+ migrations.CreateModel(
1866
+ name='CenterWaste',
1867
+ fields=[
1868
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1869
+ ('year', models.IntegerField()),
1870
+ ('quantity', models.FloatField()),
1871
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_wastes', to='endoreg_db.center')),
1872
+ ('emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.emissionfactor')),
1873
+ ('unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.unit')),
1874
+ ('waste', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.waste')),
1875
+ ],
1876
+ ),
1877
+ migrations.AddIndex(
1878
+ model_name='imageclassificationannotation',
1879
+ index=models.Index(fields=['frame', 'label'], name='endoreg_db__frame_i_47f916_idx'),
1880
+ ),
1881
+ migrations.AddIndex(
1882
+ model_name='imageclassificationannotation',
1883
+ index=models.Index(fields=['frame'], name='endoreg_db__frame_i_92c75a_idx'),
1884
+ ),
1885
+ migrations.AddConstraint(
1886
+ model_name='patientexternalid',
1887
+ constraint=models.UniqueConstraint(fields=('origin', 'external_id'), name='uniq_patient_external_id_per_origin'),
1888
+ ),
1889
+ migrations.AddIndex(
1890
+ model_name='patientfinding',
1891
+ index=models.Index(fields=['patient_examination', 'finding'], name='endoreg_db__patient_54869f_idx'),
1892
+ ),
1893
+ migrations.AddIndex(
1894
+ model_name='patientfinding',
1895
+ index=models.Index(fields=['patient_examination', 'is_active'], name='endoreg_db__patient_9359f8_idx'),
1896
+ ),
1897
+ migrations.AddIndex(
1898
+ model_name='patientfinding',
1899
+ index=models.Index(fields=['created_at'], name='endoreg_db__created_b44d86_idx'),
1900
+ ),
1901
+ migrations.AddIndex(
1902
+ model_name='patientfinding',
1903
+ index=models.Index(fields=['finding', 'is_active'], name='endoreg_db__finding_2f036b_idx'),
1904
+ ),
1905
+ migrations.AddConstraint(
1906
+ model_name='patientfinding',
1907
+ constraint=models.UniqueConstraint(condition=models.Q(('is_active', True)), fields=('patient_examination', 'finding'), name='unique_active_finding_per_examination'),
1908
+ ),
1909
+ migrations.AddConstraint(
1910
+ model_name='patientfinding',
1911
+ constraint=models.CheckConstraint(condition=models.Q(models.Q(('deactivated_at__isnull', True), ('deactivated_by__isnull', True)), models.Q(('deactivated_at__isnull', False), ('deactivated_by__isnull', False), ('is_active', False)), _connector='OR'), name='deactivation_fields_consistency'),
1912
+ ),
1913
+ migrations.AlterUniqueTogether(
1914
+ name='frame',
1915
+ unique_together={('video', 'frame_number')},
1916
+ ),
1917
+ migrations.AddIndex(
1918
+ model_name='videopredictionmeta',
1919
+ index=models.Index(fields=['model_meta', 'video_file'], name='endoreg_db__model_m_208dee_idx'),
1920
+ ),
1921
+ migrations.AddConstraint(
1922
+ model_name='videopredictionmeta',
1923
+ constraint=models.UniqueConstraint(fields=('model_meta', 'video_file'), name='unique_prediction_per_video_model'),
1924
+ ),
1925
+ migrations.AddIndex(
1926
+ model_name='labelvideosegment',
1927
+ index=models.Index(fields=['video_file', 'label', 'start_frame_number'], name='endoreg_db__video_f_fa9326_idx'),
1928
+ ),
1929
+ migrations.AddIndex(
1930
+ model_name='labelvideosegment',
1931
+ index=models.Index(fields=['prediction_meta', 'label'], name='endoreg_db__predict_2bfba4_idx'),
1932
+ ),
1933
+ migrations.AddConstraint(
1934
+ model_name='labelvideosegment',
1935
+ constraint=models.CheckConstraint(condition=models.Q(('start_frame_number__lt', models.F('end_frame_number'))), name='segment_start_lt_end'),
1936
+ ),
1937
+ migrations.AddIndex(
1938
+ model_name='videoprocessinghistory',
1939
+ index=models.Index(fields=['video', '-created_at'], name='video_proce_video_i_98ffe0_idx'),
1940
+ ),
1941
+ migrations.AddIndex(
1942
+ model_name='videoprocessinghistory',
1943
+ index=models.Index(fields=['task_id'], name='video_proce_task_id_ec8b15_idx'),
1944
+ ),
1945
+ migrations.AddIndex(
1946
+ model_name='videoprocessinghistory',
1947
+ index=models.Index(fields=['status'], name='video_proce_status_6f71fd_idx'),
1948
+ ),
1949
+ migrations.AddConstraint(
1950
+ model_name='videosegmentationannotation',
1951
+ constraint=models.CheckConstraint(condition=models.Q(('start_time__lt', models.F('stop_time'))), name='start_time_less_than_stop_time'),
1952
+ ),
1953
+ ]