endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.0__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 (360) hide show
  1. endoreg_db/authz/auth.py +74 -0
  2. endoreg_db/authz/backends.py +168 -0
  3. endoreg_db/authz/management/commands/list_routes.py +18 -0
  4. endoreg_db/authz/middleware.py +83 -0
  5. endoreg_db/authz/permissions.py +127 -0
  6. endoreg_db/authz/policy.py +218 -0
  7. endoreg_db/authz/views_auth.py +66 -0
  8. endoreg_db/config/env.py +13 -8
  9. endoreg_db/data/__init__.py +8 -31
  10. endoreg_db/data/_examples/disease.yaml +55 -0
  11. endoreg_db/data/_examples/disease_classification.yaml +13 -0
  12. endoreg_db/data/_examples/disease_classification_choice.yaml +62 -0
  13. endoreg_db/data/_examples/event.yaml +64 -0
  14. endoreg_db/data/_examples/examination.yaml +72 -0
  15. endoreg_db/data/_examples/finding/anatomy_colon.yaml +128 -0
  16. endoreg_db/data/_examples/finding/colonoscopy.yaml +40 -0
  17. endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +56 -0
  18. endoreg_db/data/_examples/finding/complication.yaml +16 -0
  19. endoreg_db/data/_examples/finding/data.yaml +105 -0
  20. endoreg_db/data/_examples/finding/examination_setting.yaml +16 -0
  21. endoreg_db/data/_examples/finding/medication_related.yaml +18 -0
  22. endoreg_db/data/_examples/finding/outcome.yaml +12 -0
  23. endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +68 -0
  24. endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +22 -0
  25. endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +25 -0
  26. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
  27. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
  28. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +68 -0
  29. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
  30. endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +80 -0
  31. endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +21 -0
  32. endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +20 -0
  33. endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +26 -0
  34. endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +22 -0
  35. endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +53 -0
  36. endoreg_db/data/_examples/finding_classification/complication_generic.yaml +25 -0
  37. endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +40 -0
  38. endoreg_db/data/_examples/finding_classification/histology_colo.yaml +51 -0
  39. endoreg_db/data/_examples/finding_classification/intervention_required.yaml +26 -0
  40. endoreg_db/data/_examples/finding_classification/medication_related.yaml +23 -0
  41. endoreg_db/data/_examples/finding_classification/visualized.yaml +33 -0
  42. endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +78 -0
  43. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +32 -0
  44. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
  45. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
  46. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +15 -0
  47. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +17 -0
  48. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_paris.yaml +57 -0
  49. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +49 -0
  50. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +14 -0
  51. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +36 -0
  52. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_location.yaml +229 -0
  53. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
  54. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +82 -0
  55. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
  56. endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +15 -0
  57. endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
  58. endoreg_db/data/_examples/finding_classification_choice/histology.yaml +24 -0
  59. endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +20 -0
  60. endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +19 -0
  61. endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +11 -0
  62. endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +48 -0
  63. endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +43 -0
  64. endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
  65. endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +128 -0
  66. endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +32 -0
  67. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +9 -0
  68. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +36 -0
  69. endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +15 -0
  70. endoreg_db/data/_examples/finding_type/data.yaml +43 -0
  71. endoreg_db/data/_examples/requirement/age.yaml +26 -0
  72. endoreg_db/data/_examples/requirement/colonoscopy_baseline_austria.yaml +45 -0
  73. endoreg_db/data/_examples/requirement/disease_cardiovascular.yaml +79 -0
  74. endoreg_db/data/_examples/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
  75. endoreg_db/data/_examples/requirement/disease_hepatology.yaml +12 -0
  76. endoreg_db/data/_examples/requirement/disease_misc.yaml +12 -0
  77. endoreg_db/data/_examples/requirement/disease_renal.yaml +96 -0
  78. endoreg_db/data/_examples/requirement/endoscopy_bleeding_risk.yaml +59 -0
  79. endoreg_db/data/_examples/requirement/event_cardiology.yaml +251 -0
  80. endoreg_db/data/_examples/requirement/event_requirements.yaml +145 -0
  81. endoreg_db/data/_examples/requirement/finding_colon_polyp.yaml +50 -0
  82. endoreg_db/data/_examples/requirement/gender.yaml +25 -0
  83. endoreg_db/data/_examples/requirement/lab_value.yaml +441 -0
  84. endoreg_db/data/_examples/requirement/medication.yaml +93 -0
  85. endoreg_db/data/_examples/requirement_operator/age.yaml +13 -0
  86. endoreg_db/data/_examples/requirement_operator/lab_operators.yaml +129 -0
  87. endoreg_db/data/_examples/requirement_operator/model_operators.yaml +96 -0
  88. endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +48 -0
  89. endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +57 -0
  90. endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
  91. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +4 -3
  92. endoreg_db/data/event_classification/data.yaml +4 -0
  93. endoreg_db/data/event_classification_choice/data.yaml +9 -0
  94. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +43 -70
  95. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +22 -52
  96. endoreg_db/data/finding_classification/colonoscopy_location.yaml +31 -62
  97. endoreg_db/data/finding_classification/histology_colo.yaml +28 -36
  98. endoreg_db/data/requirement/colon_polyp_intervention.yaml +49 -0
  99. endoreg_db/data/requirement/coloreg_colon_polyp.yaml +49 -0
  100. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +31 -12
  101. endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
  102. endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
  103. endoreg_db/data/requirement_set/90_coloreg.yaml +178 -0
  104. endoreg_db/data/requirement_set/_old_ +109 -0
  105. endoreg_db/data/requirement_set_type/data.yaml +21 -0
  106. endoreg_db/data/setup_config.yaml +4 -4
  107. endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
  108. endoreg_db/exceptions.py +5 -2
  109. endoreg_db/helpers/data_loader.py +1 -1
  110. endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
  111. endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
  112. endoreg_db/management/commands/import_video.py +9 -10
  113. endoreg_db/management/commands/import_video_with_classification.py +1 -1
  114. endoreg_db/management/commands/init_default_ai_model.py +1 -1
  115. endoreg_db/management/commands/list_routes.py +18 -0
  116. endoreg_db/management/commands/load_center_data.py +12 -12
  117. endoreg_db/management/commands/load_requirement_data.py +60 -31
  118. endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
  119. endoreg_db/management/commands/setup_endoreg_db.py +3 -3
  120. endoreg_db/management/commands/storage_management.py +271 -203
  121. endoreg_db/migrations/0001_initial.py +1799 -1300
  122. endoreg_db/migrations/0002_requirementset_depends_on.py +18 -0
  123. endoreg_db/migrations/_old/0001_initial.py +1857 -0
  124. endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +68 -0
  125. endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +77 -0
  126. endoreg_db/migrations/_old/0005_merge_20251111_1003.py +14 -0
  127. endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +68 -0
  128. endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +89 -0
  129. endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +27 -0
  130. endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +21 -0
  131. endoreg_db/models/__init__.py +78 -123
  132. endoreg_db/models/administration/__init__.py +21 -42
  133. endoreg_db/models/administration/ai/active_model.py +2 -2
  134. endoreg_db/models/administration/ai/ai_model.py +7 -6
  135. endoreg_db/models/administration/case/__init__.py +1 -15
  136. endoreg_db/models/administration/case/case.py +3 -3
  137. endoreg_db/models/administration/case/case_template/__init__.py +2 -14
  138. endoreg_db/models/administration/case/case_template/case_template.py +2 -124
  139. endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
  140. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
  141. endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
  142. endoreg_db/models/administration/center/center.py +33 -19
  143. endoreg_db/models/administration/center/center_product.py +12 -9
  144. endoreg_db/models/administration/center/center_resource.py +25 -19
  145. endoreg_db/models/administration/center/center_shift.py +21 -17
  146. endoreg_db/models/administration/center/center_waste.py +16 -8
  147. endoreg_db/models/administration/person/__init__.py +2 -0
  148. endoreg_db/models/administration/person/employee/employee.py +10 -5
  149. endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
  150. endoreg_db/models/administration/person/employee/employee_type.py +12 -6
  151. endoreg_db/models/administration/person/examiner/examiner.py +13 -11
  152. endoreg_db/models/administration/person/patient/__init__.py +2 -0
  153. endoreg_db/models/administration/person/patient/patient.py +103 -100
  154. endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
  155. endoreg_db/models/administration/person/person.py +4 -0
  156. endoreg_db/models/administration/person/profession/__init__.py +8 -4
  157. endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
  158. endoreg_db/models/administration/product/product.py +20 -15
  159. endoreg_db/models/administration/product/product_material.py +17 -18
  160. endoreg_db/models/administration/product/product_weight.py +12 -8
  161. endoreg_db/models/administration/product/reference_product.py +23 -55
  162. endoreg_db/models/administration/qualification/qualification.py +7 -3
  163. endoreg_db/models/administration/qualification/qualification_type.py +7 -3
  164. endoreg_db/models/administration/shift/scheduled_days.py +8 -5
  165. endoreg_db/models/administration/shift/shift.py +16 -12
  166. endoreg_db/models/administration/shift/shift_type.py +23 -31
  167. endoreg_db/models/label/__init__.py +7 -8
  168. endoreg_db/models/label/annotation/image_classification.py +10 -9
  169. endoreg_db/models/label/annotation/video_segmentation_annotation.py +8 -5
  170. endoreg_db/models/label/label.py +15 -15
  171. endoreg_db/models/label/label_set.py +19 -6
  172. endoreg_db/models/label/label_type.py +1 -1
  173. endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
  174. endoreg_db/models/label/label_video_segment/label_video_segment.py +76 -102
  175. endoreg_db/models/label/video_segmentation_label.py +4 -0
  176. endoreg_db/models/label/video_segmentation_labelset.py +4 -3
  177. endoreg_db/models/media/frame/frame.py +22 -22
  178. endoreg_db/models/media/pdf/raw_pdf.py +110 -182
  179. endoreg_db/models/media/pdf/report_file.py +25 -29
  180. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +30 -46
  181. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
  182. endoreg_db/models/media/video/__init__.py +1 -0
  183. endoreg_db/models/media/video/create_from_file.py +48 -56
  184. endoreg_db/models/media/video/pipe_2.py +8 -9
  185. endoreg_db/models/media/video/video_file.py +150 -108
  186. endoreg_db/models/media/video/video_file_ai.py +288 -74
  187. endoreg_db/models/media/video/video_file_anonymize.py +38 -38
  188. endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
  189. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
  190. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
  191. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
  192. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
  193. endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
  194. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
  195. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
  196. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
  197. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
  198. endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
  199. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
  200. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
  201. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
  202. endoreg_db/models/media/video/video_file_io.py +109 -62
  203. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
  204. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
  205. endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
  206. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
  207. endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
  208. endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
  209. endoreg_db/models/media/video/video_file_segments.py +24 -17
  210. endoreg_db/models/media/video/video_metadata.py +19 -35
  211. endoreg_db/models/media/video/video_processing.py +96 -95
  212. endoreg_db/models/medical/contraindication/__init__.py +13 -3
  213. endoreg_db/models/medical/disease.py +22 -16
  214. endoreg_db/models/medical/event.py +31 -18
  215. endoreg_db/models/medical/examination/__init__.py +13 -6
  216. endoreg_db/models/medical/examination/examination.py +17 -18
  217. endoreg_db/models/medical/examination/examination_indication.py +26 -25
  218. endoreg_db/models/medical/examination/examination_time.py +16 -6
  219. endoreg_db/models/medical/examination/examination_time_type.py +9 -6
  220. endoreg_db/models/medical/examination/examination_type.py +3 -4
  221. endoreg_db/models/medical/finding/finding.py +38 -39
  222. endoreg_db/models/medical/finding/finding_classification.py +37 -48
  223. endoreg_db/models/medical/finding/finding_intervention.py +27 -22
  224. endoreg_db/models/medical/finding/finding_type.py +13 -12
  225. endoreg_db/models/medical/hardware/endoscope.py +20 -26
  226. endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
  227. endoreg_db/models/medical/laboratory/lab_value.py +62 -91
  228. endoreg_db/models/medical/medication/medication.py +22 -10
  229. endoreg_db/models/medical/medication/medication_indication.py +29 -3
  230. endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
  231. endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
  232. endoreg_db/models/medical/medication/medication_schedule.py +27 -16
  233. endoreg_db/models/medical/organ/__init__.py +15 -12
  234. endoreg_db/models/medical/patient/medication_examples.py +1 -5
  235. endoreg_db/models/medical/patient/patient_disease.py +20 -23
  236. endoreg_db/models/medical/patient/patient_event.py +19 -22
  237. endoreg_db/models/medical/patient/patient_examination.py +48 -54
  238. endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
  239. endoreg_db/models/medical/patient/patient_finding.py +122 -139
  240. endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
  241. endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
  242. endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
  243. endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
  244. endoreg_db/models/medical/patient/patient_medication.py +27 -38
  245. endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
  246. endoreg_db/models/medical/risk/risk.py +7 -6
  247. endoreg_db/models/medical/risk/risk_type.py +8 -5
  248. endoreg_db/models/metadata/model_meta.py +60 -29
  249. endoreg_db/models/metadata/model_meta_logic.py +125 -18
  250. endoreg_db/models/metadata/pdf_meta.py +19 -24
  251. endoreg_db/models/metadata/sensitive_meta.py +102 -85
  252. endoreg_db/models/metadata/sensitive_meta_logic.py +192 -173
  253. endoreg_db/models/metadata/video_meta.py +51 -31
  254. endoreg_db/models/metadata/video_prediction_logic.py +16 -23
  255. endoreg_db/models/metadata/video_prediction_meta.py +29 -33
  256. endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
  257. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
  258. endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
  259. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
  260. endoreg_db/models/other/emission/emission_factor.py +18 -8
  261. endoreg_db/models/other/gender.py +10 -5
  262. endoreg_db/models/other/information_source.py +25 -25
  263. endoreg_db/models/other/material.py +9 -5
  264. endoreg_db/models/other/resource.py +6 -4
  265. endoreg_db/models/other/tag.py +10 -5
  266. endoreg_db/models/other/transport_route.py +13 -8
  267. endoreg_db/models/other/unit.py +10 -6
  268. endoreg_db/models/other/waste.py +6 -5
  269. endoreg_db/models/requirement/requirement.py +580 -272
  270. endoreg_db/models/requirement/requirement_error.py +85 -0
  271. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
  272. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
  273. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
  274. endoreg_db/models/requirement/requirement_operator.py +36 -33
  275. endoreg_db/models/requirement/requirement_set.py +74 -57
  276. endoreg_db/models/state/__init__.py +4 -4
  277. endoreg_db/models/state/abstract.py +2 -2
  278. endoreg_db/models/state/anonymization.py +12 -0
  279. endoreg_db/models/state/audit_ledger.py +46 -47
  280. endoreg_db/models/state/label_video_segment.py +9 -0
  281. endoreg_db/models/state/raw_pdf.py +40 -46
  282. endoreg_db/models/state/sensitive_meta.py +6 -2
  283. endoreg_db/models/state/video.py +58 -53
  284. endoreg_db/models/upload_job.py +32 -55
  285. endoreg_db/models/utils.py +1 -2
  286. endoreg_db/root_urls.py +21 -2
  287. endoreg_db/serializers/__init__.py +0 -2
  288. endoreg_db/serializers/anonymization.py +18 -10
  289. endoreg_db/serializers/meta/report_meta.py +1 -1
  290. endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
  291. endoreg_db/serializers/misc/file_overview.py +11 -99
  292. endoreg_db/serializers/requirements/requirement_sets.py +92 -22
  293. endoreg_db/serializers/video/segmentation.py +2 -1
  294. endoreg_db/serializers/video/video_processing_history.py +20 -5
  295. endoreg_db/services/anonymization.py +75 -73
  296. endoreg_db/services/lookup_service.py +37 -24
  297. endoreg_db/services/pdf_import.py +166 -68
  298. endoreg_db/services/storage_aware_video_processor.py +140 -114
  299. endoreg_db/services/video_import.py +193 -283
  300. endoreg_db/urls/__init__.py +7 -20
  301. endoreg_db/urls/media.py +108 -67
  302. endoreg_db/urls/root_urls.py +29 -0
  303. endoreg_db/utils/__init__.py +15 -5
  304. endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
  305. endoreg_db/utils/case_generator/__init__.py +3 -0
  306. endoreg_db/utils/dataloader.py +88 -16
  307. endoreg_db/utils/defaults/set_default_center.py +32 -0
  308. endoreg_db/utils/names.py +22 -16
  309. endoreg_db/utils/permissions.py +2 -1
  310. endoreg_db/utils/pipelines/process_video_dir.py +1 -1
  311. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +414 -127
  312. endoreg_db/utils/setup_config.py +8 -5
  313. endoreg_db/utils/storage.py +115 -0
  314. endoreg_db/utils/validate_endo_roi.py +8 -2
  315. endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
  316. endoreg_db/views/__init__.py +0 -10
  317. endoreg_db/views/anonymization/media_management.py +198 -163
  318. endoreg_db/views/anonymization/overview.py +4 -1
  319. endoreg_db/views/anonymization/validate.py +174 -40
  320. endoreg_db/views/media/__init__.py +2 -0
  321. endoreg_db/views/media/pdf_media.py +131 -152
  322. endoreg_db/views/media/sensitive_metadata.py +46 -6
  323. endoreg_db/views/media/video_media.py +89 -82
  324. endoreg_db/views/media/video_segments.py +2 -3
  325. endoreg_db/views/meta/sensitive_meta_detail.py +0 -63
  326. endoreg_db/views/patient/patient.py +5 -4
  327. endoreg_db/views/pdf/pdf_stream.py +20 -21
  328. endoreg_db/views/pdf/reimport.py +11 -32
  329. endoreg_db/views/requirement/evaluate.py +188 -187
  330. endoreg_db/views/requirement/lookup.py +17 -3
  331. endoreg_db/views/requirement/requirement_utils.py +89 -0
  332. endoreg_db/views/video/__init__.py +0 -2
  333. endoreg_db/views/video/correction.py +2 -2
  334. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/METADATA +7 -3
  335. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/RECORD +341 -245
  336. endoreg_db/models/administration/permissions/__init__.py +0 -44
  337. endoreg_db/models/media/video/video_file_frames.py +0 -0
  338. endoreg_db/models/metadata/frame_ocr_result.py +0 -0
  339. endoreg_db/models/rule/__init__.py +0 -13
  340. endoreg_db/models/rule/rule.py +0 -27
  341. endoreg_db/models/rule/rule_applicator.py +0 -224
  342. endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
  343. endoreg_db/models/rule/rule_type.py +0 -20
  344. endoreg_db/models/rule/ruleset.py +0 -17
  345. endoreg_db/serializers/video/video_metadata.py +0 -105
  346. endoreg_db/urls/report.py +0 -48
  347. endoreg_db/urls/video.py +0 -61
  348. endoreg_db/utils/case_generator/case_generator.py +0 -159
  349. endoreg_db/utils/case_generator/utils.py +0 -30
  350. endoreg_db/views/report/__init__.py +0 -9
  351. endoreg_db/views/report/report_list.py +0 -112
  352. endoreg_db/views/report/report_with_secure_url.py +0 -28
  353. endoreg_db/views/report/start_examination.py +0 -7
  354. endoreg_db/views.py +0 -0
  355. /endoreg_db/data/{requirement_set → _examples/requirement_set}/endoscopy_bleeding_risk.yaml +0 -0
  356. /endoreg_db/migrations/{0002_add_video_correction_models.py → _old/0002_add_video_correction_models.py} +0 -0
  357. /endoreg_db/migrations/{0003_add_center_display_name.py → _old/0003_add_center_display_name.py} +0 -0
  358. /endoreg_db/{models/media/video/refactor_plan.md → views/pdf/pdf_stream_views.py} +0 -0
  359. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/WHEEL +0 -0
  360. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,69 +1,71 @@
