import { test, before, after } from "node:test"; import assert from "node:assert/strict"; import { pool, withTx } from "../db/pool.ts"; import { writeAudit } from "../lib/audit.ts"; import { resetDb, seedMinimal } from "./helpers.ts"; let ids: Awaited>; before(async () => { await resetDb(); ids = await seedMinimal(); }); after(async () => { await pool.end(); }); test("writeAudit guarda el antes y el después como jsonb", async () => { await withTx(async (c) => { await writeAudit(c, { businessId: ids.businessId, actorUserId: ids.ownerUserId, entity: "clients", entityId: ids.clientId, action: "update", before: { name: "Mariana" }, after: { name: "Mariana López" }, ip: "127.0.0.1", }); }); const { rows } = await pool.query( `SELECT entity, action, before, after, ip FROM audit_log WHERE entity_id = $1 ORDER BY id DESC LIMIT 1`, [ids.clientId] ); assert.equal(rows[0].entity, "clients"); assert.equal(rows[0].action, "update"); assert.deepEqual(rows[0].before, { name: "Mariana" }); assert.deepEqual(rows[0].after, { name: "Mariana López" }); assert.equal(rows[0].ip, "127.0.0.1"); }); test("writeAudit se apunta a la transacción que lo llama", async () => { await assert.rejects( withTx(async (c) => { await writeAudit(c, { businessId: ids.businessId, actorUserId: ids.ownerUserId, entity: "clients", entityId: ids.clientId, action: "delete", }); throw new Error("boom"); }) ); const { rows } = await pool.query( `SELECT count(*)::int c FROM audit_log WHERE action = 'delete'` ); assert.equal(rows[0].c, 0, "el rollback debe llevarse también la auditoría"); });