Activity Log
The Activity Log module provides access to user activity trails stored in MongoDB (the activity_logs collection). The ActivityLogController is mounted at /activities-logs. FE uses it for the “Activity History” / “Activity Timeline” page on the user profile — the endpoints read logs for the currently logged-in user only, with activityType + status filters and pagination.
| Property | Value |
|---|---|
| Base URL | {HOST}/v1 |
| Auth | Bearer JWT (header Authorization) or cookie access_token |
| Content-Type | application/json |
| Error envelope | { "message": string | string[], "statusCode": number, "error": string } |
| Validation | Global ValidationPipe · whitelist: true, forbidNonWhitelisted: true · unknown field → 400 |
| Related modules | users, authentication, withdrawal, saving-goals, security |
| Document version | v1 · 2026-05-20 |
| Audience | Internal FE devs (mobile + web) |
Summary
Section titled “Summary”Every user activity (login, withdraw, update saving goal, etc.) is written to MongoDB by an internal log service. FE reads two endpoints: a list of activities (paginated/filtered), and aggregate stats per activityType for the activity chart over the last N days. Both endpoints are always scoped to the currently logged-in user — there is no way to read another user’s logs.
| Method | Path | Auth | Summary |
|---|---|---|---|
| GET | /v1/activities-logs | bearer | List the logged-in user’s activity log (paginated + filter) |
| GET | /v1/activities-logs/stats | bearer | Aggregate stats per activityType over N days |
GET /v1/activities-logs bearer
Section titled “GET /v1/activities-logs ”Reads the logged-in user’s activity log list with activityType/status filters, pagination, and a sort option. Supports activityType as an array (use repeated query-string parameters).
Query params — GetActivityLogsDto
Section titled “Query params — GetActivityLogsDto”| Param | Type | Default | Notes |
|---|---|---|---|
activityType | enum ActivityType or array | optional | Filter by one or many types (e.g. ?activityType=login&activityType=withdrawal_request). Validation IsEnum(..., { each: true }) |
status | enum ActivityStatus | optional | success, failed, pending, cancelled |
page | number | 1 | Page number · Min(1) |
limit | number | 20 | Records per page · Min(1), Max(100) |
sortBy | string | createdAt | One of createdAt, activityType, status |
sortOrder | 'asc' | 'desc' | desc | Sort order |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "SUCCESS", "statusCode": 200, "message": "Activity logs retrieved successfully", "data": { "data": [ { "_id": "665f1a2b3c4d5e6f7a8b9c0d", "userId": "770e8400-e29b-41d4-a716-446655440222", "userEmail": "amal@example.com", "activityType": "login", "status": "success", "description": "User logged in successfully", "metadata": {}, "deviceInfo": { "userAgent": "Mozilla/5.0 ...", "browser": "Chrome", "os": "Android 14", "device": "Pixel 7", "isMobile": true }, "locationInfo": { "ipAddress": "103.10.20.30", "country": "Indonesia", "region": "DKI Jakarta", "city": "Jakarta", "timezone": "Asia/Jakarta", "coordinates": { "lat": -6.2, "lng": 106.8 } }, "resourceId": null, "resourceType": null, "createdAt": "2026-05-20T08:30:00.000Z", "updatedAt": "2026-05-20T08:30:00.000Z" } ], "total": 124, "page": 1, "limit": 20, "totalPages": 7 }}Errors
Section titled “Errors”| Status | When it occurs |
|---|---|
400 Bad Request | Invalid query param (e.g. activityType outside the enum, limit > 100) |
401 Unauthorized | Invalid Bearer/cookie token |
403 Forbidden | Missing read-activity-log permission |
If the service throws an exception, the controller catches it and returns a body with status: "ERROR", statusCode: 500, and an error: "..." field. FE should still check statusCode before reading data.
GET /v1/activities-logs/stats bearer
Section titled “GET /v1/activities-logs/stats ”Aggregate statistics of the logged-in user’s activities over the last N days, grouped by activityType. Good for a summary chart on a profile / security dashboard.
Query params
Section titled “Query params”| Param | Type | Default | Notes |
|---|---|---|---|
days | number | 30 | Day range counted backward from today |
Response — 200 OK
Section titled “Response — 200 OK”{ "status": "SUCCESS", "statusCode": 200, "message": "Activity statistics retrieved successfully", "data": [ { "_id": "login", "count": 12, "lastActivity": "2026-05-20T08:30:00.000Z" }, { "_id": "withdrawal_request", "count": 3, "lastActivity": "2026-05-18T14:20:00.000Z" } ]}The _id field here is the activityType (result of MongoDB’s $group), not an ObjectId. count = number of activities with that type within the days window; lastActivity = timestamp of the most recent activity.
Errors
Section titled “Errors”| Status | When it occurs |
|---|---|
400 Bad Request | days is not a valid number |
401 Unauthorized | Invalid Bearer/cookie token |
403 Forbidden | Missing read-activity-log-stats permission |
Reference
Section titled “Reference”Enum: ActivityType
Section titled “Enum: ActivityType”- Authentication & Security —
login,login_new_device,login_failed,logout,password_change_request,password_changed,two_fa_enabled,two_fa_disabled - Account Management —
account_created,profile_updated,email_verified - Financial —
withdrawal_request,withdrawal_approved,withdrawal_rejected,withdrawal_completed,deposit,transfer - Saving Goals —
saving_goal_created,saving_goal_updated,saving_goal_cancelled,saving_goal_contribution,saving_goal_withdrawal_requested,saving_goal_withdrawal_completed - General —
api_access,settings_updated,document_uploaded,suspicious_activity
Enum: ActivityStatus
Section titled “Enum: ActivityStatus”success·failed·pending·cancelled
Brief shape of each log
Section titled “Brief shape of each log”_id— MongoDB ObjectId (string)userId— UUID of the user owning the loguserEmail— user’s email (snapshot when the log was created)activityType,status— the enums abovedescription— human-readable narrativemetadata— free-form object (context-dependent)deviceInfo—userAgent,browser,os,device,isMobilelocationInfo—ipAddress,country,region,city,timezone,coordinates {lat, lng}resourceId,resourceType— optional, references a related entitycreatedAt,updatedAt— ISO 8601 timestamps
Standard error envelope
Section titled “Standard error envelope”{ "message": "limit must not be greater than 100", "statusCode": 400, "error": "Bad Request"}