Files
manyangles/apps/web/src/server/audit.ts
T

36 lines
1.5 KiB
TypeScript

import { auditEvents, user, guests, type Database } from "@album/database";
import { and, eq } from "drizzle-orm";
import { getDb } from "@album/database";
export async function writeAudit(
input: {
groupId?: string | null;
eventId?: string | null;
actorUserId?: string | null;
action: string;
subjectType: string;
subjectId: string;
metadata?: Record<string, string | number | boolean | null>;
},
db: Pick<Database, "insert" | "select"> = getDb(),
) {
const [actor] = input.actorUserId ? await db.select({ name: user.name }).from(user).where(eq(user.id, input.actorUserId)).limit(1) : [];
let subjectLabel = `${input.subjectType} ${input.subjectId}`;
if (input.subjectType === "user") {
const [subject] = await db.select({ name: user.name }).from(user).where(eq(user.id, input.subjectId)).limit(1);
if (subject) subjectLabel = subject.name;
} else if (input.subjectType === "guest" && input.eventId) {
const [subject] = await db.select({ name: guests.displayName }).from(guests).where(and(eq(guests.eventId, input.eventId), eq(guests.id, input.subjectId))).limit(1);
if (subject) subjectLabel = subject.name ?? "Anonymous guest";
}
await db.insert(auditEvents).values({
groupId: input.groupId ?? null,
eventId: input.eventId ?? null,
actorUserId: input.actorUserId ?? null,
action: input.action,
subjectType: input.subjectType,
subjectId: input.subjectId,
metadata: { ...input.metadata, subjectLabel, actorName: actor?.name ?? "System" },
});
}