feat(diagnostics): correlate staff operations errors and audit records
CI / check (push) Successful in 56s
CI / deploy (push) Successful in 19s
CI / publish-container (push) Successful in 1m15s

This commit is contained in:
Simo committed 2026-09-11 00:34:49 +02:00
1 parent 440ce4e556
commit a2954e4408
14 files changed
+473 -110

No files matched your search

+16 -1
View File
@@ -1,5 +1,6 @@
import { and, count, desc, eq, gte, inArray, like, lt, or } from "drizzle-orm";
import { AdminAuditLog, db, User } from "@/lib/db";
import { getOperationContext } from "@/lib/foundation/request-context";
import { readAuditChanges } from "./audit-diff";
import { type AuditFilters, normalizeAuditFilters } from "./audit-filters";
@@ -60,6 +61,7 @@ export async function logAudit(entry: AuditEntry): Promise<void> {
await db.insert(AdminAuditLog).values({
userId: entry.userId,
details: JSON.stringify(getOperationContext()),
action: entry.action,
target: entry.target,
targetId: entry.targetId,
@@ -79,6 +81,7 @@ export async function getAuditLogs(options: AuditFilters = {}) {
? or(
like(AdminAuditLog.action, `%${search}%`),
like(AdminAuditLog.target, `%${search}%`),
like(AdminAuditLog.details, `%${search}%`),
)
: undefined,
action ? eq(AdminAuditLog.action, action) : undefined,
@@ -105,6 +108,7 @@ export async function getAuditLogs(options: AuditFilters = {}) {
target: AdminAuditLog.target,
targetId: AdminAuditLog.targetId,
diff: AdminAuditLog.diff,
operationDetails: AdminAuditLog.details,
before: AdminAuditLog.before,
after: AdminAuditLog.after,
createdAt: AdminAuditLog.createdAt,
@@ -131,8 +135,19 @@ export async function getAuditLogs(options: AuditFilters = {}) {
const enrichedRows = rows.map((r) => {
const details = readAuditChanges(r.diff, r.before, r.after);
let operationId: string | null = null;
try {
const meta = JSON.parse(r.operationDetails ?? "{}");
if (
typeof meta.operationId === "string" &&
/^[a-zA-Z0-9-]{1,100}$/.test(meta.operationId)
)
operationId = meta.operationId;
} catch {}
const { operationDetails: _privateDetails, ...safeRow } = r;
return {
...r,
...safeRow,
operationId,
// Only sanitized changes may cross the server/client boundary.
before: null,
after: null,