# 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 = [ ("contenttypes", "0002_remove_content_type_name"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name="Tenant", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "tenant_id", models.UUIDField( default=uuid.uuid4, editable=False, help_text="Unique tenant identifier", unique=True, ), ), ( "name", models.CharField(help_text="Organization name", max_length=200), ), ( "display_name", models.CharField( help_text="Display name for the organization", max_length=200 ), ), ( "description", models.TextField( blank=True, help_text="Organization description", null=True ), ), ( "organization_type", models.CharField( choices=[ ("HOSPITAL", "Hospital"), ("CLINIC", "Clinic"), ("HEALTH_SYSTEM", "Health System"), ("AMBULATORY", "Ambulatory Care"), ("SPECIALTY", "Specialty Practice"), ("URGENT_CARE", "Urgent Care"), ("REHABILITATION", "Rehabilitation Center"), ("LONG_TERM_CARE", "Long-term Care"), ], default="HOSPITAL", max_length=50, ), ), ( "address_line1", models.CharField(help_text="Address line 1", max_length=200), ), ( "address_line2", models.CharField( blank=True, help_text="Address line 2", max_length=200, null=True, ), ), ("city", models.CharField(help_text="City", max_length=100)), ( "state", models.CharField(help_text="State or province", max_length=100), ), ( "postal_code", models.CharField(help_text="Postal code", max_length=20), ), ( "country", models.CharField( default="Saudi Arabia", help_text="Country", max_length=100 ), ), ( "phone_number", models.CharField( help_text="Primary phone number", max_length=20, validators=[ django.core.validators.RegexValidator( message='Phone number must be entered in the format: "+999999999". Up to 15 digits allowed.', regex="^\\+?1?\\d{9,15}$", ) ], ), ), ( "email", models.EmailField( help_text="Primary email address", max_length=254 ), ), ( "website", models.URLField( blank=True, help_text="Organization website", null=True ), ), ( "license_number", models.CharField( blank=True, help_text="Healthcare license number", max_length=100, null=True, ), ), ( "accreditation_body", models.CharField( blank=True, help_text="Accreditation body (e.g., Joint Commission)", max_length=100, null=True, ), ), ( "accreditation_number", models.CharField( blank=True, help_text="Accreditation number", max_length=100, null=True, ), ), ( "accreditation_expiry", models.DateField( blank=True, help_text="Accreditation expiry date", null=True ), ), ( "timezone", models.CharField( default="UTC", help_text="Organization timezone", max_length=50 ), ), ( "locale", models.CharField( default="en-US", help_text="Organization locale", max_length=10 ), ), ( "currency", models.CharField( default="SAR", help_text="Organization currency code", max_length=3, ), ), ( "subscription_plan", models.CharField( choices=[ ("BASIC", "Basic"), ("STANDARD", "Standard"), ("PREMIUM", "Premium"), ("ENTERPRISE", "Enterprise"), ], default="BASIC", max_length=50, ), ), ( "max_users", models.PositiveIntegerField( default=50, help_text="Maximum number of users allowed" ), ), ( "max_patients", models.PositiveIntegerField( default=1000, help_text="Maximum number of patients allowed" ), ), ( "is_active", models.BooleanField(default=True, help_text="Tenant is active"), ), ( "is_trial", models.BooleanField(default=False, help_text="Tenant is on trial"), ), ( "trial_expires_at", models.DateTimeField( blank=True, help_text="Trial expiration date", null=True ), ), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), ], options={ "verbose_name": "Tenant", "verbose_name_plural": "Tenants", "db_table": "core_tenant", "ordering": ["name"], }, ), migrations.CreateModel( name="SystemNotification", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "notification_id", models.UUIDField( default=uuid.uuid4, editable=False, help_text="Unique notification identifier", unique=True, ), ), ( "title", models.CharField(help_text="Notification title", max_length=200), ), ("message", models.TextField(help_text="Notification message")), ( "notification_type", models.CharField( choices=[ ("INFO", "Information"), ("WARNING", "Warning"), ("ERROR", "Error"), ("SUCCESS", "Success"), ("MAINTENANCE", "Maintenance"), ("SECURITY", "Security Alert"), ("FEATURE", "New Feature"), ("UPDATE", "System Update"), ], max_length=30, ), ), ( "priority", models.CharField( choices=[ ("LOW", "Low"), ("MEDIUM", "Medium"), ("HIGH", "High"), ("URGENT", "Urgent"), ], default="MEDIUM", max_length=20, ), ), ( "target_audience", models.CharField( choices=[ ("ALL_USERS", "All Users"), ("ADMINISTRATORS", "Administrators"), ("CLINICAL_STAFF", "Clinical Staff"), ("SUPPORT_STAFF", "Support Staff"), ("SPECIFIC_ROLES", "Specific Roles"), ("SPECIFIC_USERS", "Specific Users"), ], default="ALL_USERS", max_length=30, ), ), ( "target_roles", models.JSONField( default=list, help_text="Target user roles (if target_audience is SPECIFIC_ROLES)", ), ), ( "is_dismissible", models.BooleanField( default=True, help_text="Users can dismiss this notification" ), ), ( "auto_dismiss_after", models.PositiveIntegerField( blank=True, help_text="Auto-dismiss after X seconds", null=True ), ), ( "show_on_login", models.BooleanField( default=False, help_text="Show notification on user login" ), ), ( "start_date", models.DateTimeField( default=django.utils.timezone.now, help_text="Notification start date", ), ), ( "end_date", models.DateTimeField( blank=True, help_text="Notification end date", null=True ), ), ( "action_url", models.URLField( blank=True, help_text="Action URL for the notification", null=True, ), ), ( "action_text", models.CharField( blank=True, help_text="Action button text", max_length=100, null=True, ), ), ( "is_active", models.BooleanField( default=True, help_text="Notification is active" ), ), ("created_at", models.DateTimeField(auto_now_add=True)), ( "created_by", models.ForeignKey( null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="created_notifications", to=settings.AUTH_USER_MODEL, ), ), ( "target_users", models.ManyToManyField( blank=True, related_name="targeted_notifications", to=settings.AUTH_USER_MODEL, ), ), ( "tenant", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name="notifications", to="core.tenant", ), ), ], options={ "verbose_name": "System Notification", "verbose_name_plural": "System Notifications", "db_table": "core_system_notification", "ordering": ["-priority", "-created_at"], }, ), migrations.CreateModel( name="SystemConfiguration", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "key", models.CharField(help_text="Configuration key", max_length=200), ), ("value", models.TextField(help_text="Configuration value")), ( "data_type", models.CharField( choices=[ ("STRING", "String"), ("INTEGER", "Integer"), ("FLOAT", "Float"), ("BOOLEAN", "Boolean"), ("JSON", "JSON"), ("DATE", "Date"), ("DATETIME", "DateTime"), ], default="STRING", max_length=20, ), ), ( "category", models.CharField( help_text="Configuration category", max_length=100 ), ), ( "description", models.TextField( blank=True, help_text="Configuration description", null=True ), ), ( "validation_rules", models.JSONField( default=dict, help_text="Validation rules for the configuration value", ), ), ( "default_value", models.TextField(blank=True, help_text="Default value", null=True), ), ( "is_sensitive", models.BooleanField( default=False, help_text="Configuration contains sensitive data" ), ), ( "is_encrypted", models.BooleanField( default=False, help_text="Configuration value is encrypted" ), ), ( "required_permission", models.CharField( blank=True, help_text="Permission required to modify this configuration", max_length=100, null=True, ), ), ( "is_active", models.BooleanField( default=True, help_text="Configuration is active" ), ), ( "is_readonly", models.BooleanField( default=False, help_text="Configuration is read-only" ), ), ("created_at", models.DateTimeField(auto_now_add=True)), ("updated_at", models.DateTimeField(auto_now=True)), ( "updated_by", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="updated_configurations", to=settings.AUTH_USER_MODEL, ), ), ( "tenant", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name="configurations", to="core.tenant", ), ), ], options={ "verbose_name": "System Configuration", "verbose_name_plural": "System Configurations", "db_table": "core_system_configuration", "ordering": ["category", "key"], "unique_together": {("tenant", "key")}, }, ), migrations.CreateModel( name="IntegrationLog", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "log_id", models.UUIDField( default=uuid.uuid4, editable=False, help_text="Unique log identifier", unique=True, ), ), ( "integration_type", models.CharField( choices=[ ("HL7", "HL7 Message"), ("DICOM", "DICOM Communication"), ("API", "API Call"), ("DATABASE", "Database Sync"), ("FILE_TRANSFER", "File Transfer"), ("WEBHOOK", "Webhook"), ("EMAIL", "Email"), ("SMS", "SMS"), ], max_length=30, ), ), ( "direction", models.CharField( choices=[("INBOUND", "Inbound"), ("OUTBOUND", "Outbound")], max_length=10, ), ), ( "external_system", models.CharField(help_text="External system name", max_length=200), ), ( "endpoint", models.CharField( blank=True, help_text="Integration endpoint", max_length=500, null=True, ), ), ( "message_type", models.CharField( blank=True, help_text="Message type (e.g., HL7 message type)", max_length=100, null=True, ), ), ( "message_id", models.CharField( blank=True, help_text="Message identifier", max_length=200, null=True, ), ), ( "correlation_id", models.UUIDField( blank=True, help_text="Correlation ID for tracking related messages", null=True, ), ), ( "request_data", models.TextField( blank=True, help_text="Request data sent", null=True ), ), ( "response_data", models.TextField( blank=True, help_text="Response data received", null=True ), ), ( "status", models.CharField( choices=[ ("SUCCESS", "Success"), ("FAILED", "Failed"), ("PENDING", "Pending"), ("TIMEOUT", "Timeout"), ("RETRY", "Retry"), ], max_length=20, ), ), ( "error_code", models.CharField( blank=True, help_text="Error code", max_length=50, null=True ), ), ( "error_message", models.TextField(blank=True, help_text="Error message", null=True), ), ( "processing_time_ms", models.PositiveIntegerField( blank=True, help_text="Processing time in milliseconds", null=True, ), ), ( "timestamp", models.DateTimeField( default=django.utils.timezone.now, help_text="Log timestamp" ), ), ("created_at", models.DateTimeField(auto_now_add=True)), ( "tenant", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="integration_logs", to="core.tenant", ), ), ], options={ "verbose_name": "Integration Log", "verbose_name_plural": "Integration Logs", "db_table": "core_integration_log", "ordering": ["-timestamp"], "indexes": [ models.Index( fields=["tenant", "integration_type", "timestamp"], name="core_integr_tenant__b44419_idx", ), models.Index( fields=["external_system", "status"], name="core_integr_externa_11a6db_idx", ), models.Index( fields=["correlation_id"], name="core_integr_correla_d72107_idx" ), ], }, ), migrations.CreateModel( name="AuditLogEntry", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "log_id", models.UUIDField( default=uuid.uuid4, editable=False, help_text="Unique log identifier", unique=True, ), ), ( "event_type", models.CharField( choices=[ ("CREATE", "Create"), ("READ", "Read"), ("UPDATE", "Update"), ("DELETE", "Delete"), ("LOGIN", "Login"), ("LOGOUT", "Logout"), ("ACCESS", "Access"), ("EXPORT", "Export"), ("PRINT", "Print"), ("SHARE", "Share"), ("SYSTEM", "System Event"), ("ERROR", "Error"), ("SECURITY", "Security Event"), ], max_length=50, ), ), ( "event_category", models.CharField( choices=[ ("AUTHENTICATION", "Authentication"), ("AUTHORIZATION", "Authorization"), ("DATA_ACCESS", "Data Access"), ("DATA_MODIFICATION", "Data Modification"), ("SYSTEM_ADMINISTRATION", "System Administration"), ("PATIENT_DATA", "Patient Data"), ("CLINICAL_DATA", "Clinical Data"), ("FINANCIAL_DATA", "Financial Data"), ("SECURITY", "Security"), ("INTEGRATION", "Integration"), ("REPORTING", "Reporting"), ], max_length=50, ), ), ( "user_email", models.EmailField( blank=True, help_text="User email at time of event", max_length=254, null=True, ), ), ( "user_role", models.CharField( blank=True, help_text="User role at time of event", max_length=50, null=True, ), ), ( "session_key", models.CharField( blank=True, help_text="Session key", max_length=40, null=True ), ), ( "ip_address", models.GenericIPAddressField( blank=True, help_text="IP address", null=True ), ), ( "user_agent", models.TextField( blank=True, help_text="User agent string", null=True ), ), ("object_id", models.PositiveIntegerField(blank=True, null=True)), ( "object_repr", models.CharField( blank=True, help_text="String representation of the object", max_length=200, null=True, ), ), ( "action", models.CharField(help_text="Action performed", max_length=200), ), ( "description", models.TextField(help_text="Detailed description of the event"), ), ( "changes", models.JSONField( default=dict, help_text="Field changes (before/after values)" ), ), ( "additional_data", models.JSONField(default=dict, help_text="Additional event data"), ), ( "patient_id", models.CharField( blank=True, help_text="Patient identifier if applicable", max_length=50, null=True, ), ), ( "patient_mrn", models.CharField( blank=True, help_text="Patient MRN if applicable", max_length=50, null=True, ), ), ( "risk_level", models.CharField( choices=[ ("LOW", "Low"), ("MEDIUM", "Medium"), ("HIGH", "High"), ("CRITICAL", "Critical"), ], default="LOW", max_length=20, ), ), ( "hipaa_relevant", models.BooleanField( default=False, help_text="Event is HIPAA relevant" ), ), ( "gdpr_relevant", models.BooleanField( default=False, help_text="Event is GDPR relevant" ), ), ( "is_successful", models.BooleanField(default=True, help_text="Event was successful"), ), ( "error_message", models.TextField( blank=True, help_text="Error message if event failed", null=True ), ), ( "timestamp", models.DateTimeField( default=django.utils.timezone.now, help_text="Event timestamp" ), ), ("created_at", models.DateTimeField(auto_now_add=True)), ( "content_type", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to="contenttypes.contenttype", ), ), ( "user", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="audit_logs", to=settings.AUTH_USER_MODEL, ), ), ( "tenant", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="audit_logs", to="core.tenant", ), ), ], options={ "verbose_name": "Audit Log Entry", "verbose_name_plural": "Audit Log Entries", "db_table": "core_audit_log_entry", "ordering": ["-timestamp"], "indexes": [ models.Index( fields=["tenant", "event_type", "timestamp"], name="core_audit__tenant__96449c_idx", ), models.Index( fields=["user", "timestamp"], name="core_audit__user_id_4190d3_idx", ), models.Index( fields=["patient_mrn", "timestamp"], name="core_audit__patient_9afecd_idx", ), models.Index( fields=["content_type", "object_id"], name="core_audit__content_4866d0_idx", ), models.Index( fields=["risk_level", "timestamp"], name="core_audit__risk_le_b2cf34_idx", ), ], }, ), ]