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.
This commit is contained in:
sankalp committed 2026-06-28 18:20:46 +05:45
1 parent 75bccb4528
commit 9f0f771213
15 files changed
+530 -3

No files matched your search

-3
View File
@@ -90,8 +90,5 @@ secrets.json
*.db
*.sql
# App migrations (generated by makemigrations)
src/*/migrations/
# Cloud
.cloud
+98
View File
@@ -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'),
),
]
View File
Whitespace-only changes.
+37
View File
@@ -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')],
},
),
]
View File
Whitespace-only changes.
+36
View File
@@ -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')],
},
),
]
View File
Whitespace-only changes.
+37
View File
@@ -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')],
},
),
]
View File
Whitespace-only changes.
@@ -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')],
},
),
]
Whitespace-only changes.
+73
View File
@@ -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'),
),
]
View File
Whitespace-only changes.
+193
View File
@@ -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'),
),
]
View File
Whitespace-only changes.