feat: add unified contest pool and realtime game modes

This commit is contained in:
2026-08-10 00:31:21 +08:00
parent 97ca20413e
commit 40e9462842
18 changed files with 822 additions and 152 deletions
@@ -0,0 +1,33 @@
# Generated by Django 4.2.23 on 2026-08-09 16:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contest', '0004_remove_realtimematch_matchmaking_lookup_idx_and_more'),
]
operations = [
migrations.AddField(
model_name='contestattempt',
name='question_order',
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name='mathgameattempt',
name='match',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='game_attempts', to='contest.realtimematch'),
),
migrations.AddField(
model_name='realtimematch',
name='game_kind',
field=models.CharField(choices=[('quiz', '口算竞速'), ('sudoku', '数独 Timerun'), ('twenty_four', '24 点竞速')], default='quiz', max_length=20),
),
migrations.AddConstraint(
model_name='mathgameattempt',
constraint=models.UniqueConstraint(fields=('match', 'user'), name='unique_user_realtime_math_game'),
),
]
@@ -0,0 +1,57 @@
from django.db import migrations
def expand_question_pools(apps, schema_editor):
Contest = apps.get_model("contest", "Contest")
ContestQuestion = apps.get_model("contest", "ContestQuestion")
QuestionVersion = apps.get_model("contest", "QuestionVersion")
for contest in Contest.objects.all().iterator():
existing_version_ids = set(
ContestQuestion.objects.filter(contest=contest).values_list(
"question_version_id",
flat=True,
)
)
latest_versions = {}
versions = QuestionVersion.objects.filter(
question__track=contest.track,
question__is_active=True,
).order_by("question_id", "-version")
for version in versions.iterator():
latest_versions.setdefault(version.question_id, version.id)
next_order = (
ContestQuestion.objects.filter(contest=contest)
.order_by("-order")
.values_list("order", flat=True)
.first()
or 0
)
additions = []
for version_id in latest_versions.values():
if version_id in existing_version_ids:
continue
next_order += 1
additions.append(
ContestQuestion(
contest_id=contest.id,
question_version_id=version_id,
order=next_order,
points=100,
)
)
ContestQuestion.objects.bulk_create(additions, batch_size=500)
class Migration(migrations.Migration):
dependencies = [
("contest", "0005_contestattempt_question_order_mathgameattempt_match_and_more"),
]
operations = [
migrations.RunPython(
expand_question_pools,
migrations.RunPython.noop,
),
]
@@ -0,0 +1,21 @@
# Generated by Django 4.2.23 on 2026-08-09 16:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contest', '0006_expand_contest_question_pools'),
]
operations = [
migrations.RemoveIndex(
model_name='realtimematch',
name='matchmaking_lookup_idx',
),
migrations.AddIndex(
model_name='realtimematch',
index=models.Index(fields=['contest', 'match_type', 'game_kind', 'status', 'player_one_rating', 'created_at'], name='matchmaking_mode_idx'),
),
]