feat(24-00): DB migrations and Drizzle schema updates for search/history/branching
- Add 0050_add_branch_columns.sql: parent_conversation_id + branch_from_message_id on chat_conversations - Add 0051_add_message_search_vector.sql: content_search tsvector + GIN index on chat_messages - Add 0052_create_chat_message_bookmarks.sql: new bookmarks table with company/message/conversation FK - Update chat_conversations.ts: parentConversationId + branchFromMessageId columns + parentIdx - Update chat_messages.ts: add comment for generated tsvector column - Create chat_message_bookmarks.ts: Drizzle schema with indexes - Update schema/index.ts: export chatMessageBookmarks - Update _journal.json: entries for idx 50, 51, 52
This commit is contained in:
parent
009527b809
commit
65f5603c23
8 changed files with 64 additions and 1 deletions
4
packages/db/src/migrations/0050_add_branch_columns.sql
Normal file
4
packages/db/src/migrations/0050_add_branch_columns.sql
Normal file
|
|
@ -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");
|
||||||
|
|
@ -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");
|
||||||
|
|
@ -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");
|
||||||
|
|
@ -351,6 +351,27 @@
|
||||||
"when": 1775079588000,
|
"when": 1775079588000,
|
||||||
"tag": "0049_add_message_type",
|
"tag": "0049_add_message_type",
|
||||||
"breakpoints": true
|
"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
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -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 { companies } from "./companies.js";
|
||||||
import { agents } from "./agents.js";
|
import { agents } from "./agents.js";
|
||||||
|
|
||||||
|
|
@ -14,9 +14,12 @@ export const chatConversations = pgTable(
|
||||||
deletedAt: timestamp("deleted_at", { withTimezone: true }),
|
deletedAt: timestamp("deleted_at", { withTimezone: true }),
|
||||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
updatedAt: timestamp("updated_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) => ({
|
(table) => ({
|
||||||
companyUpdatedIdx: index("chat_conversations_company_updated_idx").on(table.companyId, table.updatedAt),
|
companyUpdatedIdx: index("chat_conversations_company_updated_idx").on(table.companyId, table.updatedAt),
|
||||||
companyDeletedIdx: index("chat_conversations_company_deleted_idx").on(table.companyId, table.deletedAt),
|
companyDeletedIdx: index("chat_conversations_company_deleted_idx").on(table.companyId, table.deletedAt),
|
||||||
|
parentIdx: index("chat_conversations_parent_idx").on(table.parentConversationId),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
19
packages/db/src/schema/chat_message_bookmarks.ts
Normal file
19
packages/db/src/schema/chat_message_bookmarks.ts
Normal file
|
|
@ -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),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
@ -13,6 +13,7 @@ export const chatMessages = pgTable(
|
||||||
messageType: text("message_type"),
|
messageType: text("message_type"),
|
||||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
|
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
|
||||||
|
// content_search tsvector column exists in Postgres (generated stored) — queried via sql`` only
|
||||||
},
|
},
|
||||||
(table) => ({
|
(table) => ({
|
||||||
conversationCreatedIdx: index("chat_messages_conversation_created_idx").on(table.conversationId, table.createdAt),
|
conversationCreatedIdx: index("chat_messages_conversation_created_idx").on(table.conversationId, table.createdAt),
|
||||||
|
|
|
||||||
|
|
@ -58,3 +58,4 @@ export { pluginWebhookDeliveries } from "./plugin_webhooks.js";
|
||||||
export { pluginLogs } from "./plugin_logs.js";
|
export { pluginLogs } from "./plugin_logs.js";
|
||||||
export { chatConversations } from "./chat_conversations.js";
|
export { chatConversations } from "./chat_conversations.js";
|
||||||
export { chatMessages } from "./chat_messages.js";
|
export { chatMessages } from "./chat_messages.js";
|
||||||
|
export { chatMessageBookmarks } from "./chat_message_bookmarks.js";
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue