164 lines
12 KiB
Python
164 lines
12 KiB
Python
# Generated by Django 6.0 on 2026-01-12 09:50
|
|
|
|
import django.db.models.deletion
|
|
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'),
|
|
('organizations', '0001_initial'),
|
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
]
|
|
|
|
operations = [
|
|
migrations.CreateModel(
|
|
name='PXAction',
|
|
fields=[
|
|
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
('source_type', models.CharField(choices=[('survey', 'Negative Survey'), ('complaint', 'Complaint'), ('complaint_resolution', 'Negative Complaint Resolution'), ('social_media', 'Social Media'), ('call_center', 'Call Center'), ('kpi', 'KPI Decline'), ('manual', 'Manual')], db_index=True, max_length=50)),
|
|
('object_id', models.UUIDField(blank=True, null=True)),
|
|
('title', models.CharField(max_length=500)),
|
|
('description', models.TextField()),
|
|
('category', models.CharField(choices=[('clinical_quality', 'Clinical Quality'), ('patient_safety', 'Patient Safety'), ('service_quality', 'Service Quality'), ('staff_behavior', 'Staff Behavior'), ('facility', 'Facility & Environment'), ('process_improvement', 'Process Improvement'), ('other', 'Other')], db_index=True, max_length=100)),
|
|
('priority', models.CharField(choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High'), ('critical', 'Critical')], db_index=True, default='medium', max_length=20)),
|
|
('severity', models.CharField(choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High'), ('critical', 'Critical')], db_index=True, default='medium', max_length=20)),
|
|
('status', models.CharField(choices=[('open', 'Open'), ('in_progress', 'In Progress'), ('pending_approval', 'Pending Approval'), ('approved', 'Approved'), ('closed', 'Closed'), ('cancelled', 'Cancelled')], db_index=True, default='open', max_length=20)),
|
|
('assigned_at', models.DateTimeField(blank=True, null=True)),
|
|
('due_at', models.DateTimeField(db_index=True, help_text='SLA deadline')),
|
|
('is_overdue', models.BooleanField(db_index=True, default=False)),
|
|
('reminder_sent_at', models.DateTimeField(blank=True, null=True)),
|
|
('escalated_at', models.DateTimeField(blank=True, null=True)),
|
|
('escalation_level', models.IntegerField(default=0, help_text='Number of times escalated')),
|
|
('requires_approval', models.BooleanField(default=True, help_text='Requires PX Admin approval before closure')),
|
|
('approved_at', models.DateTimeField(blank=True, null=True)),
|
|
('closed_at', models.DateTimeField(blank=True, null=True)),
|
|
('action_plan', models.TextField(blank=True)),
|
|
('outcome', models.TextField(blank=True)),
|
|
('metadata', models.JSONField(blank=True, default=dict)),
|
|
('approved_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='approved_actions', to=settings.AUTH_USER_MODEL)),
|
|
('assigned_to', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assigned_actions', to=settings.AUTH_USER_MODEL)),
|
|
('closed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='closed_actions', to=settings.AUTH_USER_MODEL)),
|
|
('content_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
|
|
('department', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='px_actions', to='organizations.department')),
|
|
('hospital', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='px_actions', to='organizations.hospital')),
|
|
],
|
|
options={
|
|
'ordering': ['-created_at'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='PXActionAttachment',
|
|
fields=[
|
|
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
('file', models.FileField(upload_to='actions/%Y/%m/%d/')),
|
|
('filename', models.CharField(max_length=500)),
|
|
('file_type', models.CharField(blank=True, max_length=100)),
|
|
('file_size', models.IntegerField(help_text='File size in bytes')),
|
|
('description', models.TextField(blank=True)),
|
|
('is_evidence', models.BooleanField(default=False, help_text='Mark as evidence for closure')),
|
|
('action', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='px_action_center.pxaction')),
|
|
('uploaded_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='action_attachments', to=settings.AUTH_USER_MODEL)),
|
|
],
|
|
options={
|
|
'ordering': ['-created_at'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='PXActionLog',
|
|
fields=[
|
|
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
('log_type', models.CharField(choices=[('status_change', 'Status Change'), ('assignment', 'Assignment'), ('escalation', 'Escalation'), ('note', 'Note'), ('evidence', 'Evidence Added'), ('approval', 'Approval'), ('sla_reminder', 'SLA Reminder')], db_index=True, max_length=50)),
|
|
('message', models.TextField()),
|
|
('old_status', models.CharField(blank=True, max_length=20)),
|
|
('new_status', models.CharField(blank=True, max_length=20)),
|
|
('metadata', models.JSONField(blank=True, default=dict)),
|
|
('action', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='logs', to='px_action_center.pxaction')),
|
|
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='action_logs', to=settings.AUTH_USER_MODEL)),
|
|
],
|
|
options={
|
|
'ordering': ['-created_at'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='PXActionSLAConfig',
|
|
fields=[
|
|
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
('name', models.CharField(max_length=200)),
|
|
('critical_hours', models.IntegerField(default=24)),
|
|
('high_hours', models.IntegerField(default=48)),
|
|
('medium_hours', models.IntegerField(default=72)),
|
|
('low_hours', models.IntegerField(default=120)),
|
|
('reminder_hours_before', models.IntegerField(default=4, help_text='Send reminder X hours before due')),
|
|
('auto_escalate', models.BooleanField(default=True, help_text='Automatically escalate when overdue')),
|
|
('escalation_delay_hours', models.IntegerField(default=2, help_text='Hours after overdue before escalation')),
|
|
('is_active', models.BooleanField(default=True)),
|
|
('department', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='action_sla_configs', to='organizations.department')),
|
|
('hospital', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='action_sla_configs', to='organizations.hospital')),
|
|
],
|
|
options={
|
|
'ordering': ['hospital', 'name'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='RoutingRule',
|
|
fields=[
|
|
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
|
('updated_at', models.DateTimeField(auto_now=True)),
|
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
('name', models.CharField(max_length=200)),
|
|
('description', models.TextField(blank=True)),
|
|
('source_type', models.CharField(blank=True, choices=[('survey', 'Negative Survey'), ('complaint', 'Complaint'), ('complaint_resolution', 'Negative Complaint Resolution'), ('social_media', 'Social Media'), ('call_center', 'Call Center'), ('kpi', 'KPI Decline'), ('manual', 'Manual')], max_length=50)),
|
|
('category', models.CharField(blank=True, max_length=100)),
|
|
('severity', models.CharField(blank=True, choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High'), ('critical', 'Critical')], max_length=20)),
|
|
('assign_to_role', models.CharField(blank=True, help_text="Role to assign to (e.g., 'PX Coordinator')", max_length=50)),
|
|
('priority', models.IntegerField(default=0, help_text='Higher priority rules are evaluated first')),
|
|
('is_active', models.BooleanField(default=True)),
|
|
('assign_to_department', models.ForeignKey(blank=True, help_text='Department to assign to', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='routing_target_rules', to='organizations.department')),
|
|
('assign_to_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='routing_rules', to=settings.AUTH_USER_MODEL)),
|
|
('department', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='routing_rules', to='organizations.department')),
|
|
('hospital', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='routing_rules', to='organizations.hospital')),
|
|
],
|
|
options={
|
|
'ordering': ['-priority', 'name'],
|
|
},
|
|
),
|
|
migrations.AddIndex(
|
|
model_name='pxaction',
|
|
index=models.Index(fields=['status', '-created_at'], name='px_action_c_status_3bd857_idx'),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name='pxaction',
|
|
index=models.Index(fields=['hospital', 'status', '-created_at'], name='px_action_c_hospita_6b2d44_idx'),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name='pxaction',
|
|
index=models.Index(fields=['is_overdue', 'status'], name='px_action_c_is_over_e0d12c_idx'),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name='pxaction',
|
|
index=models.Index(fields=['due_at', 'status'], name='px_action_c_due_at_947f38_idx'),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name='pxaction',
|
|
index=models.Index(fields=['source_type', '-created_at'], name='px_action_c_source__3f0ae5_idx'),
|
|
),
|
|
migrations.AddIndex(
|
|
model_name='pxactionlog',
|
|
index=models.Index(fields=['action', '-created_at'], name='px_action_c_action__656e57_idx'),
|
|
),
|
|
]
|