endoreg-db 0.6.4__py3-none-any.whl → 0.8.2__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 (779) hide show
  1. endoreg_db/admin.py +26 -26
  2. endoreg_db/api_urls.py +4 -0
  3. endoreg_db/apps.py +12 -0
  4. endoreg_db/assets/dummy_model.ckpt +1 -0
  5. endoreg_db/codemods/readme.md +88 -0
  6. endoreg_db/codemods/rename_datetime_fields.py +92 -0
  7. endoreg_db/config/env.py +101 -0
  8. endoreg_db/data/__init__.py +12 -0
  9. endoreg_db/data/ai_model/data.yaml +1 -1
  10. endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
  11. endoreg_db/data/ai_model_label/label-set/data.yaml +20 -1
  12. endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
  13. endoreg_db/data/center/data.yaml +13 -12
  14. endoreg_db/data/center_shift/ukw.yaml +9 -0
  15. endoreg_db/data/db_summary.csv +58 -0
  16. endoreg_db/data/db_summary.xlsx +0 -0
  17. endoreg_db/data/disease/misc.yaml +1 -2
  18. endoreg_db/data/endoscopy_processor/data.yaml +3 -0
  19. endoreg_db/data/event/cardiology.yaml +0 -13
  20. endoreg_db/data/examination/examinations/data.yaml +14 -9
  21. endoreg_db/data/examination_indication/endoscopy.yaml +30 -30
  22. endoreg_db/data/examination_indication_classification/endoscopy.yaml +11 -11
  23. endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
  24. endoreg_db/data/finding/anatomy_colon.yaml +128 -0
  25. endoreg_db/data/finding/colonoscopy.yaml +40 -0
  26. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +56 -0
  27. endoreg_db/data/finding/complication.yaml +16 -0
  28. endoreg_db/data/finding/data.yaml +3 -46
  29. endoreg_db/data/finding/examination_setting.yaml +16 -0
  30. endoreg_db/data/finding/medication_related.yaml +18 -0
  31. endoreg_db/data/finding/outcome.yaml +12 -0
  32. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +95 -0
  33. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +22 -0
  34. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +25 -0
  35. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
  36. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
  37. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +68 -0
  38. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
  39. endoreg_db/data/finding_classification/colonoscopy_location.yaml +80 -0
  40. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +21 -0
  41. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +20 -0
  42. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +26 -0
  43. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +22 -0
  44. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +53 -0
  45. endoreg_db/data/finding_classification/complication_generic.yaml +25 -0
  46. endoreg_db/data/finding_classification/examination_setting_generic.yaml +40 -0
  47. endoreg_db/data/finding_classification/histology_colo.yaml +51 -0
  48. endoreg_db/data/finding_classification/intervention_required.yaml +26 -0
  49. endoreg_db/data/finding_classification/medication_related.yaml +23 -0
  50. endoreg_db/data/finding_classification/visualized.yaml +33 -0
  51. endoreg_db/data/finding_classification_choice/bowel_preparation.yaml +78 -0
  52. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_circularity_default.yaml +0 -2
  53. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
  54. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
  55. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +15 -0
  56. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_nice.yaml +4 -7
  57. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_paris.yaml +0 -8
  58. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_planarity_default.yaml +6 -13
  59. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
  60. endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_surface_intact_default.yaml +3 -6
  61. endoreg_db/data/{finding_location_classification_choice/colonoscopy.yaml → finding_classification_choice/colonoscopy_location.yaml} +11 -22
  62. endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
  63. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +82 -0
  64. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
  65. endoreg_db/data/finding_classification_choice/complication_generic_types.yaml +15 -0
  66. endoreg_db/data/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
  67. endoreg_db/data/finding_classification_choice/histology.yaml +24 -0
  68. endoreg_db/data/finding_classification_choice/histology_polyp.yaml +20 -0
  69. endoreg_db/data/finding_classification_choice/outcome.yaml +19 -0
  70. endoreg_db/data/finding_classification_choice/yes_no_na.yaml +11 -0
  71. endoreg_db/data/finding_classification_type/colonoscopy_basic.yaml +48 -0
  72. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +8 -3
  73. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +6 -6
  74. endoreg_db/data/finding_type/data.yaml +23 -10
  75. endoreg_db/data/gender/data.yaml +8 -1
  76. endoreg_db/data/information_source/annotation.yaml +6 -0
  77. endoreg_db/data/information_source/prediction.yaml +7 -0
  78. endoreg_db/data/information_source_type/data.yaml +8 -0
  79. endoreg_db/data/lab_value/misc.yaml +43 -0
  80. endoreg_db/data/medication/anticoagulation.yaml +5 -5
  81. endoreg_db/data/medication/tah.yaml +5 -5
  82. endoreg_db/data/medication_intake_time/base.yaml +4 -4
  83. endoreg_db/data/names_first/first_names.yaml +3 -0
  84. endoreg_db/data/pdf_type/data.yaml +26 -2
  85. endoreg_db/data/qualification/endoscopy.yaml +36 -0
  86. endoreg_db/data/qualification/m2.yaml +39 -0
  87. endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
  88. endoreg_db/data/qualification/sonography.yaml +36 -0
  89. endoreg_db/data/qualification_type/base.yaml +29 -0
  90. endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
  91. endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +5 -0
  92. endoreg_db/data/requirement/age.yaml +26 -0
  93. endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +45 -0
  94. endoreg_db/data/requirement/disease_cardiovascular.yaml +6 -6
  95. endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +9 -6
  96. endoreg_db/data/requirement/disease_hepatology.yaml +1 -1
  97. endoreg_db/data/requirement/disease_misc.yaml +3 -3
  98. endoreg_db/data/requirement/disease_renal.yaml +18 -2
  99. endoreg_db/data/requirement/{colonoscopy_indications.yaml → endoscopy_bleeding_risk.yaml} +6 -3
  100. endoreg_db/data/requirement/event_cardiology.yaml +17 -17
  101. endoreg_db/data/requirement/event_requirements.yaml +145 -0
  102. endoreg_db/data/requirement/finding_colon_polyp.yaml +50 -0
  103. endoreg_db/data/requirement/gender.yaml +25 -0
  104. endoreg_db/data/requirement/lab_value.yaml +352 -31
  105. endoreg_db/data/requirement/medication.yaml +93 -0
  106. endoreg_db/data/requirement_operator/age.yaml +13 -0
  107. endoreg_db/data/requirement_operator/lab_operators.yaml +36 -35
  108. endoreg_db/data/requirement_operator/model_operators.yaml +13 -7
  109. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +48 -0
  110. endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
  111. endoreg_db/data/requirement_set/endoscopy_bleeding_risk.yaml +42 -2
  112. endoreg_db/data/requirement_type/requirement_types.yaml +82 -0
  113. endoreg_db/data/shift/endoscopy.yaml +21 -0
  114. endoreg_db/data/shift_type/base.yaml +35 -0
  115. endoreg_db/data/tag/requirement_set_tags.yaml +11 -0
  116. endoreg_db/data/unit/concentration.yaml +23 -0
  117. endoreg_db/exceptions.py +19 -0
  118. endoreg_db/forms/patient_finding_intervention_form.py +4 -5
  119. endoreg_db/forms/patient_form.py +7 -6
  120. endoreg_db/forms/questionnaires/__init__.py +1 -1
  121. endoreg_db/forms/questionnaires/tto_questionnaire.py +19 -19
  122. endoreg_db/helpers/count_db.py +45 -0
  123. endoreg_db/helpers/data_loader.py +208 -0
  124. endoreg_db/helpers/default_objects.py +359 -0
  125. endoreg_db/helpers/download_segmentation_model.py +31 -0
  126. endoreg_db/helpers/interact.py +6 -0
  127. endoreg_db/helpers/test_video_helper.py +119 -0
  128. endoreg_db/logger_conf.py +140 -0
  129. endoreg_db/management/__init__.py +1 -0
  130. endoreg_db/management/commands/__init__.py +1 -0
  131. endoreg_db/management/commands/anonymize_video.py +0 -0
  132. endoreg_db/management/commands/check_auth.py +125 -0
  133. endoreg_db/management/commands/create_multilabel_model_meta.py +214 -0
  134. endoreg_db/management/commands/fix_missing_patient_data.py +172 -0
  135. endoreg_db/management/commands/fix_video_paths.py +165 -0
  136. endoreg_db/management/commands/import_fallback_video.py +203 -0
  137. endoreg_db/management/commands/import_report.py +298 -0
  138. endoreg_db/management/commands/import_video.py +422 -0
  139. endoreg_db/management/commands/import_video_with_classification.py +367 -0
  140. endoreg_db/management/commands/init_default_ai_model.py +112 -0
  141. endoreg_db/management/commands/load_ai_model_data.py +2 -7
  142. endoreg_db/management/commands/load_base_db_data.py +1 -0
  143. endoreg_db/management/commands/load_endoscope_data.py +2 -2
  144. endoreg_db/management/commands/load_examination_indication_data.py +2 -3
  145. endoreg_db/management/commands/load_finding_data.py +49 -92
  146. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +0 -1
  147. endoreg_db/management/commands/load_information_source.py +13 -7
  148. endoreg_db/management/commands/load_name_data.py +37 -0
  149. endoreg_db/management/commands/load_qualification_data.py +59 -0
  150. endoreg_db/management/commands/load_requirement_data.py +30 -6
  151. endoreg_db/management/commands/load_shift_data.py +60 -0
  152. endoreg_db/management/commands/load_tag_data.py +57 -0
  153. endoreg_db/management/commands/register_ai_model.py +1 -1
  154. endoreg_db/management/commands/start_filewatcher.py +106 -0
  155. endoreg_db/management/commands/storage_management.py +548 -0
  156. endoreg_db/management/commands/summarize_db_content.py +189 -0
  157. endoreg_db/management/commands/validate_video.py +204 -0
  158. endoreg_db/management/commands/validate_video_files.py +161 -0
  159. endoreg_db/management/commands/video_validation.py +22 -0
  160. endoreg_db/migrations/0001_initial.py +625 -813
  161. endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
  162. endoreg_db/models/__init__.py +270 -307
  163. endoreg_db/models/administration/__init__.py +116 -0
  164. endoreg_db/models/{ai_model → administration/ai}/__init__.py +6 -1
  165. endoreg_db/models/administration/ai/active_model.py +35 -0
  166. endoreg_db/models/administration/ai/ai_model.py +156 -0
  167. endoreg_db/models/{ai_model → administration/ai}/model_type.py +6 -1
  168. endoreg_db/models/administration/case/__init__.py +19 -0
  169. endoreg_db/models/administration/case/case.py +114 -0
  170. endoreg_db/models/{case_template → administration/case/case_template}/case_template.py +3 -3
  171. endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule.py +3 -10
  172. endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule_value.py +2 -4
  173. endoreg_db/models/{case_template → administration/case/case_template}/case_template_type.py +1 -3
  174. endoreg_db/models/{center → administration/center}/__init__.py +3 -1
  175. endoreg_db/models/administration/center/center.py +61 -0
  176. endoreg_db/models/administration/center/center_product.py +64 -0
  177. endoreg_db/models/{center → administration/center}/center_resource.py +19 -3
  178. endoreg_db/models/administration/center/center_shift.py +88 -0
  179. endoreg_db/models/administration/center/center_waste.py +30 -0
  180. endoreg_db/models/administration/permissions/__init__.py +44 -0
  181. endoreg_db/models/administration/person/__init__.py +24 -0
  182. endoreg_db/models/administration/person/employee/__init__.py +3 -0
  183. endoreg_db/models/administration/person/employee/employee.py +35 -0
  184. endoreg_db/models/administration/person/employee/employee_qualification.py +39 -0
  185. endoreg_db/models/administration/person/employee/employee_type.py +42 -0
  186. endoreg_db/models/administration/person/examiner/__init__.py +4 -0
  187. endoreg_db/models/administration/person/examiner/examiner.py +54 -0
  188. endoreg_db/models/administration/person/names/__init__.py +0 -0
  189. endoreg_db/models/{persons → administration/person/names}/first_name.py +1 -1
  190. endoreg_db/models/{persons → administration/person/names}/last_name.py +2 -3
  191. endoreg_db/models/administration/person/patient/__init__.py +5 -0
  192. endoreg_db/models/administration/person/patient/patient.py +460 -0
  193. endoreg_db/models/administration/person/profession/__init__.py +24 -0
  194. endoreg_db/models/administration/person/user/__init__.py +5 -0
  195. endoreg_db/models/administration/person/user/portal_user_information.py +37 -0
  196. endoreg_db/models/administration/product/product.py +97 -0
  197. endoreg_db/models/administration/product/product_group.py +39 -0
  198. endoreg_db/models/administration/product/product_material.py +54 -0
  199. endoreg_db/models/{product → administration/product}/product_weight.py +9 -0
  200. endoreg_db/models/{product → administration/product}/reference_product.py +26 -11
  201. endoreg_db/models/administration/qualification/__init__.py +7 -0
  202. endoreg_db/models/administration/qualification/qualification.py +37 -0
  203. endoreg_db/models/administration/qualification/qualification_type.py +35 -0
  204. endoreg_db/models/administration/shift/__init__.py +9 -0
  205. endoreg_db/models/administration/shift/scheduled_days.py +69 -0
  206. endoreg_db/models/administration/shift/shift.py +51 -0
  207. endoreg_db/models/administration/shift/shift_type.py +108 -0
  208. endoreg_db/models/label/__init__.py +24 -1
  209. endoreg_db/models/label/annotation/__init__.py +12 -0
  210. endoreg_db/models/label/annotation/image_classification.py +84 -0
  211. endoreg_db/models/label/annotation/video_segmentation_annotation.py +66 -0
  212. endoreg_db/models/label/label.py +45 -74
  213. endoreg_db/models/label/label_set.py +53 -0
  214. endoreg_db/models/label/label_type.py +29 -0
  215. endoreg_db/models/label/label_video_segment/__init__.py +3 -0
  216. endoreg_db/models/label/label_video_segment/_create_from_video.py +41 -0
  217. endoreg_db/models/label/label_video_segment/label_video_segment.py +511 -0
  218. endoreg_db/models/label/video_segmentation_label.py +31 -0
  219. endoreg_db/models/{annotation → label}/video_segmentation_labelset.py +7 -0
  220. endoreg_db/models/media/__init__.py +14 -0
  221. endoreg_db/models/media/frame/__init__.py +3 -0
  222. endoreg_db/models/media/frame/frame.py +111 -0
  223. endoreg_db/models/media/pdf/__init__.py +11 -0
  224. endoreg_db/models/media/pdf/raw_pdf.py +608 -0
  225. endoreg_db/models/media/pdf/report_file.py +162 -0
  226. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +77 -0
  227. endoreg_db/models/media/video/__init__.py +4 -0
  228. endoreg_db/models/media/video/create_from_file.py +336 -0
  229. endoreg_db/models/media/video/pipe_1.py +207 -0
  230. endoreg_db/models/media/video/pipe_2.py +105 -0
  231. endoreg_db/models/media/video/refactor_plan.md +0 -0
  232. endoreg_db/models/media/video/video_file.py +680 -0
  233. endoreg_db/models/media/video/video_file_ai.py +443 -0
  234. endoreg_db/models/media/video/video_file_anonymize.py +348 -0
  235. endoreg_db/models/media/video/video_file_frames/__init__.py +47 -0
  236. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +22 -0
  237. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
  238. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +104 -0
  239. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +174 -0
  240. endoreg_db/models/media/video/video_file_frames/_get_frame.py +28 -0
  241. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +27 -0
  242. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +20 -0
  243. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +27 -0
  244. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +34 -0
  245. endoreg_db/models/media/video/video_file_frames/_get_frames.py +27 -0
  246. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +129 -0
  247. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +129 -0
  248. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +65 -0
  249. endoreg_db/models/media/video/video_file_frames.py +0 -0
  250. endoreg_db/models/media/video/video_file_io.py +166 -0
  251. endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
  252. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +45 -0
  253. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +39 -0
  254. endoreg_db/models/media/video/video_file_meta/get_fps.py +147 -0
  255. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +143 -0
  256. endoreg_db/models/media/video/video_file_meta/text_meta.py +134 -0
  257. endoreg_db/models/media/video/video_file_meta/video_meta.py +70 -0
  258. endoreg_db/models/media/video/video_file_meta.py +11 -0
  259. endoreg_db/models/media/video/video_file_segments.py +209 -0
  260. endoreg_db/models/medical/__init__.py +146 -0
  261. endoreg_db/models/{contraindication → medical/contraindication}/__init__.py +1 -5
  262. endoreg_db/models/{disease.py → medical/disease.py} +60 -52
  263. endoreg_db/models/{event.py → medical/event.py} +31 -54
  264. endoreg_db/models/{examination → medical/examination}/__init__.py +1 -1
  265. endoreg_db/models/medical/examination/examination.py +148 -0
  266. endoreg_db/models/{examination → medical/examination}/examination_indication.py +64 -35
  267. endoreg_db/models/{examination → medical/examination}/examination_time.py +0 -4
  268. endoreg_db/models/{examination → medical/examination}/examination_time_type.py +1 -8
  269. endoreg_db/models/{examination → medical/examination}/examination_type.py +1 -7
  270. endoreg_db/models/medical/finding/__init__.py +18 -0
  271. endoreg_db/models/medical/finding/finding.py +96 -0
  272. endoreg_db/models/medical/finding/finding_classification.py +142 -0
  273. endoreg_db/models/{finding → medical/finding}/finding_intervention.py +2 -10
  274. endoreg_db/models/medical/finding/finding_type.py +35 -0
  275. endoreg_db/models/medical/hardware/__init__.py +8 -0
  276. endoreg_db/models/{hardware → medical/hardware}/endoscope.py +28 -23
  277. endoreg_db/models/medical/laboratory/__init__.py +5 -0
  278. endoreg_db/models/medical/laboratory/lab_value.py +419 -0
  279. endoreg_db/models/{medication → medical/medication}/medication.py +1 -3
  280. endoreg_db/models/{medication → medical/medication}/medication_indication_type.py +8 -3
  281. endoreg_db/models/{medication → medical/medication}/medication_intake_time.py +21 -3
  282. endoreg_db/models/{medication → medical/medication}/medication_schedule.py +13 -5
  283. endoreg_db/models/{organ → medical/organ}/__init__.py +3 -6
  284. endoreg_db/models/medical/patient/__init__.py +56 -0
  285. endoreg_db/models/medical/patient/medication_examples.py +38 -0
  286. endoreg_db/models/medical/patient/patient_disease.py +63 -0
  287. endoreg_db/models/medical/patient/patient_event.py +75 -0
  288. endoreg_db/models/medical/patient/patient_examination.py +249 -0
  289. endoreg_db/models/{persons → medical}/patient/patient_examination_indication.py +21 -9
  290. endoreg_db/models/medical/patient/patient_finding.py +357 -0
  291. endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
  292. endoreg_db/models/{patient → medical/patient}/patient_finding_intervention.py +15 -1
  293. endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
  294. endoreg_db/models/{persons → medical}/patient/patient_lab_value.py +40 -15
  295. endoreg_db/models/medical/patient/patient_medication.py +104 -0
  296. endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
  297. endoreg_db/models/{risk → medical/risk}/risk_type.py +0 -4
  298. endoreg_db/models/{data_file/metadata → metadata}/__init__.py +6 -0
  299. endoreg_db/models/metadata/frame_ocr_result.py +0 -0
  300. endoreg_db/models/metadata/model_meta.py +193 -0
  301. endoreg_db/models/metadata/model_meta_logic.py +236 -0
  302. endoreg_db/models/{data_file/metadata → metadata}/pdf_meta.py +28 -13
  303. endoreg_db/models/metadata/sensitive_meta.py +288 -0
  304. endoreg_db/models/metadata/sensitive_meta_logic.py +643 -0
  305. endoreg_db/models/metadata/video_meta.py +332 -0
  306. endoreg_db/models/metadata/video_prediction_logic.py +190 -0
  307. endoreg_db/models/metadata/video_prediction_meta.py +270 -0
  308. endoreg_db/models/other/__init__.py +17 -0
  309. endoreg_db/models/other/distribution/date_value_distribution.py +0 -2
  310. endoreg_db/models/other/distribution/numeric_value_distribution.py +30 -2
  311. endoreg_db/models/{emission → other/emission}/emission_factor.py +15 -6
  312. endoreg_db/models/{persons → other}/gender.py +8 -3
  313. endoreg_db/models/other/information_source.py +159 -0
  314. endoreg_db/models/other/material.py +10 -2
  315. endoreg_db/models/other/resource.py +6 -2
  316. endoreg_db/models/other/tag.py +27 -0
  317. endoreg_db/models/other/transport_route.py +13 -2
  318. endoreg_db/models/{unit.py → other/unit.py} +16 -6
  319. endoreg_db/models/other/waste.py +10 -3
  320. endoreg_db/models/requirement/requirement.py +556 -114
  321. endoreg_db/models/requirement/requirement_evaluation/__init__.py +4 -132
  322. endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
  323. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +9 -0
  324. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +80 -87
  325. endoreg_db/models/requirement/requirement_operator.py +132 -14
  326. endoreg_db/models/requirement/requirement_set.py +181 -21
  327. endoreg_db/models/rule/__init__.py +13 -0
  328. endoreg_db/models/{rules → rule}/rule.py +6 -3
  329. endoreg_db/models/{rules → rule}/rule_attribute_dtype.py +0 -2
  330. endoreg_db/models/{rules → rule}/rule_type.py +0 -2
  331. endoreg_db/models/{rules → rule}/ruleset.py +0 -2
  332. endoreg_db/models/state/__init__.py +12 -0
  333. endoreg_db/models/state/abstract.py +11 -0
  334. endoreg_db/models/state/audit_ledger.py +150 -0
  335. endoreg_db/models/state/label_video_segment.py +22 -0
  336. endoreg_db/models/state/raw_pdf.py +187 -0
  337. endoreg_db/models/state/sensitive_meta.py +46 -0
  338. endoreg_db/models/state/video.py +232 -0
  339. endoreg_db/models/upload_job.py +99 -0
  340. endoreg_db/models/utils.py +135 -0
  341. endoreg_db/models/video_metadata.py +66 -0
  342. endoreg_db/models/video_processing.py +153 -0
  343. endoreg_db/renames.yml +8 -0
  344. endoreg_db/root_urls.py +9 -0
  345. endoreg_db/schemas/__init__.py +0 -0
  346. endoreg_db/schemas/examination_evaluation.py +27 -0
  347. endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +775 -0
  348. endoreg_db/serializers/__init__.py +147 -10
  349. endoreg_db/serializers/{raw_pdf_meta_validation.py → _old/raw_pdf_meta_validation.py} +3 -3
  350. endoreg_db/serializers/{raw_video_meta_validation.py → _old/raw_video_meta_validation.py} +18 -14
  351. endoreg_db/serializers/_old/video.py +71 -0
  352. endoreg_db/serializers/administration/__init__.py +14 -0
  353. endoreg_db/serializers/administration/ai/__init__.py +10 -0
  354. endoreg_db/serializers/administration/ai/active_model.py +10 -0
  355. endoreg_db/serializers/administration/ai/ai_model.py +18 -0
  356. endoreg_db/serializers/administration/ai/model_type.py +10 -0
  357. endoreg_db/serializers/administration/center.py +9 -0
  358. endoreg_db/serializers/administration/gender.py +9 -0
  359. endoreg_db/serializers/anonymization.py +69 -0
  360. endoreg_db/serializers/evaluation/examination_evaluation.py +1 -0
  361. endoreg_db/serializers/examination/__init__.py +10 -0
  362. endoreg_db/serializers/examination/base.py +46 -0
  363. endoreg_db/serializers/examination/dropdown.py +21 -0
  364. endoreg_db/serializers/examination_serializer.py +12 -0
  365. endoreg_db/serializers/finding/__init__.py +5 -0
  366. endoreg_db/serializers/finding/finding.py +54 -0
  367. endoreg_db/serializers/finding_classification/__init__.py +7 -0
  368. endoreg_db/serializers/finding_classification/choice.py +19 -0
  369. endoreg_db/serializers/finding_classification/classification.py +13 -0
  370. endoreg_db/serializers/label/__init__.py +7 -0
  371. endoreg_db/serializers/label/image_classification_annotation.py +62 -0
  372. endoreg_db/serializers/label/label.py +15 -0
  373. endoreg_db/serializers/label_video_segment/__init__.py +7 -0
  374. endoreg_db/serializers/label_video_segment/_lvs_create.py +149 -0
  375. endoreg_db/serializers/label_video_segment/_lvs_update.py +138 -0
  376. endoreg_db/serializers/label_video_segment/_lvs_validate.py +149 -0
  377. endoreg_db/serializers/label_video_segment/label_video_segment.py +344 -0
  378. endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +99 -0
  379. endoreg_db/serializers/label_video_segment/label_video_segment_update.py +163 -0
  380. endoreg_db/serializers/meta/__init__.py +19 -0
  381. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +115 -0
  382. endoreg_db/serializers/meta/report_meta.py +53 -0
  383. endoreg_db/serializers/meta/sensitive_meta_detail.py +162 -0
  384. endoreg_db/serializers/meta/sensitive_meta_update.py +148 -0
  385. endoreg_db/serializers/meta/sensitive_meta_verification.py +59 -0
  386. endoreg_db/serializers/meta/video_meta.py +39 -0
  387. endoreg_db/serializers/misc/__init__.py +14 -0
  388. endoreg_db/serializers/misc/file_overview.py +152 -0
  389. endoreg_db/serializers/misc/stats.py +33 -0
  390. endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
  391. endoreg_db/serializers/misc/upload_job.py +71 -0
  392. endoreg_db/serializers/misc/vop_patient_data.py +120 -0
  393. endoreg_db/serializers/patient/__init__.py +11 -0
  394. endoreg_db/serializers/patient/patient.py +86 -0
  395. endoreg_db/serializers/patient/patient_dropdown.py +27 -0
  396. endoreg_db/serializers/patient_examination/__init__.py +7 -0
  397. endoreg_db/serializers/patient_examination/patient_examination.py +141 -0
  398. endoreg_db/serializers/patient_finding/__init__.py +15 -0
  399. endoreg_db/serializers/patient_finding/patient_finding.py +31 -0
  400. endoreg_db/serializers/patient_finding/patient_finding_classification.py +39 -0
  401. endoreg_db/serializers/patient_finding/patient_finding_detail.py +53 -0
  402. endoreg_db/serializers/patient_finding/patient_finding_intervention.py +26 -0
  403. endoreg_db/serializers/patient_finding/patient_finding_list.py +41 -0
  404. endoreg_db/serializers/patient_finding/patient_finding_write.py +126 -0
  405. endoreg_db/serializers/pdf/__init__.py +5 -0
  406. endoreg_db/serializers/pdf/anony_text_validation.py +85 -0
  407. endoreg_db/serializers/report/__init__.py +9 -0
  408. endoreg_db/serializers/report/mixins.py +45 -0
  409. endoreg_db/serializers/report/report.py +105 -0
  410. endoreg_db/serializers/report/report_list.py +22 -0
  411. endoreg_db/serializers/report/secure_file_url.py +26 -0
  412. endoreg_db/serializers/requirements/requirement_schema.py +25 -0
  413. endoreg_db/serializers/requirements/requirement_sets.py +29 -0
  414. endoreg_db/serializers/sensitive_meta_serializer.py +282 -0
  415. endoreg_db/serializers/video/__init__.py +7 -0
  416. endoreg_db/serializers/video/segmentation.py +263 -0
  417. endoreg_db/serializers/video/video_file_brief.py +10 -0
  418. endoreg_db/serializers/video/video_file_detail.py +83 -0
  419. endoreg_db/serializers/video/video_file_list.py +67 -0
  420. endoreg_db/serializers/video/video_metadata.py +105 -0
  421. endoreg_db/serializers/video/video_processing_history.py +153 -0
  422. endoreg_db/services/__init__.py +5 -0
  423. endoreg_db/services/anonymization.py +223 -0
  424. endoreg_db/services/examination_evaluation.py +149 -0
  425. endoreg_db/services/finding_description_service.py +0 -0
  426. endoreg_db/services/lookup_service.py +241 -0
  427. endoreg_db/services/lookup_store.py +122 -0
  428. endoreg_db/services/ollama_api_docs.py +1528 -0
  429. endoreg_db/services/pdf_import.py +963 -0
  430. endoreg_db/services/polling_coordinator.py +288 -0
  431. endoreg_db/services/pseudonym_service.py +89 -0
  432. endoreg_db/services/requirements_object.py +147 -0
  433. endoreg_db/services/segment_sync.py +155 -0
  434. endoreg_db/services/storage_aware_video_processor.py +344 -0
  435. endoreg_db/services/video_import.py +1118 -0
  436. endoreg_db/tasks/upload_tasks.py +207 -0
  437. endoreg_db/tasks/video_ingest.py +157 -0
  438. endoreg_db/tasks/video_processing_tasks.py +327 -0
  439. endoreg_db/urls/__init__.py +70 -0
  440. endoreg_db/urls/anonymization.py +32 -0
  441. endoreg_db/urls/auth.py +16 -0
  442. endoreg_db/urls/classification.py +39 -0
  443. endoreg_db/urls/examination.py +54 -0
  444. endoreg_db/urls/files.py +6 -0
  445. endoreg_db/urls/label_video_segment_validate.py +33 -0
  446. endoreg_db/urls/label_video_segments.py +44 -0
  447. endoreg_db/urls/media.py +229 -0
  448. endoreg_db/urls/patient.py +19 -0
  449. endoreg_db/urls/report.py +48 -0
  450. endoreg_db/urls/requirements.py +13 -0
  451. endoreg_db/urls/stats.py +46 -0
  452. endoreg_db/urls/upload.py +20 -0
  453. endoreg_db/urls/video.py +61 -0
  454. endoreg_db/urls.py +6 -283
  455. endoreg_db/utils/__init__.py +66 -57
  456. endoreg_db/utils/ai/__init__.py +9 -0
  457. endoreg_db/{models/ai_model/utils.py → utils/ai/get.py} +1 -4
  458. endoreg_db/{models/ai_model/lightning → utils/ai}/inference_dataset.py +0 -1
  459. endoreg_db/{models/ai_model/lightning → utils/ai}/multilabel_classification_net.py +14 -10
  460. endoreg_db/{models/ai_model/lightning → utils/ai}/postprocess.py +15 -5
  461. endoreg_db/utils/ai/predict.py +291 -0
  462. endoreg_db/{models/ai_model/lightning → utils/ai}/preprocess.py +1 -1
  463. endoreg_db/utils/calc_duration_seconds.py +24 -0
  464. endoreg_db/utils/case_generator/__init__.py +0 -0
  465. endoreg_db/utils/check_video_files.py +148 -0
  466. endoreg_db/utils/dataloader.py +50 -12
  467. endoreg_db/utils/dates.py +21 -0
  468. endoreg_db/utils/env.py +33 -0
  469. endoreg_db/utils/extract_specific_frames.py +72 -0
  470. endoreg_db/utils/file_operations.py +29 -1
  471. endoreg_db/utils/fix_video_path_direct.py +141 -0
  472. endoreg_db/utils/frame_anonymization_utils.py +463 -0
  473. endoreg_db/utils/links/__init__.py +0 -0
  474. endoreg_db/utils/links/requirement_link.py +193 -0
  475. endoreg_db/utils/mime_types.py +0 -0
  476. endoreg_db/utils/names.py +2 -0
  477. endoreg_db/utils/paths.py +100 -82
  478. endoreg_db/utils/permissions.py +143 -0
  479. endoreg_db/utils/pipelines/Readme.md +235 -0
  480. endoreg_db/utils/pipelines/__init__.py +0 -0
  481. endoreg_db/utils/pipelines/process_video_dir.py +120 -0
  482. endoreg_db/utils/product/__init__.py +0 -0
  483. endoreg_db/utils/product/sum_emissions.py +20 -0
  484. endoreg_db/utils/product/sum_weights.py +18 -0
  485. endoreg_db/utils/pydantic_models/db_config.py +1 -1
  486. endoreg_db/utils/requirement_helpers.py +0 -0
  487. endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
  488. endoreg_db/utils/requirement_operator_logic/lab_value_operators.py +578 -0
  489. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +368 -0
  490. endoreg_db/utils/translation.py +27 -0
  491. endoreg_db/utils/validate_video_detailed.py +357 -0
  492. endoreg_db/utils/video/__init__.py +19 -6
  493. endoreg_db/utils/video/extract_frames.py +37 -70
  494. endoreg_db/utils/video/ffmpeg_wrapper.py +772 -0
  495. endoreg_db/utils/video/names.py +42 -0
  496. endoreg_db/utils/video/streaming_processor.py +312 -0
  497. endoreg_db/utils/video/video_splitter.py +94 -0
  498. endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +238 -0
  499. endoreg_db/views/__init__.py +282 -2
  500. endoreg_db/views/anonymization/__init__.py +27 -0
  501. endoreg_db/views/anonymization/media_management.py +454 -0
  502. endoreg_db/views/anonymization/overview.py +216 -0
  503. endoreg_db/views/anonymization/validate.py +66 -0
  504. endoreg_db/views/auth/__init__.py +13 -0
  505. endoreg_db/views/{views.py → auth/keycloak.py} +19 -13
  506. endoreg_db/views/examination/__init__.py +33 -0
  507. endoreg_db/views/examination/examination.py +37 -0
  508. endoreg_db/views/examination/examination_manifest_cache.py +26 -0
  509. endoreg_db/views/examination/get_finding_classification_choices.py +59 -0
  510. endoreg_db/views/examination/get_finding_classifications.py +36 -0
  511. endoreg_db/views/examination/get_findings.py +41 -0
  512. endoreg_db/views/examination/get_instruments.py +18 -0
  513. endoreg_db/views/examination/get_interventions.py +14 -0
  514. endoreg_db/views/finding/__init__.py +9 -0
  515. endoreg_db/views/finding/finding.py +112 -0
  516. endoreg_db/views/finding/get_classifications.py +14 -0
  517. endoreg_db/views/finding/get_interventions.py +17 -0
  518. endoreg_db/views/finding_classification/__init__.py +13 -0
  519. endoreg_db/views/finding_classification/base.py +0 -0
  520. endoreg_db/views/finding_classification/finding_classification.py +42 -0
  521. endoreg_db/views/finding_classification/get_classification_choices.py +55 -0
  522. endoreg_db/views/label/__init__.py +5 -0
  523. endoreg_db/views/label/label.py +15 -0
  524. endoreg_db/views/label_video_segment/__init__.py +16 -0
  525. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +44 -0
  526. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +50 -0
  527. endoreg_db/views/label_video_segment/label_video_segment.py +77 -0
  528. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +174 -0
  529. endoreg_db/views/label_video_segment/label_video_segment_detail.py +73 -0
  530. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +46 -0
  531. endoreg_db/views/label_video_segment/validate.py +226 -0
  532. endoreg_db/views/media/__init__.py +45 -0
  533. endoreg_db/views/media/pdf_media.py +386 -0
  534. endoreg_db/views/media/segments.py +71 -0
  535. endoreg_db/views/media/sensitive_metadata.py +314 -0
  536. endoreg_db/views/media/video_media.py +272 -0
  537. endoreg_db/views/media/video_segments.py +596 -0
  538. endoreg_db/views/meta/__init__.py +15 -0
  539. endoreg_db/views/meta/available_files_list.py +146 -0
  540. endoreg_db/views/meta/report_meta.py +53 -0
  541. endoreg_db/views/meta/sensitive_meta_detail.py +148 -0
  542. endoreg_db/views/meta/sensitive_meta_list.py +104 -0
  543. endoreg_db/views/meta/sensitive_meta_verification.py +71 -0
  544. endoreg_db/views/misc/__init__.py +63 -0
  545. endoreg_db/views/misc/center.py +13 -0
  546. endoreg_db/views/misc/gender.py +14 -0
  547. endoreg_db/views/misc/secure_file_serving_view.py +80 -0
  548. endoreg_db/views/misc/secure_file_url_view.py +84 -0
  549. endoreg_db/views/misc/secure_url_validate.py +79 -0
  550. endoreg_db/views/misc/stats.py +220 -0
  551. endoreg_db/views/misc/translation.py +182 -0
  552. endoreg_db/views/misc/upload_views.py +240 -0
  553. endoreg_db/views/patient/__init__.py +5 -0
  554. endoreg_db/views/patient/patient.py +210 -0
  555. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +164 -0
  556. endoreg_db/views/patient_examination/__init__.py +11 -0
  557. endoreg_db/views/patient_examination/patient_examination.py +140 -0
  558. endoreg_db/views/patient_examination/patient_examination_create.py +63 -0
  559. endoreg_db/views/patient_examination/patient_examination_detail.py +66 -0
  560. endoreg_db/views/patient_examination/patient_examination_list.py +68 -0
  561. endoreg_db/views/patient_examination/video.py +194 -0
  562. endoreg_db/views/patient_finding/__init__.py +7 -0
  563. endoreg_db/views/patient_finding/base.py +0 -0
  564. endoreg_db/views/patient_finding/patient_finding.py +64 -0
  565. endoreg_db/views/patient_finding/patient_finding_optimized.py +259 -0
  566. endoreg_db/views/patient_finding_classification/__init__.py +5 -0
  567. endoreg_db/views/patient_finding_classification/pfc_create.py +67 -0
  568. endoreg_db/views/patient_finding_location/__init__.py +5 -0
  569. endoreg_db/views/patient_finding_location/pfl_create.py +70 -0
  570. endoreg_db/views/patient_finding_morphology/__init__.py +5 -0
  571. endoreg_db/views/patient_finding_morphology/pfm_create.py +70 -0
  572. endoreg_db/views/pdf/__init__.py +11 -0
  573. endoreg_db/views/pdf/pdf_media.py +239 -0
  574. endoreg_db/views/pdf/pdf_stream_views.py +127 -0
  575. endoreg_db/views/pdf/reimport.py +161 -0
  576. endoreg_db/views/report/__init__.py +9 -0
  577. endoreg_db/views/report/report_list.py +112 -0
  578. endoreg_db/views/report/report_with_secure_url.py +28 -0
  579. endoreg_db/views/report/start_examination.py +7 -0
  580. endoreg_db/views/requirement/__init__.py +10 -0
  581. endoreg_db/views/requirement/evaluate.py +279 -0
  582. endoreg_db/views/requirement/lookup.py +483 -0
  583. endoreg_db/views/requirement/lookup_store.py +252 -0
  584. endoreg_db/views/requirement_lookup/lookup.py +0 -0
  585. endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
  586. endoreg_db/views/stats/__init__.py +13 -0
  587. endoreg_db/views/stats/stats_views.py +229 -0
  588. endoreg_db/views/video/__init__.py +64 -0
  589. endoreg_db/views/video/correction.py +672 -0
  590. endoreg_db/views/video/reimport.py +195 -0
  591. endoreg_db/views/video/segmentation.py +274 -0
  592. endoreg_db/views/video/task_status.py +49 -0
  593. endoreg_db/views/{views_for_timeline.py → video/timeline.py} +3 -3
  594. endoreg_db/views/video/video_analyze.py +52 -0
  595. endoreg_db/views/video/video_apply_mask.py +48 -0
  596. endoreg_db/views/video/video_correction.py +21 -0
  597. endoreg_db/views/video/video_download_processed.py +58 -0
  598. endoreg_db/views/video/video_examination_viewset.py +329 -0
  599. endoreg_db/views/video/video_media.py +158 -0
  600. endoreg_db/views/video/video_meta.py +29 -0
  601. endoreg_db/views/video/video_processing_history.py +24 -0
  602. endoreg_db/views/video/video_remove_frames.py +48 -0
  603. endoreg_db/views/video/video_reprocess.py +40 -0
  604. endoreg_db/views/video/video_stream.py +306 -0
  605. endoreg_db-0.8.2.dist-info/METADATA +384 -0
  606. endoreg_db-0.8.2.dist-info/RECORD +790 -0
  607. endoreg_db/data/agl_service/data.yaml +0 -19
  608. endoreg_db/data/finding_location_classification/colonoscopy.yaml +0 -46
  609. endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +0 -48
  610. endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +0 -57
  611. endoreg_db/management/commands/_load_model_template.py +0 -41
  612. endoreg_db/management/commands/delete_all.py +0 -18
  613. endoreg_db/management/commands/fetch_legacy_image_dataset.py +0 -32
  614. endoreg_db/management/commands/fix_auth_permission.py +0 -20
  615. endoreg_db/management/commands/load_active_model_data.py +0 -45
  616. endoreg_db/management/commands/load_g_play_data.py +0 -113
  617. endoreg_db/management/commands/load_logging_data.py +0 -39
  618. endoreg_db/management/commands/load_lx_data.py +0 -64
  619. endoreg_db/management/commands/load_medication_indication_data.py +0 -63
  620. endoreg_db/management/commands/load_medication_indication_type_data.py +0 -41
  621. endoreg_db/management/commands/load_medication_intake_time_data.py +0 -41
  622. endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
  623. endoreg_db/management/commands/load_network_data.py +0 -57
  624. endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +0 -23
  625. endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +0 -23
  626. endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +0 -25
  627. endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +0 -33
  628. endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +0 -23
  629. endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +0 -24
  630. endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +0 -48
  631. endoreg_db/migrations/0009_requirementoperator_requirementsettype_and_more.py +0 -154
  632. endoreg_db/models/ai_model/active_model.py +0 -9
  633. endoreg_db/models/ai_model/ai_model.py +0 -90
  634. endoreg_db/models/ai_model/lightning/__init__.py +0 -3
  635. endoreg_db/models/ai_model/lightning/predict.py +0 -172
  636. endoreg_db/models/ai_model/lightning/prediction_visualizer.py +0 -55
  637. endoreg_db/models/ai_model/lightning/run_visualizer.py +0 -21
  638. endoreg_db/models/ai_model/model_meta.py +0 -240
  639. endoreg_db/models/annotation/__init__.py +0 -32
  640. endoreg_db/models/annotation/anonymized_image_annotation.py +0 -115
  641. endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -117
  642. endoreg_db/models/annotation/image_classification.py +0 -86
  643. endoreg_db/models/annotation/video_segmentation_annotation.py +0 -52
  644. endoreg_db/models/case/__init__.py +0 -1
  645. endoreg_db/models/case/case.py +0 -34
  646. endoreg_db/models/center/center.py +0 -51
  647. endoreg_db/models/center/center_product.py +0 -33
  648. endoreg_db/models/center/center_waste.py +0 -16
  649. endoreg_db/models/data_file/__init__.py +0 -39
  650. endoreg_db/models/data_file/base_classes/__init__.py +0 -7
  651. endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -98
  652. endoreg_db/models/data_file/base_classes/abstract_pdf.py +0 -127
  653. endoreg_db/models/data_file/base_classes/abstract_video.py +0 -806
  654. endoreg_db/models/data_file/base_classes/frame_helpers.py +0 -17
  655. endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +0 -19
  656. endoreg_db/models/data_file/base_classes/utils.py +0 -58
  657. endoreg_db/models/data_file/frame.py +0 -29
  658. endoreg_db/models/data_file/import_classes/__init__.py +0 -18
  659. endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +0 -35
  660. endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +0 -28
  661. endoreg_db/models/data_file/import_classes/processing_functions/video.py +0 -260
  662. endoreg_db/models/data_file/import_classes/raw_pdf.py +0 -254
  663. endoreg_db/models/data_file/import_classes/raw_video.py +0 -290
  664. endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -290
  665. endoreg_db/models/data_file/metadata/video_meta.py +0 -199
  666. endoreg_db/models/data_file/report_file.py +0 -56
  667. endoreg_db/models/data_file/video/__init__.py +0 -11
  668. endoreg_db/models/data_file/video/import_meta.py +0 -25
  669. endoreg_db/models/data_file/video/video.py +0 -196
  670. endoreg_db/models/data_file/video_segment.py +0 -214
  671. endoreg_db/models/examination/examination.py +0 -67
  672. endoreg_db/models/finding/__init__.py +0 -11
  673. endoreg_db/models/finding/finding.py +0 -75
  674. endoreg_db/models/finding/finding_location_classification.py +0 -94
  675. endoreg_db/models/finding/finding_morphology_classification.py +0 -89
  676. endoreg_db/models/finding/finding_type.py +0 -22
  677. endoreg_db/models/hardware/__init__.py +0 -2
  678. endoreg_db/models/information_source.py +0 -65
  679. endoreg_db/models/laboratory/__init__.py +0 -1
  680. endoreg_db/models/laboratory/lab_value.py +0 -162
  681. endoreg_db/models/logging/__init__.py +0 -11
  682. endoreg_db/models/logging/agl_service.py +0 -19
  683. endoreg_db/models/logging/base.py +0 -22
  684. endoreg_db/models/logging/log_type.py +0 -23
  685. endoreg_db/models/logging/network_device.py +0 -27
  686. endoreg_db/models/lx/__init__.py +0 -4
  687. endoreg_db/models/lx/client.py +0 -57
  688. endoreg_db/models/lx/identity.py +0 -34
  689. endoreg_db/models/lx/permission.py +0 -18
  690. endoreg_db/models/lx/user.py +0 -16
  691. endoreg_db/models/network/__init__.py +0 -9
  692. endoreg_db/models/network/agl_service.py +0 -38
  693. endoreg_db/models/network/network_device.py +0 -58
  694. endoreg_db/models/network/network_device_type.py +0 -23
  695. endoreg_db/models/other/distribution.py +0 -5
  696. endoreg_db/models/patient/__init__.py +0 -24
  697. endoreg_db/models/patient/patient_examination.py +0 -182
  698. endoreg_db/models/patient/patient_finding.py +0 -143
  699. endoreg_db/models/patient/patient_finding_location.py +0 -120
  700. endoreg_db/models/patient/patient_finding_morphology.py +0 -166
  701. endoreg_db/models/permissions/__init__.py +0 -44
  702. endoreg_db/models/persons/__init__.py +0 -34
  703. endoreg_db/models/persons/examiner/__init__.py +0 -2
  704. endoreg_db/models/persons/examiner/examiner.py +0 -60
  705. endoreg_db/models/persons/examiner/examiner_type.py +0 -2
  706. endoreg_db/models/persons/patient/__init__.py +0 -8
  707. endoreg_db/models/persons/patient/patient.py +0 -389
  708. endoreg_db/models/persons/patient/patient_disease.py +0 -22
  709. endoreg_db/models/persons/patient/patient_event.py +0 -52
  710. endoreg_db/models/persons/patient/patient_lab_sample.py +0 -108
  711. endoreg_db/models/persons/patient/patient_medication.py +0 -59
  712. endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -88
  713. endoreg_db/models/persons/portal_user_information.py +0 -27
  714. endoreg_db/models/prediction/__init__.py +0 -8
  715. endoreg_db/models/prediction/image_classification.py +0 -51
  716. endoreg_db/models/prediction/video_prediction_meta.py +0 -306
  717. endoreg_db/models/product/product.py +0 -110
  718. endoreg_db/models/product/product_group.py +0 -27
  719. endoreg_db/models/product/product_material.py +0 -28
  720. endoreg_db/models/questionnaires/__init__.py +0 -114
  721. endoreg_db/models/quiz/__init__.py +0 -9
  722. endoreg_db/models/quiz/quiz_answer.py +0 -41
  723. endoreg_db/models/quiz/quiz_question.py +0 -54
  724. endoreg_db/models/report_reader/report_reader_config.py +0 -53
  725. endoreg_db/models/rules/__init__.py +0 -5
  726. endoreg_db/queries/get/__init__.py +0 -6
  727. endoreg_db/queries/get/center.py +0 -42
  728. endoreg_db/queries/get/model.py +0 -13
  729. endoreg_db/queries/get/patient.py +0 -14
  730. endoreg_db/queries/get/patient_examination.py +0 -20
  731. endoreg_db/queries/get/report_file.py +0 -33
  732. endoreg_db/queries/get/video.py +0 -31
  733. endoreg_db/serializers/ai_model.py +0 -19
  734. endoreg_db/serializers/annotation.py +0 -14
  735. endoreg_db/serializers/center.py +0 -11
  736. endoreg_db/serializers/examination.py +0 -33
  737. endoreg_db/serializers/frame.py +0 -9
  738. endoreg_db/serializers/hardware.py +0 -21
  739. endoreg_db/serializers/label.py +0 -22
  740. endoreg_db/serializers/patient.py +0 -33
  741. endoreg_db/serializers/prediction.py +0 -10
  742. endoreg_db/serializers/raw_pdf_anony_text_validation.py +0 -137
  743. endoreg_db/serializers/report_file.py +0 -7
  744. endoreg_db/serializers/video.py +0 -20
  745. endoreg_db/serializers/video_segmentation.py +0 -574
  746. endoreg_db/tests.py +0 -3
  747. endoreg_db/utils/legacy_ocr.py +0 -201
  748. endoreg_db/utils/video/transcode_videofile.py +0 -111
  749. endoreg_db/views/patient_views.py +0 -90
  750. endoreg_db/views/raw_pdf_anony_text_validation_views.py +0 -95
  751. endoreg_db/views/raw_pdf_meta_validation_views.py +0 -111
  752. endoreg_db/views/raw_video_meta_validation_views.py +0 -148
  753. endoreg_db/views/report_views.py +0 -96
  754. endoreg_db/views/video_segmentation_views.py +0 -166
  755. endoreg_db-0.6.4.dist-info/METADATA +0 -161
  756. endoreg_db-0.6.4.dist-info/RECORD +0 -470
  757. /endoreg_db/{case_generator/__init__.py → api/serializers/finding_descriptions.py} +0 -0
  758. /endoreg_db/{queries/get/annotation.py → api/views/finding_descriptions.py} +0 -0
  759. /endoreg_db/{queries/get/prediction.py → data/shift/m2.yaml} +0 -0
  760. /endoreg_db/{queries/get/video_import_meta.py → factories/__init__.py} +0 -0
  761. /endoreg_db/{queries/get/video_prediction_meta.py → helpers/__init__.py} +0 -0
  762. /endoreg_db/models/{case_template → administration/case/case_template}/__init__.py +0 -0
  763. /endoreg_db/models/{persons → administration/person}/person.py +0 -0
  764. /endoreg_db/models/{product → administration/product}/__init__.py +0 -0
  765. /endoreg_db/models/{report_reader → media/pdf/report_reader}/__init__.py +0 -0
  766. /endoreg_db/models/{report_reader → media/pdf/report_reader}/report_reader_flag.py +0 -0
  767. /endoreg_db/models/{hardware → medical/hardware}/endoscopy_processor.py +0 -0
  768. /endoreg_db/models/{medication → medical/medication}/__init__.py +0 -0
  769. /endoreg_db/models/{medication → medical/medication}/medication_indication.py +0 -0
  770. /endoreg_db/models/{risk → medical/risk}/__init__.py +0 -0
  771. /endoreg_db/models/{risk → medical/risk}/risk.py +0 -0
  772. /endoreg_db/models/{emission → other/emission}/__init__.py +0 -0
  773. /endoreg_db/models/{rules → rule}/rule_applicator.py +0 -0
  774. /endoreg_db/{case_generator → utils/case_generator}/case_generator.py +0 -0
  775. /endoreg_db/{case_generator → utils/case_generator}/lab_sample_factory.py +0 -0
  776. /endoreg_db/{case_generator → utils/case_generator}/utils.py +0 -0
  777. /endoreg_db/views/{csrf.py → misc/csrf.py} +0 -0
  778. {endoreg_db-0.6.4.dist-info → endoreg_db-0.8.2.dist-info}/WHEEL +0 -0
  779. {endoreg_db-0.6.4.dist-info → endoreg_db-0.8.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,9 @@
1
- # Generated by Django 5.1.6 on 2025-03-08 15:58
1
+ # Generated by Django 5.2.5 on 2025-09-15 11:52
2
2
 
3
- import django.core.files.storage
4
3
  import django.core.validators
5
4
  import django.db.models.deletion
6
- import django.utils.timezone
5
+ import pathlib
6
+ import uuid
7
7
  from django.conf import settings
8
8
  from django.db import migrations, models
9
9
 
@@ -17,50 +17,20 @@ class Migration(migrations.Migration):
17
17
  ]
