diff --git a/packages/db/src/migrations/0053_create_chat_files.sql b/packages/db/src/migrations/0053_create_chat_files.sql new file mode 100644 index 00000000..1144920d --- /dev/null +++ b/packages/db/src/migrations/0053_create_chat_files.sql @@ -0,0 +1,26 @@ +CREATE TABLE IF NOT EXISTS "chat_files" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "company_id" uuid NOT NULL, + "conversation_id" uuid, + "message_id" uuid, + "filename" text NOT NULL, + "original_filename" text NOT NULL, + "mime_type" text NOT NULL, + "size_bytes" integer NOT NULL, + "object_key" text NOT NULL, + "sha256" text NOT NULL, + "source" text NOT NULL, + "category" text, + "project_id" uuid, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "chat_files_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "companies"("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "chat_files_conversation_id_chat_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "chat_conversations"("id") ON DELETE SET NULL ON UPDATE NO ACTION, + CONSTRAINT "chat_files_message_id_chat_messages_id_fk" FOREIGN KEY ("message_id") REFERENCES "chat_messages"("id") ON DELETE SET NULL ON UPDATE NO ACTION, + CONSTRAINT "chat_files_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE SET NULL ON UPDATE NO ACTION +); + +CREATE INDEX IF NOT EXISTS "chat_files_conversation_idx" ON "chat_files" ("conversation_id"); +CREATE INDEX IF NOT EXISTS "chat_files_message_idx" ON "chat_files" ("message_id"); +CREATE INDEX IF NOT EXISTS "chat_files_company_created_idx" ON "chat_files" ("company_id", "created_at"); +CREATE INDEX IF NOT EXISTS "chat_files_project_idx" ON "chat_files" ("project_id"); diff --git a/packages/db/src/migrations/0054_create_chat_file_references.sql b/packages/db/src/migrations/0054_create_chat_file_references.sql new file mode 100644 index 00000000..d1f5c66e --- /dev/null +++ b/packages/db/src/migrations/0054_create_chat_file_references.sql @@ -0,0 +1,14 @@ +CREATE TABLE IF NOT EXISTS "chat_file_references" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "file_id" uuid NOT NULL, + "conversation_id" uuid NOT NULL, + "message_id" uuid, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "chat_file_references_file_id_chat_files_id_fk" FOREIGN KEY ("file_id") REFERENCES "chat_files"("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "chat_file_references_conversation_id_chat_conversations_id_fk" FOREIGN KEY ("conversation_id") REFERENCES "chat_conversations"("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "chat_file_references_message_id_chat_messages_id_fk" FOREIGN KEY ("message_id") REFERENCES "chat_messages"("id") ON DELETE SET NULL ON UPDATE NO ACTION +); + +CREATE INDEX IF NOT EXISTS "chat_file_refs_file_idx" ON "chat_file_references" ("file_id"); +CREATE INDEX IF NOT EXISTS "chat_file_refs_conversation_idx" ON "chat_file_references" ("conversation_id"); +CREATE INDEX IF NOT EXISTS "chat_file_refs_message_idx" ON "chat_file_references" ("message_id"); diff --git a/packages/db/src/migrations/meta/_journal.json b/packages/db/src/migrations/meta/_journal.json index 9e307a01..f330d22e 100644 --- a/packages/db/src/migrations/meta/_journal.json +++ b/packages/db/src/migrations/meta/_journal.json @@ -372,6 +372,20 @@ "when": 1775200002000, "tag": "0052_create_chat_message_bookmarks", "breakpoints": true + }, + { + "idx": 53, + "version": "7", + "when": 1775300000000, + "tag": "0053_create_chat_files", + "breakpoints": true + }, + { + "idx": 54, + "version": "7", + "when": 1775300001000, + "tag": "0054_create_chat_file_references", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema/chat_file_references.ts b/packages/db/src/schema/chat_file_references.ts new file mode 100644 index 00000000..aca50c20 --- /dev/null +++ b/packages/db/src/schema/chat_file_references.ts @@ -0,0 +1,20 @@ +import { pgTable, uuid, timestamp, index } from "drizzle-orm/pg-core"; +import { chatFiles } from "./chat_files.js"; +import { chatConversations } from "./chat_conversations.js"; +import { chatMessages } from "./chat_messages.js"; + +export const chatFileReferences = pgTable( + "chat_file_references", + { + id: uuid("id").primaryKey().defaultRandom(), + fileId: uuid("file_id").notNull().references(() => chatFiles.id, { onDelete: "cascade" }), + conversationId: uuid("conversation_id").notNull().references(() => chatConversations.id, { onDelete: "cascade" }), + messageId: uuid("message_id").references(() => chatMessages.id, { onDelete: "set null" }), + createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), + }, + (table) => ({ + fileIdx: index("chat_file_refs_file_idx").on(table.fileId), + conversationIdx: index("chat_file_refs_conversation_idx").on(table.conversationId), + messageIdx: index("chat_file_refs_message_idx").on(table.messageId), + }), +); diff --git a/packages/db/src/schema/chat_files.ts b/packages/db/src/schema/chat_files.ts new file mode 100644 index 00000000..7702a473 --- /dev/null +++ b/packages/db/src/schema/chat_files.ts @@ -0,0 +1,32 @@ +import { pgTable, uuid, text, integer, timestamp, index } from "drizzle-orm/pg-core"; +import { companies } from "./companies.js"; +import { chatConversations } from "./chat_conversations.js"; +import { chatMessages } from "./chat_messages.js"; +import { projects } from "./projects.js"; + +export const chatFiles = pgTable( + "chat_files", + { + id: uuid("id").primaryKey().defaultRandom(), + companyId: uuid("company_id").notNull().references(() => companies.id), + conversationId: uuid("conversation_id").references(() => chatConversations.id, { onDelete: "set null" }), + messageId: uuid("message_id").references(() => chatMessages.id, { onDelete: "set null" }), + filename: text("filename").notNull(), + originalFilename: text("original_filename").notNull(), + mimeType: text("mime_type").notNull(), + sizeBytes: integer("size_bytes").notNull(), + objectKey: text("object_key").notNull(), + sha256: text("sha256").notNull(), + source: text("source").notNull(), + category: text("category"), + projectId: uuid("project_id").references(() => projects.id, { onDelete: "set null" }), + createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), + }, + (table) => ({ + conversationIdx: index("chat_files_conversation_idx").on(table.conversationId), + messageIdx: index("chat_files_message_idx").on(table.messageId), + companyCreatedIdx: index("chat_files_company_created_idx").on(table.companyId, table.createdAt), + projectIdx: index("chat_files_project_idx").on(table.projectId), + }), +); diff --git a/packages/db/src/schema/index.ts b/packages/db/src/schema/index.ts index 465f97ba..e27ef5f7 100644 --- a/packages/db/src/schema/index.ts +++ b/packages/db/src/schema/index.ts @@ -59,3 +59,5 @@ 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"; +export { chatFiles } from "./chat_files.js"; +export { chatFileReferences } from "./chat_file_references.js";