1
1
  """
2
2
  Defines state tracking models related to video processing.
3
3
  """
4
- from django.db import models
5
- from .abstract import AbstractState
6
- from typing import TYPE_CHECKING, Optional
4
+
7
5
  import logging
8
6
  from enum import Enum
7
+ from typing import TYPE_CHECKING, Optional
8
+
9
+ from django.db import models
10
+
11
+ from endoreg_db.models.state.anonymization import AnonymizationState
9
12
 
10
13
  logger = logging.getLogger(__name__)
11
14
 
12
15
  if TYPE_CHECKING:
13
16
  from ..media import VideoFile
14
-
15
17
 
16
- class AnonymizationStatus(str, Enum):
17
- NOT_STARTED = "not_started"
18
- EXTRACTING_FRAMES = "extracting_frames"
19
- PROCESSING_ANONYMIZING = "processing_anonymization"
20
- DONE = "done"
21
- VALIDATED = "validated"
22
- FAILED = "failed"
23
- STARTED = "started"
24
18
 
25
19
  class VideoState(models.Model):
26
20
  """
27
21
  Tracks the processing state of a VideoFile instance.
28
22
  Uses BooleanFields for clear, distinct states.
29
23
  """
24
+
25
+
30
26
  # Frame related states
31
27
  if TYPE_CHECKING:
