Careeroza
Real World Example
Audit Logging for Admin Actions
Banks, fintechs and marketplaces must record who changed what (RBI and SOC 2 audits ask for it). An @Audit('product.delete') decorator plus an interceptor writes an audit row for every admin action, without touching the handlers.
src/audit/audit.decorator.ts and src/audit/audit.interceptor.ts
import { applyDecorators, CallHandler, ExecutionContext, Injectable, NestInterceptor, UseInterceptors } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable, tap } from 'rxjs';
import { AuditService } from './audit.service';
export const AuditAction = Reflector.createDecorator<string>();
export const Audit = (action: string) => applyDecorators(AuditAction(action), UseInterceptors(AuditInterceptor));
@Injectable()
export class AuditInterceptor implements NestInterceptor {
constructor(private readonly reflector: Reflector, private readonly audit: AuditService) {}
intercept(ctx: ExecutionContext, next: CallHandler): Observable<unknown> {
const action = this.reflector.get(AuditAction, ctx.getHandler());
const req = ctx.switchToHttp().getRequest();
return next.handle().pipe(
tap(() =>
this.audit.record({
action,
actorId: req.user.id,
target: req.params.id ?? null,
ip: req.ip,
payload: req.body,
}),
),
);
}
}
// products.controller.ts
// @Auth(Role.Admin)
// @Audit('product.delete')
// @Delete(':id') remove(@Param('id', ParseIntPipe) id: number) { ... }Example
curl -H "Authorization: Bearer <admin-token>" "http://localhost:3000/admin/audit?limit=1"Example output
[{"id":90211,"action":"product.delete","actorId":1,"target":"7","ip":"10.0.4.17","createdAt":"2026-01-15T10:00:00.000Z"}]