Implements IAuditLogRepository with Prisma, AuditLogService with configurable retention policy and purge, and REST routes for querying/filtering audit logs at /api/v1/audit-logs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import type { PrismaClient, AuditLog, Prisma } from '@prisma/client';
|
|
import type { IAuditLogRepository, AuditLogFilter } from './interfaces.js';
|
|
|
|
export class AuditLogRepository implements IAuditLogRepository {
|
|
constructor(private readonly prisma: PrismaClient) {}
|
|
|
|
async findAll(filter?: AuditLogFilter): Promise<AuditLog[]> {
|
|
const where = buildWhere(filter);
|
|
return this.prisma.auditLog.findMany({
|
|
where,
|
|
orderBy: { createdAt: 'desc' },
|
|
take: filter?.limit ?? 100,
|
|
skip: filter?.offset ?? 0,
|
|
});
|
|
}
|
|
|
|
async findById(id: string): Promise<AuditLog | null> {
|
|
return this.prisma.auditLog.findUnique({ where: { id } });
|
|
}
|
|
|
|
async create(data: {
|
|
userId: string;
|
|
action: string;
|
|
resource: string;
|
|
resourceId?: string;
|
|
details?: Record<string, unknown>;
|
|
}): Promise<AuditLog> {
|
|
const createData: Prisma.AuditLogUncheckedCreateInput = {
|
|
userId: data.userId,
|
|
action: data.action,
|
|
resource: data.resource,
|
|
details: (data.details ?? {}) as Prisma.InputJsonValue,
|
|
};
|
|
if (data.resourceId !== undefined) {
|
|
createData.resourceId = data.resourceId;
|
|
}
|
|
return this.prisma.auditLog.create({ data: createData });
|
|
}
|
|
|
|
async count(filter?: AuditLogFilter): Promise<number> {
|
|
const where = buildWhere(filter);
|
|
return this.prisma.auditLog.count({ where });
|
|
}
|
|
|
|
async deleteOlderThan(date: Date): Promise<number> {
|
|
const result = await this.prisma.auditLog.deleteMany({
|
|
where: { createdAt: { lt: date } },
|
|
});
|
|
return result.count;
|
|
}
|
|
}
|
|
|
|
function buildWhere(filter?: AuditLogFilter): Prisma.AuditLogWhereInput {
|
|
const where: Prisma.AuditLogWhereInput = {};
|
|
if (!filter) return where;
|
|
|
|
if (filter.userId !== undefined) where.userId = filter.userId;
|
|
if (filter.action !== undefined) where.action = filter.action;
|
|
if (filter.resource !== undefined) where.resource = filter.resource;
|
|
if (filter.resourceId !== undefined) where.resourceId = filter.resourceId;
|
|
|
|
if (filter.since !== undefined || filter.until !== undefined) {
|
|
const createdAt: Prisma.DateTimeFilter = {};
|
|
if (filter.since !== undefined) createdAt.gte = filter.since;
|
|
if (filter.until !== undefined) createdAt.lte = filter.until;
|
|
where.createdAt = createdAt;
|
|
}
|
|
|
|
return where;
|
|
}
|