32
- video_file: Optional["VideoFile"]
33
-
28
+ video_file: models.OneToOneField["VideoFile"]
29
+
34
30
  frames_extracted = models.BooleanField(default=False, help_text="True if raw frames have been extracted to files.")
35
31
  frames_initialized = models.BooleanField(default=False, help_text="True if Frame DB objects have been created.")
36
32
  frame_count = models.PositiveIntegerField(null=True, blank=True, help_text="Number of frames extracted/initialized.")
37
33
 
38
34
  # Metadata related states
39
- video_meta_extracted = models.BooleanField(default=False, help_text="True if VideoMeta (technical specs) has been extracted.")
40
- text_meta_extracted = models.BooleanField(default=False, help_text="True if text metadata (OCR) has been extracted.")
35
+ video_meta_extracted = models.BooleanField(
36
+ default=False,
37
+ help_text="True if VideoMeta (technical specs) has been extracted.",
38
+ )
39
+ text_meta_extracted = models.BooleanField(
40
+ default=False, help_text="True if text metadata (OCR) has been extracted."
41
+ )
41
42
 
42
43
  # AI / Annotation related states
43
44
  initial_prediction_completed = models.BooleanField(default=False, help_text="True if initial AI prediction has run.")
44
45
  lvs_created = models.BooleanField(default=False, help_text="True if LabelVideoSegments have been created from predictions.")
