feat: implement audit logging system with service, controller, and interceptor to track user actions across core services

This commit is contained in:
pradeepkumar
2026-04-28 11:12:25 +05:30
parent 4eda556059
commit 80c6fd1d71
27 changed files with 895 additions and 29 deletions

View File

@@ -2,10 +2,15 @@ import { Injectable, NotFoundException, ConflictException, BadRequestException }
import { Prisma, FieldType } from '@prisma/client';
import { PrismaService } from '../prisma';
import { CreateFieldDto, UpdateFieldDto } from './dto';
import { AuditService } from '../audit/audit.service';
import { AuditAction } from '../audit/audit.constants';
@Injectable()
export class ProfileFieldsService {
constructor(private readonly prisma: PrismaService) {}
constructor(
private readonly prisma: PrismaService,
private readonly audit: AuditService,
) {}
/**
* Generate a URL-friendly slug from the name
@@ -153,7 +158,7 @@ export class ProfileFieldsService {
data.slug = newSlug;
}
return this.prisma.profileField.update({
const updated = await this.prisma.profileField.update({
where: { id },
data,
include: {
@@ -162,6 +167,15 @@ export class ProfileFieldsService {
},
},
});
this.audit.log({
action: AuditAction.PROFILE_FIELD_UPDATE,
resourceType: 'ProfileField',
resourceId: id,
metadata: { sectionId: field.sectionId, slug: updated.slug, name: updated.name },
});
return updated;
}
/**
@@ -181,9 +195,18 @@ export class ProfileFieldsService {
);
}
return this.prisma.profileField.delete({
const deleted = await this.prisma.profileField.delete({
where: { id },
});
this.audit.log({
action: AuditAction.PROFILE_FIELD_UPDATE,
resourceType: 'ProfileField',
resourceId: id,
metadata: { action: 'delete' },
});
return deleted;
}
/**

View File

@@ -1,10 +1,15 @@
import { Injectable, NotFoundException, ConflictException, ForbiddenException } from '@nestjs/common';
import { PrismaService } from '../prisma';
import { CreateSectionDto, UpdateSectionDto, AssignSectionDto, UpdateAssignmentDto } from './dto';
import { AuditService } from '../audit/audit.service';
import { AuditAction } from '../audit/audit.constants';
@Injectable()
export class ProfileSectionsService {
constructor(private readonly prisma: PrismaService) {}
constructor(
private readonly prisma: PrismaService,
private readonly audit: AuditService,
) {}
/**
* Generate a URL-friendly slug from the name
@@ -127,7 +132,7 @@ export class ProfileSectionsService {
data.slug = effectiveSlug;
}
return this.prisma.profileSection.update({
const updated = await this.prisma.profileSection.update({
where: { id },
data,
include: {
@@ -136,6 +141,15 @@ export class ProfileSectionsService {
},
},
});
this.audit.log({
action: AuditAction.PROFILE_SECTION_UPDATE,
resourceType: 'ProfileSection',
resourceId: id,
metadata: { name: updated.name, slug: updated.slug },
});
return updated;
}
/**
@@ -158,9 +172,18 @@ export class ProfileSectionsService {
);
}
return this.prisma.profileSection.delete({
const deleted = await this.prisma.profileSection.delete({
where: { id },
});
this.audit.log({
action: AuditAction.PROFILE_SECTION_UPDATE,
resourceType: 'ProfileSection',
resourceId: id,
metadata: { action: 'delete', name: section.name },
});
return deleted;
}
/**