# Generated by Django 4.2.8 on 2025-11-08 17:40 from django.conf import settings from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import django_fsm import django_lifecycle.mixins import model_utils.fields import uuid class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("contenttypes", "0002_remove_content_type_name"), ] operations = [ migrations.CreateModel( name="ContentSubmission", fields=[ ( "created", model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name="created", ), ), ( "modified", model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name="modified", ), ), ( "id", models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( "status", django_fsm.FSMField( choices=[ ("draft", "Draft"), ("pending", "Pending Review"), ("reviewing", "Under Review"), ("approved", "Approved"), ("rejected", "Rejected"), ], db_index=True, default="draft", help_text="Current submission state (managed by FSM)", max_length=20, protected=True, ), ), ( "entity_id", models.UUIDField(help_text="ID of the entity being modified"), ), ( "submission_type", models.CharField( choices=[ ("create", "Create"), ("update", "Update"), ("delete", "Delete"), ], db_index=True, help_text="Type of operation (create, update, delete)", max_length=20, ), ), ( "title", models.CharField( help_text="Brief description of changes", max_length=255 ), ), ( "description", models.TextField( blank=True, help_text="Detailed description of changes" ), ), ( "locked_at", models.DateTimeField( blank=True, help_text="When the submission was locked for review", null=True, ), ), ( "reviewed_at", models.DateTimeField( blank=True, help_text="When the submission was reviewed", null=True, ), ), ( "rejection_reason", models.TextField( blank=True, help_text="Reason for rejection (if rejected)" ), ), ( "source", models.CharField( default="web", help_text="Source of submission (web, api, mobile, etc.)", max_length=50, ), ), ( "ip_address", models.GenericIPAddressField( blank=True, help_text="IP address of submitter", null=True ), ), ( "user_agent", models.CharField( blank=True, help_text="User agent of submitter", max_length=500 ), ), ( "metadata", models.JSONField( blank=True, default=dict, help_text="Additional submission metadata", ), ), ( "entity_type", models.ForeignKey( help_text="Type of entity being modified", on_delete=django.db.models.deletion.CASCADE, to="contenttypes.contenttype", ), ), ( "locked_by", models.ForeignKey( blank=True, help_text="Moderator currently reviewing this submission", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="locked_submissions", to=settings.AUTH_USER_MODEL, ), ), ( "reviewed_by", models.ForeignKey( blank=True, help_text="Moderator who reviewed this submission", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="reviewed_submissions", to=settings.AUTH_USER_MODEL, ), ), ( "user", models.ForeignKey( help_text="User who submitted the changes", on_delete=django.db.models.deletion.CASCADE, related_name="submissions", to=settings.AUTH_USER_MODEL, ), ), ], options={ "verbose_name": "Content Submission", "verbose_name_plural": "Content Submissions", "db_table": "content_submissions", "ordering": ["-created"], }, bases=(django_lifecycle.mixins.LifecycleModelMixin, models.Model), ), migrations.CreateModel( name="SubmissionItem", fields=[ ( "created", model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name="created", ), ), ( "modified", model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name="modified", ), ), ( "id", models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( "field_name", models.CharField( help_text="Name of the field being changed", max_length=100 ), ), ( "field_label", models.CharField( blank=True, help_text="Human-readable field label", max_length=200, ), ), ( "old_value", models.JSONField( blank=True, help_text="Previous value (null for new fields)", null=True, ), ), ( "new_value", models.JSONField( blank=True, help_text="New value (null for deletions)", null=True, ), ), ( "status", models.CharField( choices=[ ("pending", "Pending"), ("approved", "Approved"), ("rejected", "Rejected"), ], db_index=True, default="pending", help_text="Status of this individual item", max_length=20, ), ), ( "reviewed_at", models.DateTimeField( blank=True, help_text="When this item was reviewed", null=True ), ), ( "rejection_reason", models.TextField( blank=True, help_text="Reason for rejecting this specific item" ), ), ( "change_type", models.CharField( choices=[ ("add", "Add"), ("modify", "Modify"), ("remove", "Remove"), ], default="modify", help_text="Type of change", max_length=20, ), ), ( "is_required", models.BooleanField( default=False, help_text="Whether this change is required for the submission", ), ), ( "order", models.IntegerField( default=0, help_text="Display order within submission" ), ), ( "reviewed_by", models.ForeignKey( blank=True, help_text="Moderator who reviewed this item", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="reviewed_items", to=settings.AUTH_USER_MODEL, ), ), ( "submission", models.ForeignKey( help_text="Parent submission", on_delete=django.db.models.deletion.CASCADE, related_name="items", to="moderation.contentsubmission", ), ), ], options={ "verbose_name": "Submission Item", "verbose_name_plural": "Submission Items", "db_table": "submission_items", "ordering": ["submission", "order", "created"], "indexes": [ models.Index( fields=["submission", "status"], name="submission__submiss_71cf2f_idx", ), models.Index( fields=["status"], name="submission__status_61deb1_idx" ), ], }, bases=(django_lifecycle.mixins.LifecycleModelMixin, models.Model), ), migrations.CreateModel( name="ModerationLock", fields=[ ( "created", model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name="created", ), ), ( "modified", model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name="modified", ), ), ( "id", models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( "locked_at", models.DateTimeField( auto_now_add=True, help_text="When the lock was acquired" ), ), ("expires_at", models.DateTimeField(help_text="When the lock expires")), ( "is_active", models.BooleanField( db_index=True, default=True, help_text="Whether the lock is currently active", ), ), ( "released_at", models.DateTimeField( blank=True, help_text="When the lock was released", null=True ), ), ( "locked_by", models.ForeignKey( help_text="User who holds the lock", on_delete=django.db.models.deletion.CASCADE, related_name="moderation_locks", to=settings.AUTH_USER_MODEL, ), ), ( "submission", models.OneToOneField( help_text="Submission that is locked", on_delete=django.db.models.deletion.CASCADE, related_name="lock_record", to="moderation.contentsubmission", ), ), ], options={ "verbose_name": "Moderation Lock", "verbose_name_plural": "Moderation Locks", "db_table": "moderation_locks", "ordering": ["-locked_at"], "indexes": [ models.Index( fields=["is_active", "expires_at"], name="moderation__is_acti_ecf427_idx", ), models.Index( fields=["locked_by", "is_active"], name="moderation__locked__d5cdfb_idx", ), ], }, bases=(django_lifecycle.mixins.LifecycleModelMixin, models.Model), ), migrations.AddIndex( model_name="contentsubmission", index=models.Index( fields=["status", "created"], name="content_sub_status_a8d552_idx" ), ), migrations.AddIndex( model_name="contentsubmission", index=models.Index( fields=["user", "status"], name="content_sub_user_id_019595_idx" ), ), migrations.AddIndex( model_name="contentsubmission", index=models.Index( fields=["entity_type", "entity_id"], name="content_sub_entity__d0f313_idx", ), ), migrations.AddIndex( model_name="contentsubmission", index=models.Index( fields=["locked_by", "locked_at"], name="content_sub_locked__feb2b3_idx" ), ), ]