diff --git a/packages/db/src/migrations/0050_add_branch_columns.sql b/packages/db/src/migrations/0050_add_branch_columns.sql new file mode 100644 index 00000000..c4674b22 --- /dev/null +++ b/packages/db/src/migrations/0050_add_branch_columns.sql @@ -0,0 +1,4 @@ +ALTER TABLE "chat_conversations" + ADD COLUMN "parent_conversation_id" uuid REFERENCES "chat_conversations"("id") ON DELETE SET NULL, + ADD COLUMN "branch_from_message_id" uuid; +CREATE INDEX "chat_conversations_parent_idx" ON "chat_conversations" ("parent_conversation_id"); diff --git a/packages/db/src/migrations/0051_add_message_search_vector.sql b/packages/db/src/migrations/0051_add_message_search_vector.sql new file mode 100644 index 00000000..f5f2a84b --- /dev/null +++ b/packages/db/src/migrations/0051_add_message_search_vector.sql @@ -0,0 +1,5 @@ +ALTER TABLE "chat_messages" + ADD COLUMN "content_search" tsvector + GENERATED ALWAYS AS (to_tsvector('english', "content")) STORED; +CREATE INDEX "chat_messages_content_search_idx" + ON "chat_messages" USING GIN ("content_search"); diff --git a/packages/db/src/migrations/0052_create_chat_message_bookmarks.sql b/packages/db/src/migrations/0052_create_chat_message_bookmarks.sql new file mode 100644 index 00000000..90376a80 --- /dev/null +++ b/packages/db/src/migrations/0052_create_chat_message_bookmarks.sql @@ -0,0 +1,9 @@ +CREATE TABLE "chat_message_bookmarks" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(), + "company_id" uuid NOT NULL REFERENCES "companies"("id"), + "message_id" uuid NOT NULL REFERENCES "chat_messages"("id") ON DELETE CASCADE, + "conversation_id" uuid NOT NULL REFERENCES "chat_conversations"("id") ON DELETE CASCADE, + "created_at" timestamp with time zone NOT NULL DEFAULT now() +); +CREATE INDEX "chat_bookmarks_company_message_idx" ON "chat_message_bookmarks" ("company_id", "message_id"); +CREATE INDEX "chat_bookmarks_company_conv_idx" ON "chat_message_bookmarks" ("company_id", "conversation_id"); diff --git a/packages/db/src/migrations/meta/_journal.json b/packages/db/src/migrations/meta/_journal.json index ccc22bf1..80f73106 100644 --- a/packages/db/src/migrations/meta/_journal.json +++ b/packages/db/src/migrations/meta/_journal.json @@ -344,6 +344,27 @@ "when": 1775145655557, "tag": "0048_flashy_marrow", "breakpoints": true + }, + { + "idx": 50, + "version": "7", + "when": 1775200000000, + "tag": "0050_add_branch_columns", + "breakpoints": true + }, + { + "idx": 51, + "version": "7", + "when": 1775200001000, + "tag": "0051_add_message_search_vector", + "breakpoints": true + }, + { + "idx": 52, + "version": "7", + "when": 1775200002000, + "tag": "0052_create_chat_message_bookmarks", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema/chat_conversations.ts b/packages/db/src/schema/chat_conversations.ts index f1d781a9..cd6b8285 100644 --- a/packages/db/src/schema/chat_conversations.ts +++ b/packages/db/src/schema/chat_conversations.ts @@ -1,4 +1,4 @@ -import { pgTable, uuid, text, timestamp, index } from "drizzle-orm/pg-core"; +import { type AnyPgColumn, pgTable, uuid, text, timestamp, index } from "drizzle-orm/pg-core"; import { companies } from "./companies.js"; import { agents } from "./agents.js"; @@ -14,9 +14,12 @@ export const chatConversations = pgTable( deletedAt: timestamp("deleted_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), + parentConversationId: uuid("parent_conversation_id").references((): AnyPgColumn => chatConversations.id, { onDelete: "set null" }), + branchFromMessageId: uuid("branch_from_message_id"), }, (table) => ({ companyUpdatedIdx: index("chat_conversations_company_updated_idx").on(table.companyId, table.updatedAt), companyDeletedIdx: index("chat_conversations_company_deleted_idx").on(table.companyId, table.deletedAt), + parentIdx: index("chat_conversations_parent_idx").on(table.parentConversationId), }), ); diff --git a/packages/db/src/schema/chat_message_bookmarks.ts b/packages/db/src/schema/chat_message_bookmarks.ts new file mode 100644 index 00000000..81c90d15 --- /dev/null +++ b/packages/db/src/schema/chat_message_bookmarks.ts @@ -0,0 +1,19 @@ +import { pgTable, uuid, timestamp, index } from "drizzle-orm/pg-core"; +import { companies } from "./companies.js"; +import { chatMessages } from "./chat_messages.js"; +import { chatConversations } from "./chat_conversations.js"; + +export const chatMessageBookmarks = pgTable( + "chat_message_bookmarks", + { + id: uuid("id").primaryKey().defaultRandom(), + companyId: uuid("company_id").notNull().references(() => companies.id), + messageId: uuid("message_id").notNull().references(() => chatMessages.id, { onDelete: "cascade" }), + conversationId: uuid("conversation_id").notNull().references(() => chatConversations.id, { onDelete: "cascade" }), + createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), + }, + (table) => ({ + companyMessageIdx: index("chat_bookmarks_company_message_idx").on(table.companyId, table.messageId), + companyConvIdx: index("chat_bookmarks_company_conv_idx").on(table.companyId, table.conversationId), + }), +); diff --git a/packages/db/src/schema/chat_messages.ts b/packages/db/src/schema/chat_messages.ts index e3c79daa..2fc1de96 100644 --- a/packages/db/src/schema/chat_messages.ts +++ b/packages/db/src/schema/chat_messages.ts @@ -13,6 +13,7 @@ export const chatMessages = pgTable( messageType: text("message_type"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(), + // content_search tsvector column exists in Postgres (generated stored) — queried via sql`` only }, (table) => ({ conversationCreatedIdx: index("chat_messages_conversation_created_idx").on(table.conversationId, table.createdAt), diff --git a/packages/db/src/schema/index.ts b/packages/db/src/schema/index.ts index 0c198b46..8a603bc1 100644 --- a/packages/db/src/schema/index.ts +++ b/packages/db/src/schema/index.ts @@ -60,3 +60,4 @@ export { pluginWebhookDeliveries } from "./plugin_webhooks.js"; export { pluginLogs } from "./plugin_logs.js"; export { chatConversations } from "./chat_conversations.js"; export { chatMessages } from "./chat_messages.js"; +export { chatMessageBookmarks } from "./chat_message_bookmarks.js";