diff --git a/services/discord-gateway/src/modules/message-capture/messageCapture.ts b/services/discord-gateway/src/modules/message-capture/messageCapture.ts index 006595e..85da268 100644 --- a/services/discord-gateway/src/modules/message-capture/messageCapture.ts +++ b/services/discord-gateway/src/modules/message-capture/messageCapture.ts @@ -13,6 +13,7 @@ import { import { getMessageById, insertAttachment, + insertMessageEdit, updateMessageAsDeleted, updateMessageAsEdited, upsertMessageForCapture, @@ -293,6 +294,15 @@ export function registerMessageCapture(client: Client): void { } const editedAt = Date.now(); + const oldContent = existing.edited_content ?? existing.content ?? ""; + + // Save edit history snapshot before overwriting + if (oldContent) { + insertMessageEdit(newMessage.id, oldContent, editedAt).catch((err: unknown) => { + logger.error({ messageId: newMessage.id, error: err }, "Failed to save edit history"); + }); + } + await updateMessageAsEdited( newMessage.id, getDisplayContent(newMessage as Message), diff --git a/services/discord-gateway/src/modules/message-capture/messageStore.ts b/services/discord-gateway/src/modules/message-capture/messageStore.ts index 1557586..d37af4b 100644 --- a/services/discord-gateway/src/modules/message-capture/messageStore.ts +++ b/services/discord-gateway/src/modules/message-capture/messageStore.ts @@ -51,6 +51,12 @@ export class MessageStore { this.retention = new RetentionDb(db, logger); } + // ── Edit History ──────────────────────────────────────────────────────── + + insertMessageEdit(messageId: string, oldContent: string, editedAt: number): Promise { + return this.messages.insertMessageEdit(messageId, oldContent, editedAt); + } + // ── Messages ─────────────────────────────────────────────────────────── insertMessage(message: MessageRecord): Promise { @@ -303,6 +309,12 @@ export class MessageStore { // These delegate to a lazy singleton MessageStore instance so existing // code that imports individual functions continues to work unchanged. +export const insertMessageEdit = ( + messageId: string, + oldContent: string, + editedAt: number, +): Promise => getInstance().insertMessageEdit(messageId, oldContent, editedAt); + // Messages export const insertMessage = (message: MessageRecord): Promise => getInstance().insertMessage(message); diff --git a/services/discord-gateway/src/modules/message-capture/messages.crud.ts b/services/discord-gateway/src/modules/message-capture/messages.crud.ts index 4097395..e1ba6e8 100644 --- a/services/discord-gateway/src/modules/message-capture/messages.crud.ts +++ b/services/discord-gateway/src/modules/message-capture/messages.crud.ts @@ -2,7 +2,7 @@ import { createChildLogger, type Logger } from "@bete/shared/logger"; import { and, desc, eq, or, type SQL } from "drizzle-orm"; import type { NodePgDatabase } from "drizzle-orm/node-postgres"; import type * as schema from "../../shared/database/schema.js"; -import { messagesTable } from "../../shared/database/schema.js"; +import { messagesTable, messageEditsTable } from "../../shared/database/schema.js"; import type { MessageRecord } from "../message-capture/types.js"; // ─── Shared Helpers ────────────────────────────────────────────────────────── @@ -141,6 +141,28 @@ export class MessagesCrud { } } + // ── EDIT HISTORY ────────────────────────────────────────────────────────────── + + async insertMessageEdit( + messageId: string, + oldContent: string, + editedAt: number, + ): Promise { + this.logger.debug({ messageId }, "insertMessageEdit entry"); + try { + await this.db + .insert(messageEditsTable) + .values({ message_id: messageId, old_content: oldContent, edited_at: editedAt }) + .onConflictDoNothing(); + } catch (error) { + this.logger.error( + { messageId, error: error instanceof Error ? error.message : String(error) }, + "Failed to insert message edit", + ); + throw error; + } + } + // ── GET ───────────────────────────────────────────────────────────────────── async getMessagesByChannel( diff --git a/services/discord-gateway/src/modules/message-capture/messages.db.ts b/services/discord-gateway/src/modules/message-capture/messages.db.ts index b9cddbb..2b4ba2d 100644 --- a/services/discord-gateway/src/modules/message-capture/messages.db.ts +++ b/services/discord-gateway/src/modules/message-capture/messages.db.ts @@ -126,6 +126,12 @@ export class MessagesDb { ); } + // ── Edit History ───────────────────────────────────────────────────────── + + insertMessageEdit(messageId: string, oldContent: string, editedAt: number): Promise { + return this.crud.insertMessageEdit(messageId, oldContent, editedAt); + } + // ── Search ────────────────────────────────────────────────────────────── searchMessages(input: {