Skip to Content
Welcome to the official DBS Documentation! πŸ“š
AdvancedSystem Logs

System & Audit Logs

Enterprise applications need a reliable way to trace who did what, and when. DBS has a built-in audit logging system powered by the auditLogger utility and the AuditLog table in PostgreSQL.

Architecture

API Route Handler └── auditLogger.log({ userId, action, details }) └── prisma.auditLog.create(...) └── AuditLog table (PostgreSQL) └── GET /api/logs └── /dashboard/logs (UI)

The auditLogger Utility

// src/lib/audit-logger.ts import { auditLogger } from '@/lib/audit-logger'; interface AuditLogEntry { userId: string; // Who performed the action action: string; // What they did (e.g., 'user.update') targetId?: string; // ID of the affected resource targetType?: string; // Type of the affected resource (e.g., 'User') details?: Record<string, unknown>; // Additional structured metadata ipAddress?: string; // Client IP address }

Writing an Audit Log Entry

Call auditLogger.log() inside any API route after a critical state change:

// src/app/api/users/[id]/route.ts import { auditLogger } from '@/lib/audit-logger'; import { apiGuard } from '@/lib/api-guard'; export async function PUT(req: Request, { params }) { const guard = await apiGuard('user.update'); if (guard.error) return guard.error; const { session } = guard; const body = await req.json(); const updatedUser = await prisma.user.update({ where: { id: params.id }, data: body, }); await auditLogger.log({ userId: session.user.id, action: 'user.update', targetId: params.id, targetType: 'User', details: { fields: Object.keys(body) }, ipAddress: req.headers.get('x-forwarded-for') ?? undefined, }); return Response.json(updatedUser); }

Audit Log API

MethodEndpointPermissionDescription
GET/api/logslog.readFetch paginated audit log entries
GET/api/logs?userId=...log.readFilter by user
GET/api/logs?action=...log.readFilter by action type
GET/api/logs?from=...&to=...log.readFilter by date range

The Audit Log Viewer

The Logs page at /dashboard/logs is accessible only to users with the log.read permission. It provides:

  • A paginated table showing all audit entries
  • Search by user, action, or target
  • Date range filter
  • Click an entry to expand the details JSON payload

Standard Action Naming Convention

To keep logs consistent and queryable, follow this naming pattern:

resource.action
ActionDescription
user.createA new user was registered
user.updateUser profile was updated
user.deleteUser was deleted
user.role.assignRole assigned to a user
auth.loginSuccessful login
auth.logoutUser logged out
auth.2fa.enabled2FA was enabled
team.createNew team created
team.member.addMember added to team
settings.updateSystem setting changed

Log entries are append-only by design. There are no delete or update operations on the AuditLog table, ensuring an immutable audit trail.

Last updated on