feat(web): conversation management — search, rename, delete, archive (#121)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
- Add search/filter input to sidebar that filters conversations by title - Add rename via double-click or context menu (right-click), confirmed with Enter or blur - Add delete with inline confirmation dialog in context menu - Add archive/unarchive via context menu with collapsible archived section - Add auto-title: generates conversation title from first message content - Show relative timestamps (e.g. "2h ago", "Yesterday") instead of raw dates - Extend Conversation type with `archived` boolean field - Add `archived` column + index to conversations DB schema (migration 0001) - Extend UpdateConversationDto with optional `archived` field Fixes #121 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
81
packages/db/drizzle/0001_cynical_ultimatum.sql
Normal file
81
packages/db/drizzle/0001_cynical_ultimatum.sql
Normal file
@@ -0,0 +1,81 @@
|
||||
CREATE TABLE "agent_logs" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"session_id" text NOT NULL,
|
||||
"user_id" text,
|
||||
"level" text DEFAULT 'info' NOT NULL,
|
||||
"category" text DEFAULT 'general' NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"metadata" jsonb,
|
||||
"tier" text DEFAULT 'hot' NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"summarized_at" timestamp with time zone,
|
||||
"archived_at" timestamp with time zone
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "insights" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"embedding" vector(1536),
|
||||
"source" text DEFAULT 'agent' NOT NULL,
|
||||
"category" text DEFAULT 'general' NOT NULL,
|
||||
"relevance_score" real DEFAULT 1 NOT NULL,
|
||||
"metadata" jsonb,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"decayed_at" timestamp with time zone
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "preferences" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"key" text NOT NULL,
|
||||
"value" jsonb NOT NULL,
|
||||
"category" text DEFAULT 'general' NOT NULL,
|
||||
"source" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "skills" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"description" text,
|
||||
"version" text,
|
||||
"source" text DEFAULT 'custom' NOT NULL,
|
||||
"config" jsonb,
|
||||
"enabled" boolean DEFAULT true NOT NULL,
|
||||
"installed_by" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "skills_name_unique" UNIQUE("name")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "summarization_jobs" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"status" text DEFAULT 'pending' NOT NULL,
|
||||
"logs_processed" integer DEFAULT 0 NOT NULL,
|
||||
"insights_created" integer DEFAULT 0 NOT NULL,
|
||||
"error_message" text,
|
||||
"started_at" timestamp with time zone,
|
||||
"completed_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "conversations" ADD COLUMN "archived" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "agent_logs" ADD CONSTRAINT "agent_logs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "insights" ADD CONSTRAINT "insights_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "preferences" ADD CONSTRAINT "preferences_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "skills" ADD CONSTRAINT "skills_installed_by_users_id_fk" FOREIGN KEY ("installed_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "agent_logs_session_id_idx" ON "agent_logs" USING btree ("session_id");--> statement-breakpoint
|
||||
CREATE INDEX "agent_logs_user_id_idx" ON "agent_logs" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "agent_logs_tier_idx" ON "agent_logs" USING btree ("tier");--> statement-breakpoint
|
||||
CREATE INDEX "agent_logs_created_at_idx" ON "agent_logs" USING btree ("created_at");--> statement-breakpoint
|
||||
CREATE INDEX "insights_user_id_idx" ON "insights" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "insights_category_idx" ON "insights" USING btree ("category");--> statement-breakpoint
|
||||
CREATE INDEX "insights_relevance_idx" ON "insights" USING btree ("relevance_score");--> statement-breakpoint
|
||||
CREATE INDEX "preferences_user_id_idx" ON "preferences" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "preferences_user_key_idx" ON "preferences" USING btree ("user_id","key");--> statement-breakpoint
|
||||
CREATE INDEX "skills_enabled_idx" ON "skills" USING btree ("enabled");--> statement-breakpoint
|
||||
CREATE INDEX "summarization_jobs_status_idx" ON "summarization_jobs" USING btree ("status");--> statement-breakpoint
|
||||
CREATE INDEX "conversations_archived_idx" ON "conversations" USING btree ("archived");
|
||||
1802
packages/db/drizzle/meta/0001_snapshot.json
Normal file
1802
packages/db/drizzle/meta/0001_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -199,12 +199,14 @@ export const conversations = pgTable(
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
projectId: uuid('project_id').references(() => projects.id, { onDelete: 'set null' }),
|
||||
archived: boolean('archived').notNull().default(false),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
},
|
||||
(t) => [
|
||||
index('conversations_user_id_idx').on(t.userId),
|
||||
index('conversations_project_id_idx').on(t.projectId),
|
||||
index('conversations_archived_idx').on(t.archived),
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user