45
46
  frame_annotations_generated = models.BooleanField(default=False, help_text="True if frame-level annotations have been generated from segments.")
46
-
47
+
47
48
  # Processing state
48
- sensitive_meta_processed = models.BooleanField(default=False, help_text="True if the video has been fully processed, meaning a anonymized person was created.")
49
+ sensitive_meta_processed = models.BooleanField(
50
+ default=False, help_text="True if the video has been fully processed, meaning a anonymized person was created."
51
+ )
49
52
 
50
53
  # Anonymization state
51
54
  anonymized = models.BooleanField(default=False, help_text="True if the anonymized video file has been created.")
52
55
  anonymization_validated = models.BooleanField(default=False, help_text="True if the anonymization process has been validated and confirmed.")
53
- anonymization_status: AnonymizationStatus
54
-
56
+
55
57
  processing_started = models.BooleanField(default=False, help_text="True if the processing has started, but not yet completed.")
56
-
58
+
57
59
  # Timestamps
58
60
  date_created = models.DateTimeField(auto_now_add=True)
59
61
  date_modified = models.DateTimeField(auto_now=True)
60
-
62
+
61
63
  # Segment Annotation State
62
64
  segment_annotations_created = models.BooleanField(default=False, help_text="True if segment annotations have been created from LabelVideoSegments.")
