feat: async task pipeline for media and llm workflows
这个提交包含在:
@@ -301,3 +301,36 @@ export const notificationLog = mysqlTable("notification_log", {
|
||||
export type NotificationLogEntry = typeof notificationLog.$inferSelect;
|
||||
export type InsertNotificationLog = typeof notificationLog.$inferInsert;
|
||||
|
||||
/**
|
||||
* Background task queue for long-running or retryable work.
|
||||
*/
|
||||
export const backgroundTasks = mysqlTable("background_tasks", {
|
||||
id: varchar("id", { length: 36 }).primaryKey(),
|
||||
userId: int("userId").notNull(),
|
||||
type: mysqlEnum("type", [
|
||||
"media_finalize",
|
||||
"training_plan_generate",
|
||||
"training_plan_adjust",
|
||||
"analysis_corrections",
|
||||
"pose_correction_multimodal",
|
||||
]).notNull(),
|
||||
status: mysqlEnum("status", ["queued", "running", "succeeded", "failed"]).notNull().default("queued"),
|
||||
title: varchar("title", { length: 256 }).notNull(),
|
||||
message: text("message"),
|
||||
progress: int("progress").notNull().default(0),
|
||||
payload: json("payload").notNull(),
|
||||
result: json("result"),
|
||||
error: text("error"),
|
||||
attempts: int("attempts").notNull().default(0),
|
||||
maxAttempts: int("maxAttempts").notNull().default(3),
|
||||
workerId: varchar("workerId", { length: 96 }),
|
||||
runAfter: timestamp("runAfter").defaultNow().notNull(),
|
||||
lockedAt: timestamp("lockedAt"),
|
||||
startedAt: timestamp("startedAt"),
|
||||
completedAt: timestamp("completedAt"),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
});
|
||||
|
||||
export type BackgroundTask = typeof backgroundTasks.$inferSelect;
|
||||
export type InsertBackgroundTask = typeof backgroundTasks.$inferInsert;
|
||||
|
||||
在新工单中引用
屏蔽一个用户