18
18
 
19
19
  operations = [
20
- migrations.CreateModel(
21
- name='AglService',
22
- fields=[
23
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24
- ('name', models.CharField(max_length=255)),
25
- ('description', models.CharField(max_length=255)),
26
- ('online', models.BooleanField(default=False)),
27
- ('created', models.DateTimeField(auto_now_add=True)),
28
- ('updated', models.DateTimeField(auto_now=True)),
29
- ('port', models.IntegerField(blank=True, null=True)),
30
- ('protocol', models.CharField(blank=True, max_length=255, null=True)),
31
- ('url', models.URLField(blank=True, null=True)),
32
- ],
33
- options={
34
- 'ordering': ['name'],
35
- },
36
- ),
37
20
  migrations.CreateModel(
38
21
  name='AiModel',
39
22
  fields=[
40
23
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
41
24
  ('name', models.CharField(max_length=255, unique=True)),
42
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
43
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
44
25
  ('description', models.TextField(blank=True, null=True)),
45
- ('model_type', models.CharField(blank=True, max_length=255, null=True)),
46
26
  ('model_subtype', models.CharField(blank=True, max_length=255, null=True)),
47
27
  ],
48
28
  ),
49
- migrations.CreateModel(
50
- name='AnonymizedImageLabel',
51
- fields=[
52
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
53
- ('name', models.CharField(max_length=255, unique=True)),
54
- ('description', models.TextField(blank=True, null=True)),
55
- ],
56
- ),
57
29
  migrations.CreateModel(
58
30
  name='CaseTemplateRuleType',
59
31
  fields=[
60
32
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
61
33
  ('name', models.CharField(max_length=255)),
62
- ('name_de', models.CharField(max_length=255, null=True)),
63
- ('name_en', models.CharField(max_length=255, null=True)),
64
34
  ('description', models.TextField(blank=True, null=True)),
65
35
  ],
66
36
  ),
@@ -80,8 +50,6 @@ class Migration(migrations.Migration):
80
50
  fields=[
81
51
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
82
52
  ('name', models.CharField(max_length=255)),
83
- ('name_de', models.CharField(max_length=255, null=True)),
84
- ('name_en', models.CharField(max_length=255, null=True)),
85
53
  ('description', models.TextField(blank=True, null=True)),
86
54
  ('distribution_type', models.CharField(choices=[('single_categorical', 'single_categorical'), ('multiple_categorical', 'multiple_categorical'), ('numeric', 'numeric')], max_length=255)),
87
55
  ],
@@ -91,8 +59,6 @@ class Migration(migrations.Migration):
91
59
  fields=[
92
60
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
93
61
  ('name', models.CharField(max_length=255)),
94
- ('name_de', models.CharField(max_length=255, null=True)),
95
- ('name_en', models.CharField(max_length=255, null=True)),
96
62
  ('description', models.TextField(blank=True, null=True)),
97
63
  ],
98
64
  ),
