Activity Log Documentation
This documentation explains the features and usage of Activity Log Module: Located at src/modules/activity-log
Overview
⚠️
Future Plan:Will support decorator-based logging for bidirectional activity and self activity.
Activity Log is a system to record successful user activities in the application. It supports self activity recording.
Notes:
- Activity logs are only recorded for successful requests. Failed requests are not logged.
@ActivityLogdecorator is only implemented for admin endpoints.@ActivityLogdecorator requires@AuthJwtAccessProtecteddecorator to be present.
Related Documents
- Authentication Documentation - For understanding user context
Table of Contents
Flow
Data
Each activity log contains:
- userId - User who performed or was affected
- action - Type of activity (enum)
- ipAddress - Request IP address
- userAgent - Browser/device info (JSON)
- metadata - Additional context (optional, JSON)
- createdAt - Timestamp
Metadata
Metadata allows you to record additional context about the activity. The decorator automatically captures metadata by reading metadataActivityLog from the service response.
How it works:
- Service returns
IResponseReturnwithmetadataActivityLogproperty - Decorator reads
metadataActivityLogfrom response - Decorator includes it in the activity log under
metadatafield
Example:
// Controller with decorator
@ActivityLog(EnumActivityLogAction.adminUserUpdateStatus)
@AuthJwtAccessProtected() // Required for ActivityLog
@Put('/user/:id/block')
async blockUser(@Param('id') userId: string) {
return this.userService.blockUser(userId); // Returns IResponseReturn
}
// Service returns IResponseReturn with metadataActivityLog
async blockUser(userId: string): Promise<IResponseReturn> {
const user = await this.userRepository.findOneById(userId);
const oldStatus = user.status; // Store old value
const updated = await this.userRepository.updateStatus(userId, 'blocked');
// Return with metadataActivityLog
return {
data: this.userUtil.mapOne(updated),
metadataActivityLog: {
userId: user.id,
userName: user.name,
oldStatus: oldStatus, // Before change
newStatus: 'blocked' // After change
}
};
}Result: Activity log will contain the metadata automatically.
{
"userId": "admin-id",
"action": "adminUserUpdateStatus",
"metadata": {
"userId": "user-123",
"userName": "John Doe",
"oldStatus": "active",
"newStatus": "blocked"
}
}Guidelines:
Never include sensitive data:
metadataActivityLog: {
password: "secret123", // Never!
accessToken: "jwt_token", // Never!
entireUserObject: { ... } // Too large
}Usage
Admin Blocks User
Implementation:
// Controller - decorator handles admin's log
@ActivityLog(EnumActivityLogAction.adminUserUpdateStatus)
@AuthJwtAccessProtected() // Required for ActivityLog decorator
@Put('/user/:id/block')
async blockUser(@Param('id') userId: string) {
return this.userService.blockUser(userId);
}
// Service - returns metadataActivityLog
async blockUser(userId: string): Promise<IResponseReturn> {
const user = await this.userRepository.findOneById(userId);
const updated = await this.userRepository.updateStatus(userId, 'blocked');
return {
data: this.userUtil.mapOne(updated),
metadataActivityLog: {
userId: user.id,
userName: user.name,
oldStatus: user.status,
newStatus: 'blocked'
}
};
}Logs Created:
{
"userId": "admin-id",
"action": "adminUserUpdateStatus",
"ipAddress": "192.168.1.1",
"userAgent": { ... },
"metadata": {
"userId": "user-123",
"userName": "John Doe",
"oldStatus": "active",
"newStatus": "blocked"
}
}Last updated on