@haykal/audit-backend
v1.0.0
Published
> Audit trail and activity logging with automatic controller/entity auditing, change diffs, programmatic logging, and configurable retention.
Readme
@haykal/audit-backend
Audit trail and activity logging with automatic controller/entity auditing, change diffs, programmatic logging, and configurable retention.
Installation
pnpm add @haykal/audit-backendConfiguration
forRoot() Options
import { AuditModule } from '@haykal/audit-backend';
@Module({
imports: [
AuditModule.forRoot({
enabled: true,
autoAuditEntities: true,
excludeFields: [
'password',
'passwordHash',
'token',
'secret',
'refreshToken',
],
retentionDays: 365,
logReads: false,
async: true,
}),
],
})
export class AppModule {}| Property | Type | Default | Description |
| ------------------- | ---------- | ----------------------------------- | ------------------------------------------------ |
| enabled | boolean | true | Enable/disable audit logging |
| autoAuditEntities | boolean | true | Auto-audit TypeORM entity changes via subscriber |
| excludeFields | string[] | ['password', 'passwordHash', ...] | Fields to redact from change diffs |
| retentionDays | number | 365 | Retention period before cleanup |
| logReads | boolean | false | Log read operations (high volume) |
| async | boolean | true | Non-blocking audit via domain events |
Key Exports
| Export | Type | Description |
| --------------------- | ------------- | ---------------------------------------------- |
| AuditModule | NestJS Module | Main module with forRoot() |
| AUDIT_CONFIG | Symbol | Inject the config object |
| AuditService | Service | Programmatic audit logging and querying |
| AuditCleanupService | Service | Retention-based cleanup |
| AuditInterceptor | Interceptor | Auto-audit controller actions |
| AuditSubscriber | Subscriber | Auto-audit TypeORM entity changes |
| @Audited() | Decorator | Mark controller methods for auto-auditing |
| @AuditedEntity() | Decorator | Mark entities for auto-auditing |
| AuditLogEntity | Entity | Audit log records |
| AUDIT_ENTITIES | Array | [AuditLogEntity] for migrations |
| AuditAction | Enum | CREATE, READ, UPDATE, DELETE, CUSTOM |
Domain Errors
| Error | Code | Status | Description |
| ----------------------- | --------------------- | ------ | ------------------------- |
| AuditDisabledError | AUDIT_DISABLED | 422 | Audit logging is disabled |
| AuditLogNotFoundError | AUDIT_LOG_NOT_FOUND | 404 | Audit log not found |
Domain Events
| Event | Payload |
| ---------------------------- | ------------------------------------------------ |
| AuditLoggedEvent | auditLogId, action, entityType, entityId |
| AuditCleanupCompletedEvent | deletedCount, beforeDate |
API Endpoints
All endpoints require JWT authentication. Base path: /api/audit.
| Method | Path | Description |
| ------ | ------------------------- | --------------------------------------------------------------------------- |
| GET | /audit | List audit logs (paginated, filterable by action, entity, user, date range) |
| GET | /audit/stats | Audit statistics (counts per action type) |
| GET | /audit/entity/:type/:id | Audit history for a specific entity |
| GET | /audit/user/:userId | Audit logs for a specific user |
Usage Examples
Decorator-Based Auditing
import { Audited, AuditedEntity } from '@haykal/audit-backend';
@AuditedEntity({ entityType: 'Order' })
@Entity('orders')
export class OrderEntity extends HaykalBaseEntity {
// Entity changes are auto-logged
}
@Controller('orders')
export class OrdersController {
@Audited({ action: 'CREATE', description: 'Created a new order' })
@Post()
create(@Body() dto: CreateOrderDto) {
return this.service.create(dto);
}
}Programmatic Audit Logging
import { AuditService, AuditAction } from '@haykal/audit-backend';
@Injectable()
export class PaymentService {
constructor(private readonly audit: AuditService) {}
async processPayment(orderId: string, amount: number) {
// ... process payment ...
await this.audit.log({
action: AuditAction.CUSTOM,
entityType: 'Payment',
entityId: paymentId,
description: `Payment of ${amount} processed for order ${orderId}`,
metadata: { amount, orderId },
});
}
}Querying Audit Logs
const logs = await this.audit.findAll({
entityType: 'Order',
entityId: orderId,
action: AuditAction.UPDATE,
fromDate: new Date('2024-01-01'),
});Related Packages
@haykal/audit-client— React Query hooks for audit log viewing@haykal/core-backend— Base infrastructure (domain events, errors)
Further Reading
- API Reference — Full endpoint listing
- Architecture Overview — System design and module composition
- Backend Style Guide — Coding conventions