@@ -101,8 +67,6 @@ class Migration(migrations.Migration):
101
67
  fields=[
102
68
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
103
69
  ('name', models.CharField(max_length=255)),
104
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
105
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
106
70
  ],
107
71
  ),
108
72
  migrations.CreateModel(
@@ -110,11 +74,7 @@ class Migration(migrations.Migration):
110
74
  fields=[
111
75
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
112
76
  ('name', models.CharField(max_length=100, unique=True)),
113
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
114
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
115
77
  ('description', models.TextField(blank=True, null=True)),
116
- ('description_de', models.TextField(blank=True, null=True)),
117
- ('description_en', models.TextField(blank=True, null=True)),
118
78
  ],
119
79
  ),
120
80
  migrations.CreateModel(
@@ -122,8 +82,6 @@ class Migration(migrations.Migration):
122
82
  fields=[
123
83
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
124
84
  ('name', models.CharField(max_length=100)),
125
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
126
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
127
85
  ('description', models.TextField(blank=True, null=True)),
128
86
  ('distribution_type', models.CharField(choices=[('uniform', 'Uniform'), ('normal', 'Normal')], max_length=20)),
129
87
  ('mode', models.CharField(choices=[('date', 'Date'), ('timedelta', 'Timedelta')], max_length=20)),
@@ -145,29 +103,44 @@ class Migration(migrations.Migration):
145
103
  fields=[
146
104
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
147
105
  ('name', models.CharField(max_length=255, unique=True)),
148
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
149
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
150
106
  ('subcategories', models.JSONField(default=dict)),
151
107
  ('numerical_descriptors', models.JSONField(default=dict)),
152
108
  ],
153
109
  ),
110
+ migrations.CreateModel(
111
+ name='DocumentType',
112
+ fields=[
113
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
114
+ ('name', models.CharField(max_length=255, unique=True)),
115
+ ('description', models.TextField(blank=True, null=True)),
116
+ ],
117
+ options={
118
+ 'verbose_name': 'Document Type',
119
+ 'verbose_name_plural': 'Document Types',
120
+ },
121
+ ),
154
122
  migrations.CreateModel(
155
123
  name='EmissionFactor',
156
124
  fields=[
157
125
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
158
126
  ('name', models.CharField(max_length=255)),
159
- ('name_de', models.CharField(max_length=255, null=True)),
160
- ('name_en', models.CharField(max_length=255, null=True)),
161
127
  ('value', models.FloatField()),
162
128
  ],
163
129
  ),
130
+ migrations.CreateModel(
131
+ name='EmployeeType',
132
+ fields=[
133
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
134
+ ('name', models.CharField(max_length=255, unique=True)),
135
+ ('description', models.TextField(blank=True, null=True)),
136
+ ('is_active', models.BooleanField(default=True)),
137
+ ],
138
+ ),
164
139
  migrations.CreateModel(
165
140
  name='EndoscopeType',
166
141
  fields=[
167
142
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
168
- ('name', models.CharField(max_length=255)),
169
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
170
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
143
+ ('name', models.CharField(max_length=255, unique=True)),
171
144
  ],
172
145
  options={
173
146
  'verbose_name': 'Endoscope Type',
@@ -180,8 +153,6 @@ class Migration(migrations.Migration):
180
153
  fields=[
181
154
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
182
155
  ('name', models.CharField(max_length=255, unique=True)),
183
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
184
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
185
156
  ],
186
157
  ),
187
158
  migrations.CreateModel(
@@ -189,8 +160,11 @@ class Migration(migrations.Migration):
189
160
  fields=[
190
161
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
191
162
  ('name', models.CharField(max_length=100, unique=True)),
192
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
193
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
163
+ ('name_de', models.CharField(max_length=100, null=True, unique=True)),
164
+ ('name_en', models.CharField(max_length=100, null=True, unique=True)),
165
+ ('description', models.TextField(blank=True, null=True)),
166
+ ('description_de', models.TextField(blank=True, null=True)),
167
+ ('description_en', models.TextField(blank=True, null=True)),
194
168
  ],
195
169
  options={
196
170
  'verbose_name': 'Examination',
@@ -198,82 +172,56 @@ class Migration(migrations.Migration):
198
172
  'ordering': ['name'],
199
173
  },
200
174
  ),
201
- migrations.CreateModel(
202
- name='ExaminationIndicationClassification',
203
- fields=[
204
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
205
- ('name', models.CharField(max_length=255, unique=True)),
206
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
207
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
208
- ],
209
- ),
210
175
  migrations.CreateModel(
211
176
  name='ExaminationType',
212
177
  fields=[
213
178
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
214
179
  ('name', models.CharField(max_length=100, unique=True)),
215
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
216
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
217
180
  ],
218
181
  ),
219
182
  migrations.CreateModel(
220
183
  name='FFMpegMeta',
221
184
  fields=[
222
185
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
223
- ('duration', models.FloatField(blank=True, null=True)),
224
186
  ('width', models.IntegerField(blank=True, null=True)),
225
187
  ('height', models.IntegerField(blank=True, null=True)),
226
- ('frame_rate', models.FloatField(blank=True, null=True)),
227
- ('video_codec', models.CharField(blank=True, max_length=50, null=True)),
228
- ('audio_codec', models.CharField(blank=True, max_length=50, null=True)),
229
- ('audio_channels', models.IntegerField(blank=True, null=True)),
230
- ('audio_sample_rate', models.IntegerField(blank=True, null=True)),
231
- ],
232
- ),
233
- migrations.CreateModel(
234
- name='FindingInterventionType',
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
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
239
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
240
- ('description', models.TextField(blank=True, null=True)),
241
- ('description_de', models.TextField(blank=True, null=True)),
242
- ('description_en', models.TextField(blank=True, null=True)),
188
+ ('duration', models.FloatField(blank=True, null=True)),
189
+ ('frame_rate_num', models.IntegerField(blank=True, null=True)),
190
+ ('frame_rate_den', models.IntegerField(blank=True, null=True)),
191
+ ('codec_name', models.CharField(blank=True, max_length=50, null=True)),
192
+ ('pixel_format', models.CharField(blank=True, max_length=50, null=True)),
193
+ ('bit_rate', models.BigIntegerField(blank=True, null=True)),
194
+ ('raw_probe_data', models.JSONField(blank=True, null=True)),
243
195
  ],
244
196
  ),
245
197
  migrations.CreateModel(
246
- name='FindingLocationClassificationChoice',
198
+ name='FindingClassificationChoice',
247
199
  fields=[
248
200
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
249
- ('name', models.CharField(max_length=100, unique=True)),
250
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
251
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
252
- ('description', models.TextField(blank=True, null=True)),
201
+ ('name', models.CharField(max_length=255, unique=True)),
202
+ ('name_de', models.CharField(max_length=255, null=True, unique=True)),
203
+ ('name_en', models.CharField(max_length=255, null=True, unique=True)),
204
+ ('description', models.TextField(blank=True)),
253
205
  ('description_de', models.TextField(blank=True, null=True)),
254
206
  ('description_en', models.TextField(blank=True, null=True)),
255
- ('subcategories', models.JSONField(blank=True, null=True)),
256
- ('numerical_descriptors', models.JSONField(blank=True, null=True)),
207
+ ('subcategories', models.JSONField(default=dict)),
208
+ ('numerical_descriptors', models.JSONField(default=dict)),
257
209
  ],
258
210
  ),
259
211
  migrations.CreateModel(
260
- name='FindingMorphologyClassification',
212
+ name='FindingClassificationType',
261
213
  fields=[
262
214
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
263
215
  ('name', models.CharField(max_length=255, unique=True)),
264
- ('name_de', models.CharField(blank=True, max_length=255)),
265
- ('name_en', models.CharField(blank=True, max_length=255)),
266
216
  ('description', models.TextField(blank=True)),
267
217
  ],
268
218
  ),
269
219
  migrations.CreateModel(
270
- name='FindingMorphologyClassificationType',
220
+ name='FindingInterventionType',
271
221
  fields=[
272
222
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
273
- ('name', models.CharField(max_length=255, unique=True)),
274
- ('name_de', models.CharField(blank=True, max_length=255)),
275
- ('name_en', models.CharField(blank=True, max_length=255)),
276
- ('description', models.TextField(blank=True)),
223
+ ('name', models.CharField(max_length=100, unique=True)),
224
+ ('description', models.TextField(blank=True, null=True)),
277
225
  ],
278
226
  ),
279
227
  migrations.CreateModel(
@@ -281,11 +229,7 @@ class Migration(migrations.Migration):
281
229
  fields=[
282
230
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
283
231
  ('name', models.CharField(max_length=100, unique=True)),
284
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
285
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
286
232
  ('description', models.TextField(blank=True, null=True)),
287
- ('description_de', models.TextField(blank=True, null=True)),
288
- ('description_en', models.TextField(blank=True, null=True)),
289
233
  ],
290
234
  ),
291
235
  migrations.CreateModel(
@@ -295,42 +239,15 @@ class Migration(migrations.Migration):
295
239
  ('name', models.CharField(max_length=255, unique=True)),
296
240
  ],
297
241
  ),
