-- -----------------------王立钊2026-04-22 10:00:00-----------------------

--------------------pgsql创建 asynch_models / asynch_task 表语句---------------------------

-- 异步模型表
CREATE TABLE IF NOT EXISTS asynch_models (
    -- 基础字段（与现有表保持一致）
    id BIGINT PRIMARY KEY, -- 主键ID（非自增）
    tenant_id BIGINT NOT NULL DEFAULT 0, -- 租户ID
    creator VARCHAR(64) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted_at timestamp(6),

    -- 业务字段
    model_name VARCHAR(128) NOT NULL, -- 模型名称（路由键）
    base_url VARCHAR(256) NOT NULL, -- 模型服务基础地址（如 http://1.2.3.4:8080）
    route VARCHAR(256) NOT NULL DEFAULT '', -- 模型服务路由（如 /v1/infer）
    http_method VARCHAR(8) NOT NULL DEFAULT 'POST', -- 请求方式：GET/POST
    api_key VARCHAR(256) DEFAULT '', -- 请求密钥绑定（请求头），示例：TTS_API_KEY:your-key
    enabled SMALLINT NOT NULL DEFAULT 1, -- 是否启用：1启用/0停用
    max_concurrency INT NOT NULL DEFAULT 10, -- 单模型最大并发（worker/队列消费侧应遵守）
    queue_limit INT NOT NULL DEFAULT 1000, -- 单模型排队上限（防堆积，可选）
    timeout_ms INT NOT NULL DEFAULT 60000, -- 调用模型服务超时（毫秒）
    retry_times SMALLINT NOT NULL DEFAULT 0, -- 失败重试次数（0表示不重试）
    auto_clean_seconds INT NOT NULL DEFAULT 86400, -- 已下载(state=4)后的保留时间（秒），到期后清理
    remark TEXT DEFAULT '' -- 备注
);

-- 索引/约束
CREATE UNIQUE INDEX IF NOT EXISTS uk_asynch_models_tenant_model_name ON asynch_models(tenant_id, model_name);
CREATE INDEX IF NOT EXISTS idx_asynch_models_tenant_id ON asynch_models(tenant_id);
CREATE INDEX IF NOT EXISTS idx_asynch_models_model_name ON asynch_models(model_name);
CREATE INDEX IF NOT EXISTS idx_asynch_models_enabled ON asynch_models(enabled);
CREATE INDEX IF NOT EXISTS idx_asynch_models_deleted_at ON asynch_models(deleted_at);

-- 表和字段注释
COMMENT ON TABLE asynch_models IS '异步模型表（模型服务配置）';
COMMENT ON COLUMN asynch_models.id IS '主键ID（非自增）';
COMMENT ON COLUMN asynch_models.tenant_id IS '租户ID';
COMMENT ON COLUMN asynch_models.creator IS '创建人';
COMMENT ON COLUMN asynch_models.created_at IS '创建时间';
COMMENT ON COLUMN asynch_models.updater IS '更新人';
COMMENT ON COLUMN asynch_models.updated_at IS '更新时间';
COMMENT ON COLUMN asynch_models.deleted_at IS '删除时间（软删）';
COMMENT ON COLUMN asynch_models.model_name IS '模型名称（路由键）';
COMMENT ON COLUMN asynch_models.base_url IS '模型服务基础地址';
COMMENT ON COLUMN asynch_models.route IS '模型服务路由';
COMMENT ON COLUMN asynch_models.http_method IS '请求方式：GET/POST';
COMMENT ON COLUMN asynch_models.api_key IS '请求密钥绑定（请求头），示例：TTS_API_KEY:your-key';
COMMENT ON COLUMN asynch_models.enabled IS '是否启用：1启用/0停用';
COMMENT ON COLUMN asynch_models.max_concurrency IS '单模型最大并发';
COMMENT ON COLUMN asynch_models.queue_limit IS '单模型排队上限';
COMMENT ON COLUMN asynch_models.timeout_ms IS '调用模型服务超时（毫秒）';
COMMENT ON COLUMN asynch_models.retry_times IS '失败重试次数';
COMMENT ON COLUMN asynch_models.auto_clean_seconds IS '已下载(state=4)后的保留时间（秒），到期后清理';
COMMENT ON COLUMN asynch_models.remark IS '备注';

-- 兼容已有库：更新字段注释
COMMENT ON COLUMN asynch_models.auto_clean_seconds IS '已下载(state=4)后的保留时间（秒），到期后清理';


