Marwan Alwali 4d06ca4b5e update
2025-09-20 14:26:19 +03:00

1414 lines
54 KiB
Python

# Generated by Django 5.2.6 on 2025-09-19 10:58
import django.core.validators
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"),
("patients", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Encounter",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"encounter_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique encounter identifier",
unique=True,
),
),
(
"encounter_type",
models.CharField(
choices=[
("INPATIENT", "Inpatient"),
("OUTPATIENT", "Outpatient"),
("EMERGENCY", "Emergency"),
("URGENT_CARE", "Urgent Care"),
("OBSERVATION", "Observation"),
("TELEMEDICINE", "Telemedicine"),
("HOME_VISIT", "Home Visit"),
("CONSULTATION", "Consultation"),
("FOLLOW_UP", "Follow-up"),
("PROCEDURE", "Procedure"),
("SURGERY", "Surgery"),
("DIAGNOSTIC", "Diagnostic"),
("PREVENTIVE", "Preventive Care"),
],
help_text="Type of encounter",
max_length=30,
),
),
(
"encounter_class",
models.CharField(
choices=[
("AMB", "Ambulatory"),
("EMER", "Emergency"),
("FLD", "Field"),
("HH", "Home Health"),
("IMP", "Inpatient"),
("ACUTE", "Inpatient Acute"),
("NONAC", "Inpatient Non-Acute"),
("OBSENC", "Observation Encounter"),
("PRENC", "Pre-Admission"),
("SS", "Short Stay"),
("VR", "Virtual"),
],
help_text="Encounter class (HL7 standard)",
max_length=20,
),
),
(
"start_datetime",
models.DateTimeField(help_text="Encounter start date and time"),
),
(
"end_datetime",
models.DateTimeField(
blank=True, help_text="Encounter end date and time", null=True
),
),
(
"status",
models.CharField(
choices=[
("PLANNED", "Planned"),
("ARRIVED", "Arrived"),
("TRIAGED", "Triaged"),
("IN_PROGRESS", "In Progress"),
("ON_HOLD", "On Hold"),
("FINISHED", "Finished"),
("CANCELLED", "Cancelled"),
("ENTERED_IN_ERROR", "Entered in Error"),
("UNKNOWN", "Unknown"),
],
default="PLANNED",
help_text="Current encounter status",
max_length=20,
),
),
(
"location",
models.CharField(
blank=True,
help_text="Encounter location",
max_length=100,
null=True,
),
),
(
"room_number",
models.CharField(
blank=True, help_text="Room number", max_length=20, null=True
),
),
(
"chief_complaint",
models.TextField(
blank=True, help_text="Chief complaint", null=True
),
),
(
"reason_for_visit",
models.TextField(
blank=True, help_text="Reason for visit", null=True
),
),
(
"priority",
models.CharField(
choices=[
("ROUTINE", "Routine"),
("URGENT", "Urgent"),
("STAT", "STAT"),
("EMERGENCY", "Emergency"),
],
default="ROUTINE",
help_text="Encounter priority",
max_length=20,
),
),
(
"acuity_level",
models.PositiveIntegerField(
blank=True,
help_text="Patient acuity level (1-5, 5 being highest)",
null=True,
validators=[
django.core.validators.MinValueValidator(1),
django.core.validators.MaxValueValidator(5),
],
),
),
(
"documentation_complete",
models.BooleanField(
default=False, help_text="Documentation is complete"
),
),
(
"signed_off",
models.BooleanField(
default=False, help_text="Encounter has been signed off"
),
),
(
"signed_datetime",
models.DateTimeField(
blank=True, help_text="Date and time of sign-off", null=True
),
),
(
"billable",
models.BooleanField(
default=True, help_text="Encounter is billable"
),
),
(
"billing_codes",
models.JSONField(
blank=True, default=list, help_text="Associated billing codes"
),
),
(
"quality_measures",
models.JSONField(
blank=True, default=dict, help_text="Quality measure data"
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Encounter",
"verbose_name_plural": "Encounters",
"db_table": "emr_encounter",
"ordering": ["-start_datetime"],
},
),
migrations.CreateModel(
name="Icd10",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("code", models.CharField(db_index=True, max_length=10, unique=True)),
("description", models.TextField(blank=True, null=True)),
(
"chapter_name",
models.CharField(blank=True, max_length=255, null=True),
),
(
"section_name",
models.CharField(blank=True, max_length=255, null=True),
),
("is_header", models.BooleanField(default=False)),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "ICD-10 Code",
"verbose_name_plural": "ICD-10 Codes",
"db_table": "emr_icd10",
"ordering": ["code"],
},
),
migrations.CreateModel(
name="NoteTemplate",
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=200)),
(
"description",
models.TextField(
blank=True, help_text="Template description", null=True
),
),
(
"note_type",
models.CharField(
choices=[
("PROGRESS", "Progress Note"),
("ADMISSION", "Admission Note"),
("DISCHARGE", "Discharge Note"),
("CONSULTATION", "Consultation Note"),
("PROCEDURE", "Procedure Note"),
("OPERATIVE", "Operative Note"),
("NURSING", "Nursing Note"),
("THERAPY", "Therapy Note"),
("SOCIAL_WORK", "Social Work Note"),
("PSYCHOLOGY", "Psychology Note"),
("NUTRITION", "Nutrition Note"),
("PHARMACY", "Pharmacy Note"),
("CASE_MANAGEMENT", "Case Management Note"),
("EDUCATION", "Patient Education Note"),
("TELEPHONE", "Telephone Note"),
("OTHER", "Other"),
],
help_text="Type of note this template is for",
max_length=30,
),
),
(
"specialty",
models.CharField(
blank=True,
choices=[
("GENERAL_MEDICINE", "General Medicine"),
("SURGERY", "Surgery"),
("CARDIOLOGY", "Cardiology"),
("NEUROLOGY", "Neurology"),
("ONCOLOGY", "Oncology"),
("PEDIATRICS", "Pediatrics"),
("OBSTETRICS", "Obstetrics"),
("GYNECOLOGY", "Gynecology"),
("ORTHOPEDICS", "Orthopedics"),
("PSYCHIATRY", "Psychiatry"),
("EMERGENCY", "Emergency Medicine"),
("CRITICAL_CARE", "Critical Care"),
("REHABILITATION", "Rehabilitation"),
("NURSING", "Nursing"),
("THERAPY", "Therapy"),
("SOCIAL_WORK", "Social Work"),
("NUTRITION", "Nutrition"),
("PHARMACY", "Pharmacy"),
("OTHER", "Other"),
],
help_text="Medical specialty",
max_length=100,
null=True,
),
),
(
"template_content",
models.TextField(help_text="Template content with placeholders"),
),
(
"structured_fields",
models.JSONField(
default=list, help_text="Structured fields definition"
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Template is active and available for use",
),
),
(
"is_default",
models.BooleanField(
default=False, help_text="Default template for this note type"
),
),
(
"usage_count",
models.PositiveIntegerField(
default=0, help_text="Number of times template has been used"
),
),
(
"version",
models.CharField(
default="1.0", help_text="Template version", max_length=20
),
),
(
"quality_indicators",
models.JSONField(
default=list, help_text="Quality indicators to track"
),
),
(
"compliance_requirements",
models.JSONField(default=list, help_text="Compliance requirements"),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Note Template",
"verbose_name_plural": "Note Templates",
"db_table": "emr_note_template",
"ordering": ["note_type", "name"],
},
),
migrations.CreateModel(
name="ProblemList",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"problem_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique problem identifier",
unique=True,
),
),
(
"problem_name",
models.CharField(
help_text="Problem name or description", max_length=200
),
),
(
"problem_code",
models.CharField(
blank=True,
help_text="ICD-10 or SNOMED code",
max_length=20,
null=True,
),
),
(
"coding_system",
models.CharField(
blank=True,
choices=[
("ICD10", "ICD-10"),
("ICD9", "ICD-9"),
("SNOMED", "SNOMED CT"),
("CPT", "CPT"),
("LOINC", "LOINC"),
("OTHER", "Other"),
],
help_text="Coding system used",
max_length=20,
null=True,
),
),
(
"problem_type",
models.CharField(
choices=[
("DIAGNOSIS", "Diagnosis"),
("SYMPTOM", "Symptom"),
("FINDING", "Finding"),
("COMPLAINT", "Complaint"),
("CONDITION", "Condition"),
("DISORDER", "Disorder"),
("SYNDROME", "Syndrome"),
("INJURY", "Injury"),
("ALLERGY", "Allergy"),
("INTOLERANCE", "Intolerance"),
("RISK_FACTOR", "Risk Factor"),
("OTHER", "Other"),
],
help_text="Type of problem",
max_length=30,
),
),
(
"onset_date",
models.DateField(blank=True, help_text="Date of onset", null=True),
),
(
"onset_description",
models.CharField(
blank=True,
help_text="Description of onset",
max_length=100,
null=True,
),
),
(
"severity",
models.CharField(
blank=True,
choices=[
("MILD", "Mild"),
("MODERATE", "Moderate"),
("SEVERE", "Severe"),
("CRITICAL", "Critical"),
("UNKNOWN", "Unknown"),
],
help_text="Problem severity",
max_length=20,
null=True,
),
),
(
"priority",
models.CharField(
choices=[
("LOW", "Low"),
("MEDIUM", "Medium"),
("HIGH", "High"),
("URGENT", "Urgent"),
],
default="MEDIUM",
help_text="Problem priority",
max_length=20,
),
),
(
"status",
models.CharField(
choices=[
("ACTIVE", "Active"),
("INACTIVE", "Inactive"),
("RESOLVED", "Resolved"),
("REMISSION", "In Remission"),
("RECURRENCE", "Recurrence"),
("RELAPSE", "Relapse"),
("UNKNOWN", "Unknown"),
("OTHER", "Other"),
],
default="ACTIVE",
help_text="Current problem status",
max_length=20,
),
),
(
"resolution_date",
models.DateField(
blank=True, help_text="Date problem was resolved", null=True
),
),
(
"resolution_notes",
models.TextField(
blank=True,
help_text="Notes about problem resolution",
null=True,
),
),
(
"body_site",
models.CharField(
blank=True,
help_text="Body site affected",
max_length=100,
null=True,
),
),
(
"laterality",
models.CharField(
blank=True,
choices=[
("LEFT", "Left"),
("RIGHT", "Right"),
("BILATERAL", "Bilateral"),
("UNILATERAL", "Unilateral"),
("NOT_APPLICABLE", "Not Applicable"),
],
help_text="Laterality",
max_length=20,
null=True,
),
),
(
"clinical_notes",
models.TextField(
blank=True,
help_text="Clinical notes about the problem",
null=True,
),
),
(
"patient_concerns",
models.TextField(
blank=True, help_text="Patient concerns and comments", null=True
),
),
(
"treatment_goals",
models.JSONField(
blank=True,
default=list,
help_text="Treatment goals for this problem",
),
),
(
"outcome_measures",
models.JSONField(
blank=True,
default=list,
help_text="Outcome measures being tracked",
),
),
(
"verified",
models.BooleanField(
default=False, help_text="Problem has been verified"
),
),
(
"verified_date",
models.DateTimeField(
blank=True, help_text="Date problem was verified", null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Problem",
"verbose_name_plural": "Problem List",
"db_table": "emr_problem_list",
"ordering": ["-created_at"],
},
),
migrations.CreateModel(
name="VitalSigns",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"measurement_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique measurement identifier",
unique=True,
),
),
(
"measured_datetime",
models.DateTimeField(
default=django.utils.timezone.now,
help_text="Date and time of measurement",
),
),
(
"temperature",
models.DecimalField(
blank=True,
decimal_places=1,
help_text="Temperature in Celsius",
max_digits=4,
null=True,
),
),
(
"temperature_method",
models.CharField(
blank=True,
choices=[
("ORAL", "Oral"),
("RECTAL", "Rectal"),
("AXILLARY", "Axillary"),
("TYMPANIC", "Tympanic"),
("TEMPORAL", "Temporal"),
("CORE", "Core"),
],
help_text="Temperature measurement method",
max_length=20,
null=True,
),
),
(
"systolic_bp",
models.PositiveIntegerField(
blank=True,
help_text="Systolic blood pressure (mmHg)",
null=True,
validators=[
django.core.validators.MinValueValidator(50),
django.core.validators.MaxValueValidator(300),
],
),
),
(
"diastolic_bp",
models.PositiveIntegerField(
blank=True,
help_text="Diastolic blood pressure (mmHg)",
null=True,
validators=[
django.core.validators.MinValueValidator(30),
django.core.validators.MaxValueValidator(200),
],
),
),
(
"bp_position",
models.CharField(
blank=True,
choices=[
("SITTING", "Sitting"),
("STANDING", "Standing"),
("LYING", "Lying"),
("SUPINE", "Supine"),
],
help_text="Patient position during BP measurement",
max_length=20,
null=True,
),
),
(
"bp_cuff_size",
models.CharField(
blank=True,
choices=[
("SMALL", "Small"),
("REGULAR", "Regular"),
("LARGE", "Large"),
("EXTRA_LARGE", "Extra Large"),
("PEDIATRIC", "Pediatric"),
],
help_text="Blood pressure cuff size",
max_length=20,
null=True,
),
),
(
"heart_rate",
models.PositiveIntegerField(
blank=True,
help_text="Heart rate (beats per minute)",
null=True,
validators=[
django.core.validators.MinValueValidator(20),
django.core.validators.MaxValueValidator(300),
],
),
),
(
"heart_rhythm",
models.CharField(
blank=True,
choices=[
("REGULAR", "Regular"),
("REGULARLY_IRREGULAR", "Regularly irregular"),
("IRREGULARLY_IRREGULAR", "Irregularly irregular"),
("IRREGULAR_UNSPECIFIED", "Irregular (unspecified)"),
],
help_text="Heart rhythm",
max_length=25,
null=True,
),
),
(
"respiratory_rate",
models.PositiveIntegerField(
blank=True,
help_text="Respiratory rate (breaths per minute)",
null=True,
validators=[
django.core.validators.MinValueValidator(5),
django.core.validators.MaxValueValidator(60),
],
),
),
(
"oxygen_saturation",
models.PositiveIntegerField(
blank=True,
help_text="Oxygen saturation (%)",
null=True,
validators=[
django.core.validators.MinValueValidator(50),
django.core.validators.MaxValueValidator(100),
],
),
),
(
"oxygen_delivery",
models.CharField(
choices=[
("ROOM_AIR", "Room Air"),
("NASAL_CANNULA", "Nasal Cannula"),
("SIMPLE_MASK", "Simple Mask"),
("NON_REBREATHER", "Non-Rebreather Mask"),
("VENTURI_MASK", "Venturi Mask"),
("CPAP", "CPAP"),
("BIPAP", "BiPAP"),
("MECHANICAL_VENTILATION", "Mechanical Ventilation"),
("OTHER", "Other"),
],
default="ROOM_AIR",
help_text="Oxygen delivery method",
max_length=30,
),
),
(
"oxygen_flow_rate",
models.DecimalField(
blank=True,
decimal_places=1,
help_text="Oxygen flow rate (L/min)",
max_digits=4,
null=True,
),
),
(
"pain_scale",
models.PositiveIntegerField(
blank=True,
help_text="Pain scale (0-10)",
null=True,
validators=[
django.core.validators.MinValueValidator(0),
django.core.validators.MaxValueValidator(10),
],
),
),
(
"pain_location",
models.CharField(
blank=True, help_text="Pain location", max_length=100, null=True
),
),
(
"pain_quality",
models.CharField(
blank=True,
help_text="Pain quality description",
max_length=50,
null=True,
),
),
(
"weight",
models.DecimalField(
blank=True,
decimal_places=1,
help_text="Weight in pounds",
max_digits=5,
null=True,
),
),
(
"height",
models.DecimalField(
blank=True,
decimal_places=1,
help_text="Height in inches",
max_digits=5,
null=True,
),
),
(
"bmi",
models.DecimalField(
blank=True,
decimal_places=1,
help_text="Body Mass Index",
max_digits=4,
null=True,
),
),
(
"head_circumference",
models.DecimalField(
blank=True,
decimal_places=1,
help_text="Head circumference in cm (pediatric)",
max_digits=4,
null=True,
),
),
(
"device_used",
models.CharField(
blank=True,
help_text="Device used for measurements",
max_length=100,
null=True,
),
),
(
"device_calibrated",
models.BooleanField(
default=True, help_text="Device was calibrated"
),
),
(
"critical_values",
models.JSONField(
blank=True, default=list, help_text="Critical values identified"
),
),
(
"alerts_generated",
models.JSONField(
blank=True,
default=list,
help_text="Alerts generated from measurements",
),
),
(
"notes",
models.TextField(
blank=True,
help_text="Additional notes about measurements",
null=True,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Vital Signs",
"verbose_name_plural": "Vital Signs",
"db_table": "emr_vital_signs",
"ordering": ["-measured_datetime"],
},
),
migrations.CreateModel(
name="CarePlan",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"care_plan_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique care plan identifier",
unique=True,
),
),
(
"title",
models.CharField(help_text="Care plan title", max_length=200),
),
("description", models.TextField(help_text="Care plan description")),
(
"plan_type",
models.CharField(
choices=[
("COMPREHENSIVE", "Comprehensive Care Plan"),
("DISEASE_SPECIFIC", "Disease-Specific Plan"),
("PREVENTIVE", "Preventive Care Plan"),
("CHRONIC_CARE", "Chronic Care Management"),
("ACUTE_CARE", "Acute Care Plan"),
("DISCHARGE", "Discharge Planning"),
("REHABILITATION", "Rehabilitation Plan"),
("PALLIATIVE", "Palliative Care Plan"),
("MENTAL_HEALTH", "Mental Health Plan"),
("MEDICATION", "Medication Management"),
("NUTRITION", "Nutrition Plan"),
("EXERCISE", "Exercise Plan"),
("OTHER", "Other"),
],
help_text="Type of care plan",
max_length=30,
),
),
(
"category",
models.CharField(
choices=[
("ASSESSMENT", "Assessment and Monitoring"),
("TREATMENT", "Treatment"),
("EDUCATION", "Patient Education"),
("COORDINATION", "Care Coordination"),
("PREVENTION", "Prevention"),
("LIFESTYLE", "Lifestyle Modification"),
("MEDICATION", "Medication Management"),
("FOLLOW_UP", "Follow-up Care"),
("EMERGENCY", "Emergency Planning"),
("SUPPORT", "Support Services"),
],
help_text="Care plan category",
max_length=50,
),
),
("start_date", models.DateField(help_text="Care plan start date")),
(
"end_date",
models.DateField(
blank=True, help_text="Care plan end date", null=True
),
),
(
"target_completion_date",
models.DateField(
blank=True, help_text="Target completion date", null=True
),
),
(
"status",
models.CharField(
choices=[
("DRAFT", "Draft"),
("ACTIVE", "Active"),
("ON_HOLD", "On Hold"),
("COMPLETED", "Completed"),
("CANCELLED", "Cancelled"),
("ENTERED_IN_ERROR", "Entered in Error"),
("UNKNOWN", "Unknown"),
],
default="DRAFT",
help_text="Care plan status",
max_length=20,
),
),
(
"priority",
models.CharField(
choices=[
("LOW", "Low"),
("ROUTINE", "Routine"),
("URGENT", "Urgent"),
("STAT", "STAT"),
],
default="ROUTINE",
help_text="Care plan priority",
max_length=20,
),
),
("goals", models.JSONField(default=list, help_text="Care plan goals")),
(
"objectives",
models.JSONField(
default=list, help_text="Specific objectives and targets"
),
),
(
"interventions",
models.JSONField(default=list, help_text="Planned interventions"),
),
(
"activities",
models.JSONField(
default=list, help_text="Specific activities and tasks"
),
),
(
"monitoring_parameters",
models.JSONField(default=list, help_text="Parameters to monitor"),
),
(
"evaluation_criteria",
models.JSONField(
default=list, help_text="Criteria for evaluating progress"
),
),
(
"patient_goals",
models.TextField(
blank=True, help_text="Patient-identified goals", null=True
),
),
(
"patient_preferences",
models.TextField(
blank=True,
help_text="Patient preferences and concerns",
null=True,
),
),
(
"patient_barriers",
models.TextField(
blank=True, help_text="Identified barriers to care", null=True
),
),
(
"resources_needed",
models.JSONField(
default=list,
help_text="Resources needed for plan implementation",
),
),
(
"support_systems",
models.JSONField(
default=list, help_text="Available support systems"
),
),
(
"progress_notes",
models.TextField(blank=True, help_text="Progress notes", null=True),
),
(
"last_reviewed",
models.DateField(
blank=True, help_text="Date of last review", null=True
),
),
(
"next_review_date",
models.DateField(
blank=True, help_text="Next scheduled review date", null=True
),
),
(
"outcomes_achieved",
models.JSONField(default=list, help_text="Outcomes achieved"),
),
(
"completion_percentage",
models.PositiveIntegerField(
default=0,
help_text="Completion percentage",
validators=[
django.core.validators.MinValueValidator(0),
django.core.validators.MaxValueValidator(100),
],
),
),
(
"approved",
models.BooleanField(
default=False, help_text="Care plan has been approved"
),
),
(
"approved_date",
models.DateTimeField(
blank=True, help_text="Date of approval", null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"approved_by",
models.ForeignKey(
blank=True,
help_text="Provider who approved the plan",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="approved_care_plans",
to=settings.AUTH_USER_MODEL,
),
),
(
"care_team",
models.ManyToManyField(
blank=True,
help_text="Care team members",
related_name="care_team_plans",
to=settings.AUTH_USER_MODEL,
),
),
(
"created_by",
models.ForeignKey(
blank=True,
help_text="User who created the care plan",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="created_care_plans",
to=settings.AUTH_USER_MODEL,
),
),
(
"patient",
models.ForeignKey(
help_text="Patient",
on_delete=django.db.models.deletion.CASCADE,
related_name="care_plans",
to="patients.patientprofile",
),
),
(
"primary_provider",
models.ForeignKey(
help_text="Primary provider responsible for care plan",
on_delete=django.db.models.deletion.CASCADE,
related_name="primary_care_plans",
to=settings.AUTH_USER_MODEL,
),
),
(
"tenant",
models.ForeignKey(
help_text="Organization tenant",
on_delete=django.db.models.deletion.CASCADE,
related_name="care_plans",
to="core.tenant",
),
),
],
options={
"verbose_name": "Care Plan",
"verbose_name_plural": "Care Plans",
"db_table": "emr_care_plan",
"ordering": ["-created_at"],
},
),
migrations.CreateModel(
name="ClinicalNote",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"note_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique note identifier",
unique=True,
),
),
(
"note_type",
models.CharField(
choices=[
("PROGRESS", "Progress"),
("ADMISSION", "Admission Note"),
("DISCHARGE", "Discharge Note"),
("CONSULTATION", "Consultation Note"),
("PROCEDURE", "Procedure Note"),
("OPERATIVE", "Operative Note"),
("NURSING", "Nursing Note"),
("THERAPY", "Therapy Note"),
("SOCIAL_WORK", "Social Work Note"),
("PSYCHOLOGY", "Psychology Note"),
("NUTRITION", "Nutrition Note"),
("PHARMACY", "Pharmacy Note"),
("CASE_MANAGEMENT", "Case Management Note"),
("EDUCATION", "Patient Education Note"),
("TELEPHONE", "Telephone Note"),
("ADDENDUM", "Addendum"),
("CORRECTION", "Correction"),
("OTHER", "Other"),
],
help_text="Type of clinical note",
max_length=30,
),
),
("title", models.CharField(help_text="Note title", max_length=200)),
("content", models.TextField(help_text="Note content")),
(
"structured_data",
models.JSONField(
blank=True,
default=dict,
help_text="Structured data from template",
),
),
(
"status",
models.CharField(
choices=[
("DRAFT", "Draft"),
("IN_PROGRESS", "In Progress"),
("COMPLETED", "Completed"),
("SIGNED", "Signed"),
("AMENDED", "Amended"),
("CORRECTED", "Corrected"),
("CANCELLED", "Cancelled"),
("ERROR", "Entered in Error"),
("UNKNOWN", "Unknown"),
],
default="DRAFT",
help_text="Note status",
max_length=20,
),
),
(
"electronically_signed",
models.BooleanField(
default=False, help_text="Note has been electronically signed"
),
),
(
"signed_datetime",
models.DateTimeField(
blank=True, help_text="Date and time of signature", null=True
),
),
(
"signature_method",
models.CharField(
blank=True,
choices=[
("ELECTRONIC", "Electronic"),
("DIGITAL", "Digital Signature"),
("BIOMETRIC", "Biometric Signature"),
("PASSWORD", "Password"),
("TOKEN", "Token Authentication"),
("OTHER", "Other"),
],
help_text="Method of signature",
max_length=20,
null=True,
),
),
(
"amendment_reason",
models.TextField(
blank=True, help_text="Reason for amendment", null=True
),
),
(
"quality_score",
models.PositiveIntegerField(
blank=True,
help_text="Documentation quality score",
null=True,
validators=[
django.core.validators.MinValueValidator(0),
django.core.validators.MaxValueValidator(100),
],
),
),
(
"compliance_flags",
models.JSONField(
blank=True,
default=list,
help_text="Compliance flags and issues",
),
),
(
"note_datetime",
models.DateTimeField(
default=django.utils.timezone.now,
help_text="Date and time note was written",
),
),
(
"confidential",
models.BooleanField(
default=False,
help_text="Note contains confidential information",
),
),
(
"restricted_access",
models.BooleanField(
default=False, help_text="Access to note is restricted"
),
),
(
"access_restrictions",
models.JSONField(
blank=True,
default=list,
help_text="Specific access restrictions",
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"amended_note",
models.ForeignKey(
blank=True,
help_text="Original note if this is an amendment",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="amendments",
to="emr.clinicalnote",
),
),
(
"author",
models.ForeignKey(
help_text="Note author",
on_delete=django.db.models.deletion.CASCADE,
related_name="authored_notes",
to=settings.AUTH_USER_MODEL,
),
),
(
"co_signers",
models.ManyToManyField(
blank=True,
help_text="Co-signers for this note",
related_name="co_signed_notes",
to=settings.AUTH_USER_MODEL,
),
),
(
"patient",
models.ForeignKey(
help_text="Patient",
on_delete=django.db.models.deletion.CASCADE,
related_name="clinical_notes",
to="patients.patientprofile",
),
),
(
"related_care_plans",
models.ManyToManyField(
blank=True,
help_text="Related care plans",
related_name="clinical_notes",
to="emr.careplan",
),
),
],
options={
"verbose_name": "Clinical Note",
"verbose_name_plural": "Clinical Notes",
"db_table": "emr_clinical_note",
"ordering": ["-note_datetime"],
},
),
]