it0/packages/services/audit-service/src/infrastructure/repositories/audit-log.repository.ts

81 lines
2.4 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { TenantAwareRepository } from '@it0/database';
import { AuditLog } from '../../domain/entities/audit-log.entity';
export interface AuditLogFilters {
actionType?: string;
actorType?: string;
actorId?: string;
resourceType?: string;
from?: string;
to?: string;
page?: number;
limit?: number;
}
@Injectable()
export class AuditLogRepository extends TenantAwareRepository<AuditLog> {
constructor(dataSource: DataSource) {
super(dataSource, AuditLog);
}
async queryLogs(filters: AuditLogFilters): Promise<{ data: AuditLog[]; total: number }> {
return this.withRepository(async (repo) => {
const qb = repo.createQueryBuilder('log');
if (filters.actionType) {
qb.andWhere('log.actionType = :actionType', { actionType: filters.actionType });
}
if (filters.actorType) {
qb.andWhere('log.actorType = :actorType', { actorType: filters.actorType });
}
if (filters.actorId) {
qb.andWhere('log.actorId = :actorId', { actorId: filters.actorId });
}
if (filters.resourceType) {
qb.andWhere('log.resourceType = :resourceType', { resourceType: filters.resourceType });
}
if (filters.from) {
qb.andWhere('log.createdAt >= :from', { from: new Date(filters.from) });
}
if (filters.to) {
qb.andWhere('log.createdAt <= :to', { to: new Date(filters.to) });
}
qb.orderBy('log.createdAt', 'DESC');
const page = filters.page ?? 1;
const limit = filters.limit ?? 50;
qb.skip((page - 1) * limit).take(limit);
const [data, total] = await qb.getManyAndCount();
return { data, total };
});
}
async exportLogs(format: 'json' | 'csv'): Promise<AuditLog[] | string> {
return this.withRepository(async (repo) => {
const logs = await repo.find({ order: { createdAt: 'DESC' } as any });
if (format === 'csv') {
const headers = ['id', 'tenantId', 'actionType', 'actorType', 'actorId', 'resourceType', 'resourceId', 'ipAddress', 'createdAt'];
const rows = logs.map(log =>
headers.map(h => {
const value = (log as any)[h];
return value !== undefined && value !== null ? String(value) : '';
}).join(','),
);
return [headers.join(','), ...rows].join('\n');
}
return logs;
});
}
}