flnxi-Wu/lib/material-log.ts

98 lines
2.4 KiB
TypeScript

import { prisma } from '@/lib/prisma'
type MaterialLogChanges = Record<
string,
{
oldValue: unknown
newValue: unknown
}
>
type MaterialSnapshot = Record<string, unknown>
let materialLogsTableEnsured = false
async function executeSafely(sql: string) {
try {
await prisma.$executeRawUnsafe(sql)
} catch (error) {
console.error('[MaterialLog] Failed to execute SQL:', error)
}
}
export async function ensureMaterialLogsTable() {
if (materialLogsTableEnsured) return
await executeSafely(`
CREATE TABLE IF NOT EXISTS "material_logs" (
"id" TEXT PRIMARY KEY,
"materialId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"action" TEXT NOT NULL,
"changes" JSONB,
"materialSnapshot" JSONB,
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
)
`)
await executeSafely(`ALTER TABLE "material_logs" ADD COLUMN IF NOT EXISTS "materialSnapshot" JSONB`)
await executeSafely(
`CREATE INDEX IF NOT EXISTS "material_logs_materialId_idx" ON "material_logs" ("materialId")`
)
await executeSafely(`CREATE INDEX IF NOT EXISTS "material_logs_userId_idx" ON "material_logs" ("userId")`)
await executeSafely(
`CREATE INDEX IF NOT EXISTS "material_logs_timestamp_idx" ON "material_logs" ("timestamp")`
)
await executeSafely(`ALTER TABLE "material_logs" DROP CONSTRAINT IF EXISTS "material_logs_materialId_fkey"`)
await executeSafely(`
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'material_logs_userId_fkey'
) THEN
ALTER TABLE "material_logs"
ADD CONSTRAINT "material_logs_userId_fkey"
FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
END IF;
END
$$;
`)
materialLogsTableEnsured = true
}
interface CreateMaterialLogParams {
materialId: string
userId: string
action: string
changes?: MaterialLogChanges | null
materialSnapshot?: MaterialSnapshot | null
}
export async function createMaterialLog({
materialId,
userId,
action,
changes = null,
materialSnapshot = null,
}: CreateMaterialLogParams) {
try {
await ensureMaterialLogsTable()
await (prisma as any).materialLog.create({
data: {
materialId,
userId,
action,
changes,
materialSnapshot,
},
})
} catch (error) {
console.error('[MaterialLog] Failed to create log:', error)
}
}