背景:A6 任务中心需要统一任务协议(九态状态机 / 队列映射 / SSE 事件)与任务落库模型,供 API、worker 与前端共用,避免各端自建枚举。
改动:
- 新增 packages/shared/src/tasks/task-protocol.ts:任务类型、架构 §3.6 九态与允许迁移、5 组 9 队列定义、Outbox/SSE 事件、进度与收敛纯函数;
- 新增 packages/shared/src/schemas/tasks.ts:提交/列表/详情/取消/重试/SSE 的 Zod DTO(body camelCase、query snake_case,列表 { items, next_cursor });
- system_configs 新增 task 分组(演练上限 20 项 / 单条成本 0.02 元 / 单条时长 3 秒),seed 按定义幂等;
- Prisma 新增 media_tasks / media_items / task_events 三表与迁移 20261104125003_a6_media_tasks(expand-only,不改旧表)。
影响面:仅新增 shared 导出、配置项与三张新表,旧接口与旧表不受影响。
回滚:撤销提交,并对三张新表执行 prisma migrate resolve/删除(无业务数据)。
验证:shared 197 tests 全绿;typecheck / lint / format:check 全绿;prisma migrate status up to date。
94 lines
3.2 KiB
SQL
94 lines
3.2 KiB
SQL
-- CreateTable
|
|
CREATE TABLE "media_tasks" (
|
|
"id" CHAR(26) NOT NULL,
|
|
"type" VARCHAR(16) NOT NULL,
|
|
"status" VARCHAR(24) NOT NULL DEFAULT 'queued',
|
|
"title" VARCHAR(200) NOT NULL,
|
|
"customer_id" CHAR(26) NOT NULL,
|
|
"customer_name" VARCHAR(128) NOT NULL,
|
|
"created_by" CHAR(26) NOT NULL,
|
|
"created_by_name" VARCHAR(64) NOT NULL,
|
|
"item_total" INTEGER NOT NULL,
|
|
"item_succeeded" INTEGER NOT NULL DEFAULT 0,
|
|
"item_failed" INTEGER NOT NULL DEFAULT 0,
|
|
"item_skipped" INTEGER NOT NULL DEFAULT 0,
|
|
"estimated_items" INTEGER NOT NULL,
|
|
"estimated_cost" DECIMAL(14,4) NOT NULL,
|
|
"estimated_seconds" INTEGER NOT NULL,
|
|
"progress" INTEGER NOT NULL DEFAULT 0,
|
|
"payload_json" JSONB NOT NULL,
|
|
"cancel_requested_at" TIMESTAMPTZ(3),
|
|
"canceled_at" TIMESTAMPTZ(3),
|
|
"canceled_by" CHAR(26),
|
|
"last_error_code" VARCHAR(32),
|
|
"last_error_message" VARCHAR(500),
|
|
"started_at" TIMESTAMPTZ(3),
|
|
"finished_at" TIMESTAMPTZ(3),
|
|
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
|
|
|
CONSTRAINT "media_tasks_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "media_items" (
|
|
"id" CHAR(26) NOT NULL,
|
|
"task_id" CHAR(26) NOT NULL,
|
|
"seq" INTEGER NOT NULL,
|
|
"status" VARCHAR(24) NOT NULL DEFAULT 'queued',
|
|
"failure_code" VARCHAR(64),
|
|
"failure_message" VARCHAR(500),
|
|
"attempts" INTEGER NOT NULL DEFAULT 0,
|
|
"started_at" TIMESTAMPTZ(3),
|
|
"finished_at" TIMESTAMPTZ(3),
|
|
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
|
|
|
CONSTRAINT "media_items_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "task_events" (
|
|
"id" CHAR(26) NOT NULL,
|
|
"task_id" CHAR(26) NOT NULL,
|
|
"seq" BIGSERIAL NOT NULL,
|
|
"event_type" VARCHAR(16) NOT NULL,
|
|
"payload_json" JSONB NOT NULL,
|
|
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "task_events_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "media_tasks_customer_id_created_at_idx" ON "media_tasks"("customer_id", "created_at" DESC);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "media_tasks_status_created_at_idx" ON "media_tasks"("status", "created_at" DESC);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "media_tasks_type_created_at_idx" ON "media_tasks"("type", "created_at" DESC);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "media_tasks_created_by_created_at_idx" ON "media_tasks"("created_by", "created_at" DESC);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "media_items_task_id_status_idx" ON "media_items"("task_id", "status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "media_items_status_idx" ON "media_items"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "media_items_task_id_seq_key" ON "media_items"("task_id", "seq");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "task_events_seq_key" ON "task_events"("seq");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "task_events_task_id_seq_idx" ON "task_events"("task_id", "seq");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "media_items" ADD CONSTRAINT "media_items_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "media_tasks"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "task_events" ADD CONSTRAINT "task_events_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "media_tasks"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|