-- 异步任务表
CREATE TABLE IF NOT EXISTS asynch_task (
    -- 基础字段（与现有表保持一致）
    id BIGINT PRIMARY KEY, -- 主键ID（非自增）
    tenant_id BIGINT NOT NULL DEFAULT 0, -- 租户ID
    creator VARCHAR(64) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted_at timestamp(6),

    -- 任务核心字段
    model_name VARCHAR(128) NOT NULL, -- 模型名称
    task_id VARCHAR(64) NOT NULL, -- 任务ID（对外返回）
    state SMALLINT NOT NULL DEFAULT 0, -- 状态：0排队中/1执行中/2成功/3失败/4已下载
    oss_file VARCHAR(512) DEFAULT '', -- OSS文件URL/Key
    file_type VARCHAR(32) DEFAULT '', -- 文件类型（如 mp3/mp4/png/pdf/...）
    file_size BIGINT NOT NULL DEFAULT 0, -- 文件大小（字节）
    error_msg TEXT DEFAULT '', -- 错误信息

    -- 执行与清理字段
    started_at TIMESTAMP, -- 开始执行时间
    finished_at TIMESTAMP, -- 执行结束时间
    expire_at TIMESTAMP, -- 过期清理时间（已下载后写入：updated_at + auto_clean_seconds）
    retry_count INT NOT NULL DEFAULT 0, -- 已重试次数（不含首次）
    enqueue_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 入队时间（用于排队顺序，重试会更新时间到队尾）

    -- 输入信息（用于排障/重放；如不需要可不写入或置空）
    input_ref TEXT DEFAULT '', -- 输入引用（如上传文件URL/OSS key/业务侧资源ID）
    request_payload JSONB -- 请求参数（可选）
);

-- 索引/约束
CREATE UNIQUE INDEX IF NOT EXISTS uk_asynch_task_tenant_task_id ON asynch_task(tenant_id, task_id);
CREATE INDEX IF NOT EXISTS idx_asynch_task_tenant_id ON asynch_task(tenant_id);
CREATE INDEX IF NOT EXISTS idx_asynch_task_model_name ON asynch_task(model_name);
CREATE INDEX IF NOT EXISTS idx_asynch_task_state ON asynch_task(state);
CREATE INDEX IF NOT EXISTS idx_asynch_task_updated_at ON asynch_task(updated_at);
CREATE INDEX IF NOT EXISTS idx_asynch_task_expire_at ON asynch_task(expire_at);
CREATE INDEX IF NOT EXISTS idx_asynch_task_deleted_at ON asynch_task(deleted_at);

-- 表和字段注释
COMMENT ON TABLE asynch_task IS '异步任务表';
COMMENT ON COLUMN asynch_task.id IS '主键ID（非自增）';
COMMENT ON COLUMN asynch_task.tenant_id IS '租户ID';
COMMENT ON COLUMN asynch_task.creator IS '创建人';
COMMENT ON COLUMN asynch_task.created_at IS '创建时间';
COMMENT ON COLUMN asynch_task.updater IS '更新人';
COMMENT ON COLUMN asynch_task.updated_at IS '更新时间';
COMMENT ON COLUMN asynch_task.deleted_at IS '删除时间（软删）';
COMMENT ON COLUMN asynch_task.model_name IS '模型名称';
COMMENT ON COLUMN asynch_task.task_id IS '任务ID（对外返回）';
COMMENT ON COLUMN asynch_task.state IS '状态：0排队中/1执行中/2成功/3失败/4已下载';
COMMENT ON COLUMN asynch_task.oss_file IS 'OSS文件URL/Key';
COMMENT ON COLUMN asynch_task.file_type IS '文件类型';
COMMENT ON COLUMN asynch_task.file_size IS '文件大小（字节）';
COMMENT ON COLUMN asynch_task.error_msg IS '错误信息';
COMMENT ON COLUMN asynch_task.started_at IS '开始执行时间';
COMMENT ON COLUMN asynch_task.finished_at IS '执行结束时间';
COMMENT ON COLUMN asynch_task.expire_at IS '过期清理时间（已下载后保留到期）';
COMMENT ON COLUMN asynch_task.retry_count IS '已重试次数（不含首次）';
COMMENT ON COLUMN asynch_task.enqueue_at IS '入队时间（用于排队顺序，重试会更新时间到队尾）';
COMMENT ON COLUMN asynch_task.input_ref IS '输入引用（如上传文件URL/OSS key/业务侧资源ID）';
COMMENT ON COLUMN asynch_task.request_payload IS '请求参数（JSON）';

-- 兼容已有库：增量加字段（PostgreSQL 支持 IF NOT EXISTS）
ALTER TABLE asynch_task ADD COLUMN IF NOT EXISTS retry_count INT NOT NULL DEFAULT 0;
ALTER TABLE asynch_task ADD COLUMN IF NOT EXISTS enqueue_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
COMMENT ON COLUMN asynch_task.retry_count IS '已重试次数（不含首次）';
COMMENT ON COLUMN asynch_task.enqueue_at IS '入队时间（用于排队顺序，重试会更新时间到队尾）';
COMMENT ON COLUMN asynch_task.state IS '状态：0排队中/1执行中/2成功/3失败/4已下载';
COMMENT ON COLUMN asynch_task.expire_at IS '过期清理时间（已下载后保留到期）';

-- 对存量数据进行入队时间回填（只在 enqueue_at 为空时）
UPDATE asynch_task SET enqueue_at = created_at WHERE enqueue_at IS NULL;
