From 9f0f771213ccad178317d65462bcda84730c4f3c Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Sun, 28 Jun 2026 18:20:46 +0545 Subject: [PATCH] fix(src): commit migration files to prevent InconsistentMigrationHistory Remove src/*/migrations/ from .gitignore and commit all generated migration files. The admin.0001_initial migration uses swappable_dependency(AUTH_USER_MODEL) which requires accounts.0001_initial to exist before admin migrations can be applied. Without committed migration files, running migrate before makemigrations causes admin to apply first (since accounts appears to have no migrations), leading to an InconsistentMigrationHistory error when makemigrations is run later. This follows Django's recommended workflow of committing migrations. --- .gitignore | 3 - src/accounts/migrations/0001_initial.py | 98 ++++++++++ src/accounts/migrations/__init__.py | 0 src/epics/migrations/0001_initial.py | 37 ++++ src/epics/migrations/__init__.py | 0 src/external/migrations/0001_initial.py | 36 ++++ src/external/migrations/__init__.py | 0 src/notes/migrations/0001_initial.py | 37 ++++ src/notes/migrations/__init__.py | 0 src/notifications/migrations/0001_initial.py | 56 ++++++ src/notifications/migrations/__init__.py | 0 src/projects/migrations/0001_initial.py | 73 +++++++ src/projects/migrations/__init__.py | 0 src/tickets/migrations/0001_initial.py | 193 +++++++++++++++++++ src/tickets/migrations/__init__.py | 0 15 files changed, 530 insertions(+), 3 deletions(-) create mode 100644 src/accounts/migrations/0001_initial.py create mode 100644 src/accounts/migrations/__init__.py create mode 100644 src/epics/migrations/0001_initial.py create mode 100644 src/epics/migrations/__init__.py create mode 100644 src/external/migrations/0001_initial.py create mode 100644 src/external/migrations/__init__.py create mode 100644 src/notes/migrations/0001_initial.py create mode 100644 src/notes/migrations/__init__.py create mode 100644 src/notifications/migrations/0001_initial.py create mode 100644 src/notifications/migrations/__init__.py create mode 100644 src/projects/migrations/0001_initial.py create mode 100644 src/projects/migrations/__init__.py create mode 100644 src/tickets/migrations/0001_initial.py create mode 100644 src/tickets/migrations/__init__.py diff --git a/.gitignore b/.gitignore index e1ed042..226a212 100644 --- a/.gitignore +++ b/.gitignore @@ -90,8 +90,5 @@ secrets.json *.db *.sql -# App migrations (generated by makemigrations) -src/*/migrations/ - # Cloud .cloud diff --git a/src/accounts/migrations/0001_initial.py b/src/accounts/migrations/0001_initial.py new file mode 100644 index 0000000..7ee2987 --- /dev/null +++ b/src/accounts/migrations/0001_initial.py @@ -0,0 +1,98 @@ +# Generated by Django 6.0.6 on 2026-06-28 12:27 + +import django.contrib.auth.models +import django.contrib.auth.validators +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='SiteBranding', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('favicon', models.FileField(blank=True, help_text='Favicon file (.ico, .png)', null=True, upload_to='branding/')), + ('logo', models.ImageField(blank=True, help_text='Main logo image', null=True, upload_to='branding/')), + ('logo_small', models.ImageField(blank=True, help_text='Small logo for collapsed sidebar', null=True, upload_to='branding/')), + ('brand_name', models.CharField(default='Project Management', max_length=100)), + ('copyright_name', models.CharField(default='Project Management', max_length=200)), + ('is_active', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Site Branding', + 'verbose_name_plural': 'Site Branding', + 'db_table': 'site_branding', + }, + ), + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('role', models.CharField(choices=[('superadmin', 'Superadmin'), ('manager', 'Manager'), ('member', 'Member'), ('guest', 'Guest')], default='member', max_length=20)), + ('google_id', models.CharField(blank=True, max_length=255, null=True, unique=True)), + ('profile_image', models.ImageField(blank=True, null=True, upload_to='profiles/')), + ('receive_deadline_emails', models.BooleanField(default=True, help_text='Receive email reminders when ticket deadlines are approaching')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'User', + 'verbose_name_plural': 'Users', + 'db_table': 'users', + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name='Setting', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('group', models.CharField(blank=True, max_length=255, null=True)), + ('key', models.CharField(max_length=255)), + ('value', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='settings', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Setting', + 'verbose_name_plural': 'Settings', + 'db_table': 'settings', + }, + ), + migrations.AddIndex( + model_name='user', + index=models.Index(fields=['role'], name='users_role_0ace22_idx'), + ), + migrations.AddIndex( + model_name='setting', + index=models.Index(fields=['user', 'group'], name='settings_user_id_ab191f_idx'), + ), + migrations.AddConstraint( + model_name='setting', + constraint=models.UniqueConstraint(fields=('user', 'key'), name='unique_user_setting'), + ), + ] diff --git a/src/accounts/migrations/__init__.py b/src/accounts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/epics/migrations/0001_initial.py b/src/epics/migrations/0001_initial.py new file mode 100644 index 0000000..929ce82 --- /dev/null +++ b/src/epics/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# Generated by Django 6.0.6 on 2026-06-28 12:27 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('projects', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Epic', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField(blank=True, null=True)), + ('start_date', models.DateField(blank=True, null=True)), + ('end_date', models.DateField(blank=True, null=True)), + ('sort_order', models.IntegerField(default=0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='epics', to='projects.project')), + ], + options={ + 'verbose_name': 'Epic', + 'verbose_name_plural': 'Epics', + 'db_table': 'epics', + 'ordering': ('sort_order',), + 'indexes': [models.Index(fields=['project', 'sort_order'], name='epics_project_eeb4de_idx')], + }, + ), + ] diff --git a/src/epics/migrations/__init__.py b/src/epics/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/external/migrations/0001_initial.py b/src/external/migrations/0001_initial.py new file mode 100644 index 0000000..f2572de --- /dev/null +++ b/src/external/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# Generated by Django 6.0.6 on 2026-06-28 12:27 + +import django.db.models.deletion +import src.external.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('projects', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='ExternalAccess', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('access_token', models.CharField(default=src.external.models.generate_access_token, max_length=255, unique=True)), + ('password', models.CharField(default=src.external.models.generate_access_password, max_length=255)), + ('is_active', models.BooleanField(default=True)), + ('last_accessed_at', models.DateTimeField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='external_accesses', to='projects.project')), + ], + options={ + 'verbose_name': 'External Access', + 'verbose_name_plural': 'External Accesses', + 'db_table': 'external_access', + 'indexes': [models.Index(fields=['project', 'is_active'], name='external_ac_project_d7e6b3_idx')], + }, + ), + ] diff --git a/src/external/migrations/__init__.py b/src/external/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/notes/migrations/0001_initial.py b/src/notes/migrations/0001_initial.py new file mode 100644 index 0000000..f57cac4 --- /dev/null +++ b/src/notes/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# Generated by Django 6.0.6 on 2026-06-28 12:27 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('projects', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='ProjectNote', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=255)), + ('content', models.TextField(blank=True, null=True)), + ('note_date', models.DateField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='project_notes', to=settings.AUTH_USER_MODEL)), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='projects.project')), + ], + options={ + 'verbose_name': 'Project Note', + 'verbose_name_plural': 'Project Notes', + 'db_table': 'project_notes', + 'indexes': [models.Index(fields=['project', 'note_date'], name='project_not_project_833ff9_idx')], + }, + ), + ] diff --git a/src/notes/migrations/__init__.py b/src/notes/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/notifications/migrations/0001_initial.py b/src/notifications/migrations/0001_initial.py new file mode 100644 index 0000000..3eb3dde --- /dev/null +++ b/src/notifications/migrations/0001_initial.py @@ -0,0 +1,56 @@ +# Generated by Django 6.0.6 on 2026-06-28 12:27 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('tickets', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='DeadlineReminderLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('days_before', models.IntegerField(help_text='How many days before the deadline this reminder was sent')), + ('sent_at', models.DateTimeField(auto_now_add=True)), + ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='deadline_reminders', to='tickets.ticket')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='deadline_reminders', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Deadline Reminder Log', + 'verbose_name_plural': 'Deadline Reminder Logs', + 'db_table': 'deadline_reminder_log', + 'indexes': [models.Index(fields=['ticket', 'user'], name='deadline_re_ticket__850437_idx')], + 'constraints': [models.UniqueConstraint(fields=('ticket', 'user', 'days_before'), name='unique_ticket_user_days_reminder')], + }, + ), + migrations.CreateModel( + name='Notification', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(help_text='e.g. comment_added, project_assigned', max_length=255)), + ('title', models.CharField(max_length=255)), + ('message', models.TextField(blank=True, null=True)), + ('data', models.JSONField(blank=True, help_text='Arbitrary payload e.g. ticket_id, comment_id', null=True)), + ('read_at', models.DateTimeField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Notification', + 'verbose_name_plural': 'Notifications', + 'db_table': 'notifications', + 'ordering': ('-created_at',), + 'indexes': [models.Index(fields=['user', 'read_at'], name='notificatio_user_id_6c7360_idx'), models.Index(fields=['user', 'created_at'], name='notificatio_user_id_7336fd_idx')], + }, + ), + ] diff --git a/src/notifications/migrations/__init__.py b/src/notifications/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/projects/migrations/0001_initial.py b/src/projects/migrations/0001_initial.py new file mode 100644 index 0000000..b1be45c --- /dev/null +++ b/src/projects/migrations/0001_initial.py @@ -0,0 +1,73 @@ +# Generated by Django 6.0.6 on 2026-06-28 12:27 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Project', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField(blank=True, null=True)), + ('ticket_prefix', models.CharField(max_length=255)), + ('color', models.CharField(blank=True, help_text='Hex color e.g. #3B82F6', max_length=7, null=True)), + ('start_date', models.DateField(blank=True, null=True)), + ('end_date', models.DateField(blank=True, null=True)), + ('pinned_date', models.DateTimeField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Project', + 'verbose_name_plural': 'Projects', + 'db_table': 'projects', + }, + ), + migrations.CreateModel( + name='ProjectMember', + 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)), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='project_members', to='projects.project')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='project_memberships', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Project Member', + 'verbose_name_plural': 'Project Members', + 'db_table': 'project_members', + }, + ), + migrations.AddField( + model_name='project', + name='members', + field=models.ManyToManyField(related_name='projects', through='projects.ProjectMember', to=settings.AUTH_USER_MODEL), + ), + migrations.AddIndex( + model_name='projectmember', + index=models.Index(fields=['user', 'project'], name='project_mem_user_id_6b0bb0_idx'), + ), + migrations.AddConstraint( + model_name='projectmember', + constraint=models.UniqueConstraint(fields=('project', 'user'), name='unique_project_member'), + ), + migrations.AddIndex( + model_name='project', + index=models.Index(fields=['pinned_date'], name='projects_pinned__118cce_idx'), + ), + migrations.AddIndex( + model_name='project', + index=models.Index(fields=['start_date', 'end_date'], name='projects_start_d_cb24a6_idx'), + ), + ] diff --git a/src/projects/migrations/__init__.py b/src/projects/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/tickets/migrations/0001_initial.py b/src/tickets/migrations/0001_initial.py new file mode 100644 index 0000000..ad618aa --- /dev/null +++ b/src/tickets/migrations/0001_initial.py @@ -0,0 +1,193 @@ +# Generated by Django 6.0.6 on 2026-06-28 12:27 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('epics', '0001_initial'), + ('projects', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='TicketPriority', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), + ('color', models.CharField(default='#6B7280', max_length=7)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Ticket Priority', + 'verbose_name_plural': 'Ticket Priorities', + 'db_table': 'ticket_priorities', + }, + ), + migrations.CreateModel( + name='Ticket', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('description', models.TextField(blank=True, null=True)), + ('uuid', models.CharField(editable=False, max_length=255, unique=True)), + ('start_date', models.DateField(blank=True, null=True)), + ('due_date', models.DateField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_tickets', to=settings.AUTH_USER_MODEL)), + ('epic', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tickets', to='epics.epic')), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='projects.project')), + ('priority', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tickets', to='tickets.ticketpriority')), + ], + options={ + 'verbose_name': 'Ticket', + 'verbose_name_plural': 'Tickets', + 'db_table': 'tickets', + }, + ), + migrations.CreateModel( + name='TicketStatus', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('color', models.CharField(default='#10B981', max_length=7)), + ('sort_order', models.IntegerField(default=0)), + ('is_completed', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_statuses', to='projects.project')), + ], + options={ + 'verbose_name': 'Ticket Status', + 'verbose_name_plural': 'Ticket Statuses', + 'db_table': 'ticket_statuses', + }, + ), + migrations.CreateModel( + name='TicketHistory', + 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)), + ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='histories', to='tickets.ticket')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_histories', to=settings.AUTH_USER_MODEL)), + ('status', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='histories', to='tickets.ticketstatus')), + ], + options={ + 'verbose_name': 'Ticket History', + 'verbose_name_plural': 'Ticket Histories', + 'db_table': 'ticket_histories', + }, + ), + migrations.AddField( + model_name='ticket', + name='status', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='tickets.ticketstatus'), + ), + migrations.CreateModel( + name='TicketUser', + 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)), + ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_assignees', to='tickets.ticket')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Ticket Assignee', + 'verbose_name_plural': 'Ticket Assignees', + 'db_table': 'ticket_users', + }, + ), + migrations.AddField( + model_name='ticket', + name='assignees', + field=models.ManyToManyField(related_name='assigned_tickets', through='tickets.TicketUser', to=settings.AUTH_USER_MODEL), + ), + migrations.CreateModel( + name='TicketComment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('comment', models.TextField(help_text='Rich text HTML content')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='replies', to='tickets.ticketcomment')), + ('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='tickets.ticket')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_comments', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Ticket Comment', + 'verbose_name_plural': 'Ticket Comments', + 'db_table': 'ticket_comments', + 'indexes': [models.Index(fields=['ticket', 'created_at'], name='ticket_comm_ticket__5ef05d_idx')], + }, + ), + migrations.AddIndex( + model_name='ticketstatus', + index=models.Index(fields=['project', 'sort_order'], name='ticket_stat_project_262e3f_idx'), + ), + migrations.AddIndex( + model_name='ticketstatus', + index=models.Index(fields=['project', 'is_completed'], name='ticket_stat_project_283078_idx'), + ), + migrations.AddIndex( + model_name='ticketstatus', + index=models.Index(fields=['project', 'name'], name='ticket_stat_project_1d8cf1_idx'), + ), + migrations.AddIndex( + model_name='tickethistory', + index=models.Index(fields=['ticket', 'created_at'], name='ticket_hist_ticket__e81360_idx'), + ), + migrations.AddIndex( + model_name='tickethistory', + index=models.Index(fields=['user', 'created_at'], name='ticket_hist_user_id_116996_idx'), + ), + migrations.AddIndex( + model_name='ticketuser', + index=models.Index(fields=['ticket', 'user'], name='ticket_user_ticket__0340c3_idx'), + ), + migrations.AddIndex( + model_name='ticketuser', + index=models.Index(fields=['user'], name='ticket_user_user_id_437f9e_idx'), + ), + migrations.AddConstraint( + model_name='ticketuser', + constraint=models.UniqueConstraint(fields=('ticket', 'user'), name='unique_ticket_user'), + ), + migrations.AddIndex( + model_name='ticket', + index=models.Index(fields=['project', 'status'], name='tickets_project_3ab72a_idx'), + ), + migrations.AddIndex( + model_name='ticket', + index=models.Index(fields=['status', 'created_at'], name='tickets_status__3a7341_idx'), + ), + migrations.AddIndex( + model_name='ticket', + index=models.Index(fields=['project', 'created_at'], name='tickets_project_5cdbb2_idx'), + ), + migrations.AddIndex( + model_name='ticket', + index=models.Index(fields=['project', 'updated_at'], name='tickets_project_4298d2_idx'), + ), + migrations.AddIndex( + model_name='ticket', + index=models.Index(fields=['due_date'], name='tickets_due_dat_c75c11_idx'), + ), + migrations.AddIndex( + model_name='ticket', + index=models.Index(fields=['priority'], name='tickets_priorit_1ce021_idx'), + ), + migrations.AddIndex( + model_name='ticket', + index=models.Index(fields=['created_by'], name='tickets_created_b5c671_idx'), + ), + ] diff --git a/src/tickets/migrations/__init__.py b/src/tickets/migrations/__init__.py new file mode 100644 index 0000000..e69de29