# Generated by Django 5.2.12 on 2026-05-13 07:59

import django.db.models.deletion
import django.utils.timezone
import uuid
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),
        ("account", "0027_remove_systemsettingsmodel_macro_index_catalog"),
    ]

    operations = [
        migrations.CreateModel(
            name="QlibTrainingProfileModel",
            fields=[
                (
                    "id",
                    models.BigAutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                (
                    "profile_key",
                    models.CharField(
                        db_index=True,
                        max_length=64,
                        unique=True,
                        verbose_name="模板键",
                    ),
                ),
                ("name", models.CharField(max_length=120, verbose_name="模板名称")),
                ("model_name", models.CharField(max_length=100, verbose_name="模型名称")),
                ("model_type", models.CharField(max_length=50, verbose_name="模型类型")),
                (
                    "universe",
                    models.CharField(
                        blank=True,
                        default="",
                        max_length=50,
                        verbose_name="股票池",
                    ),
                ),
                ("start_date", models.DateField(blank=True, null=True, verbose_name="训练开始日期")),
                ("end_date", models.DateField(blank=True, null=True, verbose_name="训练结束日期")),
                (
                    "feature_set_id",
                    models.CharField(
                        blank=True,
                        default="",
                        max_length=50,
                        verbose_name="特征集标识",
                    ),
                ),
                (
                    "label_id",
                    models.CharField(
                        blank=True,
                        default="",
                        max_length=50,
                        verbose_name="标签标识",
                    ),
                ),
                ("learning_rate", models.FloatField(blank=True, null=True, verbose_name="学习率")),
                ("epochs", models.PositiveIntegerField(blank=True, null=True, verbose_name="训练轮数")),
                ("model_params", models.JSONField(blank=True, default=dict, verbose_name="模型参数")),
                (
                    "extra_train_config",
                    models.JSONField(blank=True, default=dict, verbose_name="附加训练配置"),
                ),
                (
                    "activate_after_train",
                    models.BooleanField(default=False, verbose_name="训练完成后自动激活"),
                ),
                ("is_active", models.BooleanField(default=True, verbose_name="是否启用")),
                ("notes", models.TextField(blank=True, verbose_name="备注")),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
            ],
            options={
                "verbose_name": "Qlib 训练模板",
                "verbose_name_plural": "Qlib 训练模板",
                "db_table": "config_center_qlib_training_profile",
                "ordering": ["name", "profile_key"],
            },
        ),
        migrations.SeparateDatabaseAndState(
            state_operations=[
                migrations.CreateModel(
                    name="SystemSettingsModel",
                    fields=[
                        (
                            "id",
                            models.BigAutoField(
                                auto_created=True,
                                primary_key=True,
                                serialize=False,
                                verbose_name="ID",
                            ),
                        ),
                        (
                            "require_user_approval",
                            models.BooleanField(
                                default=True,
                                help_text="关闭后新用户注册将自动批准",
                                verbose_name="需要管理员审批新用户",
                            ),
                        ),
                        (
                            "auto_approve_first_admin",
                            models.BooleanField(
                                default=True,
                                help_text="系统无管理员时，首个注册的用户自动成为管理员并获得批准",
                                verbose_name="自动批准首个管理员用户",
                            ),
                        ),
                        (
                            "default_mcp_enabled",
                            models.BooleanField(
                                default=True,
                                help_text="新注册或新批准用户默认是否允许 MCP/SDK 访问，由管理员决定",
                                verbose_name="新用户默认开启 MCP/SDK",
                            ),
                        ),
                        (
                            "market_color_convention",
                            models.CharField(
                                choices=[("cn_a_share", "A股红涨绿跌"), ("us_market", "美股绿涨红跌")],
                                default="cn_a_share",
                                help_text="统一控制涨跌、资金流入流出的语义颜色映射。",
                                max_length=32,
                                verbose_name="市场颜色约定",
                            ),
                        ),
                        (
                            "allow_token_plaintext_view",
                            models.BooleanField(
                                default=True,
                                help_text="关闭后，生成后不再显示完整 Token，历史 Token 也不可明文查看",
                                verbose_name="允许查看 Token 明文",
                            ),
                        ),
                        (
                            "user_agreement_content",
                            models.TextField(
                                blank=True,
                                help_text="用户注册时需要同意的协议内容，支持HTML",
                                verbose_name="用户协议内容",
                            ),
                        ),
                        (
                            "risk_warning_content",
                            models.TextField(
                                blank=True,
                                help_text="用户注册时需要确认的风险提示内容，支持HTML",
                                verbose_name="风险提示内容",
                            ),
                        ),
                        ("notes", models.TextField(blank=True, verbose_name="备注")),
                        (
                            "benchmark_code_map",
                            models.JSONField(
                                blank=True,
                                default=dict,
                                help_text="系统运行时使用的基准/默认指数代码映射",
                                verbose_name="基准代码映射",
                            ),
                        ),
                        (
                            "asset_proxy_code_map",
                            models.JSONField(
                                blank=True,
                                default=dict,
                                help_text="资产类别到实际交易/价格代理代码的映射",
                                verbose_name="资产代理代码映射",
                            ),
                        ),
                        (
                            "backup_email",
                            models.EmailField(
                                blank=True,
                                help_text="启用后按周期发送数据库全量备份下载链接到该邮箱",
                                max_length=254,
                                verbose_name="数据库备份接收邮箱",
                            ),
                        ),
                        (
                            "backup_app_base_url",
                            models.URLField(
                                blank=True,
                                help_text="用于生成邮件中的绝对下载链接，如 https://example.com",
                                verbose_name="备份下载站点地址",
                            ),
                        ),
                        (
                            "backup_mail_from_email",
                            models.EmailField(
                                blank=True,
                                help_text="留空则回退到系统默认发件人",
                                max_length=254,
                                verbose_name="备份邮件发件人",
                            ),
                        ),
                        (
                            "backup_smtp_host",
                            models.CharField(blank=True, max_length=255, verbose_name="SMTP 主机"),
                        ),
                        ("backup_smtp_port", models.PositiveIntegerField(default=587, verbose_name="SMTP 端口")),
                        (
                            "backup_smtp_username",
                            models.CharField(blank=True, max_length=255, verbose_name="SMTP 用户名"),
                        ),
                        (
                            "backup_smtp_password_encrypted",
                            models.TextField(
                                blank=True,
                                help_text="系统内部加密存储",
                                verbose_name="SMTP 密码（密文）",
                            ),
                        ),
                        ("backup_smtp_use_tls", models.BooleanField(default=True, verbose_name="SMTP 使用 TLS")),
                        ("backup_smtp_use_ssl", models.BooleanField(default=False, verbose_name="SMTP 使用 SSL")),
                        (
                            "backup_enabled",
                            models.BooleanField(
                                default=False,
                                help_text="开启后系统会按设定周期发送备份下载链接",
                                verbose_name="启用数据库备份邮件",
                            ),
                        ),
                        (
                            "backup_interval_days",
                            models.PositiveIntegerField(
                                default=7,
                                help_text="每隔多少天发送一次数据库备份下载链接",
                                verbose_name="备份周期（天）",
                            ),
                        ),
                        (
                            "backup_link_ttl_days",
                            models.PositiveIntegerField(
                                default=3,
                                help_text="邮件中的备份下载链接有效天数",
                                verbose_name="下载链接有效期（天）",
                            ),
                        ),
                        (
                            "backup_password_encrypted",
                            models.TextField(
                                blank=True,
                                help_text="系统内部加密存储，用于生成加密备份文件",
                                verbose_name="备份压缩密码（密文）",
                            ),
                        ),
                        (
                            "backup_password_hint",
                            models.CharField(
                                blank=True,
                                help_text="可选，用于管理员识别当前使用的备份密码",
                                max_length=255,
                                verbose_name="备份密码提示",
                            ),
                        ),
                        (
                            "backup_last_sent_at",
                            models.DateTimeField(blank=True, null=True, verbose_name="上次备份邮件发送时间"),
                        ),
                        (
                            "qlib_enabled",
                            models.BooleanField(
                                default=False,
                                help_text="开启后系统将使用 Qlib 进行量化分析",
                                verbose_name="启用 Qlib",
                            ),
                        ),
                        (
                            "qlib_provider_uri",
                            models.CharField(
                                blank=True,
                                default="",
                                help_text="Qlib 数据存储路径，如 D:/qlib_data/cn_data 或 /var/lib/qlib/cn_data",
                                max_length=500,
                                verbose_name="Qlib 数据目录",
                            ),
                        ),
                        (
                            "qlib_region",
                            models.CharField(
                                default="CN",
                                help_text="市场区域，如 CN（中国）、US（美国）",
                                max_length=10,
                                verbose_name="Qlib 区域",
                            ),
                        ),
                        (
                            "qlib_model_path",
                            models.CharField(
                                blank=True,
                                default="",
                                help_text="Qlib 模型存储路径，留空使用默认路径",
                                max_length=500,
                                verbose_name="Qlib 模型目录",
                            ),
                        ),
                        (
                            "qlib_default_universe",
                            models.CharField(default="csi300", max_length=50, verbose_name="Qlib 默认股票池"),
                        ),
                        (
                            "qlib_default_feature_set_id",
                            models.CharField(default="v1", max_length=50, verbose_name="Qlib 默认特征集标识"),
                        ),
                        (
                            "qlib_default_label_id",
                            models.CharField(
                                default="return_5d",
                                max_length=50,
                                verbose_name="Qlib 默认标签标识",
                            ),
                        ),
                        (
                            "qlib_train_queue_name",
                            models.CharField(default="qlib_train", max_length=64, verbose_name="Qlib 训练队列名"),
                        ),
                        (
                            "qlib_infer_queue_name",
                            models.CharField(default="qlib_infer", max_length=64, verbose_name="Qlib 推理队列名"),
                        ),
                        (
                            "qlib_allow_auto_activate",
                            models.BooleanField(
                                default=False,
                                help_text="训练触发未显式指定时，使用该全局默认值控制是否自动切换 active model。",
                                verbose_name="允许训练后自动激活",
                            ),
                        ),
                        (
                            "alpha_fixed_provider",
                            models.CharField(
                                blank=True,
                                choices=[
                                    ("", "自动降级（默认）"),
                                    ("qlib", "仅使用 Qlib"),
                                    ("cache", "仅使用缓存"),
                                    ("simple", "仅使用 Simple"),
                                    ("etf", "仅使用 ETF"),
                                ],
                                default="",
                                help_text="强制使用指定的 Provider（禁用自动降级），留空则启用自动降级",
                                max_length=20,
                                verbose_name="固定 Alpha Provider",
                            ),
                        ),
                        (
                            "alpha_pool_mode",
                            models.CharField(
                                choices=[
                                    ("strict_valuation", "严格估值覆盖池"),
                                    ("market", "市场可交易池"),
                                    ("price_covered", "价格覆盖池"),
                                ],
                                default="strict_valuation",
                                help_text="控制首页 Alpha 和实时推理默认使用哪个候选股票集合",
                                max_length=32,
                                verbose_name="Alpha 默认股票池模式",
                            ),
                        ),
                        ("created_at", models.DateTimeField(auto_now_add=True, verbose_name="创建时间")),
                        ("updated_at", models.DateTimeField(auto_now=True, verbose_name="更新时间")),
                    ],
                    options={
                        "verbose_name": "系统配置",
                        "verbose_name_plural": "系统配置",
                        "db_table": "system_settings",
                    },
                ),
            ],
            database_operations=[],
        ),
        migrations.RunSQL(
            sql=(
                "ALTER TABLE system_settings "
                "ADD COLUMN qlib_default_universe varchar(50) NOT NULL DEFAULT 'csi300'"
            ),
            reverse_sql=migrations.RunSQL.noop,
        ),
        migrations.RunSQL(
            sql=(
                "ALTER TABLE system_settings "
                "ADD COLUMN qlib_default_feature_set_id varchar(50) NOT NULL DEFAULT 'v1'"
            ),
            reverse_sql=migrations.RunSQL.noop,
        ),
        migrations.RunSQL(
            sql=(
                "ALTER TABLE system_settings "
                "ADD COLUMN qlib_default_label_id varchar(50) NOT NULL DEFAULT 'return_5d'"
            ),
            reverse_sql=migrations.RunSQL.noop,
        ),
        migrations.RunSQL(
            sql=(
                "ALTER TABLE system_settings "
                "ADD COLUMN qlib_train_queue_name varchar(64) NOT NULL DEFAULT 'qlib_train'"
            ),
            reverse_sql=migrations.RunSQL.noop,
        ),
        migrations.RunSQL(
            sql=(
                "ALTER TABLE system_settings "
                "ADD COLUMN qlib_infer_queue_name varchar(64) NOT NULL DEFAULT 'qlib_infer'"
            ),
            reverse_sql=migrations.RunSQL.noop,
        ),
        migrations.RunSQL(
            sql=(
                "ALTER TABLE system_settings "
                "ADD COLUMN qlib_allow_auto_activate bool NOT NULL DEFAULT 0"
            ),
            reverse_sql=migrations.RunSQL.noop,
        ),
        migrations.CreateModel(
            name="QlibTrainingRunModel",
            fields=[
                (
                    "id",
                    models.BigAutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("run_id", models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, unique=True)),
                (
                    "status",
                    models.CharField(
                        choices=[
                            ("PENDING", "等待中"),
                            ("RUNNING", "运行中"),
                            ("SUCCEEDED", "成功"),
                            ("FAILED", "失败"),
                            ("CANCELLED", "取消"),
                        ],
                        db_index=True,
                        default="PENDING",
                        max_length=16,
                        verbose_name="状态",
                    ),
                ),
                (
                    "requested_at",
                    models.DateTimeField(
                        db_index=True,
                        default=django.utils.timezone.now,
                        verbose_name="发起时间",
                    ),
                ),
                ("started_at", models.DateTimeField(blank=True, null=True, verbose_name="开始时间")),
                ("finished_at", models.DateTimeField(blank=True, null=True, verbose_name="结束时间")),
                (
                    "celery_task_id",
                    models.CharField(blank=True, default="", max_length=100, verbose_name="Celery Task ID"),
                ),
                ("model_name", models.CharField(max_length=100, verbose_name="模型名称")),
                ("model_type", models.CharField(max_length=50, verbose_name="模型类型")),
                (
                    "resolved_train_config",
                    models.JSONField(blank=True, default=dict, verbose_name="最终训练配置"),
                ),
                (
                    "result_model_name",
                    models.CharField(blank=True, default="", max_length=100, verbose_name="结果模型名"),
                ),
                (
                    "result_artifact_hash",
                    models.CharField(blank=True, default="", max_length=64, verbose_name="结果 Artifact Hash"),
                ),
                ("result_metrics", models.JSONField(blank=True, default=dict, verbose_name="结果指标")),
                ("registry_result", models.JSONField(blank=True, default=dict, verbose_name="注册结果")),
                ("error_message", models.TextField(blank=True, verbose_name="错误信息")),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                (
                    "profile",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="runs",
                        to="config_center.qlibtrainingprofilemodel",
                        verbose_name="训练模板",
                    ),
                ),
                (
                    "requested_by",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="qlib_training_runs",
                        to=settings.AUTH_USER_MODEL,
                        verbose_name="发起人",
                    ),
                ),
            ],
            options={
                "verbose_name": "Qlib 训练任务",
                "verbose_name_plural": "Qlib 训练任务",
                "db_table": "config_center_qlib_training_run",
                "ordering": ["-requested_at", "-id"],
            },
        ),
    ]

