85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import { Inject, Injectable, NotFoundException } from '@nestjs/common';
|
|
import { Prisma } from '@lisglosips/database';
|
|
import { PrismaService } from '../database/prisma.service.js';
|
|
|
|
export interface AuditLogQuery {
|
|
module?: string;
|
|
action?: string;
|
|
userId?: string;
|
|
objectType?: string;
|
|
objectId?: string;
|
|
result?: 'SUCCESS' | 'FAILURE';
|
|
createdFrom?: Date;
|
|
createdTo?: Date;
|
|
take: number;
|
|
skip: number;
|
|
}
|
|
|
|
export interface AuditLogSummary {
|
|
id: string;
|
|
requestId: string;
|
|
userId: string | null;
|
|
username: string | null;
|
|
roleNames: string | null;
|
|
ip: string | null;
|
|
userAgent: string | null;
|
|
module: string;
|
|
action: string;
|
|
objectType: string;
|
|
objectId: string | null;
|
|
result: 'SUCCESS' | 'FAILURE';
|
|
errorCode: string | null;
|
|
createdAt: Date;
|
|
}
|
|
|
|
export interface AuditLogDetail extends AuditLogSummary {
|
|
beforeSummary: unknown;
|
|
afterSummary: unknown;
|
|
}
|
|
|
|
export interface AuditLogsRepository {
|
|
list(query: AuditLogQuery): Promise<{ items: AuditLogSummary[]; total: number }>;
|
|
get(id: string): Promise<AuditLogDetail>;
|
|
}
|
|
|
|
export const AUDIT_LOGS_REPOSITORY = Symbol('AUDIT_LOGS_REPOSITORY');
|
|
|
|
@Injectable()
|
|
export class PrismaAuditLogsRepository implements AuditLogsRepository {
|
|
constructor(@Inject(PrismaService) private readonly prisma: PrismaService) {}
|
|
|
|
async list(query: AuditLogQuery): Promise<{ items: AuditLogSummary[]; total: number }> {
|
|
const where: Prisma.AuditLogWhereInput = {
|
|
module: query.module,
|
|
action: query.action,
|
|
userId: query.userId,
|
|
objectType: query.objectType,
|
|
objectId: query.objectId,
|
|
result: query.result,
|
|
createdAt: query.createdFrom || query.createdTo ? { gte: query.createdFrom, lte: query.createdTo } : undefined
|
|
};
|
|
|
|
const [items, total] = await this.prisma.$transaction([
|
|
this.prisma.auditLog.findMany({
|
|
where,
|
|
orderBy: [{ createdAt: 'desc' }],
|
|
take: query.take,
|
|
skip: query.skip
|
|
}),
|
|
this.prisma.auditLog.count({ where })
|
|
]);
|
|
|
|
return { items, total };
|
|
}
|
|
|
|
async get(id: string): Promise<AuditLogDetail> {
|
|
const auditLog = await this.prisma.auditLog.findUnique({ where: { id } });
|
|
|
|
if (!auditLog) {
|
|
throw new NotFoundException({ code: 'AUDIT_LOG_NOT_FOUND', message: 'Audit log not found.' });
|
|
}
|
|
|
|
return auditLog;
|
|
}
|
|
}
|