-- model-asynch 三张核心表（pgsql）
-- 1) asynch_models：模型配置
-- 2) asynch_task：异步任务
-- 3) asynch_op_log：操作日志（统计用）

-- =========================
-- 1) asynch_models
-- =========================
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(1024) DEFAULT '',      -- 请求头绑定（支持多个，逗号分隔）：X-API-Key:xxx,operation:true

    enabled SMALLINT NOT NULL DEFAULT 1,   -- 是否启用：1启用/0停用
    max_concurrency INT NOT NULL DEFAULT 10, -- 单模型最大并发
    queue_limit INT NOT NULL DEFAULT 1000, -- 排队上限（近似控制）
    timeout_seconds INT NOT NULL DEFAULT 60, -- 调用模型服务超时（秒）

    retry_times SMALLINT NOT NULL DEFAULT 0, -- 失败后最多再重试 N 次（不含首次）
    retry_queue_max_seconds INT NOT NULL DEFAULT 0, -- 失败重试最大排队时间（秒）：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.model_name IS '模型名称（路由键）';
COMMENT ON COLUMN asynch_models.api_key IS '请求头绑定（支持多个，逗号分隔）：X-API-Key:xxx,operation:true';
COMMENT ON COLUMN asynch_models.retry_times IS '失败后最多再重试 N 次（不含首次）';
COMMENT ON COLUMN asynch_models.retry_queue_max_seconds IS '失败重试最大排队时间（秒）：0=插队到队首；>0=排队超过该时间后插队，否则仍到队尾';
COMMENT ON COLUMN asynch_models.auto_clean_seconds IS '已下载(state=4)后的保留时间（秒），到期清理';


-- =========================
-- 2) asynch_task
-- =========================
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地址
    file_type VARCHAR(32) DEFAULT '',      -- 文件类型（mp3/mp4/png/...）
    file_size BIGINT NOT NULL DEFAULT 0,   -- 文件大小（字节）
    error_msg TEXT DEFAULT '',             -- 错误信息

    started_at TIMESTAMP,                 -- 开始执行时间
    finished_at TIMESTAMP,                -- 执行结束时间

    expire_at TIMESTAMP,                  -- state=4 后写入，用于清理

    -- 重试/排队
    retry_count INT NOT NULL DEFAULT 0,   -- 已重试次数（不含首次）
    enqueue_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 入队时间（用于排队顺序）

    -- 任务执行阶段：用于区分“重试模型”与“仅重试 OSS”
    phase SMALLINT NOT NULL DEFAULT 0,    -- 0模型阶段/1OSS阶段
    tmp_file TEXT DEFAULT '',             -- 临时结果文件路径（phase=1 时仅重试 OSS 上传）

    -- 输入信息（可选）
    input_ref TEXT DEFAULT '',            -- 输入引用（如OSS/业务资源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_enqueue_at ON asynch_task(enqueue_at);
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.state IS '0排队中/1执行中/2成功/3失败/4已下载';
COMMENT ON COLUMN asynch_task.retry_count IS '已重试次数（不含首次）';
COMMENT ON COLUMN asynch_task.enqueue_at IS '入队时间（用于排队顺序）';
COMMENT ON COLUMN asynch_task.phase IS '执行阶段：0模型阶段/1OSS阶段（模型已成功，等待上传OSS）';
COMMENT ON COLUMN asynch_task.tmp_file IS '临时结果文件路径（phase=1 时仅重试 OSS 上传）';


-- =========================
-- 3) asynch_op_log
-- =========================
CREATE TABLE IF NOT EXISTS asynch_op_log (
    -- 基础字段（与现有表保持一致）
    id BIGINT PRIMARY KEY,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    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),

    -- 基础审计信息
    ip VARCHAR(64) DEFAULT '',
    user_agent VARCHAR(256) DEFAULT '',
    api_path VARCHAR(256) DEFAULT '',
    http_method VARCHAR(16) DEFAULT '',

    -- 业务信息
    biz_name VARCHAR(128) NOT NULL DEFAULT '', -- 调用方业务模块/系统
    model_name VARCHAR(128) NOT NULL DEFAULT '',
    task_id VARCHAR(64) NOT NULL DEFAULT '',

    -- 统计字段
    op_type VARCHAR(64) NOT NULL DEFAULT 'createTask', -- 操作类型（默认创建任务）
    success SMALLINT NOT NULL DEFAULT 1, -- 1成功/0失败
    error_msg TEXT DEFAULT '',
    cost_ms BIGINT NOT NULL DEFAULT 0, -- 耗时（毫秒）

    -- 请求/响应 JSON（用于后期统计分析）
    request_payload JSONB,
    response_payload JSONB
);

CREATE INDEX IF NOT EXISTS idx_asynch_op_log_tenant_time ON asynch_op_log(tenant_id, created_at);
CREATE INDEX IF NOT EXISTS idx_asynch_op_log_model_name ON asynch_op_log(model_name);
CREATE INDEX IF NOT EXISTS idx_asynch_op_log_biz_name ON asynch_op_log(biz_name);
CREATE INDEX IF NOT EXISTS idx_asynch_op_log_task_id ON asynch_op_log(task_id);
CREATE INDEX IF NOT EXISTS idx_asynch_op_log_op_type ON asynch_op_log(op_type);
CREATE INDEX IF NOT EXISTS idx_asynch_op_log_deleted_at ON asynch_op_log(deleted_at);

COMMENT ON TABLE asynch_op_log IS '操作记录日志表（创建任务等，用于统计）';
COMMENT ON COLUMN asynch_op_log.biz_name IS '业务名称（调用方模块/系统）';
COMMENT ON COLUMN asynch_op_log.model_name IS '模型名称';
COMMENT ON COLUMN asynch_op_log.task_id IS '任务ID';
COMMENT ON COLUMN asynch_op_log.op_type IS '操作类型（如 createTask/getTaskResult/getTaskBatch 等）';
COMMENT ON COLUMN asynch_op_log.success IS '是否成功：1成功/0失败';
COMMENT ON COLUMN asynch_op_log.error_msg IS '错误信息（失败时）';
COMMENT ON COLUMN asynch_op_log.cost_ms IS '耗时（毫秒）';
COMMENT ON COLUMN asynch_op_log.request_payload IS '请求 JSON';
COMMENT ON COLUMN asynch_op_log.response_payload IS '响应 JSON';