298
- migrations.CreateModel(
299
- name='Frame',
300
- fields=[
301
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
302
- ('frame_number', models.IntegerField()),
303
- ('suffix', models.CharField(max_length=255)),
304
- ('image', models.ImageField(blank=True, null=True, upload_to='frames')),
305
- ('is_raw', models.BooleanField(default=False)),
306
- ],
307
- options={
308
- 'abstract': False,
309
- },
310
- ),
311
242
  migrations.CreateModel(
312
243
  name='Gender',
313
244
  fields=[
314
245
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
315
246
  ('name', models.CharField(max_length=255)),
316
- ('name_de', models.CharField(max_length=255, null=True)),
317
- ('name_en', models.CharField(max_length=255, null=True)),
318
247
  ('abbreviation', models.CharField(max_length=255, null=True)),
319
248
  ('description', models.TextField(blank=True, null=True)),
320
249
  ],
321
250
  ),
322
- migrations.CreateModel(
323
- name='InformationSource',
324
- fields=[
325
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
326
- ('name', models.CharField(max_length=100)),
327
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
328
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
329
- ('url', models.URLField(blank=True, null=True)),
330
- ('description', models.TextField(blank=True, null=True)),
331
- ('date', models.DateField(blank=True, null=True)),
332
- ],
333
- ),
334
251
  migrations.CreateModel(
335
252
  name='Label',
336
253
  fields=[
@@ -354,67 +271,11 @@ class Migration(migrations.Migration):
354
271
  ('name', models.CharField(max_length=255, unique=True)),
355
272
  ],
356
273
  ),
357
- migrations.CreateModel(
358
- name='LogType',
359
- fields=[
360
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
361
- ('name', models.CharField(max_length=255)),
362
- ('description', models.CharField(max_length=255)),
363
- ('created', models.DateTimeField(auto_now_add=True)),
364
- ('updated', models.DateTimeField(auto_now=True)),
365
- ],
366
- options={
367
- 'ordering': ['name'],
368
- },
369
- ),
370
- migrations.CreateModel(
371
- name='LxClientTag',
372
- fields=[
373
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
374
- ('name', models.CharField(max_length=100, unique=True)),
375
- ('description', models.TextField(blank=True)),
376
- ],
377
- ),
378
- migrations.CreateModel(
379
- name='LxClientType',
380
- fields=[
381
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
382
- ('name', models.CharField(max_length=100, unique=True)),
383
- ('abbreviation', models.CharField(max_length=10, unique=True)),
384
- ('description', models.TextField(blank=True)),
385
- ],
386
- ),
387
- migrations.CreateModel(
388
- name='LxIdentityType',
389
- fields=[
390
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
391
- ('name', models.CharField(max_length=100, unique=True)),
392
- ('description', models.TextField(blank=True)),
393
- ],
394
- ),
395
- migrations.CreateModel(
396
- name='LxPermission',
397
- fields=[
398
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
399
- ('name', models.CharField(max_length=100, unique=True)),
400
- ('description', models.TextField(blank=True)),
401
- ],
402
- ),
403
- migrations.CreateModel(
404
- name='LxUser',
405
- fields=[
406
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
407
- ('name', models.CharField(max_length=100, unique=True)),
408
- ('description', models.TextField(blank=True)),
409
- ],
410
- ),
411
274
  migrations.CreateModel(
412
275
  name='Medication',
413
276
  fields=[
414
277
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
415
278
  ('name', models.CharField(max_length=255, unique=True)),
416
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
417
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
418
279
  ('adapt_to_renal_function', models.BooleanField(default=False)),
419
280
  ('adapt_to_hepatic_function', models.BooleanField(default=False)),
420
281
  ('adapt_to_indication', models.BooleanField(default=False)),
@@ -428,17 +289,13 @@ class Migration(migrations.Migration):
428
289
  fields=[
429
290
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
430
291
  ('name', models.CharField(max_length=255, unique=True)),
431
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
432
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
433
292
  ],
434
293
  ),
435
294
  migrations.CreateModel(
436
295
  name='MedicationIntakeTime',
437
296
  fields=[
438
297
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
439
- ('name', models.CharField(max_length=255)),
440
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
441
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
298
+ ('name', models.CharField(max_length=255, unique=True)),
442
299
  ('repeats', models.CharField(default='daily', max_length=20)),
443
300
  ('time', models.TimeField()),
444
301
  ],
@@ -467,36 +324,6 @@ class Migration(migrations.Migration):
467
324
  'abstract': False,
468
325
  },
469
326
  ),
470
- migrations.CreateModel(
471
- name='NetworkDevice',
472
- fields=[
473
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
474
- ('name', models.CharField(max_length=255)),
475
- ('ip', models.GenericIPAddressField(blank=True, null=True)),
476
- ('description', models.CharField(max_length=255)),
477
- ('online', models.BooleanField(default=False)),
478
- ('created', models.DateTimeField(auto_now_add=True)),
479
- ('updated', models.DateTimeField(auto_now=True)),
480
- ],
481
- options={
482
- 'db_table': 'network_devices',
483
- 'ordering': ['name'],
484
- },
485
- ),
486
- migrations.CreateModel(
487
- name='NetworkDeviceType',
488
- fields=[
489
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
490
- ('name', models.CharField(max_length=255)),
491
- ('description', models.CharField(max_length=255)),
492
- ('created', models.DateTimeField(auto_now_add=True)),
493
- ('updated', models.DateTimeField(auto_now=True)),
494
- ],
495
- options={
496
- 'db_table': 'network_device_types',
497
- 'ordering': ['name'],
498
- },
499
- ),
500
327
  migrations.CreateModel(
501
328
  name='NumericValueDistribution',
502
329
  fields=[
@@ -515,8 +342,6 @@ class Migration(migrations.Migration):
515
342
  fields=[
516
343
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
517
344
  ('name', models.CharField(max_length=255)),
518
- ('name_de', models.CharField(max_length=255, null=True)),
519
- ('name_en', models.CharField(max_length=255, null=True)),
520
345
  ('description', models.TextField(blank=True, null=True)),
521
346
  ],
522
347
  ),
@@ -532,8 +357,6 @@ class Migration(migrations.Migration):
532
357
  fields=[
533
358
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
534
359
  ('name', models.CharField(max_length=255)),
535
- ('name_de', models.CharField(max_length=255, null=True)),
536
- ('name_en', models.CharField(max_length=255, null=True)),
537
360
  ],
538
361
  ),
539
362
  migrations.CreateModel(
@@ -541,8 +364,6 @@ class Migration(migrations.Migration):
541
364
  fields=[
542
365
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
543
366
  ('name', models.CharField(max_length=255)),
544
- ('name_de', models.CharField(max_length=255, null=True)),
545
- ('name_en', models.CharField(max_length=255, null=True)),
546
367
  ],
547
368
  ),
548
369
  migrations.CreateModel(
@@ -550,54 +371,79 @@ class Migration(migrations.Migration):
550
371
  fields=[
551
372
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
552
373
  ('name', models.CharField(max_length=100)),
553
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
554
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
555
374
  ('description', models.TextField(blank=True, null=True)),
556
375
  ],
557
376
  ),
558
377
  migrations.CreateModel(
559
- name='QuizAnswerType',
378
+ name='Qualification',
560
379
  fields=[
561
380
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
562
- ('name', models.CharField(max_length=255)),
381
+ ('name', models.CharField(max_length=255, unique=True)),
563
382
  ('description', models.TextField(blank=True, null=True)),
383
+ ('is_active', models.BooleanField(default=True)),
564
384
  ],
565
385
  ),
566
386
  migrations.CreateModel(
567
- name='QuizQuestion',
387
+ name='QualificationType',
568
388
  fields=[
569
389
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
570
- ('text', models.TextField()),
390
+ ('name', models.CharField(max_length=255, unique=True)),
571
391
  ('description', models.TextField(blank=True, null=True)),
392
+ ('is_active', models.BooleanField(default=True)),
572
393
  ],
573
394
  ),
574
395
  migrations.CreateModel(
575
- name='QuizQuestionType',
396
+ name='RawPdfState',
576
397
  fields=[
577
398
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
578
- ('name', models.CharField(max_length=255)),
399
+ ('text_meta_extracted', models.BooleanField(default=False, help_text='True if text metadata (OCR) has been extracted.')),
400
+ ('initial_prediction_completed', models.BooleanField(default=False, help_text='True if initial AI prediction has run.')),
401
+ ('sensitive_meta_processed', models.BooleanField(default=False, help_text='True if the video has been fully processed, meaning a anonymized person was created.')),
402
+ ('anonymized', models.BooleanField(default=False, help_text='True if the anonymized video file has been created.')),
403
+ ('anonymization_validated', models.BooleanField(default=False, help_text='True if the anonymization process has been validated and confirmed.')),
404
+ ('processing_started', models.BooleanField(default=False, help_text='True if the processing has started, but not yet completed.')),
405
+ ('processing_error', models.BooleanField(default=False, help_text='True if an error occurred during processing.')),
406
+ ('date_created', models.DateTimeField(auto_now_add=True)),
407
+ ('date_modified', models.DateTimeField(auto_now=True)),
408
+ ('was_created', models.BooleanField(default=True, help_text='True if this state was created for the first time.')),
409
+ ('pdf_meta_extracted', models.BooleanField(default=False, help_text='True if PDF metadata has been extracted.')),
410
+ ],
411
+ options={
412
+ 'verbose_name': 'Raw PDF Processing State',
413
+ 'verbose_name_plural': 'Raw PDF Processing States',
414
+ },
415
+ ),
416
+ migrations.CreateModel(
417
+ name='ReportReaderFlag',
418
+ fields=[
419
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
420
+ ('name', models.CharField(max_length=255, unique=True)),
421
+ ('value', models.CharField(max_length=255)),
422
+ ],
423
+ ),
424
+ migrations.CreateModel(
425
+ name='RequirementOperator',
426
+ fields=[
427
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
428
+ ('name', models.CharField(max_length=100, unique=True)),
579
429
  ('description', models.TextField(blank=True, null=True)),
430
+ ('evaluation_function_name', models.CharField(blank=True, max_length=255, null=True)),
580
431
  ],
581
432
  ),
582
433
  migrations.CreateModel(
583
- name='RawFrame',
434
+ name='RequirementSetType',
584
435
  fields=[
585
436
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
586
- ('frame_number', models.IntegerField()),
587
- ('suffix', models.CharField(max_length=255)),
588
- ('image', models.ImageField(blank=True, null=True, upload_to='frames')),
589
- ('is_raw', models.BooleanField(default=False)),
437
+ ('name', models.CharField(max_length=100, unique=True)),
438
+ ('description', models.TextField(blank=True, null=True)),
590
439
  ],
591
- options={
592
- 'abstract': False,
593
- },
594
440
  ),
595
441
  migrations.CreateModel(
596
- name='ReportReaderFlag',
442
+ name='RequirementType',
597
443
  fields=[
598
444
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
599
- ('name', models.CharField(max_length=255, unique=True)),
600
- ('value', models.CharField(max_length=255)),
445
+ ('name', models.CharField(max_length=100, unique=True)),
446
+ ('description', models.TextField(blank=True, null=True)),
601
447
  ],
602
448
  ),
603
449
  migrations.CreateModel(
@@ -605,8 +451,14 @@ class Migration(migrations.Migration):
605
451
  fields=[
606
452
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
607
453
  ('name', models.CharField(max_length=255)),
608
- ('name_de', models.CharField(max_length=255, null=True)),
609
- ('name_en', models.CharField(max_length=255, null=True)),
454
+ ],
455
+ ),
456
+ migrations.CreateModel(
457
+ name='RiskType',
458
+ fields=[
459
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
460
+ ('name', models.CharField(max_length=100, unique=True)),
461
+ ('description', models.TextField(blank=True, null=True)),
610
462
  ],
611
463
  ),
612
464
  migrations.CreateModel(
@@ -614,8 +466,6 @@ class Migration(migrations.Migration):
614
466
  fields=[
615
467
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
616
468
  ('name', models.CharField(max_length=255, unique=True)),
617
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
618
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
619
469
  ],
620
470
  ),
621
471
  migrations.CreateModel(
@@ -623,14 +473,33 @@ class Migration(migrations.Migration):
623
473
  fields=[
624
474
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
625
475
  ('name', models.CharField(max_length=255, unique=True)),
626
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
627
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
628
476
  ],
629
477
  options={
630
478
  'verbose_name': 'Rule Type',
631
479
  'verbose_name_plural': 'Rule Types',
632
480
  },
633
481
  ),
482
+ migrations.CreateModel(
483
+ name='ScheduledDays',
484
+ fields=[
485
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
486
+ ('name', models.CharField(help_text='Name of the scheduled days.', max_length=255, unique=True)),
487
+ ('working_days', models.BooleanField(blank=True, default=True, null=True)),
488
+ ('non_working_days', models.BooleanField(blank=True, default=False, null=True)),
489
+ ('limited_time', models.BooleanField(blank=True, default=False, null=True)),
490
+ ('start_date', models.DateField(blank=True, null=True)),
491
+ ('end_date', models.DateField(blank=True, null=True)),
492
+ ],
493
+ ),
494
+ migrations.CreateModel(
495
+ name='ShiftType',
496
+ fields=[
497
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
498
+ ('name', models.CharField(max_length=255, unique=True)),
499
+ ('description', models.TextField(blank=True, null=True)),
500
+ ('is_active', models.BooleanField(default=True)),
501
+ ],
502
+ ),
634
503
  migrations.CreateModel(
635
504
  name='SingleCategoricalValueDistribution',
636
505
  fields=[
@@ -643,69 +512,30 @@ class Migration(migrations.Migration):
643
512
  },
644
513
  ),
