diff --git a/apps/bot/src/audit.test.ts b/apps/bot/src/audit.test.ts new file mode 100644 index 0000000..22835b6 --- /dev/null +++ b/apps/bot/src/audit.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import type { DB } from "./db.js"; +import { writeAuditLog } from "./audit.js"; + +describe("writeAuditLog", () => { + it("inserts a row with normalized fields", async () => { + const inserted: unknown[] = []; + const fakeDb = { + insert: () => ({ + values: (v: unknown) => { + inserted.push(v); + return Promise.resolve(); + }, + }), + } as unknown as DB; + + await writeAuditLog(fakeDb, { + operatorId: null, + source: "telegram", + action: "test.event", + payload: { foo: "bar" }, + }); + + expect(inserted).toHaveLength(1); + expect(inserted[0]).toMatchObject({ + operatorId: null, + source: "telegram", + action: "test.event", + payload: { foo: "bar" }, + }); + }); +}); diff --git a/apps/bot/src/audit.ts b/apps/bot/src/audit.ts new file mode 100644 index 0000000..fd3e8a8 --- /dev/null +++ b/apps/bot/src/audit.ts @@ -0,0 +1,22 @@ +import { auditLog, type DB, type NewAuditLogEntry } from "@cmbot/db"; + +export type AuditInput = { + operatorId: string | null; + source: "web" | "telegram" | "system"; + action: string; + targetType?: string | null; + targetId?: string | null; + payload?: Record; +}; + +export async function writeAuditLog(db: DB, input: AuditInput): Promise { + const row: NewAuditLogEntry = { + operatorId: input.operatorId, + source: input.source, + action: input.action, + targetType: input.targetType ?? null, + targetId: input.targetId ?? null, + payload: input.payload ?? {}, + }; + await db.insert(auditLog).values(row); +}