63
65
  segment_annotations_validated = models.BooleanField(default=False, help_text="True if segment annotations have been validated.")
64
-
66
+
65
67
  was_created = models.BooleanField(default=True, help_text="True if this state was created for the first time.")
66
-
68
+
67
69
  objects = models.Manager()
68
70
 
69
71
  def __str__(self):
@@ -71,10 +73,11 @@ class VideoState(models.Model):
71
73
  video_uuid = "Unknown"
72
74
  try:
73
75
  # Access the related VideoFile via the reverse relation 'video_file'
74
- if hasattr(self, 'video_file') and self.video_file:
76
+ if hasattr(self, "video_file") and self.video_file:
75
77
  video_uuid = self.video_file.uuid
76
78
  except Exception:
77
- pass # Ignore errors if relation doesn't exist or causes issues
79
+ pass # Ignore errors if relation doesn't exist or causes issues
80
+ pass # Ignore errors if relation doesn't exist or causes issues
78
81
 
79
82
  states = [
80
83
  f"FramesExtracted={self.frames_extracted}",
@@ -86,32 +89,36 @@ class VideoState(models.Model):
86
89
  f"Anonymized={self.anonymized}",
87
90
  f"AnonymizationValidated={self.anonymization_validated}",
88
91
  f"SensitiveMetaProcessed={self.sensitive_meta_processed}",
89
- f"FrameCount={self.frame_count}" if self.frame_count is not None else "FrameCount=None",
92
+ f"FrameCount={self.frame_count}"
93
+ if self.frame_count is not None
94
+ else "FrameCount=None",
90
95
  f"SegmentAnnotationsCreated={self.segment_annotations_created}",
91
96
  f"SegmentAnnotationsValidated={self.segment_annotations_validated}",
92
97
  f"DateCreated={self.date_created.isoformat()}",
93
- f"DateModified={self.date_modified.isoformat()}"
98
+ f"DateModified={self.date_modified.isoformat()}",
94
99
  ]
95
100
  return f"VideoState(Video:{video_uuid}): {', '.join(states)}"
96
101
 
97
102
  @property
98
- def anonymization_status(self) -> AnonymizationStatus:
103
+ def anonymization_status(self) -> AnonymizationState:
99
104
  """
100
105
  Fast, side‑effect‑free status resolution used by API & UI.
101
106
  """
102
107
  if self.anonymization_validated:
103
- return AnonymizationStatus.VALIDATED
108
+ return AnonymizationState.VALIDATED # Validation in Frontend completed -> Views related to this /home/admin/endoreg-db/endoreg_db/views/anonymization/validate.py
104
109
  if self.sensitive_meta_processed:
105
- return AnonymizationStatus.DONE
110
+ return AnonymizationState.DONE_PROCESSING_ANONYMIZATION # /home/admin/endoreg-db/endoreg_db/services/video_import.py /home/admin/endoreg-db/endoreg_db/views/video/reimport.py
106
111
  if self.frames_extracted and not self.anonymized:
