# Generated by Django 4.2.23 on 2026-08-08 11:15 from django.conf import settings from django.db import migrations, models import django.db.models.deletion import uuid class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Contest', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', models.SlugField(unique=True)), ('title', models.CharField(max_length=120)), ('kind', models.CharField(choices=[('realtime', '实时 1v1'), ('daily', '今日挑战'), ('practice', '单人闯关'), ('weekly', '主题周赛')], max_length=16)), ('track', models.CharField(choices=[('beginner', '入门'), ('standard', '标准'), ('advanced', '进阶'), ('open', 'Open')], max_length=16)), ('status', models.CharField(choices=[('draft', '草稿'), ('published', '已发布'), ('closed', '已结束')], default='draft', max_length=16)), ('duration_seconds', models.PositiveIntegerField(default=60)), ('starts_at', models.DateTimeField(blank=True, null=True)), ('ends_at', models.DateTimeField(blank=True, null=True)), ], ), migrations.CreateModel( name='Question', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', models.SlugField(unique=True)), ('track', models.CharField(choices=[('beginner', '入门'), ('standard', '标准'), ('advanced', '进阶'), ('open', 'Open')], max_length=16)), ('tags', models.JSONField(blank=True, default=list)), ('is_active', models.BooleanField(default=True)), ], ), migrations.CreateModel( name='RealtimeMatch', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('status', models.CharField(choices=[('waiting', '等待对手'), ('active', '进行中'), ('completed', '已完成'), ('cancelled', '已取消')], default='waiting', max_length=16)), ('player_one_rating', models.PositiveIntegerField()), ('player_two_rating', models.PositiveIntegerField(blank=True, null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('started_at', models.DateTimeField(blank=True, null=True)), ('completed_at', models.DateTimeField(blank=True, null=True)), ('contest', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contest.contest')), ('player_one', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='matches_as_player_one', to=settings.AUTH_USER_MODEL)), ('player_two', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='matches_as_player_two', to=settings.AUTH_USER_MODEL)), ('winner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='won_matches', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='RatingHistory', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('rating_before', models.PositiveIntegerField()), ('rating_after', models.PositiveIntegerField()), ('delta', models.SmallIntegerField()), ('created_at', models.DateTimeField(auto_now_add=True)), ('match', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='rating_changes', to='contest.realtimematch')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rating_history', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='QuestionVersion', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('version', models.PositiveIntegerField()), ('prompt', models.TextField()), ('answer', models.CharField(max_length=200)), ('explanation', models.TextField(blank=True)), ('metadata', models.JSONField(blank=True, default=dict)), ('created_at', models.DateTimeField(auto_now_add=True)), ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='contest.question')), ], ), migrations.CreateModel( name='LeaderboardSnapshot', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('track', models.CharField(choices=[('beginner', '入门'), ('standard', '标准'), ('advanced', '进阶'), ('open', 'Open')], max_length=16)), ('period', models.CharField(max_length=40)), ('rankings', models.JSONField(default=list)), ('generated_at', models.DateTimeField(auto_now_add=True)), ('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contest.contest')), ], ), migrations.CreateModel( name='ContestQuestion', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('order', models.PositiveIntegerField()), ('points', models.PositiveIntegerField(default=100)), ('contest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contest_questions', to='contest.contest')), ('question_version', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contest.questionversion')), ], options={ 'ordering': ['order'], }, ), migrations.CreateModel( name='ContestAttempt', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('status', models.CharField(choices=[('active', '进行中'), ('submitted', '已提交'), ('expired', '已超时')], default='active', max_length=16)), ('score', models.PositiveIntegerField(default=0)), ('correct_count', models.PositiveIntegerField(default=0)), ('answer_count', models.PositiveIntegerField(default=0)), ('duration_ms', models.PositiveIntegerField(default=0)), ('submission_key', models.CharField(blank=True, max_length=80, null=True)), ('started_at', models.DateTimeField(auto_now_add=True)), ('submitted_at', models.DateTimeField(blank=True, null=True)), ('contest', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='attempts', to='contest.contest')), ('match', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='attempts', to='contest.realtimematch')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contest_attempts', to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['-started_at'], }, ), migrations.CreateModel( name='ContestAnswer', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('submitted_answer', models.CharField(max_length=200)), ('is_correct', models.BooleanField()), ('elapsed_ms', models.PositiveIntegerField()), ('answered_at', models.DateTimeField(auto_now_add=True)), ('attempt', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='contest.contestattempt')), ('contest_question', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contest.contestquestion')), ], ), migrations.CreateModel( name='CheatFlag', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('reason', models.CharField(max_length=120)), ('evidence', models.JSONField(default=dict)), ('status', models.CharField(choices=[('open', '待处理'), ('dismissed', '已忽略'), ('confirmed', '已确认')], default='open', max_length=16)), ('created_at', models.DateTimeField(auto_now_add=True)), ('attempt', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cheat_flags', to='contest.contestattempt')), ], ), migrations.AddConstraint( model_name='questionversion', constraint=models.UniqueConstraint(fields=('question', 'version'), name='unique_question_version'), ), migrations.AddConstraint( model_name='contestquestion', constraint=models.UniqueConstraint(fields=('contest', 'order'), name='unique_contest_question_order'), ), migrations.AddConstraint( model_name='contestattempt', constraint=models.UniqueConstraint(fields=('user', 'submission_key'), name='unique_user_contest_submission'), ), migrations.AddConstraint( model_name='contestanswer', constraint=models.UniqueConstraint(fields=('attempt', 'contest_question'), name='unique_attempt_question_answer'), ), ]