mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
🗃️ chore: add userId to all task sub-tables and consolidate handoff into jsonb
- Add userId (NOT NULL, FK cascade) to taskDependencies, taskDocuments, taskComments - Rename taskComments userId/agentId to authorUserId/authorAgentId for clarity - Consolidate 4 handoff columns into single jsonb field on taskTopics - Add updatedAt/accessedAt timestamps to taskTopics - Merge migration 0096 into 0095 (feature branch, not yet released) - Change default identifier prefix from TASK to T Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,8 +22,9 @@ CREATE TABLE IF NOT EXISTS "briefs" (
|
||||
CREATE TABLE IF NOT EXISTS "task_comments" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"task_id" text NOT NULL,
|
||||
"user_id" text,
|
||||
"agent_id" text,
|
||||
"user_id" text NOT NULL,
|
||||
"author_user_id" text,
|
||||
"author_agent_id" text,
|
||||
"content" text NOT NULL,
|
||||
"editor_data" jsonb,
|
||||
"brief_id" uuid,
|
||||
@@ -37,6 +38,7 @@ CREATE TABLE IF NOT EXISTS "task_dependencies" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"task_id" text NOT NULL,
|
||||
"depends_on_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"type" text DEFAULT 'blocks' NOT NULL,
|
||||
"condition" jsonb,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
@@ -46,6 +48,7 @@ CREATE TABLE IF NOT EXISTS "task_documents" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"task_id" text NOT NULL,
|
||||
"document_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"pinned_by" text DEFAULT 'agent' NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
@@ -54,15 +57,19 @@ CREATE TABLE IF NOT EXISTS "task_topics" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"task_id" text NOT NULL,
|
||||
"topic_id" text NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"seq" integer NOT NULL,
|
||||
"operation_id" text,
|
||||
"status" text DEFAULT 'running' NOT NULL,
|
||||
"handoff" jsonb,
|
||||
"review_passed" integer,
|
||||
"review_score" integer,
|
||||
"review_scores" jsonb,
|
||||
"review_iteration" integer,
|
||||
"reviewed_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
"accessed_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "tasks" (
|
||||
@@ -106,16 +113,24 @@ ALTER TABLE "briefs" DROP CONSTRAINT IF EXISTS "briefs_cron_job_id_agent_cron_jo
|
||||
ALTER TABLE "briefs" ADD CONSTRAINT "briefs_cron_job_id_agent_cron_jobs_id_fk" FOREIGN KEY ("cron_job_id") REFERENCES "public"."agent_cron_jobs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_comments" DROP CONSTRAINT IF EXISTS "task_comments_task_id_tasks_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_comments" ADD CONSTRAINT "task_comments_task_id_tasks_id_fk" FOREIGN KEY ("task_id") REFERENCES "public"."tasks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_comments" DROP CONSTRAINT IF EXISTS "task_comments_user_id_users_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_comments" ADD CONSTRAINT "task_comments_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_dependencies" DROP CONSTRAINT IF EXISTS "task_dependencies_task_id_tasks_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_dependencies" ADD CONSTRAINT "task_dependencies_task_id_tasks_id_fk" FOREIGN KEY ("task_id") REFERENCES "public"."tasks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_dependencies" DROP CONSTRAINT IF EXISTS "task_dependencies_depends_on_id_tasks_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_dependencies" ADD CONSTRAINT "task_dependencies_depends_on_id_tasks_id_fk" FOREIGN KEY ("depends_on_id") REFERENCES "public"."tasks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_dependencies" DROP CONSTRAINT IF EXISTS "task_dependencies_user_id_users_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_dependencies" ADD CONSTRAINT "task_dependencies_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_documents" DROP CONSTRAINT IF EXISTS "task_documents_task_id_tasks_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_documents" ADD CONSTRAINT "task_documents_task_id_tasks_id_fk" FOREIGN KEY ("task_id") REFERENCES "public"."tasks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_documents" DROP CONSTRAINT IF EXISTS "task_documents_document_id_documents_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_documents" ADD CONSTRAINT "task_documents_document_id_documents_id_fk" FOREIGN KEY ("document_id") REFERENCES "public"."documents"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_documents" DROP CONSTRAINT IF EXISTS "task_documents_user_id_users_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_documents" ADD CONSTRAINT "task_documents_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" DROP CONSTRAINT IF EXISTS "task_topics_task_id_tasks_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" ADD CONSTRAINT "task_topics_task_id_tasks_id_fk" FOREIGN KEY ("task_id") REFERENCES "public"."tasks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" DROP CONSTRAINT IF EXISTS "task_topics_user_id_users_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" ADD CONSTRAINT "task_topics_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "tasks" DROP CONSTRAINT IF EXISTS "tasks_created_by_user_id_users_id_fk";--> statement-breakpoint
|
||||
ALTER TABLE "tasks" ADD CONSTRAINT "tasks_created_by_user_id_users_id_fk" FOREIGN KEY ("created_by_user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "briefs_user_id_idx" ON "briefs" USING btree ("user_id");--> statement-breakpoint
|
||||
@@ -127,18 +142,22 @@ CREATE INDEX IF NOT EXISTS "briefs_priority_idx" ON "briefs" USING btree ("prior
|
||||
CREATE INDEX IF NOT EXISTS "briefs_unresolved_idx" ON "briefs" USING btree ("user_id","resolved_at");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_comments_task_id_idx" ON "task_comments" USING btree ("task_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_comments_user_id_idx" ON "task_comments" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_comments_agent_id_idx" ON "task_comments" USING btree ("agent_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_comments_author_user_id_idx" ON "task_comments" USING btree ("author_user_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_comments_agent_id_idx" ON "task_comments" USING btree ("author_agent_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_comments_brief_id_idx" ON "task_comments" USING btree ("brief_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_comments_topic_id_idx" ON "task_comments" USING btree ("topic_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "task_deps_unique_idx" ON "task_dependencies" USING btree ("task_id","depends_on_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_deps_task_id_idx" ON "task_dependencies" USING btree ("task_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_deps_depends_on_id_idx" ON "task_dependencies" USING btree ("depends_on_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_deps_user_id_idx" ON "task_dependencies" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "task_docs_unique_idx" ON "task_documents" USING btree ("task_id","document_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_docs_task_id_idx" ON "task_documents" USING btree ("task_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_docs_document_id_idx" ON "task_documents" USING btree ("document_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_docs_user_id_idx" ON "task_documents" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "task_topics_unique_idx" ON "task_topics" USING btree ("task_id","topic_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_topics_task_id_idx" ON "task_topics" USING btree ("task_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_topics_topic_id_idx" ON "task_topics" USING btree ("topic_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_topics_user_id_idx" ON "task_topics" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "task_topics_status_idx" ON "task_topics" USING btree ("task_id","status");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "tasks_identifier_idx" ON "tasks" USING btree ("identifier","created_by_user_id");--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "tasks_created_by_user_id_idx" ON "tasks" USING btree ("created_by_user_id");--> statement-breakpoint
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
ALTER TABLE "task_topics" ADD COLUMN "user_id" text NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" ADD COLUMN "handoff_title" text;--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" ADD COLUMN "handoff_summary" text;--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" ADD COLUMN "handoff_key_findings" jsonb;--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" ADD COLUMN "handoff_next_action" text;--> statement-breakpoint
|
||||
ALTER TABLE "task_topics" ADD CONSTRAINT "task_topics_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "task_topics_user_id_idx" ON "task_topics" USING btree ("user_id");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -672,13 +672,6 @@
|
||||
"when": 1774180022586,
|
||||
"tag": "0095_add_agent_task_system",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 96,
|
||||
"version": "7",
|
||||
"when": 1774189914853,
|
||||
"tag": "0096_lush_praxagora",
|
||||
"breakpoints": true
|
||||
}
|
||||
],
|
||||
"version": "6"
|
||||
|
||||
@@ -311,7 +311,7 @@ export class TaskModel {
|
||||
async addDependency(taskId: string, dependsOnId: string, type: string = 'blocks'): Promise<void> {
|
||||
await this.db
|
||||
.insert(taskDependencies)
|
||||
.values({ dependsOnId, taskId, type })
|
||||
.values({ dependsOnId, taskId, type, userId: this.userId })
|
||||
.onConflictDoNothing();
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ export class TaskModel {
|
||||
async pinDocument(taskId: string, documentId: string, pinnedBy: string = 'agent'): Promise<void> {
|
||||
await this.db
|
||||
.insert(taskDocuments)
|
||||
.values({ documentId, pinnedBy, taskId })
|
||||
.values({ documentId, pinnedBy, taskId, userId: this.userId })
|
||||
.onConflictDoNothing();
|
||||
}
|
||||
|
||||
@@ -516,6 +516,7 @@ export class TaskModel {
|
||||
const result = await this.db
|
||||
.delete(taskComments)
|
||||
.where(and(eq(taskComments.id, id), eq(taskComments.userId, this.userId)))
|
||||
|
||||
.returning();
|
||||
return result.length > 0;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,9 @@ export const taskDependencies = pgTable(
|
||||
dependsOnId: text('depends_on_id')
|
||||
.references(() => tasks.id, { onDelete: 'cascade' })
|
||||
.notNull(),
|
||||
userId: text('user_id')
|
||||
.references(() => users.id, { onDelete: 'cascade' })
|
||||
.notNull(),
|
||||
|
||||
// 'blocks' | 'relates'
|
||||
type: text('type').notNull().default('blocks'),
|
||||
@@ -108,6 +111,7 @@ export const taskDependencies = pgTable(
|
||||
uniqueIndex('task_deps_unique_idx').on(t.taskId, t.dependsOnId),
|
||||
index('task_deps_task_id_idx').on(t.taskId),
|
||||
index('task_deps_depends_on_id_idx').on(t.dependsOnId),
|
||||
index('task_deps_user_id_idx').on(t.userId),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -126,6 +130,9 @@ export const taskDocuments = pgTable(
|
||||
documentId: text('document_id')
|
||||
.references(() => documents.id, { onDelete: 'cascade' })
|
||||
.notNull(),
|
||||
userId: text('user_id')
|
||||
.references(() => users.id, { onDelete: 'cascade' })
|
||||
.notNull(),
|
||||
|
||||
// 'agent' | 'user' | 'system'
|
||||
pinnedBy: text('pinned_by').notNull().default('agent'),
|
||||
@@ -136,6 +143,7 @@ export const taskDocuments = pgTable(
|
||||
uniqueIndex('task_docs_unique_idx').on(t.taskId, t.documentId),
|
||||
index('task_docs_task_id_idx').on(t.taskId),
|
||||
index('task_docs_document_id_idx').on(t.documentId),
|
||||
index('task_docs_user_id_idx').on(t.userId),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -162,10 +170,8 @@ export const taskTopics = pgTable(
|
||||
status: text('status').notNull().default('running'),
|
||||
|
||||
// Handoff (populated after topic completes via LLM summarization)
|
||||
handoffTitle: text('handoff_title'),
|
||||
handoffSummary: text('handoff_summary'),
|
||||
handoffKeyFindings: jsonb('handoff_key_findings'), // string[]
|
||||
handoffNextAction: text('handoff_next_action'),
|
||||
// { title, summary, keyFindings: string[], nextAction }
|
||||
handoff: jsonb('handoff'),
|
||||
|
||||
// Review results (populated after topic completes + review runs)
|
||||
reviewPassed: integer('review_passed'), // 1 = passed, 0 = failed, null = not reviewed
|
||||
@@ -174,7 +180,7 @@ export const taskTopics = pgTable(
|
||||
reviewIteration: integer('review_iteration'), // which iteration (1, 2, 3...)
|
||||
reviewedAt: timestamptz('reviewed_at'),
|
||||
|
||||
createdAt: createdAt(),
|
||||
...timestamps,
|
||||
},
|
||||
(t) => [
|
||||
uniqueIndex('task_topics_unique_idx').on(t.taskId, t.topicId),
|
||||
@@ -197,10 +203,13 @@ export const taskComments = pgTable(
|
||||
taskId: text('task_id')
|
||||
.references(() => tasks.id, { onDelete: 'cascade' })
|
||||
.notNull(),
|
||||
userId: text('user_id')
|
||||
.references(() => users.id, { onDelete: 'cascade' })
|
||||
.notNull(),
|
||||
|
||||
// Author (one of)
|
||||
userId: text('user_id'),
|
||||
agentId: text('agent_id'),
|
||||
authorUserId: text('author_user_id'),
|
||||
authorAgentId: text('author_agent_id'),
|
||||
|
||||
// Content
|
||||
content: text('content').notNull(),
|
||||
@@ -215,7 +224,8 @@ export const taskComments = pgTable(
|
||||
(t) => [
|
||||
index('task_comments_task_id_idx').on(t.taskId),
|
||||
index('task_comments_user_id_idx').on(t.userId),
|
||||
index('task_comments_agent_id_idx').on(t.agentId),
|
||||
index('task_comments_author_user_id_idx').on(t.authorUserId),
|
||||
index('task_comments_agent_id_idx').on(t.authorAgentId),
|
||||
index('task_comments_brief_id_idx').on(t.briefId),
|
||||
index('task_comments_topic_id_idx').on(t.topicId),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user