import { type Kysely, sql } from "kysely"; // @umt/tasks 自带的三张表(W2 合并进 packages/db 迁移流程): // - tasks_run_meta:引擎 run 的业务侧元数据(traceId/优先级/取消标志),取消标志是 abortSignal 的来源 // - tasks_fact:signal 之前先落库的事实;waitForFact 以它为准,信号只用来加速唤醒 // - tasks_op_ledger:操作账本(fencing),记录 attempt_token,旧 attempt 的提交会被拒绝 // biome-ignore lint/suspicious/noExplicitAny: 迁移不依赖应用表类型 export async function up(db: Kysely): Promise { await db.schema .createTable("tasks_run_meta") .addColumn("run_id", "text", (c) => c.primaryKey()) .addColumn("task_name", "text", (c) => c.notNull()) .addColumn("task_version", "integer", (c) => c.notNull()) .addColumn("idempotency_key", "text", (c) => c.notNull()) .addColumn("trace_id", "text") .addColumn("priority", "integer", (c) => c.notNull().defaultTo(0)) .addColumn("cancel_requested_at", "timestamptz") .addColumn("cancel_reason", "text") .addColumn("created_at", "timestamptz", (c) => c.notNull().defaultTo(sql`now()`)) .execute(); await db.schema .createIndex("tasks_run_meta_task_idx") .on("tasks_run_meta") .columns(["task_name", "created_at"]) .execute(); await db.schema .createTable("tasks_fact") .addColumn("id", "bigserial", (c) => c.primaryKey()) .addColumn("run_id", "text", (c) => c.notNull()) .addColumn("name", "text", (c) => c.notNull()) .addColumn("payload", "jsonb") .addColumn("created_at", "timestamptz", (c) => c.notNull().defaultTo(sql`now()`)) .execute(); await db.schema.createIndex("tasks_fact_run_name_idx").on("tasks_fact").columns(["run_id", "name", "id"]).execute(); await db.schema .createTable("tasks_op_ledger") .addColumn("op_key", "text", (c) => c.primaryKey()) .addColumn("run_id", "text") .addColumn("attempt_token", "uuid", (c) => c.notNull()) .addColumn("attempts", "integer", (c) => c.notNull().defaultTo(1)) .addColumn("status", "text", (c) => c.notNull().check(sql`status in ('started','succeeded')`)) .addColumn("result", "jsonb") .addColumn("last_error", "text") .addColumn("started_at", "timestamptz", (c) => c.notNull().defaultTo(sql`now()`)) .addColumn("completed_at", "timestamptz") .execute(); } // biome-ignore lint/suspicious/noExplicitAny: 同上 export async function down(db: Kysely): Promise { await db.schema.dropTable("tasks_op_ledger").ifExists().execute(); await db.schema.dropTable("tasks_fact").ifExists().execute(); await db.schema.dropTable("tasks_run_meta").ifExists().execute(); }