@edirect/audit-nestjs
v11.0.54
Published
NestJS integration for the eDirect Audit system. Provides a configurable `AuditModule` and a request-scoped `AuditService` that automatically extracts trace/session context from Express requests and dispatches audit events via a configurable exporter.
Maintainers
Keywords
Readme
@edirect/audit-nestjs
NestJS integration for the eDirect Audit system. Provides a configurable AuditModule and a request-scoped AuditService that automatically extracts trace/session context from Express requests and dispatches audit events via a configurable exporter.
Features
- Request-scoped
AuditService— one instance per HTTP request for automatic context propagation - Configurable exporter factory per request (useful for per-tenant auth tokens)
- Built-in Express instrumentation support
- Supports
registerandregisterAsyncfor flexible configuration - Works with
@edirect/audit-exporter-http-axiosor@edirect/audit-exporter-http-fetch
Installation
pnpm add @edirect/audit-nestjs @edirect/audit-core @edirect/audit-domain @edirect/audit-instrumentation-express @edirect/audit-exporter-http-axios
# or
npm install @edirect/audit-nestjs ...Usage
1. Register AuditModule in your AppModule
import { Module } from '@nestjs/common';
import { AuditModule } from '@edirect/audit-nestjs';
import { HttpAxiosExporter } from '@edirect/audit-exporter-http-axios';
import { InstrumentationExpress } from '@edirect/audit-instrumentation-express';
@Module({
imports: [
AuditModule.register({
// Factory receives the current Express request — useful for extracting auth tokens
exporter: request =>
new HttpAxiosExporter({
basePath: 'https://audit.internal.example.com',
accessToken: request.headers.authorization,
}),
service: 'policy-issuing-service',
domain: 'policy',
tenant: process.env.NAMESPACE ?? 'th-broker',
instrumentation: [new InstrumentationExpress()],
throwErrors: false,
}),
],
})
export class AppModule {}2. Inject and use AuditService
import { Injectable } from '@nestjs/common';
import { AuditService } from '@edirect/audit-nestjs';
@Injectable()
export class PolicyService {
constructor(private readonly audit: AuditService) {}
async createPolicy(policyData: object, actorId: string) {
const policy = await this.savePolicyToDb(policyData);
await this.audit.audit({
originType: 'HTTP',
actorType: 'AGENT',
actorGroup: 'th-broker-agents',
actorId,
actionCategory: 'DATA_MODIFICATION_EVENT',
actionKey: 'CREATE',
targetKey: 'Policy',
targetId: [policy.id],
actionDetail: `Agent created policy for customer`,
actionPayload: policyData,
resultKey: 'SUCCESS',
resultDetail: `Policy ${policy.id} created`,
eventTimestamp: new Date(),
});
return policy;
}
}AuditModuleOptions
| Option | Type | Required | Description |
| ----------------- | ------------------------------------------- | -------- | ----------------------------------------------------- |
| exporter | (request: Request) => Exporter | Yes | Factory function that creates an exporter per request |
| service | string | Yes | Service name for all audit events |
| domain | string | Yes | Business domain (e.g., 'policy') |
| tenant | string | Yes | Tenant identifier (e.g., 'th-broker') |
| instrumentation | Middleware[] | No | Auto-instrumentation middlewares |
| sessionId | (request: Request) => string \| undefined | No | Custom session ID extractor |
| disabled | boolean | No | Disable all audit events (default: false) |
| throwErrors | boolean | No | Re-throw exporter errors (default: false) |
| bulkLimit | number | No | Max events per bulk export |
AuditService.audit() Method
The audit() method accepts a subset of AuditRequest — service, domain, tenant, traceId, sessionId, originIpAddress, and originUrl are filled automatically from module options and the current request.
audit(data: {
originType: string;
actorType: 'ANONYMOUS' | 'AGENT' | 'CUSTOMER' | 'INTERNAL' | 'INTEGRATION' | 'AUTOMATION';
actorGroup: string;
actorId?: string;
actionCategory: 'DATA_ACCESS_EVENT' | 'DATA_MODIFICATION_EVENT' | 'AUTHENTICATION_EVENT' | 'INFORMATIONAL_EVENT';
actionKey: 'CREATE' | 'READ' | 'UPDATE' | 'DELETE' | 'LOGIN' | 'LOGOUT' | 'OTHER';
targetKey: string;
targetId?: string[];
actionDetail: string;
actionPayload?: object;
resultKey: 'SUCCESS' | 'FAIL' | 'PARTIAL_SUCCESS';
resultDetail?: string;
resultPayload?: object;
eventTimestamp: Date;
}): Promise<void>Async Configuration
AuditModule.registerAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
exporter: request =>
new HttpAxiosExporter({
basePath: configService.get('AUDIT_SERVICE_URL'),
accessToken: request.headers.authorization,
}),
service: configService.get('APP_NAME') ?? 'my-service',
domain: configService.get('AUDIT_DOMAIN') ?? 'default',
tenant: configService.get('NAMESPACE') ?? 'default',
instrumentation: [new InstrumentationExpress()],
}),
inject: [ConfigService],
});