mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 06:28:12 +00:00
Backoffice portal updates: dashboard, seat management, pricing, audit logging, reporting
This commit is contained in:
10
apps/edr-passenger-api/src/common/audit.module.ts
Normal file
10
apps/edr-passenger-api/src/common/audit.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PrismaModule } from './prisma.module';
|
||||
import { AuditService } from './audit.service';
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
providers: [AuditService],
|
||||
exports: [AuditService],
|
||||
})
|
||||
export class AuditModule {}
|
||||
92
apps/edr-passenger-api/src/common/audit.service.ts
Normal file
92
apps/edr-passenger-api/src/common/audit.service.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import { Injectable, Inject, Optional } from '@nestjs/common';
|
||||
import { REQUEST } from '@nestjs/core';
|
||||
import { PrismaService } from './prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuditService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
@Optional() @Inject(REQUEST) private request?: any,
|
||||
) {}
|
||||
|
||||
async log(input: {
|
||||
userId?: string;
|
||||
action: 'CREATE' | 'UPDATE' | 'DELETE' | 'LOGIN' | 'LOGOUT' | 'VERIFY' | string;
|
||||
entityType: string;
|
||||
entityId?: string;
|
||||
oldData?: any;
|
||||
newData?: any;
|
||||
}) {
|
||||
try {
|
||||
const ipAddress = this.getIpAddress();
|
||||
const userAgent = this.getUserAgent();
|
||||
|
||||
await this.prisma.auditLog.create({
|
||||
data: {
|
||||
userId: input.userId,
|
||||
action: input.action,
|
||||
entityType: input.entityType,
|
||||
entityId: input.entityId,
|
||||
oldData: input.oldData,
|
||||
newData: input.newData,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to log audit event:', error);
|
||||
// Don't throw - audit logging should not break main operations
|
||||
}
|
||||
}
|
||||
|
||||
private getIpAddress(): string {
|
||||
if (!this.request) return '';
|
||||
|
||||
return (
|
||||
this.request.headers['x-forwarded-for']?.split(',')[0].trim() ||
|
||||
this.request.headers['x-real-ip'] ||
|
||||
this.request.connection?.remoteAddress ||
|
||||
this.request.socket?.remoteAddress ||
|
||||
this.request.ip ||
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
private getUserAgent(): string {
|
||||
return this.request?.headers?.['user-agent'] || '';
|
||||
}
|
||||
|
||||
async getLogs(filters: any = {}) {
|
||||
const where: any = {};
|
||||
|
||||
if (filters.search) {
|
||||
where.OR = [
|
||||
{ entityId: { contains: filters.search, mode: 'insensitive' } },
|
||||
{ user: { email: { contains: filters.search, mode: 'insensitive' } } },
|
||||
{ user: { fullName: { contains: filters.search, mode: 'insensitive' } } },
|
||||
];
|
||||
}
|
||||
|
||||
if (filters.action) {
|
||||
where.action = filters.action;
|
||||
}
|
||||
|
||||
if (filters.entityType) {
|
||||
where.entityType = filters.entityType;
|
||||
}
|
||||
|
||||
return this.prisma.auditLog.findMany({
|
||||
where,
|
||||
include: { user: true },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 500, // Limit to last 500 logs
|
||||
});
|
||||
}
|
||||
|
||||
async getLog(id: string) {
|
||||
return this.prisma.auditLog.findUnique({
|
||||
where: { id },
|
||||
include: { user: true },
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user