74 lines
1.9 KiB
TypeScript
Executable File
74 lines
1.9 KiB
TypeScript
Executable File
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)
|
|
)
|
|
);
|
|
}
|