107
- return AnonymizationStatus.PROCESSING_ANONYMIZING
112
+ return AnonymizationState.PROCESSING_ANONYMIZING
108
113
  if self.was_created and not self.frames_extracted:
109
- return AnonymizationStatus.EXTRACTING_FRAMES
114
+ return AnonymizationState.EXTRACTING_FRAMES
110
115
  if getattr(self, "processing_error", False):
111
- return AnonymizationStatus.FAILED
116
+ return AnonymizationState.FAILED
112
117
  if self.processing_started:
113
- return AnonymizationStatus.STARTED
114
- return AnonymizationStatus.NOT_STARTED
118
+ return AnonymizationState.STARTED
119
+ if self.anonymized:
120
+ return AnonymizationState.ANONYMIZED
121
+ return AnonymizationState.NOT_STARTED
115
122
 
116
123
  # ---- Single‑responsibility mutators ---------------------------------
117
124
  def mark_sensitive_meta_processed(self, *, save: bool = True) -> None:
@@ -122,7 +129,7 @@ class VideoState(models.Model):
122
129
  def mark_anonymization_validated(self, *, save: bool = True) -> None:
123
130
  """
124
131
  Mark the anonymization process as validated for this video state.
125
-
132
+
126
133
  Parameters:
127
134
  save (bool): If True, persist the change to the database immediately.
128
135
  """
@@ -133,7 +140,7 @@ class VideoState(models.Model):
133
140
  def mark_frames_extracted(self, *, save: bool = True) -> None:
134
141
  """
135
142
  Mark the video as having its frames extracted.
136
-
143
+
137
144
  Parameters:
138
145
  save (bool): If True, persist the change to the database immediately.
139
146
  """
@@ -144,7 +151,7 @@ class VideoState(models.Model):
144
151
  def mark_frames_not_extracted(self, *, save: bool = True) -> None:
145
152
  """
146
153
  Mark the video as having no extracted frames.
147
-
154
+
148
155
  If `save` is True, updates the database record for this state.
149
156
  """
150
157
  self.frames_extracted = False
@@ -154,7 +161,7 @@ class VideoState(models.Model):
154
161
  def mark_anonymized(self, *, save: bool = True) -> None:
155
162
  """
156
163
  Mark the video as anonymized by setting the anonymized flag to True.
157
-
164
+
158
165
  Parameters:
159
166
  save (bool): If True, immediately saves the updated state to the database.
160
167
  """
@@ -165,7 +172,7 @@ class VideoState(models.Model):
165
172
  def mark_initial_prediction_completed(self, *, save: bool = True) -> None:
166
173
  """
167
174
  Mark the initial AI prediction as completed for this video state.
168
-
175
+
169
176
  Parameters:
170
177
  save (bool): If True, persist the change to the database immediately.
171
178
  """
@@ -176,7 +183,7 @@ class VideoState(models.Model):
176
183
  def mark_video_meta_extracted(self, *, save: bool = True) -> None:
177
184
  """
178
185
  Mark the video metadata as extracted for this video state.
179
-
186
+
180
187
  Parameters:
181
188
  save (bool): If True, immediately saves the updated state to the database.
182
189
  """
@@ -187,45 +194,43 @@ class VideoState(models.Model):
187
194
  def mark_text_meta_extracted(self, *, save: bool = True) -> None:
188
195
  """
189
196
  Mark the video as having its text metadata extracted.
190
-
197
+
191
198
  Parameters:
192
- save (bool): If True, immediately saves the updated state to the database.
199
+ save (bool): If True, immediately saves the updated state to the database.
193
200
  """
194
201
  self.text_meta_extracted = True
195
202
  if save:
196
203
  self.save(update_fields=["text_meta_extracted", "date_modified"])
197
-
204
+
198
205
  def get_or_create_state(self):
199
206
  """
200
207
  Get the current state of the video, or create a new one if it doesn't exist.
201
-
208
+
202
209
  Returns:
203
210
  VideoState: The current or newly created state.
204
211
  """
205
- if not hasattr(self, 'video_file'):
212
+ if not hasattr(self, "video_file"):
206
213
  raise ValueError("This method requires a related VideoFile instance.")
207
-
214
+
208
215
  # If the state already exists, return it
209
216
  if self.video_file.state:
210
217
  return self.video_file.state
211
-
218
+
212
219
  # Otherwise, create a new state
213
220
  new_state = VideoState(video_file=self.video_file)
214
221
  new_state.save()
215
222
  return new_state
216
-
223
+
217
224
  def mark_processing_started(self, *, save: bool = True) -> None:
218
225
  """
219
226
  Mark the processing as started for this video state.
220
-
227
+
221
228
  Parameters:
222
229
  save (bool): If True, immediately saves the updated state to the database.
223
230
  """
224
231
  self.processing_started = True
225
232
  if save:
226
233
  self.save(update_fields=["processing_started", "date_modified"])
227
-
228
-
229
234
 
230
235
  class Meta:
231
236
  verbose_name = "Video Processing State"
@@ -1,4 +1,6 @@
1
1
  import uuid
2
+ from typing import TYPE_CHECKING, cast
3
+
2
4
  from django.db import models
3
5
 
4
6
 
@@ -7,63 +9,38 @@ class UploadJob(models.Model):
7
9
  Tracks file upload jobs and their processing status.