645
514
  migrations.CreateModel(
646
- name='TtoQuestionnaire',
647
- fields=[
648
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
649
- ('patient_name', models.CharField(max_length=255, verbose_name='Identifikation des Patienten (Name)')),
650
- ('birth_date', models.DateField(verbose_name='Geburtsdatum')),
651
- ('emergency_patient', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Notfallpatient/kürzlich untersuchter Patient (Verzicht auf Team-Time-Out möglich)')),
652
- ('consent_signed', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Einverständniserklärung unterschrieben (Arzt, Patient)')),
653
- ('documents_present', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Alle Dokumente liegen vor (Labor, Befunde, etc.)')),
654
- ('communication_possible', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Kommunikation mit Patient möglich')),
655
- ('work_incapacity_certificate', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Arbeitsunfähigkeitsbescheinigung')),
656
- ('pregnancy', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Schwangerschaft')),
657
- ('asa_classification_checked', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='ASA-Klassifikation/Komorbidität geprüft')),
658
- ('previous_anesthesia_complications', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Komplikationen bei bisherigen Narkosen?')),
659
- ('last_meal_over_6_hours_ago', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Zeitpunkt letzte Mahlzeit > 6 Stunden')),
660
- ('allergies', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Allergien, welche?')),
661
- ('outpatient_accompaniment_post_sedation', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Nur bei ambulanter Vorstellung: Begleitung nach Sedierung?')),
662
- ('dental_prosthesis', models.BooleanField(default=False, verbose_name='Zahnprothese')),
663
- ('glasses', models.BooleanField(default=False, verbose_name='Brille')),
664
- ('implants', models.BooleanField(default=False, verbose_name='Implantate')),
665
- ('hearing_aids', models.BooleanField(default=False, verbose_name='Hörgeräte')),
666
- ('anticoagulants_ass', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Antikoagulation, ASS')),
667
- ('blood_pressure_medication', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Blutdruckmedikamente')),
668
- ('glaucoma', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Glaukom')),
669
- ('metal_implants', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Metallimplantate')),
670
- ('pacemaker_icd', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Herzschrittmacher/ICD')),
671
- ('copd', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='COPD')),
672
- ('liver_cirrhosis', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Leberzirrhose')),
673
- ('ibd', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='CED (Chronisch entzündliche Darmerkrankungen)')),
674
- ('radiation', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Bestrahlung')),
675
- ('surgeries', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='OP´s')),
676
- ('team_introduction', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Teamvorstellung mit Name und Aufgabe')),
677
- ('instruments_available', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Notwendige Instrumente vorhanden?')),
678
- ('monitoring_medications_equipment_checked', models.CharField(choices=[('yes', 'Ja'), ('no', 'Nein')], max_length=3, verbose_name='Monitoring, Medikamente, Equipment zum Atemwegsmanagement zur Verfügung und überprüft?')),
679
- ('complete_documentation_inclusive_care_notes', models.TextField(verbose_name='Vollständige Dokumentation inklusive Hinweise für Nachsorge')),
680
- ('notes', models.TextField(default='Keine Bemerkungen', verbose_name='Bemerkungen')),
681
- ('specimens_secured', models.BooleanField(default=False, verbose_name='Histologische Proben gesichert')),
682
- ('patient_condition_documented', models.TextField(verbose_name='Patientenzustand dokumentiert (je nach Ausgangszustand)')),
515
+ name='Tag',
516
+ fields=[
517
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
518
+ ('name', models.CharField(max_length=100, unique=True)),
683
519
  ],
520
+ options={
521
+ 'verbose_name': 'Tag',
522
+ 'verbose_name_plural': 'Tags',
523
+ },
684
524
  ),
685
525
  migrations.CreateModel(
686
526
  name='Unit',
687
527
  fields=[
688
528
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
689
529
  ('name', models.CharField(max_length=100)),
690
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
691
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
692
530
  ('description', models.CharField(blank=True, max_length=100, null=True)),
693
531
  ('abbreviation', models.CharField(blank=True, max_length=25, null=True)),
694
532
  ],
695
533
  ),
696
- migrations.CreateModel(
697
- name='UploadedFile',
698
- fields=[
699
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
700
- ('original_file', models.FileField(upload_to='uploads/original/')),
701
- ('upload_date', models.DateTimeField(default=django.utils.timezone.now)),
702
- ('description', models.TextField(blank=True, null=True)),
703
- ],
704
- ),
705
534
  migrations.CreateModel(
706
535
  name='VideoImportMeta',
707
536
  fields=[
708
537
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
538
+ ('file_name', models.CharField(blank=True, max_length=255, null=True)),
709
539
  ('video_anonymized', models.BooleanField(default=False)),
710
540
  ('video_patient_data_detected', models.BooleanField(default=False)),
711
541
  ('outside_detected', models.BooleanField(default=False)),
@@ -718,36 +548,43 @@ class Migration(migrations.Migration):
718
548
  fields=[
719
549
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
720
550
  ('name', models.CharField(max_length=255)),
721
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
722
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
723
551
  ('description', models.TextField(blank=True, null=True)),
724
552
  ('color', models.CharField(blank=True, max_length=255, null=True)),
725
553
  ('order_priority', models.IntegerField(default=0)),
726
554
  ],
727
555
  ),
728
556
  migrations.CreateModel(
729
- name='Waste',
557
+ name='VideoState',
730
558
  fields=[
731
559
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
732
- ('name', models.CharField(max_length=255)),
733
- ('name_de', models.CharField(max_length=255, null=True)),
734
- ('name_en', models.CharField(max_length=255, null=True)),
560
+ ('frames_extracted', models.BooleanField(default=False, help_text='True if raw frames have been extracted to files.')),
561
+ ('frames_initialized', models.BooleanField(default=False, help_text='True if Frame DB objects have been created.')),
562
+ ('frame_count', models.PositiveIntegerField(blank=True, help_text='Number of frames extracted/initialized.', null=True)),
563
+ ('video_meta_extracted', models.BooleanField(default=False, help_text='True if VideoMeta (technical specs) has been extracted.')),
564
+ ('text_meta_extracted', models.BooleanField(default=False, help_text='True if text metadata (OCR) has been extracted.')),
565
+ ('initial_prediction_completed', models.BooleanField(default=False, help_text='True if initial AI prediction has run.')),
566
+ ('lvs_created', models.BooleanField(default=False, help_text='True if LabelVideoSegments have been created from predictions.')),
567
+ ('frame_annotations_generated', models.BooleanField(default=False, help_text='True if frame-level annotations have been generated from segments.')),
568
+ ('sensitive_meta_processed', models.BooleanField(default=False, help_text='True if the video has been fully processed, meaning a anonymized person was created.')),
569
+ ('anonymized', models.BooleanField(default=False, help_text='True if the anonymized video file has been created.')),
570
+ ('anonymization_validated', models.BooleanField(default=False, help_text='True if the anonymization process has been validated and confirmed.')),
571
+ ('processing_started', models.BooleanField(default=False, help_text='True if the processing has started, but not yet completed.')),
572
+ ('date_created', models.DateTimeField(auto_now_add=True)),
573
+ ('date_modified', models.DateTimeField(auto_now=True)),
574
+ ('segment_annotations_created', models.BooleanField(default=False, help_text='True if segment annotations have been created from LabelVideoSegments.')),
575
+ ('segment_annotations_validated', models.BooleanField(default=False, help_text='True if segment annotations have been validated.')),
576
+ ('was_created', models.BooleanField(default=True, help_text='True if this state was created for the first time.')),
735
577
  ],
578
+ options={
579
+ 'verbose_name': 'Video Processing State',
580
+ 'verbose_name_plural': 'Video Processing States',
581
+ },
736
582
  ),
737
583
  migrations.CreateModel(
738
- name='AnonymousImageAnnotation',
584
+ name='Waste',
739
585
  fields=[
740
586
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
741
- ('image_name', models.CharField(max_length=255)),
742
- ('original_image_url', models.CharField(default='https://example.com/placeholder.jpg', max_length=255)),
743
- ('slug', models.SlugField(blank=True, null=True, unique=True)),
744
- ('polyp_count', models.IntegerField()),
745
- ('comments', models.TextField(blank=True, null=True)),
746
- ('gender', models.CharField(max_length=255)),
747
- ('name_image_url', models.CharField(max_length=255)),
748
- ('date_created', models.DateTimeField(auto_now_add=True)),
749
- ('processed', models.BooleanField(default=False)),
750
- ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.anonymizedimagelabel')),
587
+ ('name', models.CharField(max_length=255)),
751
588
  ],
752
589
  ),
753
590
  migrations.CreateModel(
@@ -755,8 +592,6 @@ class Migration(migrations.Migration):
755
592
  fields=[
756
593
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
757
594
  ('name', models.CharField(max_length=255)),
758
- ('name_de', models.CharField(max_length=255, null=True)),
759
- ('name_en', models.CharField(max_length=255, null=True)),
760
595
  ('description', models.TextField(blank=True, null=True)),
761
596
  ('parent_model', models.CharField(blank=True, max_length=255, null=True)),
762
597
  ('parent_field', models.CharField(blank=True, max_length=255, null=True)),
@@ -789,8 +624,6 @@ class Migration(migrations.Migration):
789
624
  fields=[
790
625
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
791
626
  ('name', models.CharField(max_length=255, unique=True)),
792
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
793
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
794
627
  ('disease', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='disease_classifications', to='endoreg_db.disease')),
795
628
  ],
796
629
  ),
@@ -799,31 +632,14 @@ class Migration(migrations.Migration):
799
632
  fields=[
800
633
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
801
634
  ('name', models.CharField(max_length=255, unique=True)),
802
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
803
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
804
635
  ('disease_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='disease_classification_choices', to='endoreg_db.diseaseclassification')),
805
636
  ],
806
637
  ),
807
- migrations.CreateModel(
808
- name='DroppedName',
809
- fields=[
810
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
811
- ('name', models.CharField(max_length=255)),
812
- ('gender', models.CharField(max_length=255)),
813
- ('x', models.FloatField()),
814
- ('y', models.FloatField()),
815
- ('name_image_url', models.CharField(max_length=255)),
816
- ('box_coordinates', models.CharField(blank=True, max_length=255, null=True)),
817
- ('annotation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dropped_names', to='endoreg_db.anonymousimageannotation')),
818
- ],
819
- ),
820
638
  migrations.CreateModel(
821
639
  name='Endoscope',
822
640
  fields=[
823
641
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
824
642
  ('name', models.CharField(max_length=255)),
825
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
826
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
827
643
  ('sn', models.CharField(max_length=255)),
828
644
  ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='endoscopes', to='endoreg_db.center')),
829
645
  ('endoscope_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='endoscopes', to='endoreg_db.endoscopetype')),
@@ -881,8 +697,6 @@ class Migration(migrations.Migration):
881
697
  fields=[
882
698
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
883
699
  ('name', models.CharField(max_length=100, unique=True)),
884
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
885
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
886
700
  ('description', models.TextField(blank=True, null=True)),
887
701
  ('event_classification', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='events', to='endoreg_db.eventclassification')),
888
702
  ],
@@ -892,22 +706,18 @@ class Migration(migrations.Migration):
892
706
  fields=[
893
707
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
894
708
  ('name', models.CharField(max_length=255, unique=True)),
895
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
896
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
897
709
  ('subcategories', models.JSONField(default=dict)),
898
710
  ('numerical_descriptors', models.JSONField(default=dict)),
899
711
  ('event_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='event_classification_choices', to='endoreg_db.eventclassification')),
900
712
  ],
901
713
  ),
902
714
  migrations.CreateModel(
903
- name='ExaminationIndication',
715
+ name='ExaminationIndicationClassification',
904
716
  fields=[
905
717
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
906
718
  ('name', models.CharField(max_length=255, unique=True)),
907
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
908
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
909
- ('examination', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='indications', to='endoreg_db.examination')),
910
- ('classification', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='indications', to='endoreg_db.examinationindicationclassification')),
719
+ ('description', models.TextField(blank=True, null=True)),
720
+ ('examinations', models.ManyToManyField(blank=True, related_name='indication_classifications', to='endoreg_db.examination')),
911
721
  ],
912
722
  ),
913
723
  migrations.CreateModel(
@@ -915,20 +725,25 @@ class Migration(migrations.Migration):
915
725
  fields=[
916
726
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
917
727
  ('name', models.CharField(max_length=255, unique=True)),
918
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
919
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
920
728
  ('subcategories', models.JSONField(default=dict)),
921
729
  ('numerical_descriptors', models.JSONField(default=dict)),
922
730
  ('classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='choices', to='endoreg_db.examinationindicationclassification')),
923
731
  ],
924
732
  ),
733
+ migrations.CreateModel(
734
+ name='ExaminationRequirementSet',
735
+ fields=[
736
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
737
+ ('enabled_by_default', models.BooleanField(default=False)),
738
+ ('name', models.CharField(max_length=100, unique=True)),
739
+ ('examinations', models.ManyToManyField(blank=True, related_name='exam_reqset_links', to='endoreg_db.examination')),
740
+ ],
741
+ ),
925
742
  migrations.CreateModel(
926
743
  name='ExaminationTimeType',
927
744
  fields=[
928
745
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
929
746
  ('name', models.CharField(max_length=100, unique=True)),
930
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
931
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
932
747
  ('examinations', models.ManyToManyField(blank=True, to='endoreg_db.examination')),
933
748
  ],
934
749
  options={
@@ -942,8 +757,6 @@ class Migration(migrations.Migration):
942
757
  fields=[
943
758
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
944
759
  ('name', models.CharField(max_length=100, unique=True)),
945
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
946
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
947
760
  ('start_time', models.TimeField(blank=True, null=True)),
948
761
  ('end_time', models.TimeField(blank=True, null=True)),
949
762
  ('time_types', models.ManyToManyField(blank=True, to='endoreg_db.examinationtimetype')),
@@ -959,13 +772,31 @@ class Migration(migrations.Migration):
959
772
  name='examination_types',
960
773
  field=models.ManyToManyField(blank=True, to='endoreg_db.examinationtype'),
961
774
  ),
775
+ migrations.CreateModel(
776
+ name='Examiner',
777
+ fields=[
778
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
779
+ ('first_name', models.CharField(max_length=255)),
780
+ ('last_name', models.CharField(max_length=255)),
781
+ ('dob', models.DateField(blank=True, null=True, verbose_name='Date of Birth')),
782
+ ('email', models.EmailField(blank=True, max_length=255, null=True)),
783
+ ('phone', models.CharField(blank=True, max_length=255, null=True)),
784
+ ('is_real_person', models.BooleanField(default=True)),
785
+ ('hash', models.CharField(max_length=255, unique=True)),
786
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
787
+ ('gender', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.gender')),
788
+ ],
789
+ options={
790
+ 'abstract': False,
791
+ },
792
+ ),
962
793
  migrations.CreateModel(
963
794
  name='FindingIntervention',
964
795
  fields=[
965
796
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
966
797
  ('name', models.CharField(max_length=100, unique=True)),
967
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
968
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
798
+ ('name_de', models.CharField(max_length=100, null=True, unique=True)),
799
+ ('name_en', models.CharField(max_length=100, null=True, unique=True)),
969
800
  ('description', models.TextField(blank=True, null=True)),
970
801
  ('description_de', models.TextField(blank=True, null=True)),
971
802
  ('description_en', models.TextField(blank=True, null=True)),
@@ -978,52 +809,42 @@ class Migration(migrations.Migration):
978
809
  fields=[
979
810
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
980
811
  ('name', models.CharField(max_length=100, unique=True)),
981
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
982
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
812
+ ('name_de', models.CharField(max_length=100, null=True, unique=True)),
813
+ ('name_en', models.CharField(max_length=100, null=True, unique=True)),
983
814
  ('description', models.TextField(blank=True, null=True)),
984
815
  ('description_de', models.TextField(blank=True, null=True)),
985
816
  ('description_en', models.TextField(blank=True, null=True)),
986
817
  ('examinations', models.ManyToManyField(blank=True, related_name='findings', to='endoreg_db.examination')),
987
- ('causing_finding_interventions', models.ManyToManyField(blank=True, related_name='causing_findings', to='endoreg_db.findingintervention')),
988
818
  ('finding_interventions', models.ManyToManyField(blank=True, related_name='findings', to='endoreg_db.findingintervention')),
989
- ('opt_causing_finding_interventions', models.ManyToManyField(blank=True, related_name='opt_causing_findings', to='endoreg_db.findingintervention')),
990
- ('optional_morphology_classification_types', models.ManyToManyField(blank=True, related_name='optional_for_findings', to='endoreg_db.findingmorphologyclassificationtype')),
991
- ('required_morphology_classification_types', models.ManyToManyField(blank=True, related_name='required_by_findings', to='endoreg_db.findingmorphologyclassificationtype')),
992
819
  ('finding_types', models.ManyToManyField(blank=True, related_name='findings', to='endoreg_db.findingtype')),
993
820
  ],
994
821
  ),
995
822
  migrations.CreateModel(
996
- name='FindingMorphologyClassificationChoice',
823
+ name='ExaminationIndication',
997
824
  fields=[
998
825
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
999
826
  ('name', models.CharField(max_length=255, unique=True)),
1000
- ('name_de', models.CharField(blank=True, max_length=255)),
1001
- ('name_en', models.CharField(blank=True, max_length=255)),
1002
- ('description', models.TextField(blank=True)),
1003
- ('subcategories', models.JSONField(default=dict)),
1004
- ('numerical_descriptors', models.JSONField(default=dict)),
1005
- ('classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='choices', to='endoreg_db.findingmorphologyclassification')),
827
+ ('description', models.TextField(blank=True, null=True)),
828
+ ('examinations', models.ManyToManyField(blank=True, related_name='indications', to='endoreg_db.examination')),
829
+ ('classifications', models.ManyToManyField(blank=True, related_name='indications', to='endoreg_db.examinationindicationclassification')),
830
+ ('expected_interventions', models.ManyToManyField(blank=True, related_name='indications', to='endoreg_db.findingintervention')),
1006
831
  ],
1007
832
  ),
1008
- migrations.AddField(
1009
- model_name='findingmorphologyclassification',
1010
- name='classification_type',
1011
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.findingmorphologyclassificationtype'),
1012
- ),
1013
833
  migrations.CreateModel(
1014
- name='FindingLocationClassification',
834
+ name='FindingClassification',
1015
835
  fields=[
1016
836
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1017
- ('name', models.CharField(max_length=100, unique=True)),
1018
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
1019
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
1020
- ('description', models.TextField(blank=True, null=True)),
837
+ ('name', models.CharField(max_length=255, unique=True)),
838
+ ('name_de', models.CharField(max_length=255, null=True, unique=True)),
839
+ ('name_en', models.CharField(max_length=255, null=True, unique=True)),
840
+ ('description', models.TextField(blank=True)),
1021
841
  ('description_de', models.TextField(blank=True, null=True)),
1022
842
  ('description_en', models.TextField(blank=True, null=True)),
1023
- ('examinations', models.ManyToManyField(blank=True, related_name='location_classifications', to='endoreg_db.examination')),
1024
- ('findings', models.ManyToManyField(blank=True, related_name='location_classifications', to='endoreg_db.finding')),
1025
- ('choices', models.ManyToManyField(blank=True, related_name='location_classifications', to='endoreg_db.findinglocationclassificationchoice')),
1026
- ('finding_types', models.ManyToManyField(blank=True, related_name='location_classifications', to='endoreg_db.findingtype')),
843
+ ('examinations', models.ManyToManyField(blank=True, related_name='finding_classifications', to='endoreg_db.examination')),
844
+ ('findings', models.ManyToManyField(blank=True, related_name='finding_classifications', to='endoreg_db.finding')),
845
+ ('choices', models.ManyToManyField(blank=True, related_name='classifications', to='endoreg_db.findingclassificationchoice')),
846
+ ('classification_types', models.ManyToManyField(to='endoreg_db.findingclassificationtype')),
847
+ ('finding_types', models.ManyToManyField(blank=True, related_name='finding_classifications', to='endoreg_db.findingtype')),
1027
848
  ],
1028
849
  ),
1029
850
  migrations.AddField(
@@ -1032,7 +853,7 @@ class Migration(migrations.Migration):
1032
853
  field=models.ManyToManyField(related_name='centers', to='endoreg_db.firstname'),
1033
854
  ),
1034
855
  migrations.CreateModel(
1035
- name='Examiner',
856
+ name='Employee',
1036
857
  fields=[
1037
858
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1038
859
  ('first_name', models.CharField(max_length=255)),
@@ -1041,8 +862,7 @@ class Migration(migrations.Migration):
1041
862
  ('email', models.EmailField(blank=True, max_length=255, null=True)),
1042
863
  ('phone', models.CharField(blank=True, max_length=255, null=True)),
1043
864
  ('is_real_person', models.BooleanField(default=True)),
1044
- ('hash', models.CharField(max_length=255, unique=True)),
1045
- ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
865
+ ('employee_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='employees', to='endoreg_db.employeetype')),
1046
866
  ('gender', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.gender')),
1047
867
  ],
1048
868
  options={
@@ -1050,21 +870,34 @@ class Migration(migrations.Migration):
1050
870
  },
1051
871
  ),
1052
872
  migrations.CreateModel(
1053
- name='BinaryClassificationAnnotationTask',
873
+ name='InformationSource',
1054
874
  fields=[
1055
875
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1056
- ('is_finished', models.BooleanField(default=False)),
1057
- ('date_created', models.DateTimeField(auto_now_add=True)),
1058
- ('date_finished', models.DateTimeField(blank=True, null=True)),
1059
- ('image_path', models.CharField(blank=True, max_length=255, null=True)),
1060
- ('labelstudio_project_id', models.IntegerField(blank=True, null=True)),
1061
- ('labelstudio_task_id', models.IntegerField(blank=True, null=True)),
1062
- ('image_type', models.CharField(default='frame', max_length=255)),
1063
- ('frame', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='binary_classification_annotation_tasks', to='endoreg_db.frame')),
1064
- ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.label')),
876
+ ('name', models.CharField(max_length=100)),
877
+ ('url', models.URLField(blank=True, null=True)),
878
+ ('description', models.TextField(blank=True, null=True)),
879
+ ('date', models.DateField(blank=True, null=True)),
880
+ ('date_created', models.DateField(auto_now_add=True)),
881
+ ('date_modified', models.DateField(auto_now=True)),
882
+ ('abbreviation', models.CharField(blank=True, max_length=100, null=True, unique=True)),
1065
883
  ],
1066
884
  options={
1067
- 'abstract': False,
885
+ 'verbose_name': 'Information Source',
886
+ 'verbose_name_plural': 'Information Sources',
887
+ 'indexes': [models.Index(fields=['name'], name='endoreg_db__name_febac5_idx'), models.Index(fields=['abbreviation'], name='endoreg_db__abbrevi_5a07c4_idx')],
888
+ },
889
+ ),
890
+ migrations.CreateModel(
891
+ name='InformationSourceType',
892
+ fields=[
893
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
894
+ ('name', models.CharField(max_length=100, unique=True)),
895
+ ('description', models.TextField(blank=True, null=True)),
896
+ ('information_sources', models.ManyToManyField(blank=True, related_name='information_source_types', to='endoreg_db.informationsource')),
897
+ ],
898
+ options={
899
+ 'verbose_name': 'Information Source Type',
900
+ 'verbose_name_plural': 'Information Source Types',
1068
901
  },
1069
902
  ),
1070
903
  migrations.CreateModel(
@@ -1074,27 +907,53 @@ class Migration(migrations.Migration):
1074
907
  ('name', models.CharField(max_length=255)),
1075
908
  ('description', models.TextField(blank=True, null=True)),
1076
909
  ('version', models.IntegerField()),
1077
- ('labels', models.ManyToManyField(related_name='labels', to='endoreg_db.label')),
910
+ ('labels', models.ManyToManyField(related_name='label_sets', to='endoreg_db.label')),
1078
911
  ],
1079
912
  ),
1080
913
  migrations.AddField(
1081
914
  model_name='label',
1082
915
  name='label_type',
1083
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='labels', to='endoreg_db.labeltype'),
916
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='labels', to='endoreg_db.labeltype'),
917
+ ),
918
+ migrations.CreateModel(
919
+ name='LabelVideoSegment',
920
+ fields=[
921
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
922
+ ('start_frame_number', models.IntegerField()),
923
+ ('end_frame_number', models.IntegerField()),
924
+ ('label', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.label')),
925
+ ('source', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.informationsource')),
926
+ ],
927
+ ),
928
+ migrations.CreateModel(
929
+ name='LabelVideoSegmentState',
930
+ fields=[
931
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
932
+ ('created_at', models.DateTimeField(auto_now_add=True)),
933
+ ('updated_at', models.DateTimeField(auto_now=True)),
934
+ ('prediction', models.BooleanField(default=False)),
935
+ ('annotation', models.BooleanField(default=False)),
936
+ ('frames_extracted', models.BooleanField(default=False)),
937
+ ('is_validated', models.BooleanField(default=False)),
938
+ ('origin', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='state', to='endoreg_db.labelvideosegment')),
939
+ ],
940
+ options={
941
+ 'verbose_name': 'Label Video Segment State',
942
+ 'verbose_name_plural': 'Label Video Segment States',
943
+ },
1084
944
  ),
1085
945
  migrations.CreateModel(
1086
946
  name='LabValue',
1087
947
  fields=[
1088
948
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1089
949
  ('name', models.CharField(max_length=255, unique=True)),
1090
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
1091
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
1092
950
  ('abbreviation', models.CharField(blank=True, max_length=10, null=True)),
1093
951
  ('numeric_precision', models.IntegerField(default=3)),
1094
952
  ('default_normal_range', models.JSONField(blank=True, null=True)),
1095
953
  ('normal_range_age_dependent', models.BooleanField(default=False)),
1096
954
  ('normal_range_gender_dependent', models.BooleanField(default=False)),
1097
955
  ('normal_range_special_case', models.BooleanField(default=False)),
956
+ ('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%.')),
1098
957
  ('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')),
1099
958
  ('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')),
1100
959
  ('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')),
@@ -1112,39 +971,11 @@ class Migration(migrations.Migration):
1112
971
  name='last_names',
1113
972
  field=models.ManyToManyField(related_name='centers', to='endoreg_db.lastname'),
1114
973
  ),
1115
- migrations.CreateModel(
1116
- name='LxClient',
1117
- fields=[
1118
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1119
- ('name', models.CharField(max_length=100, unique=True)),
1120
- ('description', models.TextField(blank=True)),
1121
- ('vpn_ip', models.GenericIPAddressField(blank=True, null=True)),
1122
- ('client_tags', models.ManyToManyField(blank=True, to='endoreg_db.lxclienttag')),
1123
- ('client_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.lxclienttype')),
1124
- ],
1125
- ),
1126
- migrations.AddField(
1127
- model_name='lxclienttag',
1128
- name='permissions',
1129
- field=models.ManyToManyField(blank=True, related_name='allowed_client_tags', to='endoreg_db.lxpermission'),
1130
- ),
1131
- migrations.CreateModel(
1132
- name='LxIdentity',
1133
- fields=[
1134
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1135
- ('name', models.CharField(max_length=100, unique=True)),
1136
- ('description', models.TextField(blank=True)),
1137
- ('identity_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.lxidentitytype')),
1138
- ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.lxuser')),
1139
- ],
1140
- ),
1141
974
  migrations.CreateModel(
1142
975
  name='Material',
1143
976
  fields=[
1144
977
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1145
978
  ('name', models.CharField(max_length=255)),
1146
- ('name_de', models.CharField(max_length=255, null=True)),
1147
- ('name_en', models.CharField(max_length=255, null=True)),
1148
979
  ('emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.emissionfactor')),
1149
980
  ],
1150
981
  ),
@@ -1152,9 +983,7 @@ class Migration(migrations.Migration):
1152
983
  name='MedicationSchedule',
1153
984
  fields=[
1154
985
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1155
- ('name', models.CharField(max_length=255)),
1156
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
1157
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
986
+ ('name', models.CharField(max_length=255, unique=True)),
1158
987
  ('description', models.TextField(blank=True, null=True)),
1159
988
  ('therapy_duration_d', models.FloatField(blank=True, null=True)),
1160
989
  ('dose', models.FloatField()),
@@ -1180,21 +1009,21 @@ class Migration(migrations.Migration):
1180
1009
  name='ModelMeta',
1181
1010
  fields=[
1182
1011
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1183
- ('name', models.CharField(max_length=255)),
1184
- ('version', models.CharField(max_length=255)),
1185
- ('activation', models.CharField(default='sigmoid', max_length=255)),
1186
- ('weights', models.FileField(blank=True, null=True, upload_to='db_model_weights', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['ckpt'])])),
1187
- ('mean', models.CharField(default='0.45211223,0.27139644,0.19264949', max_length=255)),
1188
- ('std', models.CharField(default='0.31418097,0.21088019,0.16059452', max_length=255)),
1189
- ('size_x', models.IntegerField(default=716)),
1190
- ('size_y', models.IntegerField(default=716)),
1191
- ('axes', models.CharField(default='2,0,1', max_length=255)),
1192
- ('batchsize', models.IntegerField(default=16)),
1193
- ('num_workers', models.IntegerField(default=0)),
1194
- ('description', models.TextField(blank=True, null=True)),
1012
+ ('name', models.CharField(help_text="User-defined name for this specific model metadata set (e.g., 'segmentation_base').", max_length=255)),
1013
+ ('version', models.CharField(help_text="Version identifier for this metadata set (e.g., '1', '2a').", max_length=255)),
1014
+ ('activation', models.CharField(default='sigmoid', help_text="Output activation function (e.g., 'sigmoid', 'softmax', 'none').", max_length=50)),
1015
+ ('weights', models.FileField(blank=True, help_text='Path to the model weights file (.ckpt), relative to MEDIA_ROOT.', null=True, upload_to='model_weights', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['ckpt'])])),
1016
+ ('mean', models.CharField(default='0.45211223,0.27139644,0.19264949', help_text='Comma-separated mean values for input normalization.', max_length=255)),
1017
+ ('std', models.CharField(default='0.31418097,0.21088019,0.16059452', help_text='Comma-separated standard deviation values for input normalization.', max_length=255)),
1018
+ ('size_x', models.IntegerField(default=716, help_text='Expected input image width.')),
1019
+ ('size_y', models.IntegerField(default=716, help_text='Expected input image height.')),
1020
+ ('axes', models.CharField(default='2,0,1', help_text="Comma-separated target axis order (e.g., '2,0,1' for CHW).", max_length=10)),
1021
+ ('batchsize', models.IntegerField(default=16, help_text='Default batch size for inference.')),
1022
+ ('num_workers', models.IntegerField(default=0, help_text='Default number of workers for data loading.')),
1023
+ ('description', models.TextField(blank=True, help_text='Optional description.', null=True)),
1195
1024
  ('date_created', models.DateTimeField(auto_now_add=True)),
1196
- ('labelset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='models', to='endoreg_db.labelset')),
1197
- ('model', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='models', to='endoreg_db.aimodel')),
1025
+ ('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')),
1026
+ ('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')),
1198
1027
  ],
1199
1028
  ),
1200
1029
  migrations.AddField(
@@ -1207,75 +1036,21 @@ class Migration(migrations.Migration):
1207
1036
  fields=[
1208
1037
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1209
1038
  ('name', models.CharField(max_length=255, unique=True)),
1210
- ('model_meta', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.modelmeta')),
1211
- ],
1212
- ),
1213
- migrations.CreateModel(
1214
- name='AglServiceLogEntry',
1215
- fields=[
1216
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1217
- ('timestamp', models.DateTimeField(auto_now_add=True)),
1218
- ('ip_address', models.GenericIPAddressField(blank=True, null=True)),
1219
- ('user_agent', models.CharField(blank=True, max_length=256, null=True)),
1220
- ('message', models.TextField()),
1221
- ('json_content', models.JSONField(blank=True, null=True)),
1222
- ('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.aglservice')),
1223
- ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
1224
- ('log_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.logtype')),
1225
- ('device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.networkdevice')),
1039
+ ('model_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.modelmeta')),
1226
1040
  ],
1227
- options={
1228
- 'verbose_name': 'AGL Service Log Entry',
1229
- 'verbose_name_plural': 'AGL Service Log Entries',
1230
- },
1231
- ),
1232
- migrations.AddField(
1233
- model_name='aglservice',
1234
- name='devices',
1235
- field=models.ManyToManyField(related_name='services', to='endoreg_db.networkdevice'),
1236
- ),
1237
- migrations.CreateModel(
1238
- name='NetworkDeviceLogEntry',
1239
- fields=[
1240
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1241
- ('timestamp', models.DateTimeField(auto_now_add=True)),
1242
- ('ip_address', models.GenericIPAddressField(blank=True, null=True)),
1243
- ('user_agent', models.CharField(blank=True, max_length=256, null=True)),
1244
- ('message', models.TextField()),
1245
- ('json_content', models.JSONField(blank=True, null=True)),
1246
- ('datetime', models.DateTimeField(blank=True, default=None, null=True)),
1247
- ('aglnet_ip', models.GenericIPAddressField(blank=True, null=True)),
1248
- ('vpn_service_status', models.CharField(blank=True, max_length=255, null=True)),
1249
- ('vpn_service_restart_attempt', models.BooleanField(default=False)),
1250
- ('vpn_service_restart_success', models.BooleanField(blank=True, null=True)),
1251
- ('ping_vpn', models.BooleanField(default=False)),
1252
- ('ping_www', models.BooleanField(default=False)),
1253
- ('transferred_to_host', models.BooleanField(default=False)),
1254
- ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.networkdevice')),
1255
- ('log_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.logtype')),
1256
- ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
1257
- ],
1258
- options={
1259
- 'verbose_name': 'Network Device Log Entry',
1260
- 'verbose_name_plural': 'Network Device Log Entries',
1261
- },
1262
1041
  ),
1263
1042
  migrations.AddField(
1264
- model_name='networkdevice',
1265
- name='device_type',
1266
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.networkdevicetype'),
1043
+ model_name='aimodel',
1044
+ name='model_type',
1045
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ai_models', to='endoreg_db.modeltype'),
1267
1046
  ),
1268
1047
  migrations.CreateModel(
1269
1048
  name='Organ',
1270
1049
  fields=[
1271
1050
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1272
1051
  ('name', models.CharField(max_length=100, unique=True)),
1273
- ('name_de', models.CharField(blank=True, max_length=100, null=True)),
1274
- ('name_en', models.CharField(blank=True, max_length=100, null=True)),
1275
1052
  ('description', models.TextField(blank=True, null=True)),
1276
- ('description_de', models.TextField(blank=True, null=True)),
1277
- ('description_en', models.TextField(blank=True, null=True)),
1278
- ('location_choices', models.ManyToManyField(blank=True, related_name='organs', to='endoreg_db.findinglocationclassificationchoice')),
1053
+ ('location_choices', models.ManyToManyField(blank=True, related_name='organs', to='endoreg_db.findingclassificationchoice')),
1279
1054
  ],
1280
1055
  ),
1281
1056
  migrations.CreateModel(
@@ -1306,8 +1081,8 @@ class Migration(migrations.Migration):
1306
1081
  ('subcategories', models.JSONField(default=dict)),
1307
1082
  ('last_update', models.DateTimeField(auto_now=True)),
1308
1083
  ('classification_choices', models.ManyToManyField(to='endoreg_db.diseaseclassificationchoice')),
1309
- ('disease', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.disease')),
1310
- ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patient')),
1084
+ ('disease', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_diseases', to='endoreg_db.disease')),
1085
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='diseases', to='endoreg_db.patient')),
1311
1086
  ],
1312
1087
  options={
1313
1088
  'verbose_name': 'Patient Disease',
@@ -1325,8 +1100,8 @@ class Migration(migrations.Migration):
1325
1100
  ('numerical_descriptors', models.JSONField(default=dict)),
1326
1101
  ('last_update', models.DateTimeField(auto_now=True)),
1327
1102
  ('classification_choice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.eventclassificationchoice')),
1328
- ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.event')),
1329
- ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patient')),
1103
+ ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_events', to='endoreg_db.event')),
1104
+ ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='endoreg_db.patient')),
1330
1105
  ],
