Marwan Alwali 263292f6be update
2025-11-04 00:50:06 +03:00

1654 lines
61 KiB
Python

# Generated by Django 5.2.7 on 2025-10-06 21:15
import django.db.models.deletion
import django.utils.timezone
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("core", "0001_initial"),
("emr", "0001_initial"),
("patients", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="ImagingSeries",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"series_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique series identifier",
unique=True,
),
),
(
"series_instance_uid",
models.CharField(
help_text="DICOM Series Instance UID",
max_length=64,
unique=True,
),
),
(
"series_number",
models.PositiveIntegerField(help_text="Series number within study"),
),
(
"modality",
models.CharField(
choices=[
("CR", "Computed Radiography"),
("CT", "Computed Tomography"),
("MR", "Magnetic Resonance"),
("US", "Ultrasound"),
("XA", "X-Ray Angiography"),
("RF", "Radiofluoroscopy"),
("DX", "Digital Radiography"),
("MG", "Mammography"),
("NM", "Nuclear Medicine"),
("PT", "Positron Emission Tomography"),
("OT", "Other"),
],
help_text="Series modality",
max_length=10,
),
),
(
"series_description",
models.CharField(
blank=True,
help_text="Series description",
max_length=200,
null=True,
),
),
(
"protocol_name",
models.CharField(
blank=True, help_text="Protocol name", max_length=100, null=True
),
),
(
"series_datetime",
models.DateTimeField(help_text="Series acquisition date and time"),
),
(
"started_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time series acquisition started",
null=True,
),
),
(
"completed_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time series acquisition completed",
null=True,
),
),
(
"processed_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time series was processed",
null=True,
),
),
(
"archived_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time series was archived",
null=True,
),
),
(
"slice_thickness",
models.FloatField(
blank=True, help_text="Slice thickness in mm", null=True
),
),
(
"spacing_between_slices",
models.FloatField(
blank=True, help_text="Spacing between slices in mm", null=True
),
),
(
"pixel_spacing",
models.CharField(
blank=True, help_text="Pixel spacing", max_length=50, null=True
),
),
(
"image_orientation",
models.CharField(
blank=True,
help_text="Image orientation",
max_length=100,
null=True,
),
),
(
"number_of_instances",
models.PositiveIntegerField(
default=0, help_text="Number of instances in series"
),
),
(
"series_size",
models.BigIntegerField(default=0, help_text="Series size in bytes"),
),
(
"body_part",
models.CharField(
blank=True,
help_text="Body part examined",
max_length=100,
null=True,
),
),
(
"patient_position",
models.CharField(
blank=True,
choices=[
("HFP", "Head First-Prone"),
("HFS", "Head First-Supine"),
("HFDR", "Head First-Decubitus Right"),
("HFDL", "Head First-Decubitus Left"),
("FFP", "Feet First-Prone"),
("FFS", "Feet First-Supine"),
("FFDR", "Feet First-Decubitus Right"),
("FFDL", "Feet First-Decubitus Left"),
],
help_text="Patient position",
max_length=20,
null=True,
),
),
(
"contrast_agent",
models.CharField(
blank=True,
help_text="Contrast agent used",
max_length=100,
null=True,
),
),
(
"contrast_route",
models.CharField(
blank=True,
choices=[
("IV", "Intravenous"),
("ORAL", "Oral"),
("RECTAL", "Rectal"),
("INTRATHECAL", "Intrathecal"),
("INTRA_ARTICULAR", "Intra-articular"),
("OTHER", "Other"),
],
help_text="Contrast administration route",
max_length=20,
null=True,
),
),
(
"image_quality",
models.CharField(
blank=True,
choices=[
("EXCELLENT", "Excellent"),
("GOOD", "Good"),
("ADEQUATE", "Adequate"),
("POOR", "Poor"),
("UNACCEPTABLE", "Unacceptable"),
],
help_text="Image quality assessment",
max_length=20,
null=True,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Imaging Series",
"verbose_name_plural": "Imaging Series",
"db_table": "radiology_imaging_series",
"ordering": ["study", "series_number"],
},
),
migrations.CreateModel(
name="ImagingOrder",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"order_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique order identifier",
unique=True,
),
),
(
"order_number",
models.CharField(
help_text="Imaging order number", max_length=20, unique=True
),
),
(
"order_datetime",
models.DateTimeField(
default=django.utils.timezone.now,
help_text="Date and time order was placed",
),
),
(
"priority",
models.CharField(
choices=[
("ROUTINE", "Routine"),
("URGENT", "Urgent"),
("STAT", "STAT"),
("EMERGENCY", "Emergency"),
],
default="ROUTINE",
help_text="Order priority",
max_length=20,
),
),
(
"modality",
models.CharField(
choices=[
("CR", "Computed Radiography"),
("CT", "Computed Tomography"),
("MR", "Magnetic Resonance"),
("US", "Ultrasound"),
("XA", "X-Ray Angiography"),
("RF", "Radiofluoroscopy"),
("DX", "Digital Radiography"),
("MG", "Mammography"),
("NM", "Nuclear Medicine"),
("PT", "Positron Emission Tomography"),
],
help_text="Requested modality",
max_length=10,
),
),
(
"study_description",
models.CharField(help_text="Study description", max_length=200),
),
(
"body_part",
models.CharField(
choices=[
("HEAD", "Head"),
("NECK", "Neck"),
("CHEST", "Chest"),
("ABDOMEN", "Abdomen"),
("PELVIS", "Pelvis"),
("SPINE", "Spine"),
("EXTREMITY", "Extremity"),
("BREAST", "Breast"),
("HEART", "Heart"),
("BRAIN", "Brain"),
("WHOLE_BODY", "Whole Body"),
("OTHER", "Other"),
],
help_text="Body part to be examined",
max_length=100,
),
),
(
"clinical_indication",
models.TextField(help_text="Clinical indication for imaging"),
),
(
"clinical_history",
models.TextField(
blank=True, help_text="Relevant clinical history", null=True
),
),
(
"diagnosis_code",
models.CharField(
blank=True,
help_text="ICD-10 diagnosis code",
max_length=20,
null=True,
),
),
(
"contrast_required",
models.BooleanField(
default=False, help_text="Contrast agent required"
),
),
(
"contrast_type",
models.CharField(
blank=True,
help_text="Type of contrast agent",
max_length=50,
null=True,
),
),
(
"contrast_route",
models.CharField(
blank=True,
choices=[
("IV", "Intravenous"),
("ORAL", "Oral"),
("RECTAL", "Rectal"),
("INTRATHECAL", "Intrathecal"),
("INTRA_ARTICULAR", "Intra-articular"),
("OTHER", "Other"),
],
help_text="Contrast administration route",
max_length=20,
null=True,
),
),
(
"requested_datetime",
models.DateTimeField(
blank=True, help_text="Requested study date and time", null=True
),
),
(
"approved_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time order was approved",
null=True,
),
),
(
"scheduled_datetime",
models.DateTimeField(
blank=True, help_text="Scheduled study date and time", null=True
),
),
(
"cancelled_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time order was cancelled",
null=True,
),
),
(
"completed_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time order was completed",
null=True,
),
),
(
"status",
models.CharField(
choices=[
("PENDING", "Pending"),
("SCHEDULED", "Scheduled"),
("IN_PROGRESS", "In Progress"),
("COMPLETED", "Completed"),
("CANCELLED", "Cancelled"),
("ON_HOLD", "On Hold"),
],
default="PENDING",
help_text="Order status",
max_length=20,
),
),
(
"special_instructions",
models.TextField(
blank=True,
help_text="Special instructions for imaging",
null=True,
),
),
(
"patient_preparation",
models.TextField(
blank=True,
help_text="Patient preparation instructions",
null=True,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"encounter",
models.ForeignKey(
blank=True,
help_text="Related encounter",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="imaging_orders",
to="emr.encounter",
),
),
(
"ordering_provider",
models.ForeignKey(
help_text="Ordering provider",
on_delete=django.db.models.deletion.CASCADE,
related_name="ordered_imaging_studies",
to=settings.AUTH_USER_MODEL,
),
),
(
"patient",
models.ForeignKey(
help_text="Patient",
on_delete=django.db.models.deletion.CASCADE,
related_name="imaging_orders",
to="patients.patientprofile",
),
),
(
"tenant",
models.ForeignKey(
help_text="Organization tenant",
on_delete=django.db.models.deletion.CASCADE,
related_name="imaging_orders",
to="core.tenant",
),
),
],
options={
"verbose_name": "Imaging Order",
"verbose_name_plural": "Imaging Orders",
"db_table": "radiology_imaging_order",
"ordering": ["-order_datetime"],
},
),
migrations.CreateModel(
name="DICOMImage",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"image_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique image identifier",
unique=True,
),
),
(
"sop_instance_uid",
models.CharField(
help_text="DICOM SOP Instance UID", max_length=64, unique=True
),
),
(
"instance_number",
models.PositiveIntegerField(
help_text="Instance number within series"
),
),
(
"image_type",
models.CharField(
blank=True,
help_text="DICOM image type",
max_length=100,
null=True,
),
),
(
"sop_class_uid",
models.CharField(help_text="DICOM SOP Class UID", max_length=64),
),
(
"rows",
models.PositiveIntegerField(help_text="Number of rows in image"),
),
(
"columns",
models.PositiveIntegerField(help_text="Number of columns in image"),
),
(
"bits_allocated",
models.PositiveIntegerField(
help_text="Number of bits allocated for each pixel"
),
),
(
"bits_stored",
models.PositiveIntegerField(
help_text="Number of bits stored for each pixel"
),
),
(
"image_position",
models.CharField(
blank=True,
help_text="Image position (patient)",
max_length=100,
null=True,
),
),
(
"image_orientation",
models.CharField(
blank=True,
help_text="Image orientation (patient)",
max_length=100,
null=True,
),
),
(
"slice_location",
models.FloatField(
blank=True, help_text="Slice location", null=True
),
),
(
"window_center",
models.FloatField(blank=True, help_text="Window center", null=True),
),
(
"window_width",
models.FloatField(blank=True, help_text="Window width", null=True),
),
(
"file_path",
models.CharField(
help_text="File path on storage system", max_length=500
),
),
("file_size", models.BigIntegerField(help_text="File size in bytes")),
(
"transfer_syntax_uid",
models.CharField(
blank=True,
help_text="Transfer syntax UID",
max_length=64,
null=True,
),
),
(
"content_date",
models.DateField(blank=True, help_text="Content date", null=True),
),
(
"content_time",
models.TimeField(blank=True, help_text="Content time", null=True),
),
(
"acquisition_datetime",
models.DateTimeField(
blank=True, help_text="Acquisition date and time", null=True
),
),
(
"processed_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time image was processed",
null=True,
),
),
(
"quality_checked_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time image quality was checked",
null=True,
),
),
(
"archived_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time image was archived",
null=True,
),
),
(
"image_quality",
models.CharField(
blank=True,
choices=[
("EXCELLENT", "Excellent"),
("GOOD", "Good"),
("ADEQUATE", "Adequate"),
("POOR", "Poor"),
("UNACCEPTABLE", "Unacceptable"),
],
help_text="Image quality assessment",
max_length=20,
null=True,
),
),
(
"processed",
models.BooleanField(
default=False, help_text="Image has been processed"
),
),
(
"archived",
models.BooleanField(default=False, help_text="Image is archived"),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"series",
models.ForeignKey(
help_text="Parent imaging series",
on_delete=django.db.models.deletion.CASCADE,
related_name="images",
to="radiology.imagingseries",
),
),
],
options={
"verbose_name": "DICOM Image",
"verbose_name_plural": "DICOM Images",
"db_table": "radiology_dicom_image",
"ordering": ["series", "instance_number"],
},
),
migrations.CreateModel(
name="ImagingStudy",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"study_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique study identifier",
unique=True,
),
),
(
"study_instance_uid",
models.CharField(
help_text="DICOM Study Instance UID", max_length=64, unique=True
),
),
(
"accession_number",
models.CharField(
help_text="Study accession number", max_length=20, unique=True
),
),
(
"modality",
models.CharField(
choices=[
("CR", "Computed Radiography"),
("CT", "Computed Tomography"),
("MR", "Magnetic Resonance"),
("US", "Ultrasound"),
("XA", "X-Ray Angiography"),
("RF", "Radiofluoroscopy"),
("DX", "Digital Radiography"),
("MG", "Mammography"),
("NM", "Nuclear Medicine"),
("PT", "Positron Emission Tomography"),
("OT", "Other"),
],
help_text="Study modality",
max_length=10,
),
),
(
"study_description",
models.CharField(help_text="Study description", max_length=200),
),
(
"body_part",
models.CharField(
choices=[
("HEAD", "Head"),
("NECK", "Neck"),
("CHEST", "Chest"),
("ABDOMEN", "Abdomen"),
("PELVIS", "Pelvis"),
("SPINE", "Spine"),
("EXTREMITY", "Extremity"),
("BREAST", "Breast"),
("HEART", "Heart"),
("BRAIN", "Brain"),
("WHOLE_BODY", "Whole Body"),
("OTHER", "Other"),
],
help_text="Body part examined",
max_length=100,
),
),
(
"scheduled_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time study was scheduled",
null=True,
),
),
(
"study_datetime",
models.DateTimeField(help_text="Planned study date and time"),
),
(
"arrived_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time patient arrived for study",
null=True,
),
),
(
"started_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time study acquisition started",
null=True,
),
),
(
"completed_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time study acquisition completed",
null=True,
),
),
(
"interpreted_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time study was interpreted",
null=True,
),
),
(
"finalized_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time study was finalized",
null=True,
),
),
(
"clinical_indication",
models.TextField(
blank=True, help_text="Clinical indication for study", null=True
),
),
(
"clinical_history",
models.TextField(
blank=True, help_text="Clinical history", null=True
),
),
(
"diagnosis_code",
models.CharField(
blank=True,
help_text="ICD-10 diagnosis code",
max_length=20,
null=True,
),
),
(
"status",
models.CharField(
choices=[
("SCHEDULED", "Scheduled"),
("ARRIVED", "Arrived"),
("IN_PROGRESS", "In Progress"),
("COMPLETED", "Completed"),
("INTERPRETED", "Interpreted"),
("FINALIZED", "Finalized"),
("CANCELLED", "Cancelled"),
],
default="SCHEDULED",
help_text="Study status",
max_length=20,
),
),
(
"priority",
models.CharField(
choices=[
("ROUTINE", "Routine"),
("URGENT", "Urgent"),
("STAT", "STAT"),
("EMERGENCY", "Emergency"),
],
default="ROUTINE",
help_text="Study priority",
max_length=20,
),
),
(
"kvp",
models.FloatField(
blank=True, help_text="Peak kilovoltage (kVp)", null=True
),
),
(
"mas",
models.FloatField(
blank=True, help_text="Milliampere-seconds (mAs)", null=True
),
),
(
"exposure_time",
models.FloatField(
blank=True, help_text="Exposure time in milliseconds", null=True
),
),
(
"slice_thickness",
models.FloatField(
blank=True, help_text="Slice thickness in mm", null=True
),
),
(
"station_name",
models.CharField(
blank=True,
help_text="Acquisition station name",
max_length=50,
null=True,
),
),
(
"manufacturer",
models.CharField(
blank=True,
help_text="Equipment manufacturer",
max_length=50,
null=True,
),
),
(
"model_name",
models.CharField(
blank=True,
help_text="Equipment model name",
max_length=50,
null=True,
),
),
(
"number_of_series",
models.PositiveIntegerField(
default=0, help_text="Number of series in study"
),
),
(
"number_of_instances",
models.PositiveIntegerField(
default=0, help_text="Number of instances in study"
),
),
(
"study_size",
models.BigIntegerField(default=0, help_text="Study size in bytes"),
),
(
"image_quality",
models.CharField(
blank=True,
choices=[
("EXCELLENT", "Excellent"),
("GOOD", "Good"),
("ADEQUATE", "Adequate"),
("POOR", "Poor"),
("UNACCEPTABLE", "Unacceptable"),
],
help_text="Image quality assessment",
max_length=20,
null=True,
),
),
(
"completion_status",
models.CharField(
choices=[
("COMPLETE", "Complete"),
("PARTIAL", "Partial"),
("INCOMPLETE", "Incomplete"),
],
default="COMPLETE",
help_text="Study completion status",
max_length=20,
),
),
(
"pacs_location",
models.CharField(
blank=True,
help_text="PACS storage location",
max_length=200,
null=True,
),
),
(
"archived",
models.BooleanField(default=False, help_text="Study is archived"),
),
(
"archive_location",
models.CharField(
blank=True,
help_text="Archive storage location",
max_length=200,
null=True,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"created_by",
models.ForeignKey(
blank=True,
help_text="User who created the study",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="created_studies",
to=settings.AUTH_USER_MODEL,
),
),
(
"encounter",
models.ForeignKey(
blank=True,
help_text="Related encounter",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="imaging_studies",
to="emr.encounter",
),
),
(
"imaging_order",
models.ForeignKey(
blank=True,
help_text="Related imaging order",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="studies",
to="radiology.imagingorder",
),
),
(
"patient",
models.ForeignKey(
help_text="Patient",
on_delete=django.db.models.deletion.CASCADE,
related_name="imaging_studies",
to="patients.patientprofile",
),
),
(
"radiologist",
models.ForeignKey(
blank=True,
help_text="Interpreting radiologist",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="interpreted_studies",
to=settings.AUTH_USER_MODEL,
),
),
(
"referring_physician",
models.ForeignKey(
help_text="Referring physician",
on_delete=django.db.models.deletion.CASCADE,
related_name="referred_studies",
to=settings.AUTH_USER_MODEL,
),
),
(
"tenant",
models.ForeignKey(
help_text="Organization tenant",
on_delete=django.db.models.deletion.CASCADE,
related_name="imaging_studies",
to="core.tenant",
),
),
],
options={
"verbose_name": "Imaging Study",
"verbose_name_plural": "Imaging Studies",
"db_table": "radiology_imaging_study",
"ordering": ["-study_datetime"],
},
),
migrations.AddField(
model_name="imagingseries",
name="study",
field=models.ForeignKey(
help_text="Parent imaging study",
on_delete=django.db.models.deletion.CASCADE,
related_name="series",
to="radiology.imagingstudy",
),
),
migrations.CreateModel(
name="ReportTemplate",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"template_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique template identifier",
unique=True,
),
),
("name", models.CharField(help_text="Template name", max_length=100)),
(
"description",
models.TextField(
blank=True, help_text="Template description", null=True
),
),
(
"modality",
models.CharField(
choices=[
("ALL", "All Modalities"),
("CR", "Computed Radiography"),
("CT", "Computed Tomography"),
("MR", "Magnetic Resonance"),
("US", "Ultrasound"),
("XA", "X-Ray Angiography"),
("RF", "Radiofluoroscopy"),
("DX", "Digital Radiography"),
("MG", "Mammography"),
("NM", "Nuclear Medicine"),
("PT", "Positron Emission Tomography"),
],
default="ALL",
help_text="Applicable modality",
max_length=10,
),
),
(
"body_part",
models.CharField(
choices=[
("ALL", "All Body Parts"),
("HEAD", "Head"),
("NECK", "Neck"),
("CHEST", "Chest"),
("ABDOMEN", "Abdomen"),
("PELVIS", "Pelvis"),
("SPINE", "Spine"),
("EXTREMITY", "Extremity"),
("BREAST", "Breast"),
("HEART", "Heart"),
("BRAIN", "Brain"),
],
default="ALL",
help_text="Applicable body part",
max_length=100,
),
),
(
"clinical_history_template",
models.TextField(
blank=True, help_text="Clinical history template", null=True
),
),
(
"technique_template",
models.TextField(
blank=True, help_text="Technique template", null=True
),
),
("findings_template", models.TextField(help_text="Findings template")),
(
"impression_template",
models.TextField(help_text="Impression template"),
),
(
"recommendations_template",
models.TextField(
blank=True, help_text="Recommendations template", null=True
),
),
(
"structured_fields",
models.JSONField(
default=dict, help_text="Structured reporting field definitions"
),
),
(
"is_active",
models.BooleanField(default=True, help_text="Template is active"),
),
(
"is_default",
models.BooleanField(
default=False,
help_text="Default template for modality/body part",
),
),
(
"usage_count",
models.PositiveIntegerField(
default=0, help_text="Number of times template has been used"
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"created_by",
models.ForeignKey(
blank=True,
help_text="User who created the template",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="created_report_templates",
to=settings.AUTH_USER_MODEL,
),
),
(
"tenant",
models.ForeignKey(
help_text="Organization tenant",
on_delete=django.db.models.deletion.CASCADE,
related_name="report_templates",
to="core.tenant",
),
),
],
options={
"verbose_name": "Report Template",
"verbose_name_plural": "Report Templates",
"db_table": "radiology_report_template",
"ordering": ["modality", "body_part", "name"],
},
),
migrations.CreateModel(
name="RadiologyReport",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"report_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique report identifier",
unique=True,
),
),
(
"clinical_history",
models.TextField(
blank=True,
help_text="Clinical history and indication",
null=True,
),
),
(
"technique",
models.TextField(
blank=True,
help_text="Imaging technique and protocol",
null=True,
),
),
("findings", models.TextField(help_text="Imaging findings")),
(
"impression",
models.TextField(help_text="Radiologist impression and conclusion"),
),
(
"recommendations",
models.TextField(
blank=True, help_text="Recommendations for follow-up", null=True
),
),
(
"status",
models.CharField(
choices=[
("DRAFT", "Draft"),
("PRELIMINARY", "Preliminary"),
("FINAL", "Final"),
("AMENDED", "Amended"),
("CORRECTED", "Corrected"),
],
default="DRAFT",
help_text="Report status",
max_length=20,
),
),
(
"critical_finding",
models.BooleanField(
default=False, help_text="Report contains critical findings"
),
),
(
"critical_communicated",
models.BooleanField(
default=False,
help_text="Critical findings have been communicated",
),
),
(
"critical_communicated_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time critical findings were communicated",
null=True,
),
),
(
"dictated_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time report was dictated",
null=True,
),
),
(
"transcribed_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time report was transcribed",
null=True,
),
),
(
"verified_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time report was verified",
null=True,
),
),
(
"finalized_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time report was finalized",
null=True,
),
),
(
"structured_data",
models.JSONField(
default=dict, help_text="Structured reporting data"
),
),
(
"report_length",
models.PositiveIntegerField(
default=0, help_text="Report length in characters"
),
),
(
"turnaround_time",
models.PositiveIntegerField(
blank=True, help_text="Turnaround time in minutes", null=True
),
),
(
"addendum",
models.TextField(
blank=True, help_text="Report addendum", null=True
),
),
(
"addendum_datetime",
models.DateTimeField(
blank=True,
help_text="Date and time addendum was added",
null=True,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"critical_communicated_to",
models.ForeignKey(
blank=True,
help_text="Person critical findings were communicated to",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="critical_communicated_reports",
to=settings.AUTH_USER_MODEL,
),
),
(
"dictated_by",
models.ForeignKey(
blank=True,
help_text="Radiologist who dictated the report",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="dictated_reports",
to=settings.AUTH_USER_MODEL,
),
),
(
"radiologist",
models.ForeignKey(
help_text="Interpreting radiologist",
on_delete=django.db.models.deletion.CASCADE,
related_name="radiology_reports",
to=settings.AUTH_USER_MODEL,
),
),
(
"study",
models.OneToOneField(
help_text="Related imaging study",
on_delete=django.db.models.deletion.CASCADE,
related_name="report",
to="radiology.imagingstudy",
),
),
(
"transcribed_by",
models.ForeignKey(
blank=True,
help_text="Person who transcribed the report",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="transcribed_reports",
to=settings.AUTH_USER_MODEL,
),
),
(
"template_used",
models.ForeignKey(
blank=True,
help_text="Report template used",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="reports",
to="radiology.reporttemplate",
),
),
],
options={
"verbose_name": "Radiology Report",
"verbose_name_plural": "Radiology Reports",
"db_table": "radiology_radiology_report",
"ordering": ["-created_at"],
},
),
migrations.AddIndex(
model_name="imagingorder",
index=models.Index(
fields=["tenant", "status"], name="radiology_i_tenant__3b515d_idx"
),
),
migrations.AddIndex(
model_name="imagingorder",
index=models.Index(
fields=["patient", "status"], name="radiology_i_patient_afd52e_idx"
),
),
migrations.AddIndex(
model_name="imagingorder",
index=models.Index(
fields=["ordering_provider"], name="radiology_i_orderin_ea97ce_idx"
),
),
migrations.AddIndex(
model_name="imagingorder",
index=models.Index(
fields=["order_datetime"], name="radiology_i_order_d_39e57c_idx"
),
),
migrations.AddIndex(
model_name="imagingorder",
index=models.Index(
fields=["order_number"], name="radiology_i_order_n_f62d46_idx"
),
),
migrations.AddIndex(
model_name="imagingorder",
index=models.Index(
fields=["priority"], name="radiology_i_priorit_361aea_idx"
),
),
migrations.AddIndex(
model_name="imagingorder",
index=models.Index(
fields=["modality"], name="radiology_i_modalit_6b3ebb_idx"
),
),
migrations.AddIndex(
model_name="dicomimage",
index=models.Index(
fields=["series", "instance_number"],
name="radiology_d_series__235f82_idx",
),
),
migrations.AddIndex(
model_name="dicomimage",
index=models.Index(
fields=["sop_instance_uid"], name="radiology_d_sop_ins_ea9ded_idx"
),
),
migrations.AddIndex(
model_name="dicomimage",
index=models.Index(
fields=["sop_class_uid"], name="radiology_d_sop_cla_c69ac4_idx"
),
),
migrations.AddIndex(
model_name="dicomimage",
index=models.Index(
fields=["processed"], name="radiology_d_process_8c5300_idx"
),
),
migrations.AddIndex(
model_name="dicomimage",
index=models.Index(
fields=["archived"], name="radiology_d_archive_35bb5b_idx"
),
),
migrations.AlterUniqueTogether(
name="dicomimage",
unique_together={("series", "instance_number")},
),
migrations.AddIndex(
model_name="imagingstudy",
index=models.Index(
fields=["tenant", "status"], name="radiology_i_tenant__871dc8_idx"
),
),
migrations.AddIndex(
model_name="imagingstudy",
index=models.Index(
fields=["patient", "study_datetime"],
name="radiology_i_patient_a17d50_idx",
),
),
migrations.AddIndex(
model_name="imagingstudy",
index=models.Index(
fields=["modality", "study_datetime"],
name="radiology_i_modalit_2ac54f_idx",
),
),
migrations.AddIndex(
model_name="imagingstudy",
index=models.Index(
fields=["accession_number"], name="radiology_i_accessi_c8e131_idx"
),
),
migrations.AddIndex(
model_name="imagingstudy",
index=models.Index(
fields=["study_instance_uid"], name="radiology_i_study_i_dc0c38_idx"
),
),
migrations.AddIndex(
model_name="imagingstudy",
index=models.Index(
fields=["priority"], name="radiology_i_priorit_d47183_idx"
),
),
migrations.AddIndex(
model_name="imagingstudy",
index=models.Index(
fields=["radiologist"], name="radiology_i_radiolo_25d4fb_idx"
),
),
migrations.AddIndex(
model_name="imagingseries",
index=models.Index(
fields=["study", "series_number"], name="radiology_i_study_i_bd909c_idx"
),
),
migrations.AddIndex(
model_name="imagingseries",
index=models.Index(
fields=["series_instance_uid"], name="radiology_i_series__4593e0_idx"
),
),
migrations.AddIndex(
model_name="imagingseries",
index=models.Index(
fields=["modality"], name="radiology_i_modalit_cee22e_idx"
),
),
migrations.AddIndex(
model_name="imagingseries",
index=models.Index(
fields=["series_datetime"], name="radiology_i_series__059f84_idx"
),
),
migrations.AlterUniqueTogether(
name="imagingseries",
unique_together={("study", "series_number")},
),
migrations.AddIndex(
model_name="reporttemplate",
index=models.Index(
fields=["tenant", "is_active"], name="radiology_r_tenant__33f651_idx"
),
),
migrations.AddIndex(
model_name="reporttemplate",
index=models.Index(
fields=["modality", "body_part"], name="radiology_r_modalit_03374f_idx"
),
),
migrations.AddIndex(
model_name="reporttemplate",
index=models.Index(
fields=["is_default"], name="radiology_r_is_defa_6ba573_idx"
),
),
migrations.AlterUniqueTogether(
name="reporttemplate",
unique_together={("tenant", "name")},
),
migrations.AddIndex(
model_name="radiologyreport",
index=models.Index(fields=["study"], name="radiology_r_study_i_137be2_idx"),
),
migrations.AddIndex(
model_name="radiologyreport",
index=models.Index(
fields=["radiologist"], name="radiology_r_radiolo_5e2c07_idx"
),
),
migrations.AddIndex(
model_name="radiologyreport",
index=models.Index(fields=["status"], name="radiology_r_status_cb1ea4_idx"),
),
migrations.AddIndex(
model_name="radiologyreport",
index=models.Index(
fields=["critical_finding"], name="radiology_r_critica_894831_idx"
),
),
migrations.AddIndex(
model_name="radiologyreport",
index=models.Index(
fields=["finalized_datetime"], name="radiology_r_finaliz_edf9b3_idx"
),
),
]