8
10
  Supports both PDF and video file uploads with asynchronous processing.
9
11
  """
10
-
12
+
11
13
  class Status(models.TextChoices):
12
- PENDING = 'pending', 'Pending'
13
- PROCESSING = 'processing', 'Processing'
14
- ANONYMIZED = 'anonymized', 'Anonymized'
15
- ERROR = 'error', 'Error'
16
-
17
- id = models.UUIDField(
18
- primary_key=True,
19
- default=uuid.uuid4,
20
- editable=False,
21
- help_text="Unique identifier for the upload job"
22
- )
23
-
24
- file = models.FileField(
25
- upload_to='uploads/%Y/%m/%d/',
26
- help_text="Uploaded file (PDF or video)"
27
- )
28
-
29
- status = models.CharField(
30
- max_length=20,
31
- choices=Status.choices,
32
- default=Status.PENDING,
33
- help_text="Current processing status of the upload"
34
- )
35
-
36
- content_type = models.CharField(
37
- max_length=100,
38
- blank=True,
39
- help_text="MIME type of the uploaded file"
40
- )
41
-
14
+ PENDING = "pending", "Pending"
15
+ PROCESSING = "processing", "Processing"
16
+ ANONYMIZED = "anonymized", "Anonymized"
17
+ ERROR = "error", "Error"
18
+
19
+ id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, help_text="Unique identifier for the upload job")
20
+
21
+ file = models.FileField(upload_to="uploads/%Y/%m/%d/", help_text="Uploaded file (PDF or video)")
22
+
23
+ status = models.CharField(max_length=20, choices=Status.choices, default=Status.PENDING, help_text="Current processing status of the upload")
24
+
25
+ content_type = models.CharField(max_length=100, blank=True, help_text="MIME type of the uploaded file")
26
+
42
27
  sensitive_meta = models.ForeignKey(
43
- 'SensitiveMeta',
44
- null=True,
45
- blank=True,
46
- on_delete=models.SET_NULL,
47
- help_text="Link to the created SensitiveMeta record after processing"
48
- )
49
-
50
- error_detail = models.TextField(
51
- blank=True,
52
- help_text="Error message if processing failed"
53
- )
54
-
55
- created_at = models.DateTimeField(
56
- auto_now_add=True,
57
- help_text="When the upload job was created"
58
- )
59
-
60
- updated_at = models.DateTimeField(
61
- auto_now=True,
62
- help_text="When the upload job was last updated"
28
+ "SensitiveMeta", null=True, blank=True, on_delete=models.SET_NULL, help_text="Link to the created SensitiveMeta record after processing"
63
29
  )
64
30
 
31
+ error_detail = models.TextField(blank=True, help_text="Error message if processing failed")
32
+
33
+ created_at = models.DateTimeField(auto_now_add=True, help_text="When the upload job was created")
34
+
35
+ updated_at = models.DateTimeField(auto_now=True, help_text="When the upload job was last updated")
36
+
37
+ if TYPE_CHECKING:
38
+ from django.db.models.fields.files import FieldFile
39
+
40
+ file = cast(FieldFile, file)
41
+
65
42
  class Meta:
66
- ordering = ['-created_at']
43
+ ordering = ["-created_at"]
67
44
  verbose_name = "Upload Job"
68
45
  verbose_name_plural = "Upload Jobs"
69
46
 
@@ -83,17 +60,17 @@ class UploadJob(models.Model):
83
60
  def mark_processing(self):
84
61
  """Mark the job as processing."""
85
62
  self.status = self.Status.PROCESSING
86
- self.save(update_fields=['status', 'updated_at'])
63
+ self.save(update_fields=["status", "updated_at"])
87
64
 
88
65
  def mark_completed(self, sensitive_meta=None):
89
66
  """Mark the job as successfully completed."""
90
67
  self.status = self.Status.ANONYMIZED
91
68
  if sensitive_meta:
92
69
  self.sensitive_meta = sensitive_meta
93
- self.save(update_fields=['status', 'sensitive_meta', 'updated_at'])
70
+ self.save(update_fields=["status", "sensitive_meta", "updated_at"])
94
71
 
95
72
  def mark_error(self, error_detail: str):
96
73
  """Mark the job as failed with error details."""
97
74
  self.status = self.Status.ERROR
98
75
  self.error_detail = error_detail
99
- self.save(update_fields=['status', 'error_detail', 'updated_at'])
76
+ self.save(update_fields=["status", "error_detail", "updated_at"])
@@ -6,13 +6,12 @@ from django.core.files import File
6
6
  from django.core.files.storage import FileSystemStorage
7
7
  import io
8
8
  import os
9
- from tqdm import tqdm
10
9
  import numpy as np
11
10
  import cv2
12
11
  from typing import TYPE_CHECKING, List, Tuple
13
12
  from pathlib import Path
14
13
  if TYPE_CHECKING:
15
- from ..models.media import VideoFile
14
+ pass
16
15
 
17
16
  from logging import getLogger
18
17
 
endoreg_db/root_urls.py CHANGED
@@ -1,9 +1,28 @@
1
+ # endoreg_db/root_urls.py
2
+ from django.contrib import admin
1
3
  from django.urls import include, path
4
+ from django.http import HttpResponse
5
+ from django.conf import settings
6
+ from django.conf.urls.static import static
2
7
 
3
- # Import raw API urlpatterns (no prefix) from the URLs package
8
+ # Import raw API urlpatterns (no prefix) from your API urls package
4
9
  from endoreg_db.urls import urlpatterns as api_urlpatterns
5
10
 
6
- # Mount the API under /api/
11
+ def public_home(_request):
12
+ return HttpResponse("Public home – no login required.")
13
+
7
14
  urlpatterns = [
15
+ path("", public_home, name="public_home"),
16
+ #path("admin/", admin.site.urls),
17
+
18
+ # Mount ALL API endpoints under /api/
8
19
  path("api/", include((api_urlpatterns, "endoreg_db"), namespace="api")),
20
+
21
+ # OIDC (mozilla-django-oidc provides /oidc/authenticate/ and /oidc/callback/)
22
+ path("oidc/", include("mozilla_django_oidc.urls")),
9
23
  ]
24
+
25
+ # Serve static/media only in DEBUG (at root, not under /api/)
26
+ if settings.DEBUG:
27
+ urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
28
+ urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
@@ -48,7 +48,6 @@ from .patient_finding import (
48
48
  )
49
49
  from .pdf import RawPdfAnonyTextSerializer
50
50
  from .report import ReportDataSerializer, ReportListSerializer, SecureFileUrlSerializer
51
- from .video.video_metadata import VideoMetadataSerializer
52
51
  from .video.video_processing_history import VideoProcessingHistorySerializer
53
52
  from .video_examination import (
54
53
  VideoExaminationCreateSerializer,
@@ -109,7 +108,6 @@ __all__ = [
109
108
  "ReportDataSerializer",
110
109
  "SecureFileUrlSerializer",
111
110
  # Video Correction (Phase 1.1)
112
- "VideoMetadataSerializer",
113
111
  "VideoProcessingHistorySerializer",
114
112
  # Video Examination
115
113
  "VideoExaminationSerializer",
@@ -7,7 +7,6 @@ Unterstützt DD.MM.YYYY als Primärformat und YYYY-MM-DD als Fallback.
7
7
  from rest_framework import serializers
8
8
  from endoreg_db.models.metadata.sensitive_meta_logic import parse_any_date
9
9
 
10
-
11
10
  class SensitiveMetaValidateSerializer(serializers.Serializer):
12
11
  """
