# Generated by Django 5.1.1 on 2026-09-05 07:03 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 = [ ('messaging', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='SLAConfig', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('priority', models.CharField(max_length=15, unique=True)), ('first_response_minutes', models.PositiveIntegerField()), ('resolution_minutes', models.PositiveIntegerField()), ('is_active', models.BooleanField(default=True)), ], ), migrations.CreateModel( name='TicketCategory', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('title', models.CharField(max_length=100)), ('slug', models.SlugField(unique=True)), ('description', models.TextField(blank=True)), ('icon', models.CharField(blank=True, max_length=50)), ('sort_order', models.PositiveIntegerField(default=0)), ('is_active', models.BooleanField(default=True)), ], options={ 'ordering': ['sort_order', 'title'], }, ), migrations.CreateModel( name='Ticket', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('public_id', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), ('ticket_number', models.CharField(editable=False, max_length=30, unique=True)), ('subject', models.CharField(max_length=200, validators=[django.core.validators.MinLengthValidator(5)])), ('status', models.CharField(choices=[('NEW', 'جدید'), ('OPEN', 'باز'), ('WAITING_CUSTOMER', 'در انتظار مشتری'), ('WAITING_STAFF', 'در انتظار کارشناس'), ('RESOLVED', 'حل\u200cشده'), ('CLOSED', 'بسته'), ('REOPENED', 'بازگشایی\u200cشده')], db_index=True, default='NEW', max_length=25)), ('priority', models.CharField(choices=[('NORMAL', 'عادی'), ('IMPORTANT', 'مهم'), ('URGENT', 'فوری')], db_index=True, default='NORMAL', max_length=15)), ('origin_visibility', models.CharField(choices=[('PUBLIC', 'عمومی'), ('SELECTED', 'کارشناس انتخابی')], default='PUBLIC', max_length=15)), ('last_activity_at', models.DateTimeField(db_index=True)), ('first_response_at', models.DateTimeField(blank=True, null=True)), ('last_customer_message_at', models.DateTimeField(blank=True, null=True)), ('last_staff_message_at', models.DateTimeField(blank=True, null=True)), ('first_response_due_at', models.DateTimeField(blank=True, null=True)), ('resolution_due_at', models.DateTimeField(blank=True, null=True)), ('resolved_at', models.DateTimeField(blank=True, null=True)), ('closed_at', models.DateTimeField(blank=True, null=True)), ('reopened_at', models.DateTimeField(blank=True, null=True)), ('customer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='customer_tickets', to=settings.AUTH_USER_MODEL)), ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='owned_tickets', to=settings.AUTH_USER_MODEL)), ('selected_expert', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='selected_tickets', to=settings.AUTH_USER_MODEL)), ('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='tickets', to='tickets.ticketcategory')), ], options={ 'ordering': ['-last_activity_at'], 'permissions': [('view_all_tickets', 'Can view all tickets'), ('claim_ticket', 'Can claim ticket'), ('transfer_ticket', 'Can transfer ticket'), ('share_ticket', 'Can share ticket'), ('change_ticket_priority', 'Can change ticket priority'), ('view_customer_history', 'Can view customer history')], }, ), migrations.CreateModel( name='TicketEvent', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('event_type', models.CharField(choices=[('CREATED', 'ایجاد'), ('CLAIMED', 'برداشت'), ('TRANSFERRED', 'انتقال'), ('SHARED', 'اشتراک'), ('ACCESS_REVOKED', 'لغو دسترسی'), ('STATUS_CHANGED', 'تغییر وضعیت'), ('PRIORITY_CHANGED', 'تغییر اولویت'), ('REOPENED', 'بازگشایی'), ('RESOLVED', 'حل'), ('CLOSED', 'بستن')], max_length=30)), ('metadata', models.JSONField(blank=True, default=dict)), ('created_at', models.DateTimeField(auto_now_add=True)), ('actor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='tickets.ticket')), ], ), migrations.CreateModel( name='TicketReadState', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('last_read_at', models.DateTimeField()), ('last_read_message', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='messaging.message')), ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tickets.ticket')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='TicketAccessGrant', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('permission_level', models.CharField(choices=[('VIEW_ONLY', 'فقط مشاهده'), ('REPLY', 'پاسخ'), ('FULL', 'کامل')], default='FULL', max_length=15)), ('created_at', models.DateTimeField(auto_now_add=True)), ('revoked_at', models.DateTimeField(blank=True, null=True)), ('granted_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='granted_ticket_access', to=settings.AUTH_USER_MODEL)), ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='access_grants', to='tickets.ticket')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_grants', to=settings.AUTH_USER_MODEL)), ], options={ 'constraints': [models.UniqueConstraint(condition=models.Q(('revoked_at__isnull', True)), fields=('ticket', 'user'), name='unique_active_ticket_grant')], }, ), migrations.AddIndex( model_name='ticket', index=models.Index(fields=['status', 'last_activity_at'], name='tickets_tic_status_dbef56_idx'), ), migrations.AddIndex( model_name='ticket', index=models.Index(fields=['owner', 'status'], name='tickets_tic_owner_i_70fd59_idx'), ), migrations.AddIndex( model_name='ticket', index=models.Index(fields=['selected_expert', 'status'], name='tickets_tic_selecte_71a761_idx'), ), migrations.AddConstraint( model_name='ticketreadstate', constraint=models.UniqueConstraint(fields=('ticket', 'user'), name='unique_ticket_read_state'), ), ]