1331
1106
  ),
1332
1107
  migrations.CreateModel(
@@ -1345,6 +1120,46 @@ class Migration(migrations.Migration):
1345
1120
  'ordering': ['patient', 'examination', 'date_start'],
1346
1121
  },
1347
1122
  ),
1123
+ migrations.CreateModel(
1124
+ name='Case',
1125
+ fields=[
1126
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1127
+ ('hash', models.CharField(blank=True, help_text='An optional hash value associated with the case.', max_length=255, null=True)),
1128
+ ('start_date', models.DateTimeField(db_index=True, help_text='The start date and time of the case.')),
1129
+ ('end_date', models.DateTimeField(blank=True, help_text='The end date and time of the case (optional).', null=True)),
1130
+ ('is_active', models.BooleanField(db_index=True, default=True, help_text='Flag indicating if the case is currently active.')),
1131
+ ('is_closed', models.BooleanField(db_index=True, default=False, help_text='Flag indicating if the case has been closed.')),
1132
+ ('is_deleted', models.BooleanField(db_index=True, default=False, help_text='Flag indicating if the case is marked as deleted.')),
1133
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='The date and time the case was created.')),
1134
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='The date and time the case was last updated.')),
1135
+ ('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')),
1136
+ ('patient_examinations', models.ManyToManyField(help_text='The examinations included in this case.', related_name='cases', to='endoreg_db.patientexamination')),
1137
+ ],
1138
+ options={
1139
+ 'verbose_name': 'Case',
1140
+ 'verbose_name_plural': 'Cases',
1141
+ 'ordering': ['-start_date', 'patient'],
1142
+ },
1143
+ ),
1144
+ migrations.CreateModel(
1145
+ name='AnonymExaminationReport',
1146
+ fields=[
1147
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1148
+ ('meta', models.JSONField(blank=True, null=True)),
1149
+ ('text', models.TextField(blank=True, null=True)),
1150
+ ('date', models.DateField(blank=True, null=True)),
1151
+ ('time', models.TimeField(blank=True, null=True)),
1152
+ ('file', models.FileField(blank=True, null=True, upload_to=pathlib.PurePosixPath('pdfs'))),
1153
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1154
+ ('type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.documenttype')),
1155
+ ('examiners', models.ManyToManyField(blank=True, to='endoreg_db.examiner')),
1156
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='endoreg_db.patient')),
1157
+ ('patient_examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.patientexamination')),
1158
+ ],
1159
+ options={
1160
+ 'abstract': False,
1161
+ },
1162
+ ),
1348
1163
  migrations.CreateModel(
1349
1164
  name='PatientExaminationIndication',
1350
1165
  fields=[
@@ -1358,8 +1173,15 @@ class Migration(migrations.Migration):
1358
1173
  name='PatientFinding',
1359
1174
  fields=[
1360
1175
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1361
- ('finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_findings', to='endoreg_db.finding')),
1176
+ ('created_at', models.DateTimeField(auto_now_add=True)),
1177
+ ('updated_at', models.DateTimeField(auto_now=True)),
1178
+ ('is_active', models.BooleanField(default=True, help_text='Deaktiviert statt gelöscht für Audit-Trail')),
1179
+ ('deactivated_at', models.DateTimeField(blank=True, null=True)),
1180
+ ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='created_findings', to=settings.AUTH_USER_MODEL)),
1181
+ ('deactivated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deactivated_findings', to=settings.AUTH_USER_MODEL)),
1182
+ ('finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='finding_patient_findings', to='endoreg_db.finding')),
1362
1183
  ('patient_examination', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_findings', to='endoreg_db.patientexamination')),
1184
+ ('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='updated_findings', to=settings.AUTH_USER_MODEL)),
1363
1185
  ],
1364
1186
  options={
1365
1187
  'verbose_name': 'Patient Finding',
@@ -1367,57 +1189,40 @@ class Migration(migrations.Migration):
1367
1189
  'ordering': ['patient_examination', 'finding'],
1368
1190
  },
1369
1191
  ),
1370
- migrations.CreateModel(
1371
- name='PatientFindingIntervention',
1372
- fields=[
1373
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1374
- ('state', models.CharField(blank=True, max_length=100, null=True)),
1375
- ('time_start', models.DateTimeField(blank=True, null=True)),
1376
- ('time_end', models.DateTimeField(blank=True, null=True)),
1377
- ('date', models.DateField(blank=True, null=True)),
1378
- ('intervention', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_interventions', to='endoreg_db.findingintervention')),
1379
- ('patient_finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interventions', to='endoreg_db.patientfinding')),
1380
- ],
1192
+ migrations.AddField(
1193
+ model_name='labelvideosegment',
1194
+ name='patient_findings',
1195
+ field=models.ManyToManyField(blank=True, related_name='video_segments', to='endoreg_db.patientfinding'),
1381
1196
  ),
1382
1197
  migrations.CreateModel(
1383
- name='PatientFindingLocation',
1198
+ name='PatientFindingClassification',
1384
1199
  fields=[
1385
1200
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1201
+ ('is_active', models.BooleanField(default=True, help_text='Indicates if the classification is currently active.')),
1386
1202
  ('subcategories', models.JSONField(blank=True, null=True)),
1387
1203
  ('numerical_descriptors', models.JSONField(blank=True, null=True)),
1388
- ('location_choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_locations', to='endoreg_db.findinglocationclassificationchoice')),
1389
- ('location_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_locations', to='endoreg_db.findinglocationclassification')),
1204
+ ('classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_classifications', to='endoreg_db.findingclassification')),
1205
+ ('classification_choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_classifications', to='endoreg_db.findingclassificationchoice')),
1206
+ ('finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='classifications', to='endoreg_db.patientfinding')),
1390
1207
  ],
1391
1208
  options={
1392
- 'verbose_name': 'Patient Finding Location',
1393
- 'verbose_name_plural': 'Patient Finding Locations',
1394
- 'ordering': ['location_classification', 'location_choice'],
1209
+ 'verbose_name': 'Patient Finding Classification',
1210
+ 'verbose_name_plural': 'Patient Finding Classifications',
1211
+ 'ordering': ['finding', 'classification', 'classification_choice'],
1395
1212
  },
1396
1213
  ),
1397
- migrations.AddField(
1398
- model_name='patientfinding',
1399
- name='locations',
1400
- field=models.ManyToManyField(blank=True, related_name='patient_findings', to='endoreg_db.patientfindinglocation'),
1401
- ),
1402
1214
  migrations.CreateModel(
1403
- name='PatientFindingMorphology',
1215
+ name='PatientFindingIntervention',
1404
1216
  fields=[
1405
1217
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1406
- ('subcategories', models.JSONField(default=dict)),
1407
- ('numerical_descriptors', models.JSONField(default=dict)),
1408
- ('morphology_choice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_morphologies', to='endoreg_db.findingmorphologyclassificationchoice')),
1409
- ('morphology_classification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_morphologies', to='endoreg_db.findingmorphologyclassification')),
1218
+ ('is_active', models.BooleanField(default=True, help_text='Indicates if the intervention is currently active.')),
1219
+ ('state', models.CharField(blank=True, max_length=100, null=True)),
1220
+ ('time_start', models.DateTimeField(blank=True, null=True)),
1221
+ ('time_end', models.DateTimeField(blank=True, null=True)),
1222
+ ('date', models.DateField(blank=True, null=True)),
1223
+ ('finding', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interventions', to='endoreg_db.patientfinding')),
1224
+ ('intervention', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patient_finding_interventions', to='endoreg_db.findingintervention')),
1410
1225
  ],
1411
- options={
1412
- 'verbose_name': 'Patient Finding Morphology',
1413
- 'verbose_name_plural': 'Patient Finding Morphologies',
1414
- 'ordering': ['morphology_classification', 'morphology_choice'],
1415
- },
1416
- ),
1417
- migrations.AddField(
1418
- model_name='patientfinding',
1419
- name='morphologies',
1420
- field=models.ManyToManyField(blank=True, related_name='patient_findings', to='endoreg_db.patientfindingmorphology'),
1421
1226
  ),
