initial 2
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-06-26 09:26:50 +01:00
parent 194330fb47
commit 3b37368e7d
213 changed files with 14688 additions and 1 deletions

View File

@@ -0,0 +1,73 @@
import { db, actionEvents } from "../db";
import { eq, desc, and, isNull, lt, sql } from "drizzle-orm";
export interface RecordActionInput {
userId: string;
actionType: string;
entityType: string;
entityId: string;
summary: string;
beforeState: Record<string, unknown>;
afterState: Record<string, unknown>;
inversePatch?: Record<string, unknown>;
metadata?: Record<string, unknown>;
undoable?: boolean;
}
export async function recordAction(input: RecordActionInput) {
const [event] = await db
.insert(actionEvents)
.values({
userId: input.userId,
actionType: input.actionType,
entityType: input.entityType,
entityId: input.entityId,
summary: input.summary,
beforeState: input.beforeState,
afterState: input.afterState,
inversePatch: input.inversePatch,
metadata: input.metadata ?? {},
undoable: input.undoable ?? true,
})
.returning();
return event;
}
export async function getRecentActions(userId: string, limit = 20) {
return db
.select()
.from(actionEvents)
.where(and(eq(actionEvents.userId, userId), isNull(actionEvents.undoneAt)))
.orderBy(desc(actionEvents.createdAt))
.limit(limit);
}
export async function getActionEvent(userId: string, actionEventId: string) {
const [event] = await db
.select()
.from(actionEvents)
.where(
and(eq(actionEvents.id, actionEventId), eq(actionEvents.userId, userId))
);
return event ?? null;
}
export async function markUndone(actionEventId: string) {
await db
.update(actionEvents)
.set({ undoneAt: new Date() })
.where(eq(actionEvents.id, actionEventId));
}
export async function pruneOldActions(userId: string, daysOld = 90) {
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - daysOld);
await db
.delete(actionEvents)
.where(
and(
eq(actionEvents.userId, userId),
lt(actionEvents.createdAt, cutoff)
)
);
}