const prisma = require('../config/db'); // Fire-and-forget by design — a logging failure must never break the underlying admin // action, so this swallows its own errors rather than propagating them to the caller // (same posture as logSecurityEvent). async function logAdminAction({ actorId, actorRole, action, targetType, targetId, metadata, ip }) { try { await prisma.adminAuditLog.create({ data: { actorId: actorId || null, actorRole, action, targetType, targetId: targetId || null, metadata: metadata || undefined, ip: ip || null, }, }); } catch (e) { console.error('Failed to log admin action:', e?.message); } } // Paginated listing for the admin audit-log page, with optional actor/action/date filters. async function getAdminAuditLog({ page = 1, limit = 50, actorId, action, from, to } = {}) { const where = {}; if (actorId) where.actorId = actorId; if (action) where.action = action; if (from || to) { where.createdAt = {}; if (from) where.createdAt.gte = new Date(from); if (to) where.createdAt.lte = new Date(to); } const take = Math.min(Math.max(Number(limit) || 50, 1), 200); const skip = (Math.max(Number(page) || 1, 1) - 1) * take; const [rows, total] = await Promise.all([ prisma.adminAuditLog.findMany({ where, orderBy: { createdAt: 'desc' }, take, skip, include: { actor: { select: { id: true, name: true, email: true } } }, }), prisma.adminAuditLog.count({ where }), ]); return { rows, total, page: Math.max(Number(page) || 1, 1), limit: take }; } module.exports = { logAdminAction, getAdminAuditLog };