1422
1227
  migrations.CreateModel(
1423
1228
  name='PatientLabSample',
@@ -1434,9 +1239,9 @@ class Migration(migrations.Migration):
1434
1239
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1435
1240
  ('dosage', models.JSONField(blank=True, null=True)),
1436
1241
  ('active', models.BooleanField(default=True)),
1437
- ('intake_times', models.ManyToManyField(blank=True, related_name='patient_medications', to='endoreg_db.medicationintaketime')),
1438
- ('medication', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='patient_medications', to='endoreg_db.medication')),
1439
- ('medication_indication', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='patient_medications', to='endoreg_db.medicationindication')),
1242
+ ('intake_times', models.ManyToManyField(blank=True, related_name='intake_time_patient_medications', to='endoreg_db.medicationintaketime')),
1243
+ ('medication', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='medication_patient_medications', to='endoreg_db.medication')),
1244
+ ('medication_indication', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='indication_patient_medications', to='endoreg_db.medicationindication')),
1440
1245
  ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patient')),
1441
1246
  ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.unit')),
1442
1247
  ],
@@ -1470,140 +1275,47 @@ class Migration(migrations.Migration):
1470
1275
  fields=[
1471
1276
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1472
1277
  ('date_used', models.DateField()),
1473
- ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1474
- ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.product')),
1278
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_products', to='endoreg_db.center')),
1279
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_products', to='endoreg_db.product')),
1475
1280
  ],
1281
+ options={
1282
+ 'verbose_name': 'Center Product Usage',
1283
+ 'verbose_name_plural': 'Center Product Usages',
1284
+ 'ordering': ['center', '-date_used', 'product'],
1285
+ },
1476
1286
  ),
1477
1287
  migrations.AddField(
1478
1288
  model_name='product',
1479
1289
  name='product_group',
1480
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.productgroup'),
1290
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='products', to='endoreg_db.productgroup'),
1481
1291
  ),
1482
1292
  migrations.CreateModel(
1483
1293
  name='PortalUserInfo',
1484
1294
  fields=[
1485
1295
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1486
1296
  ('works_in_endoscopy', models.BooleanField(blank=True, null=True)),
1297
+ ('examiner', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portal_user_info', to='endoreg_db.examiner')),
1487
1298
  ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
1488
- ('profession', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.profession')),
1489
- ],
1490
- ),
1491
- migrations.CreateModel(
1492
- name='QuizAnswer',
1493
- fields=[
1494
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1495
- ('text_value', models.CharField(blank=True, max_length=255, null=True)),
1496
- ('number_value', models.FloatField(blank=True, null=True)),
1497
- ('last_updated', models.DateTimeField(auto_now=True)),
1498
- ('answer_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.quizanswertype')),
1499
- ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.quizquestion')),
1299
+ ('profession', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='portal_user_infos', to='endoreg_db.profession')),
1500
1300
  ],
1501
1301
  ),
1502
1302
  migrations.AddField(
1503
- model_name='quizquestion',
1504
- name='question_type',
1505
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.quizquestiontype'),
1506
- ),
1507
- migrations.CreateModel(
1508
- name='ImageClassificationAnnotation',
1509
- fields=[
1510
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1511
- ('value', models.BooleanField()),
1512
- ('float_value', models.FloatField(blank=True, null=True)),
1513
- ('annotator', models.CharField(blank=True, max_length=255, null=True)),
1514
- ('date_created', models.DateTimeField(auto_now_add=True)),
1515
- ('date_modified', models.DateTimeField(auto_now=True)),
1516
- ('frame', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_annotations', to='endoreg_db.frame')),
1517
- ('information_source', 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')),
1518
- ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_annotations', to='endoreg_db.label')),
1519
- ('model_meta', 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')),
1520
- ('raw_frame', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_annotations', to='endoreg_db.rawframe')),
1521
- ],
1303
+ model_name='employeetype',
1304
+ name='qualifications',
1305
+ field=models.ManyToManyField(related_name='employee_types', to='endoreg_db.qualification'),
1522
1306
  ),
1523
1307
  migrations.CreateModel(
1524
- name='RawVideoFile',
1308
+ name='EmployeeQualification',
1525
1309
  fields=[
1526
1310
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1527
- ('uuid', models.UUIDField()),
1528
- ('original_file_name', models.CharField(max_length=255)),
1529
- ('video_hash', models.CharField(max_length=255, unique=True)),
1530
- ('uploaded_at', models.DateTimeField(auto_now_add=True)),
1531
- ('frame_dir', models.CharField(max_length=255)),
1532
- ('prediction_dir', models.CharField(max_length=255)),
1533
- ('predictions', models.JSONField(default=dict)),
1534
- ('fps', models.FloatField(blank=True, null=True)),
1535
- ('duration', models.FloatField(blank=True, null=True)),
1536
- ('readable_predictions', models.JSONField(default=dict)),
1537
- ('merged_predictions', models.JSONField(default=dict)),
1538
- ('smooth_merged_predictions', models.JSONField(default=dict)),
1539
- ('binary_smooth_merged_predictions', models.JSONField(default=dict)),
1540
- ('sequences', models.JSONField(default=dict)),
1541
- ('state_frames_required', models.BooleanField(default=True)),
1542
- ('state_frames_extracted', models.BooleanField(default=False)),
1543
- ('state_initial_prediction_required', models.BooleanField(default=True)),
1544
- ('state_initial_prediction_completed', models.BooleanField(default=False)),
1545
- ('state_initial_prediction_import_required', models.BooleanField(default=True)),
1546
- ('state_initial_prediction_import_completed', models.BooleanField(default=False)),
1547
- ('state_histology_required', models.BooleanField(blank=True, null=True)),
1548
- ('state_histology_available', models.BooleanField(default=False)),
1549
- ('state_follow_up_intervention_required', models.BooleanField(blank=True, null=True)),
1550
- ('state_follow_up_intervention_available', models.BooleanField(default=False)),
1551
- ('state_dataset_complete', models.BooleanField(default=False)),
1552
- ('is_raw', models.BooleanField(default=False)),
1553
- ('file', models.FileField(storage=django.core.files.storage.FileSystemStorage(location='/home/admin/test-data'), upload_to='videos', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['mp4'])])),
1554
- ('state_anonymized_frames_generated', models.BooleanField(default=False)),
1555
- ('state_ocr_required', models.BooleanField(default=True)),
1556
- ('state_ocr_completed', models.BooleanField(default=False)),
1557
- ('state_outside_validated', models.BooleanField(default=False)),
1558
- ('state_ocr_result_validated', models.BooleanField(default=False)),
1559
- ('state_sensitive_data_retrieved', models.BooleanField(default=False)),
1560
- ('state_censor_outside_required', models.BooleanField(default=True)),
1561
- ('state_censor_outside_completed', models.BooleanField(default=False)),
1562
- ('state_make_anonymized_video_required', models.BooleanField(default=True)),
1563
- ('state_make_anonymized_video_completed', models.BooleanField(default=False)),
1564
- ('ai_model_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.modelmeta')),
1565
- ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1566
- ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.patient')),
1567
- ('processor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.endoscopyprocessor')),
1311
+ ('employee', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='qualification', to='endoreg_db.employee')),
1312
+ ('qualifications', models.ManyToManyField(related_name='employee_qualifications', to='endoreg_db.qualification')),
1568
1313
  ],
1569
- options={
1570
- 'abstract': False,
1571
- },
1572
1314
  ),
1573
1315
  migrations.AddField(
1574
- model_name='rawframe',
1575
- name='video',
1576
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frames', to='endoreg_db.rawvideofile'),
1577
- ),
1578
- migrations.CreateModel(
1579
- name='RawVideoPredictionMeta',
1580
- fields=[
1581
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1582
- ('date_created', models.DateTimeField(auto_now_add=True)),
1583
- ('date_modified', models.DateTimeField(auto_now=True)),
1584
- ('prediction_array', models.BinaryField(blank=True, null=True)),
1585
- ('is_raw', models.BooleanField(default=False)),
1586
- ('model_meta', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.modelmeta')),
1587
- ('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='video_prediction_meta', to='endoreg_db.rawvideofile')),
1588
- ],
1589
- options={
1590
- 'abstract': False,
1591
- },
1592
- ),
1593
- migrations.CreateModel(
1594
- name='LabelRawVideoSegment',
1595
- fields=[
1596
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1597
- ('start_frame_number', models.IntegerField()),
1598
- ('end_frame_number', models.IntegerField()),
1599
- ('label', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.label')),
1600
- ('source', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.informationsource')),
1601
- ('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='label_video_segments', to='endoreg_db.rawvideofile')),
1602
- ('prediction_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='label_video_segments', to='endoreg_db.rawvideopredictionmeta')),
1603
- ],
1604
- options={
1605
- 'abstract': False,
1606
- },
1316
+ model_name='qualification',
1317
+ name='qualification_types',
1318
+ field=models.ManyToManyField(related_name='qualifications', to='endoreg_db.qualificationtype'),
1607
1319
  ),
1608
1320
  migrations.CreateModel(
1609
1321
  name='ReferenceProduct',
@@ -1612,8 +1324,8 @@ class Migration(migrations.Migration):
1612
1324
  ('name', models.CharField(max_length=255)),
1613
1325
  ('emission_factor_package', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reference_product_package', to='endoreg_db.emissionfactor')),
1614
1326
  ('emission_factor_product', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reference_product_product', to='endoreg_db.emissionfactor')),
1615
- ('emission_factor_total', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.emissionfactor')),
1616
- ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.product')),
1327
+ ('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')),
1328
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reference_products', to='endoreg_db.product')),
1617
1329
  ('product_group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='reference_product', to='endoreg_db.productgroup')),
1618
1330
  ],
1619
1331
  ),
@@ -1657,13 +1369,54 @@ class Migration(migrations.Migration):
1657
1369
  name='patient_info_line',
1658
1370
  field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pdf_type_patient_info_line', to='endoreg_db.reportreaderflag'),
1659
1371
  ),
1372
+ migrations.CreateModel(
1373
+ name='Requirement',
1374
+ fields=[
1375
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1376
+ ('name', models.CharField(max_length=100, unique=True)),
1377
+ ('description', models.TextField(blank=True, null=True)),
1378
+ ('numeric_value', models.FloatField(blank=True, help_text='Numeric value for the requirement. If not set, the requirement is not used in calculations.', null=True)),
1379
+ ('numeric_value_min', models.FloatField(blank=True, help_text='Minimum numeric value for the requirement. If not set, the requirement is not used in calculations.', null=True)),
1380
+ ('numeric_value_max', models.FloatField(blank=True, help_text='Maximum numeric value for the requirement. If not set, the requirement is not used in calculations.', null=True)),
1381
+ ('string_value', models.CharField(blank=True, help_text='String value for the requirement. If not set, the requirement is not used in calculations.', max_length=100, null=True)),
1382
+ ('string_values', models.TextField(blank=True, help_text=" ','-separated list of string values for the requirement.If not set, the requirement is not used in calculations.", null=True)),
1383
+ ('disease_classification_choices', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.diseaseclassificationchoice')),
1384
+ ('diseases', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.disease')),
1385
+ ('events', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.event')),
1386
+ ('examination_indications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.examinationindication')),
1387
+ ('examinations', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.examination')),
1388
+ ('finding_classification_choices', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.findingclassificationchoice')),
1389
+ ('finding_classifications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.findingclassification')),
1390
+ ('finding_interventions', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.findingintervention')),
1391
+ ('findings', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.finding')),
1392
+ ('genders', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.gender')),
1393
+ ('lab_values', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.labvalue')),
1394
+ ('medication_indications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medicationindication')),
1395
+ ('medication_intake_times', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medicationintaketime')),
1396
+ ('medication_schedules', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medicationschedule')),
1397
+ ('medications', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.medication')),
1398
+ ('operators', models.ManyToManyField(blank=True, related_name='required_in', to='endoreg_db.requirementoperator')),
1399
+ ('requirement_types', models.ManyToManyField(blank=True, related_name='linked_requirements', to='endoreg_db.requirementtype')),
1400
+ ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='required_in', to='endoreg_db.unit')),
1401
+ ],
1402
+ ),
1403
+ migrations.CreateModel(
1404
+ name='Risk',
1405
+ fields=[
1406
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1407
+ ('name', models.CharField(max_length=100, unique=True)),
1408
+ ('name_de', models.CharField(blank=True, max_length=100, null=True)),
1409
+ ('name_en', models.CharField(blank=True, max_length=100, null=True)),
1410
+ ('description', models.TextField(blank=True, null=True)),
1411
+ ('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)),
1412
+ ('risk_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='risks', to='endoreg_db.risktype')),
1413
+ ],
1414
+ ),
1660
1415
  migrations.CreateModel(
1661
1416
  name='Rule',
1662
1417
  fields=[
1663
1418
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1664
1419
  ('name', models.CharField(max_length=255, unique=True)),
1665
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
1666
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
1667
1420
  ('description', models.TextField(blank=True, null=True)),
1668
1421
  ('attribute_key', models.CharField(max_length=255)),
1669
1422
  ('attribute_dtype', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.ruleattributedtype')),
@@ -1679,8 +1432,6 @@ class Migration(migrations.Migration):
1679
1432
  fields=[
1680
1433
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1681
1434
  ('name', models.CharField(max_length=255, unique=True)),
1682
- ('name_de', models.CharField(blank=True, max_length=255, null=True)),
1683
- ('name_en', models.CharField(blank=True, max_length=255, null=True)),
1684
1435
  ('rules', models.ManyToManyField(to='endoreg_db.rule')),
1685
1436
  ],
1686
1437
  ),
@@ -1691,82 +1442,130 @@ class Migration(migrations.Migration):
1691
1442
  ('examination_date', models.DateField(blank=True, null=True)),
1692
1443
  ('patient_first_name', models.CharField(blank=True, max_length=255, null=True)),
1693
1444
  ('patient_last_name', models.CharField(blank=True, max_length=255, null=True)),
1694
- ('patient_dob', models.DateField(blank=True, null=True)),
1695
- ('examiner_first_name', models.CharField(blank=True, max_length=255, null=True)),
1696
- ('examiner_last_name', models.CharField(blank=True, max_length=255, null=True)),
1697
- ('examination_hash', models.CharField(blank=True, max_length=255, null=True)),
1698
- ('patient_hash', models.CharField(blank=True, max_length=255, null=True)),
1445
+ ('patient_dob', models.DateTimeField(blank=True, help_text='Date of birth (can be auto-generated if missing).', null=True)),
1446
+ ('examiner_first_name', models.CharField(blank=True, editable=False, max_length=255, null=True)),
1447
+ ('examiner_last_name', models.CharField(blank=True, editable=False, max_length=255, null=True)),
1448
+ ('examination_hash', models.CharField(blank=True, db_index=True, editable=False, max_length=64, null=True)),
1449
+ ('patient_hash', models.CharField(blank=True, db_index=True, editable=False, max_length=64, null=True)),
1699
1450
  ('endoscope_type', models.CharField(blank=True, max_length=255, null=True)),
1700
1451
  ('endoscope_sn', models.CharField(blank=True, max_length=255, null=True)),
1701
- ('state_verified', models.BooleanField(default=False)),
1702
- ('state_hash_generated', models.BooleanField(default=False)),
1703
- ('state_names_substituted', models.BooleanField(default=False)),
1704
- ('state_dob_substituted', models.BooleanField(default=False)),
1705
- ('state_examination_date_substituted', models.BooleanField(default=False)),
1706
- ('state_endoscope_sn_substituted', models.BooleanField(default=False)),
1707
- ('state_examiners_substituted', models.BooleanField(default=False)),
1708
1452
  ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1709
- ('examiners', models.ManyToManyField(blank=True, to='endoreg_db.examiner')),
1453
+ ('examiners', models.ManyToManyField(blank=True, help_text='Pseudo-anonymized examiner(s) associated with the examination.', to='endoreg_db.examiner')),
1710
1454
  ('patient_gender', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.gender')),
1711
- ('pseudo_examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patientexamination')),
1712
- ('pseudo_patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.patient')),
1455
+ ('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')),
1456
+ ('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')),
1713
1457
  ],
1714
1458
  ),
1715
1459
  migrations.CreateModel(
1716
- name='ReportFile',
1460
+ name='RawPdfFile',
1717
1461
  fields=[
1718
1462
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1719
1463
  ('pdf_hash', models.CharField(max_length=255, unique=True)),
1720
- ('created_at', models.DateTimeField(auto_now_add=True)),
1464
+ ('text', models.TextField(blank=True, null=True)),
1465
+ ('date_created', models.DateTimeField(auto_now_add=True)),
1466
+ ('date_modified', models.DateTimeField(auto_now=True)),
1467
+ ('anonymized', models.BooleanField(default=False, help_text='True if the PDF has been anonymized.')),
1468
+ ('file', models.FileField(upload_to='raw_pdfs', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])])),
1469
+ ('anonymized_file', models.FileField(blank=True, null=True, upload_to='raw_pdfs', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])])),
1470
+ ('state_report_processing_required', models.BooleanField(default=True)),
1471
+ ('state_report_processed', models.BooleanField(default=False)),
1472
+ ('raw_meta', models.JSONField(blank=True, null=True)),
1473
+ ('anonymized_text', models.TextField(blank=True, null=True)),
1474
+ ('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')),
1475
+ ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1476
+ ('examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_files', to='endoreg_db.patientexamination')),
1477
+ ('examiner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.examiner')),
1478
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_files', to='endoreg_db.patient')),
1479
+ ('pdf_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.pdftype')),
1480
+ ('state', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_file', to='endoreg_db.rawpdfstate')),
1481
+ ('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')),
1482
+ ],
1483
+ ),
1484
+ migrations.CreateModel(
1485
+ name='AnonymHistologyReport',
1486
+ fields=[
1487
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1721
1488
  ('meta', models.JSONField(blank=True, null=True)),
1722
1489
  ('text', models.TextField(blank=True, null=True)),
1723
1490
  ('date', models.DateField(blank=True, null=True)),
1724
1491
  ('time', models.TimeField(blank=True, null=True)),
1492
+ ('file', models.FileField(blank=True, null=True, upload_to=pathlib.PurePosixPath('pdfs'))),
1725
1493
  ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1726
- ('examiner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='endoreg_db.examiner')),
1494
+ ('type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.documenttype')),
1495
+ ('examiners', models.ManyToManyField(blank=True, to='endoreg_db.examiner')),
1727
1496
  ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='endoreg_db.patient')),
1728
- ('patient_examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='report_files', to='endoreg_db.patientexamination')),
1729
- ('pdf_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.pdftype')),
1730
- ('sensitive_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='report_files', to='endoreg_db.sensitivemeta')),
1497
+ ('patient_examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.patientexamination')),
1498
+ ('sensitive_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.sensitivemeta')),
1731
1499
  ],
1732
1500
  options={
1733
1501
  'abstract': False,
1734
1502
  },
1735
1503
  ),
1736
1504
  migrations.AddField(
1737
- model_name='rawvideofile',
1505
+ model_name='anonymexaminationreport',
1738
1506
  name='sensitive_meta',
1739
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_videos', to='endoreg_db.sensitivemeta'),
1507
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.sensitivemeta'),
1740
1508
  ),
1741
1509
  migrations.CreateModel(
1742
- name='RawPdfFile',
1510
+ name='SensitiveMetaState',
1743
1511
  fields=[
1744
1512
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1745
- ('pdf_hash', models.CharField(max_length=255, unique=True)),
1746
- ('text', models.TextField(blank=True, null=True)),
1747
1513
  ('created_at', models.DateTimeField(auto_now_add=True)),
1748
- ('file', models.FileField(storage=django.core.files.storage.FileSystemStorage(location='/home/admin/test-data'), upload_to='raw_pdf/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])])),
1749
- ('state_report_processing_required', models.BooleanField(default=True)),
1750
- ('state_report_processed', models.BooleanField(default=False)),
1751
- ('raw_meta', models.JSONField(blank=True, null=True)),
1752
- ('anonymized_text', models.TextField(blank=True, null=True)),
1753
- ('center', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.center')),
1754
- ('pdf_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.pdftype')),
1755
- ('report_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_pdf_files', to='endoreg_db.reportfile')),
1756
- ('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')),
1514
+ ('updated_at', models.DateTimeField(auto_now=True)),
1515
+ ('dob_verified', models.BooleanField(default=False)),
1516
+ ('names_verified', models.BooleanField(default=False)),
1517
+ ('origin', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='state', to='endoreg_db.sensitivemeta')),
1757
1518
  ],
1758
1519
  options={
1759
- 'abstract': False,
1520
+ 'verbose_name': 'Sensitive Meta State',
1521
+ 'verbose_name_plural': 'Sensitive Meta States',
1760
1522
  },
1761
1523
  ),
