Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
11 KiB
Users Controller Documentation
File: controllers/admin/users.controller.js
Base URL: /api/admin/users
Guards: authenticate → requireAdmin() → adminLimiter
Table of Contents
- Get All Users
- Get Single User
- Add Staff User
- Update User
- Deactivate User
- Bulk Deactivate Users
- Restore User
- Bulk Restore Users
- Get Archived Users
- Get User Field Values
- Get User Sessions
- Terminate Session
Get All Users
GET /api/admin/users
Returns a paginated list of active users.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | number | No | Page number. Default: 1 |
| limit | number | No | Records per page. Default: 20 |
| search | string | No | Search across user fields |
| sort_by | string | No | Column to sort by. Default: createdAt |
| sort_dir | string | No | Sort direction: ASC or DESC. Default: DESC |
| filters | array | No | Column filters from DataTable |
Response 200
{
"status": "success",
"message": "Users retrieved.",
"data": {
"rows": [
{
"user_id": 1,
"email": "john@example.com",
"acc_type": "admin",
"reg_type": "system",
"is_active": true,
"is_verified": true,
"personal_info": {
"name": {
"given_name": "John",
"middle_name": null,
"last_name": "Doe",
"extension_name": null,
"full_name": "John Doe"
},
"date_of_birth": null,
"occupation": null,
"addresses": [],
"phone_number": []
},
"groups": [],
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z",
"deletedAt": null
}
],
"pagination": {
"total": 100,
"page": 1,
"limit": 20,
"totalPages": 5
}
}
}
Get Single User
GET /api/admin/users/:id
Returns a single user with their group memberships.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | number | Yes | User ID |
Response 200
{
"status": "success",
"message": "User retrieved.",
"data": {
"user_id": 1,
"email": "john@example.com",
"acc_type": "admin",
"is_active": true,
"is_verified": true,
"personal_info": { ... },
"groups": [
{ "group_id": 1, "name": "Administrators" }
],
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
}
}
Response 404
{
"status": "error",
"message": "User not found."
}
Add Staff User
POST /api/admin/users/staff
Creates a new staff user with an auto-generated temporary password.
A welcome email is sent with the credentials and a 24-hour expiry notice.
The user is forced to change their password on first login.
Request Body application/json
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Staff user email address | |
| personal_info.name.given_name | string | Yes | First name |
| personal_info.name.last_name | string | Yes | Last name |
| personal_info.name.middle_name | string | No | Middle name |
| personal_info.name.extension_name | string | No | Extension name e.g. Jr. |
| personal_info.date_of_birth | string | No | Date of birth |
| personal_info.occupation | string | No | Occupation |
Response 201
{
"status": "success",
"message": "Staff user created successfully.",
"data": {
"user_id": 5,
"email": "staff@example.com",
"acc_type": "staff"
}
}
Response 409
{
"status": "error",
"message": "Email is already in use."
}
Update User
PUT /api/admin/users/:id
Updates a user's account type, active status, or personal information.
Admins cannot change their own acc_type.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | number | Yes | User ID |
Request Body application/json
| Field | Type | Required | Description |
|---|---|---|---|
| acc_type | string | No | admin, staff, user |
| is_active | boolean | No | Active status |
| personal_info | object | No | Personal information object |
Response 200
{
"status": "success",
"message": "User updated.",
"data": { ...user }
}
Response 400
{
"status": "error",
"message": "Admins cannot change their own role."
}
Deactivate User
DELETE /api/admin/users/:id
Soft deletes a user by setting deletedAt and is_active: false.
All active sessions are force-terminated.
Admins cannot deactivate their own account.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | number | Yes | User ID |
Response 200
{
"status": "success",
"message": "User deactivated successfully."
}
Response 400
{
"status": "error",
"message": "You cannot deactivate your own account."
}
Bulk Deactivate Users
DELETE /api/admin/users/bulk
Soft deletes multiple users at once.
Already-deactivated users are skipped and reported.
All active sessions for deactivated users are force-terminated.
Request Body application/json
| Field | Type | Required | Description |
|---|---|---|---|
| ids | number[] | Yes | Array of user IDs |
Response 200
{
"status": "success",
"message": "3 user(s) deactivated successfully.",
"data": {
"deactivated_ids": [1, 2, 3],
"skipped_ids": [4]
}
}
Restore User
POST /api/admin/users/:id/restore
Restores a soft-deleted user by clearing deletedAt and setting is_active: true.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | number | Yes | User ID |
Response 200
{
"status": "success",
"message": "User restored successfully."
}
Response 400
{
"status": "error",
"message": "User is not deactivated."
}
Bulk Restore Users
POST /api/admin/users/bulk/restore
Restores multiple soft-deleted users at once.
Already-active users are skipped and reported.
Request Body application/json
| Field | Type | Required | Description |
|---|---|---|---|
| ids | number[] | Yes | Array of user IDs |
Response 200
{
"status": "success",
"message": "3 user(s) restored successfully.",
"data": {
"restored_ids": [1, 2, 3],
"skipped_ids": [4]
}
}
Get Archived Users
GET /api/admin/users/archived
Returns a paginated list of soft-deleted users.
Query Parameters
Same as Get All Users.
Response 200
{
"status": "success",
"message": "Archived users retrieved.",
"data": {
"rows": [ ...soft-deleted users ],
"pagination": { ... }
}
}
Get User Field Values
GET /api/admin/users/field-values
Returns distinct values for a given column — used to populate filter dropdowns in the DataTable.
Supports regular columns, date fields, audit fields, and JSONB dot-notation.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| field | string | Yes | Column name or JSONB path e.g. personal_info.name.given_name |
Supported Field Types
| Type | Example | Returns |
|---|---|---|
| Regular | acc_type |
Distinct string values |
| Date | createdAt |
Distinct dates (no time) |
| Audit by | createdBy |
Full names of referenced users |
| JSONB | personal_info.name.given_name |
Distinct JSONB path values |
Response 200
{
"status": "success",
"message": "Field values retrieved.",
"data": ["admin", "staff", "user"]
}
Response 400
{
"status": "error",
"message": "Invalid or restricted field."
}
Get User Sessions
GET /api/admin/users/:id/sessions
Returns all sessions for a specific user, ordered by most recent.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | number | Yes | User ID |
Response 200
{
"status": "success",
"message": "Sessions retrieved.",
"data": [
{
"session_id": 1,
"user_id": 1,
"is_active": true,
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"createdAt": "2025-01-01T00:00:00.000Z",
"logout_info": null
}
]
}
Terminate Session
DELETE /api/admin/users/:id/sessions/:sid
Force-terminates a specific user session.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | number | Yes | User ID |
| sid | number | Yes | Session ID |
Response 200
{
"status": "success",
"message": "Session terminated."
}
Response 404
{
"status": "error",
"message": "Session not found."
}
Error Responses
All endpoints return the following on server error:
{
"status": "error",
"message": "Internal server error."
}
Notes
- Excluded fields —
password,otp_code,otp_expires_at,must_change_password,password_expires_atare never returned in any response. - Soft delete — deactivation sets
deletedAt+is_active: false. Users are excluded from all queries unless explicitly queried withparanoid: false. - Session termination — deactivating a user (single or bulk) always force-terminates all their active sessions.
- Audit fields —
createdBy,updatedBy,deletedBystore theuser_idof the admin who performed the action.