Files
perauset-e2e-mrfzot2p/packages/functions/src/functions/audit/list-audit-log.function.ts
2026-07-11 08:34:30 +02:00

57 lines
2.1 KiB
TypeScript

import { z } from 'zod'
import { pikkuFunc } from '#pikku/pikku-types.gen.js'
export const ListAuditLogInput = z.object({
tableName: z.string().optional().describe('Filter by table name'),
recordId: z.string().optional().describe('Filter by record ID'),
userId: z.string().optional().describe('Filter by user who made the change'),
action: z.string().optional().describe('Filter by action type (INSERT, UPDATE, DELETE)'),
limit: z.coerce.number().optional().default(50).describe('Maximum number of results'),
offset: z.coerce.number().optional().default(0).describe('Offset for pagination'),
})
export const ListAuditLogOutput = z.object({
items: z.array(z.object({
auditId: z.string().describe('Audit log entry ID'),
tableName: z.string().describe('Table that was modified'),
recordId: z.string().describe('ID of the modified record'),
action: z.string().describe('Type of action performed'),
changedFields: z.any().nullable().describe('Fields that were changed'),
userId: z.string().nullable().describe('User who made the change'),
occurredAt: z.string().describe('When the change occurred'),
})).describe('List of audit log entries'),
})
export const listAuditLog = pikkuFunc({
expose: true,
tags: ['audit_log.view'],
input: ListAuditLogInput,
output: ListAuditLogOutput,
func: async ({ kysely }, { tableName, recordId, userId, action, limit: rawLimit, offset: rawOffset }) => {
const limit = rawLimit ?? 50
const offset = rawOffset ?? 0
let query = kysely
.selectFrom('auditLog')
.select(['auditId', 'tableName', 'recordId', 'action', 'changedFields', 'userId', 'occurredAt'])
if (tableName) query = query.where('tableName', '=', tableName)
if (recordId) query = query.where('recordId', '=', recordId)
if (userId) query = query.where('userId', '=', userId)
if (action) query = query.where('action', '=', action)
const rows = await query
.orderBy('occurredAt', 'desc')
.limit(limit)
.offset(offset)
.execute()
return {
items: rows.map((r) => ({
...r,
occurredAt: new Date(r.occurredAt as any).toISOString(),
})),
}
},
})