# Generated by Django 5.2.15 on 2026-07-08 13:44 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 = [ ('billing', '0007_alter_pointsledger_change_type_signupbonusgrant'), ('users', '0005_alter_apikey_created_at_alter_apikey_key_hash_and_more'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='ImageGenerationTask', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('task_id', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='任务 ID')), ('status', models.CharField(choices=[('queued', '排队中'), ('running', '处理中'), ('succeeded', '成功'), ('failed', '失败'), ('expired', '已过期')], default='queued', max_length=20, verbose_name='状态')), ('idempotency_key', models.CharField(blank=True, max_length=128, verbose_name='幂等键')), ('idempotency_key_hash', models.CharField(blank=True, editable=False, max_length=64, null=True, verbose_name='幂等键哈希')), ('request_hash', models.CharField(max_length=64, verbose_name='请求哈希')), ('request_payload', models.JSONField(blank=True, default=dict, verbose_name='请求快照')), ('input_image', models.FileField(blank=True, upload_to='generated/task_inputs/%Y/%m/%d/', verbose_name='输入图片')), ('result_url', models.TextField(blank=True, verbose_name='结果 URL')), ('error_code', models.CharField(blank=True, max_length=64, verbose_name='错误码')), ('error_message', models.TextField(blank=True, verbose_name='错误信息')), ('points_balance_after_charge', models.BigIntegerField(default=0, verbose_name='扣费后余额')), ('started_at', models.DateTimeField(blank=True, null=True, verbose_name='开始时间')), ('finished_at', models.DateTimeField(blank=True, null=True, verbose_name='完成时间')), ('expires_at', models.DateTimeField(blank=True, null=True, verbose_name='任务元数据过期时间')), ('locked_at', models.DateTimeField(blank=True, null=True, verbose_name='锁定时间')), ('lease_expires_at', models.DateTimeField(blank=True, null=True, verbose_name='租约过期时间')), ('heartbeat_at', models.DateTimeField(blank=True, null=True, verbose_name='心跳时间')), ('worker_id', models.CharField(blank=True, max_length=128, verbose_name='Worker ID')), ('attempt_count', models.PositiveIntegerField(default=0, verbose_name='尝试次数')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), ('api_key', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='image_generation_tasks', to='users.apikey', verbose_name='API 密钥')), ('call_record', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='image_generation_task', to='billing.callrecord', verbose_name='调用记录')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='image_generation_tasks', to=settings.AUTH_USER_MODEL, verbose_name='用户')), ], options={ 'verbose_name': '图片生成任务', 'verbose_name_plural': '图片生成任务', 'db_table': 'image_generation_task', 'ordering': ('-created_at', '-id'), 'indexes': [models.Index(fields=['user', 'created_at'], name='image_gener_user_id_1e7164_idx'), models.Index(fields=['api_key', 'created_at'], name='image_gener_api_key_30d9ad_idx'), models.Index(fields=['status', 'created_at'], name='image_gener_status_727db2_idx'), models.Index(fields=['status', 'lease_expires_at'], name='image_gener_status_7a7bd1_idx'), models.Index(fields=['worker_id', 'status'], name='image_gener_worker__f9e534_idx'), models.Index(fields=['expires_at'], name='image_gener_expires_545a78_idx')], 'constraints': [models.UniqueConstraint(fields=('api_key', 'idempotency_key_hash'), name='unique_image_task_idempotency_hash_per_api_key'), models.CheckConstraint(condition=models.Q(('points_balance_after_charge__gte', 0)), name='image_task_balance_after_charge_non_negative')], }, ), ]