1524
+ migrations.CreateModel(
1525
+ name='Shift',
1526
+ fields=[
1527
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1528
+ ('name', models.CharField(max_length=255, unique=True)),
1529
+ ('description', models.TextField(blank=True, null=True)),
1530
+ ('is_active', models.BooleanField(default=True)),
1531
+ ('required_qualifications', models.ManyToManyField(related_name='shifts', to='endoreg_db.qualification')),
1532
+ ('shift_types', models.ManyToManyField(related_name='shifts', to='endoreg_db.shifttype')),
1533
+ ],
1534
+ ),
1535
+ migrations.CreateModel(
1536
+ name='CenterShift',
1537
+ fields=[
1538
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1539
+ ('name', models.CharField(max_length=255, unique=True)),
1540
+ ('description', models.TextField(blank=True, null=True)),
1541
+ ('start_time', models.TimeField()),
1542
+ ('end_time', models.TimeField()),
1543
+ ('estimated_presence_fraction', models.DecimalField(decimal_places=4, default=0.0, max_digits=5)),
1544
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_shifts', to='endoreg_db.center')),
1545
+ ('scheduled_days', models.ManyToManyField(related_name='center_shifts', to='endoreg_db.scheduleddays')),
1546
+ ('shift', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_shifts', to='endoreg_db.shift')),
1547
+ ],
1548
+ ),
1549
+ migrations.CreateModel(
1550
+ name='RequirementSet',
1551
+ fields=[
1552
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1553
+ ('name', models.CharField(max_length=100, unique=True)),
1554
+ ('description', models.TextField(blank=True, null=True)),
1555
+ ('information_sources', models.ManyToManyField(blank=True, related_name='requirement_sets', to='endoreg_db.informationsource')),
1556
+ ('links_to_sets', models.ManyToManyField(blank=True, related_name='links_from_sets', to='endoreg_db.requirementset')),
1557
+ ('reqset_exam_links', models.ManyToManyField(blank=True, related_name='requirement_set', to='endoreg_db.examinationrequirementset')),
1558
+ ('requirements', models.ManyToManyField(blank=True, related_name='requirement_sets', to='endoreg_db.requirement')),
1559
+ ('requirement_set_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='requirement_sets', to='endoreg_db.requirementsettype')),
1560
+ ('tags', models.ManyToManyField(blank=True, related_name='requirement_sets', to='endoreg_db.tag')),
1561
+ ],
1562
+ ),
1762
1563
  migrations.CreateModel(
1763
1564
  name='TransportRoute',
1764
1565
  fields=[
1765
1566
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1766
1567
  ('distance', models.FloatField()),
1767
1568
  ('name', models.CharField(max_length=255)),
1768
- ('name_de', models.CharField(max_length=255, null=True)),
1769
- ('name_en', models.CharField(max_length=255, null=True)),
1770
1569
  ('emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.emissionfactor')),
1771
1570
  ('unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.unit')),
1772
1571
  ],
@@ -1794,9 +1593,9 @@ class Migration(migrations.Migration):
1794
1593
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1795
1594
  ('component', models.CharField(max_length=255)),
1796
1595
  ('quantity', models.FloatField()),
1797
- ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.material')),
1798
- ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='product_materials', to='endoreg_db.product')),
1799
- ('unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.unit')),
1596
+ ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_product_materials', to='endoreg_db.material')),
1597
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='product_product_materials', to='endoreg_db.product')),
1598
+ ('unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_product_materials', to='endoreg_db.unit')),
1800
1599
  ],
1801
1600
  ),
1802
1601
  migrations.CreateModel(
@@ -1828,11 +1627,9 @@ class Migration(migrations.Migration):
1828
1627
  fields=[
1829
1628
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1830
1629
  ('name', models.CharField(max_length=255, null=True)),
1831
- ('name_de', models.CharField(max_length=255, null=True)),
1832
- ('name_en', models.CharField(max_length=255, null=True)),
1833
1630
  ('quantity', models.FloatField()),
1834
1631
  ('year', models.IntegerField()),
1835
- ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1632
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_resources', to='endoreg_db.center')),
1836
1633
  ('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')),
1837
1634
  ('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')),
1838
1635
  ('resource', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.resource')),
@@ -1840,80 +1637,78 @@ class Migration(migrations.Migration):
1840
1637
  ],
1841
1638
  ),
1842
1639
  migrations.CreateModel(
1843
- name='AnonymizedFile',
1640
+ name='UploadJob',
1844
1641
  fields=[
1845
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1846
- ('anonymized_file', models.FileField(upload_to='uploads/anonymized/')),
1847
- ('anonymization_date', models.DateTimeField(default=django.utils.timezone.now)),
1848
- ('original_file', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='anonymized_file', to='endoreg_db.uploadedfile')),
1642
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='Unique identifier for the upload job', primary_key=True, serialize=False)),
1643
+ ('file', models.FileField(help_text='Uploaded file (PDF or video)', upload_to='uploads/%Y/%m/%d/')),
1644
+ ('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)),
1645
+ ('content_type', models.CharField(blank=True, help_text='MIME type of the uploaded file', max_length=100)),
1646
+ ('error_detail', models.TextField(blank=True, help_text='Error message if processing failed')),
1647
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='When the upload job was created')),
1648
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='When the upload job was last updated')),
1649
+ ('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')),
1849
1650
  ],
1651
+ options={
1652
+ 'verbose_name': 'Upload Job',
1653
+ 'verbose_name_plural': 'Upload Jobs',
1654
+ 'ordering': ['-created_at'],
1655
+ },
1850
1656
  ),
1851
1657
  migrations.CreateModel(
1852
- name='Video',
1658
+ name='VideoFile',
1853
1659
  fields=[
1854
1660
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1855
- ('uuid', models.UUIDField()),
1856
- ('original_file_name', models.CharField(max_length=255)),
1857
- ('video_hash', models.CharField(max_length=255, unique=True)),
1661
+ ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
1662
+ ('raw_file', models.FileField(blank=True, null=True, upload_to='videos', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['mp4'])])),
1663
+ ('processed_file', models.FileField(blank=True, null=True, upload_to='videos', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['mp4'])])),
1664
+ ('video_hash', models.CharField(help_text='Hash of the raw video file.', max_length=255, unique=True)),
1665
+ ('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)),
1666
+ ('original_file_name', models.CharField(blank=True, max_length=255, null=True)),
1858
1667
  ('uploaded_at', models.DateTimeField(auto_now_add=True)),
1859
- ('frame_dir', models.CharField(max_length=255)),
1860
- ('prediction_dir', models.CharField(max_length=255)),
1861
- ('predictions', models.JSONField(default=dict)),
1862
- ('readable_predictions', models.JSONField(default=dict)),
1863
- ('merged_predictions', models.JSONField(default=dict)),
1864
- ('smooth_merged_predictions', models.JSONField(default=dict)),
1865
- ('binary_smooth_merged_predictions', models.JSONField(default=dict)),
1866
- ('sequences', models.JSONField(default=dict)),
1867
- ('state_frames_required', models.BooleanField(default=True)),
1868
- ('state_initial_prediction_required', models.BooleanField(default=True)),
1869
- ('state_initial_prediction_completed', models.BooleanField(default=False)),
1870
- ('state_initial_prediction_import_required', models.BooleanField(default=True)),
1871
- ('state_initial_prediction_import_completed', models.BooleanField(default=False)),
1872
- ('state_histology_required', models.BooleanField(blank=True, null=True)),
1873
- ('state_histology_available', models.BooleanField(default=False)),
1874
- ('state_follow_up_intervention_required', models.BooleanField(blank=True, null=True)),
1875
- ('state_follow_up_intervention_available', models.BooleanField(default=False)),
1876
- ('state_dataset_complete', models.BooleanField(default=False)),
1877
- ('is_raw', models.BooleanField(default=False)),
1878
- ('file', models.FileField(storage=django.core.files.storage.FileSystemStorage(location='/home/admin/test-data'), upload_to='videos', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['mp4'])])),
1879
- ('date', models.DateField(blank=True, null=True)),
1880
- ('suffix', models.CharField(blank=True, max_length=255, null=True)),
1668
+ ('frame_dir', models.CharField(blank=True, help_text='Path to frames extracted from the raw video.', max_length=512)),
1881
1669
  ('fps', models.FloatField(blank=True, null=True)),
1882
1670
  ('duration', models.FloatField(blank=True, null=True)),
1671
+ ('frame_count', models.IntegerField(blank=True, null=True)),
1883
1672
  ('width', models.IntegerField(blank=True, null=True)),
1884
1673
  ('height', models.IntegerField(blank=True, null=True)),
1885
- ('endoscope_image_x', models.IntegerField(blank=True, null=True)),
1886
- ('endoscope_image_y', models.IntegerField(blank=True, null=True)),
1887
- ('endoscope_image_width', models.IntegerField(blank=True, null=True)),
1888
- ('endoscope_image_height', models.IntegerField(blank=True, null=True)),
1889
- ('state_frames_extracted', models.BooleanField(default=False)),
1674
+ ('suffix', models.CharField(blank=True, max_length=10, null=True)),
1675
+ ('sequences', models.JSONField(blank=True, default=dict, help_text='AI prediction sequences based on raw frames.')),
1676
+ ('date', models.DateField(blank=True, null=True)),
1890
1677
  ('meta', models.JSONField(blank=True, null=True)),
1891
- ('ai_model_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.modelmeta')),
1892
- ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1893
- ('examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='videos', to='endoreg_db.patientexamination')),
1894
- ('processor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.endoscopyprocessor')),
1895
- ('pseudo_patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='videos', to='endoreg_db.patient')),
1896
- ('sensitive_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='videos', to='endoreg_db.sensitivemeta')),
1678
+ ('date_created', models.DateTimeField(auto_now_add=True)),
1679
+ ('date_modified', models.DateTimeField(auto_now=True)),
1680
+ ('ai_model_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.modelmeta')),
1681
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='endoreg_db.center')),
1682
+ ('examination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_files', to='endoreg_db.patientexamination')),
1683
+ ('patient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_files', to='endoreg_db.patient')),
1684
+ ('processor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='endoreg_db.endoscopyprocessor')),
1685
+ ('sensitive_meta', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_file', to='endoreg_db.sensitivemeta')),
1897
1686
  ('import_meta', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.videoimportmeta')),
1898
1687
  ],
1899
- options={
1900
- 'abstract': False,
1901
- },
1902
- ),
1903
- migrations.AddField(
1904
- model_name='rawvideofile',
1905
- name='video',
1906
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='raw_videos', to='endoreg_db.video'),
1907
1688
  ),
1908
1689
  migrations.AddField(
1909
1690
  model_name='patientexamination',
1910
1691
  name='video',
1911
- field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='patient_examination', to='endoreg_db.video'),
1692
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='patient_examination', to='endoreg_db.videofile'),
1912
1693
  ),
1913
1694
  migrations.AddField(
1914
- model_name='frame',
1915
- name='video',
1916
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frames', to='endoreg_db.video'),
1695
+ model_name='labelvideosegment',
1696
+ name='video_file',
1697
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='label_video_segments', to='endoreg_db.videofile'),
1698
+ ),
1699
+ migrations.CreateModel(
1700
+ name='Frame',
1701
+ fields=[
1702
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1703
+ ('frame_number', models.PositiveIntegerField()),
1704
+ ('relative_path', models.CharField(max_length=512)),
1705
+ ('timestamp', models.FloatField(blank=True, null=True)),
1706
+ ('is_extracted', models.BooleanField(default=False)),
1707
+ ('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frames', to='endoreg_db.videofile')),
1708
+ ],
1709
+ options={
1710
+ 'ordering': ['video', 'frame_number'],
1711
+ },
1917
1712
  ),
1918
1713
  migrations.CreateModel(
1919
1714
  name='VideoMeta',
@@ -1927,14 +1722,9 @@ class Migration(migrations.Migration):
1927
1722
  ],
1928
1723
  ),
1929
1724
  migrations.AddField(
1930
- model_name='video',
1931
- name='video_meta',
1932
- field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.videometa'),
1933
- ),
1934
- migrations.AddField(
1935
- model_name='rawvideofile',
1725
+ model_name='videofile',
1936
1726
  name='video_meta',
1937
- field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.videometa'),
1727
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_file', to='endoreg_db.videometa'),
1938
1728
  ),
1939
1729
  migrations.CreateModel(
1940
1730
  name='VideoPredictionMeta',
@@ -1943,28 +1733,14 @@ class Migration(migrations.Migration):
1943
1733
  ('date_created', models.DateTimeField(auto_now_add=True)),
1944
1734
  ('date_modified', models.DateTimeField(auto_now=True)),
1945
1735
  ('prediction_array', models.BinaryField(blank=True, null=True)),
1946
- ('is_raw', models.BooleanField(default=False)),
1947
1736
  ('model_meta', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.modelmeta')),
1948
- ('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='video_prediction_meta', to='endoreg_db.video')),
1737
+ ('video_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='video_prediction_meta', to='endoreg_db.videofile')),
1949
1738
  ],
1950
- options={
1951
- 'abstract': False,
1952
- },
1953
1739
  ),
1954
- migrations.CreateModel(
1955
- name='LabelVideoSegment',
1956
- fields=[
1957
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1958
- ('start_frame_number', models.IntegerField()),
1959
- ('end_frame_number', models.IntegerField()),
1960
- ('label', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.label')),
1961
- ('source', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.informationsource')),
1962
- ('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='label_video_segments', to='endoreg_db.video')),
1963
- ('prediction_meta', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='label_video_segments', to='endoreg_db.videopredictionmeta')),
1964
- ],
1965
- options={
1966
- 'abstract': False,
1967
- },
1740
+ migrations.AddField(
1741
+ model_name='labelvideosegment',
1742
+ name='prediction_meta',
1743
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='label_video_segments', to='endoreg_db.videopredictionmeta'),
1968
1744
  ),
1969
1745
  migrations.CreateModel(
1970
1746
  name='VideoSegmentationAnnotation',
@@ -1973,7 +1749,7 @@ class Migration(migrations.Migration):
1973
1749
  ('start_time', models.FloatField()),
1974
1750
  ('stop_time', models.FloatField()),
1975
1751
  ('is_true', models.BooleanField(default=True)),
1976
- ('video', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.rawvideofile')),
1752
+ ('video_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='video_segmentation_annotations', to='endoreg_db.videofile')),
1977
1753
  ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.videosegmentationlabel')),
1978
1754
  ],
1979
1755
  ),
@@ -1991,55 +1767,91 @@ class Migration(migrations.Migration):
1991
1767
  name='video_segmentation_labelset',
1992
1768
  field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ai_models', to='endoreg_db.videosegmentationlabelset'),
1993
1769
  ),
1770
+ migrations.AddField(
1771
+ model_name='videofile',
1772
+ name='state',
1773
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='video_file', to='endoreg_db.videostate'),
1774
+ ),
1994
1775
  migrations.CreateModel(
1995
1776
  name='CenterWaste',
1996
1777
  fields=[
1997
1778
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1998
1779
  ('year', models.IntegerField()),
1999
1780
  ('quantity', models.FloatField()),
2000
- ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.center')),
1781
+ ('center', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='center_wastes', to='endoreg_db.center')),
2001
1782
  ('emission_factor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.emissionfactor')),
2002
1783
  ('unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='endoreg_db.unit')),
2003
1784
  ('waste', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endoreg_db.waste')),
2004
1785
  ],
2005
1786
  ),
2006
1787
  migrations.CreateModel(
2007
- name='ImageClassificationPrediction',
1788
+ name='ImageClassificationAnnotation',
2008
1789
  fields=[
2009
1790
  ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
2010
1791
  ('value', models.BooleanField()),
2011
- ('confidence', models.FloatField()),
1792
+ ('float_value', models.FloatField(blank=True, null=True)),
1793
+ ('annotator', models.CharField(blank=True, max_length=255, null=True)),
2012
1794
  ('date_created', models.DateTimeField(auto_now_add=True)),
2013
- ('frame', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_predictions', to='endoreg_db.frame')),
2014
- ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_predictions', to='endoreg_db.label')),
2015
- ('model_meta', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_predictions', to='endoreg_db.modelmeta')),
1795
+ ('date_modified', models.DateTimeField(auto_now=True)),
1796
+ ('frame', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_annotations', to='endoreg_db.frame')),
1797
+ ('information_source', 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')),
1798
+ ('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_classification_annotations', to='endoreg_db.label')),
1799
+ ('model_meta', 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')),
2016
1800
  ],
2017
1801
  options={
2018
- 'unique_together': {('label', 'frame', 'model_meta')},
1802
+ 'indexes': [models.Index(fields=['frame', 'label'], name='endoreg_db__frame_i_47f916_idx'), models.Index(fields=['frame'], name='endoreg_db__frame_i_92c75a_idx')],
2019
1803
  },
2020
1804
  ),
2021
1805
  migrations.AddIndex(
2022
- model_name='rawframe',
2023
- index=models.Index(fields=['video', 'frame_number'], name='endoreg_db__video_i_b5dc58_idx'),
1806
+ model_name='patientfinding',
1807
+ index=models.Index(fields=['patient_examination', 'finding'], name='endoreg_db__patient_54869f_idx'),
2024
1808
  ),
2025
- migrations.AlterUniqueTogether(
2026
- name='rawframe',
2027
- unique_together={('video', 'frame_number')},
1809
+ migrations.AddIndex(
1810
+ model_name='patientfinding',
1811
+ index=models.Index(fields=['patient_examination', 'is_active'], name='endoreg_db__patient_9359f8_idx'),
2028
1812
  ),
2029
- migrations.AlterUniqueTogether(
2030
- name='rawvideopredictionmeta',
2031
- unique_together={('model_meta', 'video')},
1813
+ migrations.AddIndex(
1814
+ model_name='patientfinding',
1815
+ index=models.Index(fields=['created_at'], name='endoreg_db__created_b44d86_idx'),
2032
1816
  ),
2033
1817
  migrations.AddIndex(
2034
- model_name='frame',
2035
- index=models.Index(fields=['video', 'frame_number'], name='endoreg_db__video_i_56cc44_idx'),
1818
+ model_name='patientfinding',
1819
+ index=models.Index(fields=['finding', 'is_active'], name='endoreg_db__finding_2f036b_idx'),
1820
+ ),
1821
+ migrations.AddConstraint(
1822
+ model_name='patientfinding',
1823
+ constraint=models.UniqueConstraint(condition=models.Q(('is_active', True)), fields=('patient_examination', 'finding'), name='unique_active_finding_per_examination'),
1824
+ ),
1825
+ migrations.AddConstraint(
1826
+ model_name='patientfinding',
1827
+ 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'),
2036
1828
  ),
2037
1829
  migrations.AlterUniqueTogether(
2038
1830
  name='frame',
2039
1831
  unique_together={('video', 'frame_number')},
2040
1832
  ),
2041
- migrations.AlterUniqueTogether(
2042
- name='videopredictionmeta',
2043
- unique_together={('model_meta', 'video')},
1833
+ migrations.AddIndex(
1834
+ model_name='videopredictionmeta',
1835
+ index=models.Index(fields=['model_meta', 'video_file'], name='endoreg_db__model_m_208dee_idx'),
1836
+ ),
1837
+ migrations.AddConstraint(
1838
+ model_name='videopredictionmeta',
1839
+ constraint=models.UniqueConstraint(fields=('model_meta', 'video_file'), name='unique_prediction_per_video_model'),
1840
+ ),
1841
+ migrations.AddIndex(
1842
+ model_name='labelvideosegment',
1843
+ index=models.Index(fields=['video_file', 'label', 'start_frame_number'], name='endoreg_db__video_f_fa9326_idx'),
1844
+ ),
1845
+ migrations.AddIndex(
1846
+ model_name='labelvideosegment',
1847
+ index=models.Index(fields=['prediction_meta', 'label'], name='endoreg_db__predict_2bfba4_idx'),
1848
+ ),
1849
+ migrations.AddConstraint(
1850
+ model_name='labelvideosegment',
1851
+ constraint=models.CheckConstraint(condition=models.Q(('start_frame_number__lt', models.F('end_frame_number'))), name='segment_start_lt_end'),
1852
+ ),
1853
+ migrations.AddConstraint(
1854
+ model_name='videosegmentationannotation',
1855
+ constraint=models.CheckConstraint(condition=models.Q(('start_time__lt', models.F('stop_time'))), name='start_time_less_than_stop_time'),
2044
1856
  ),
2045
1857
  ]