Files
lisglosips/apps/api/src/modules/audit-logs/audit-logs.service.ts
T

60 lines
1.9 KiB
TypeScript

import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { AUDIT_LOGS_REPOSITORY, type AuditLogQuery, type AuditLogsRepository } from './audit-logs.repository.js';
@Injectable()
export class AuditLogsService {
constructor(@Inject(AUDIT_LOGS_REPOSITORY) private readonly auditLogs: AuditLogsRepository) {}
list(rawQuery: Record<string, unknown>) {
const query: AuditLogQuery = {
module: this.optionalString(rawQuery.module),
action: this.optionalString(rawQuery.action),
userId: this.optionalString(rawQuery.userId),
objectType: this.optionalString(rawQuery.objectType),
objectId: this.optionalString(rawQuery.objectId),
result: rawQuery.result === undefined ? undefined : this.result(rawQuery.result),
take: this.positiveInt(rawQuery.take, 50, 100),
skip: this.positiveInt(rawQuery.skip, 0, 10_000)
};
return this.auditLogs.list(query);
}
get(id: string) {
return this.auditLogs.get(id);
}
private optionalString(value: unknown): string | undefined {
if (value === undefined) {
return undefined;
}
if (typeof value !== 'string' || value.trim().length === 0) {
throw new BadRequestException({ code: 'QUERY_INVALID', message: 'Query parameter is invalid.' });
}
return value.trim();
}
private result(value: unknown): 'SUCCESS' | 'FAILURE' {
if (value !== 'SUCCESS' && value !== 'FAILURE') {
throw new BadRequestException({ code: 'AUDIT_RESULT_INVALID', message: 'Audit result is invalid.' });
}
return value;
}
private positiveInt(value: unknown, defaultValue: number, max: number): number {
if (value === undefined) {
return defaultValue;
}
const parsed = Number(value);
if (!Number.isInteger(parsed) || parsed < 0 || parsed > max) {
throw new BadRequestException({ code: 'QUERY_INVALID', message: 'Query parameter is invalid.' });
}
return parsed;
}
}