All checks were successful
Build and Push Docker Image / build (push) Successful in 1m5s
165 lines
12 KiB
Python
165 lines
12 KiB
Python
# Generated by Django 6.0.1 on 2026-05-11 20:32
|
|
|
|
import django.core.validators
|
|
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 = [
|
|
('organizations', '0001_initial'),
|
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
]
|
|
|
|
operations = [
|
|
migrations.CreateModel(
|
|
name='ActivityType',
|
|
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)),
|
|
('name_ar', models.CharField(blank=True, max_length=200, verbose_name='Name (Arabic)')),
|
|
('description', models.TextField(blank=True)),
|
|
('is_active', models.BooleanField(db_index=True, default=True)),
|
|
],
|
|
options={
|
|
'verbose_name': 'Activity Type',
|
|
'verbose_name_plural': 'Activity Types',
|
|
'ordering': ['name'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='StandardCategory',
|
|
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=100)),
|
|
('name_ar', models.CharField(blank=True, max_length=100, verbose_name='Name (Arabic)')),
|
|
('description', models.TextField(blank=True)),
|
|
('order', models.PositiveIntegerField(default=0, help_text='Display order')),
|
|
('is_active', models.BooleanField(db_index=True, default=True)),
|
|
('max_score', models.DecimalField(decimal_places=2, default=0, help_text='Maximum possible score for this category (MOH)', max_digits=8)),
|
|
],
|
|
options={
|
|
'verbose_name': 'Standard Category',
|
|
'verbose_name_plural': 'Standard Categories',
|
|
'ordering': ['order', 'name'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='StandardSource',
|
|
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=100)),
|
|
('name_ar', models.CharField(blank=True, max_length=100, verbose_name='Name (Arabic)')),
|
|
('code', models.CharField(max_length=50, unique=True)),
|
|
('description', models.TextField(blank=True)),
|
|
('website', models.URLField(blank=True)),
|
|
('is_active', models.BooleanField(db_index=True, default=True)),
|
|
],
|
|
options={
|
|
'verbose_name': 'Standard Source',
|
|
'verbose_name_plural': 'Standard Sources',
|
|
'ordering': ['name'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='Standard',
|
|
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)),
|
|
('code', models.CharField(db_index=True, help_text='e.g., CBAHI-PS-01, 22.1, 1.1', max_length=50)),
|
|
('title', models.CharField(max_length=500)),
|
|
('title_ar', models.CharField(blank=True, max_length=500, verbose_name='Title (Arabic)')),
|
|
('description', models.TextField(blank=True, help_text='Full description of the standard')),
|
|
('assessment_method', models.CharField(blank=True, choices=[('document_review', 'Document Review'), ('staff_interview', 'Staff Interview'), ('observation', 'Observation'), ('evidence', 'Evidence'), ('quality_committee', 'Quality Committee'), ('multiple', 'Multiple Methods')], help_text='How compliance is assessed', max_length=30)),
|
|
('assessment_method_ar', models.CharField(blank=True, help_text='Arabic assessment method text from source file', max_length=200)),
|
|
('order_within_category', models.PositiveIntegerField(default=0, help_text='Display order within category')),
|
|
('effective_date', models.DateField(blank=True, help_text='When standard becomes effective', null=True)),
|
|
('review_date', models.DateField(blank=True, help_text='Next review date', null=True)),
|
|
('is_active', models.BooleanField(db_index=True, default=True)),
|
|
('is_heading', models.BooleanField(default=False, help_text="True for section headers (e.g. 'القيادة رقم 22: ...')")),
|
|
('is_assessable', models.BooleanField(default=True, help_text='If False, this standard is informational only (no assessment required). Headings are always non-assessable.')),
|
|
('activity_type', models.ForeignKey(blank=True, help_text='Activity type for this standard', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='standards', to='standards.activitytype')),
|
|
('departments', models.ManyToManyField(blank=True, help_text='Select departments this standard applies to (empty = applies to all)', related_name='standards', to='organizations.department')),
|
|
('parent_standard', models.ForeignKey(blank=True, help_text='Parent standard for sub-items like 4.3.1 under 4.3', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sub_standards', to='standards.standard')),
|
|
('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='standards', to='standards.standardcategory')),
|
|
('source', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='standards', to='standards.standardsource')),
|
|
],
|
|
options={
|
|
'verbose_name': 'Standard',
|
|
'verbose_name_plural': 'Standards',
|
|
'ordering': ['source', 'category', 'order_within_category', 'code'],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='StandardCompliance',
|
|
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)),
|
|
('status', models.CharField(choices=[('not_assessed', 'Not Assessed'), ('met', 'Met'), ('partially_met', 'Partially Met'), ('not_met', 'Not Met'), ('not_applicable', 'Not Applicable')], db_index=True, default='not_assessed', max_length=20)),
|
|
('status_ar', models.CharField(blank=True, help_text='Original Arabic status text from source', max_length=50)),
|
|
('last_assessed_date', models.DateField(blank=True, help_text='Date of last assessment', null=True)),
|
|
('notes', models.TextField(blank=True, help_text='Assessment notes')),
|
|
('recommendations', models.TextField(blank=True, help_text='Recommendations / strengths / findings')),
|
|
('evidence_summary', models.TextField(blank=True, help_text='Summary of evidence')),
|
|
('target_status', models.CharField(blank=True, choices=[('not_assessed', 'Not Assessed'), ('met', 'Met'), ('partially_met', 'Partially Met'), ('not_met', 'Not Met'), ('not_applicable', 'Not Applicable')], default='', help_text='Target compliance status', max_length=20)),
|
|
('corrective_action', models.TextField(blank=True, help_text='Corrective action plan')),
|
|
('priority', models.CharField(blank=True, choices=[('high', 'High'), ('medium', 'Medium'), ('low', 'Low')], default='', max_length=10)),
|
|
('target_date', models.CharField(blank=True, default='', help_text='Target completion date (text, from source)', max_length=100)),
|
|
('target_date_actual', models.DateField(blank=True, help_text='Parsed target date', null=True)),
|
|
('score', models.DecimalField(blank=True, decimal_places=2, help_text='Score achieved', max_digits=8, null=True)),
|
|
('max_score', models.DecimalField(blank=True, decimal_places=2, help_text='Maximum possible score', max_digits=8, null=True)),
|
|
('assessment_code', models.CharField(blank=True, choices=[('TM', 'Fully Met'), ('TM2', 'Met (Level 2)'), ('TM3', 'Met (Level 3)'), ('PM', 'Partially Met'), ('PM2', 'Partially Met (Level 2)'), ('PM3', 'Partially Met (Level 3)'), ('NM', 'Not Met'), ('NM2', 'Not Met (Level 2)'), ('NM3', 'Not Met (Level 3)')], default='', help_text='TM/PM/NM assessment code', max_length=5)),
|
|
('assessment_code_target', models.CharField(blank=True, default='', help_text='Target assessment code (col D in MOH framework)', max_length=5)),
|
|
('supporting_documents', models.TextField(blank=True, help_text='Supporting document references')),
|
|
('action_note', models.TextField(blank=True, help_text='Action notes / improvement suggestions')),
|
|
('assessor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assessments', to=settings.AUTH_USER_MODEL)),
|
|
('department', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='compliance_records', to='organizations.department')),
|
|
('hospital', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='standard_compliance_records', to='organizations.hospital')),
|
|
('standard', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='compliance_records', to='standards.standard')),
|
|
],
|
|
options={
|
|
'verbose_name': 'Standard Compliance',
|
|
'verbose_name_plural': 'Standard Compliance',
|
|
'ordering': ['-created_at'],
|
|
'unique_together': {('hospital', 'standard')},
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name='StandardAttachment',
|
|
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='standards/attachments/%Y/%m/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf', 'doc', 'docx', 'xls', 'xlsx', 'jpg', 'jpeg', 'png', 'zip'])])),
|
|
('filename', models.CharField(help_text='Original filename', max_length=255)),
|
|
('description', models.TextField(blank=True, help_text='Attachment description')),
|
|
('standard', models.ForeignKey(blank=True, help_text='Direct evidence attached to the standard itself', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='direct_attachments', to='standards.standard')),
|
|
('uploaded_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='uploaded_standards_attachments', to=settings.AUTH_USER_MODEL)),
|
|
('compliance', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='standards.standardcompliance')),
|
|
],
|
|
options={
|
|
'verbose_name': 'Standard Attachment',
|
|
'verbose_name_plural': 'Standard Attachments',
|
|
'ordering': ['-created_at'],
|
|
},
|
|
),
|
|
migrations.AddField(
|
|
model_name='standardcategory',
|
|
name='source',
|
|
field=models.ForeignKey(blank=True, help_text='Which source this category belongs to', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='categories', to='standards.standardsource'),
|
|
),
|
|
]
|