13
12
  Serializer für SensitiveMeta-Validierung mit deutscher Datums-Priorität.
@@ -19,11 +18,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
19
18
  Alle Datumsfelder werden in date-Objekte konvertiert.
20
19
  """
21
20
 
22
- patient_first_name = serializers.CharField(required=False, allow_blank=True)
23
- patient_last_name = serializers.CharField(required=False, allow_blank=True)
24
- patient_dob = serializers.CharField(required=False, allow_blank=True)
25
- examination_date = serializers.CharField(required=False, allow_blank=True)
26
- casenumber = serializers.CharField(required=False, allow_blank=True)
21
+ patient_first_name = serializers.CharField(required=True, allow_blank=True)
22
+ patient_last_name = serializers.CharField(required=True, allow_blank=True)
23
+ patient_dob = serializers.CharField(required=True, allow_blank=True)
24
+ examination_date = serializers.CharField(required=True, allow_blank=True)
25
+ casenumber = serializers.CharField(required=True, allow_blank=True)
27
26
  anonymized_text = serializers.CharField(required=False, allow_blank=True)
28
27
  patient_gender = serializers.CharField(required=False, allow_blank=True)
29
28
  center_name = serializers.CharField(required=False, allow_blank=True)
@@ -31,6 +30,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
31
30
  file_type = serializers.ChoiceField(
32
31
  choices=['video', 'pdf'], required=False
33
32
  ) # Optional: "video" oder "pdf"
33
+ center_name = serializers.CharField(required=False, allow_blank=True)
34
+ external_id = serializers.CharField(required=False, allow_blank=True)
35
+ external_id_origin = serializers.CharField(required=False, allow_blank=True)
36
+
34
37
 
35
38
  def validate_patient_dob(self, value):
36
39
  """
@@ -40,8 +43,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
40
43
  - DD.MM.YYYY (z.B. "21.03.1994")
41
44
  - YYYY-MM-DD (z.B. "1994-03-21")
42
45
  """
43
- if not value:
44
- return None
46
+
47
+ if value == '' or not value:
48
+ raise serializers.ValidationError(
49
+ "Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
50
+ )
45
51
 
46
52
  parsed_date = parse_any_date(value)
47
53
  if not parsed_date:
@@ -58,8 +64,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
58
64
  - DD.MM.YYYY (z.B. "15.02.2024")
59
65
  - YYYY-MM-DD (z.B. "2024-02-15")
60
66
  """
61
- if not value:
62
- return None
67
+ if value == '' or not value:
68
+ raise serializers.ValidationError(
69
+ "Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
70
+ )
63
71
 
64
72
  parsed_date = parse_any_date(value)
65
73
  if not parsed_date:
@@ -12,7 +12,7 @@ class ReportMetaSerializer(serializers.ModelSerializer):
12
12
  # Füge fehlende Zeitstempel-Felder hinzu
13
13
  created_at = serializers.SerializerMethodField()
14
14
  updated_at = serializers.SerializerMethodField()
15
- casenumber = serializers.CharField(source='case_number', allow_blank=True, allow_null=True)
15
+ casenumber = serializers.CharField(source='casenumber', allow_blank=True, allow_null=True)
16
16
 
17
17
  class Meta:
18
18
  model = SensitiveMeta