mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
491 lines
11 KiB
Markdown
491 lines
11 KiB
Markdown
# User Groups Controller Documentation
|
|
|
|
**File:** `controllers/admin/user_groups.controller.js`
|
|
**Base URL:** `/api/admin/groups`
|
|
**Guards:** `authenticate → requireAdmin() → adminLimiter`
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
- [Get All Groups](#get-all-groups)
|
|
- [Get Single Group](#get-single-group)
|
|
- [Create Group](#create-group)
|
|
- [Update Group](#update-group)
|
|
- [Deactivate Group](#deactivate-group)
|
|
- [Bulk Deactivate Groups](#bulk-deactivate-groups)
|
|
- [Restore Group](#restore-group)
|
|
- [Bulk Restore Groups](#bulk-restore-groups)
|
|
- [Get Archived Groups](#get-archived-groups)
|
|
- [Get Group Field Values](#get-group-field-values)
|
|
- [Get Users In Group](#get-users-in-group)
|
|
- [Get Users Not In Group](#get-users-not-in-group)
|
|
- [Add Users To Group](#add-users-to-group)
|
|
- [Remove Users From Group](#remove-users-from-group)
|
|
|
|
---
|
|
|
|
## Get All Groups
|
|
|
|
**`GET /api/admin/groups`**
|
|
|
|
Returns a paginated list of active groups.
|
|
|
|
### 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 group 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`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Groups retrieved.",
|
|
"data": {
|
|
"rows": [
|
|
{
|
|
"group_id": 1,
|
|
"name": "Administrators",
|
|
"description": "Full access group.",
|
|
"is_active": true,
|
|
"member_count": 5,
|
|
"createdBy": 1,
|
|
"updatedBy": null,
|
|
"deletedBy": null,
|
|
"createdAt": "2025-01-01T00:00:00.000Z",
|
|
"updatedAt": "2025-01-01T00:00:00.000Z",
|
|
"deletedAt": null
|
|
}
|
|
],
|
|
"pagination": {
|
|
"total": 10,
|
|
"page": 1,
|
|
"limit": 20,
|
|
"totalPages": 1
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Get Single Group
|
|
|
|
**`GET /api/admin/groups/:gid`**
|
|
|
|
Returns a single group with a paginated list of its members.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Query Parameters
|
|
Same pagination/filter params as [Get All Groups](#get-all-groups) — applied to the members list.
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Group retrieved.",
|
|
"data": {
|
|
"group": {
|
|
"group_id": 1,
|
|
"name": "Administrators",
|
|
"description": "Full access group.",
|
|
"is_active": true,
|
|
"createdAt": "2025-01-01T00:00:00.000Z",
|
|
"updatedAt": "2025-01-01T00:00:00.000Z"
|
|
},
|
|
"members": {
|
|
"rows": [ ...users ],
|
|
"pagination": { ... }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Response `404`
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Group not found."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Create Group
|
|
|
|
**`POST /api/admin/groups`**
|
|
|
|
Creates a new user group.
|
|
|
|
### Request Body `application/json`
|
|
| Field | Type | Required | Description |
|
|
|------------|--------|----------|--------------------|
|
|
| name | string | Yes | Group name |
|
|
| description | string | No | Group description |
|
|
|
|
### Response `201`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Group created.",
|
|
"data": {
|
|
"group_id": 1,
|
|
"name": "Administrators",
|
|
"description": "Full access group.",
|
|
"is_active": true,
|
|
"createdBy": 1,
|
|
"createdAt": "2025-01-01T00:00:00.000Z",
|
|
"updatedAt": "2025-01-01T00:00:00.000Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Response `400`
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Group name is required."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Update Group
|
|
|
|
**`PUT /api/admin/groups/:gid`**
|
|
|
|
Updates a group's name or description.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Request Body `application/json`
|
|
| Field | Type | Required | Description |
|
|
|------------|--------|----------|------------------------|
|
|
| name | string | No | Updated group name |
|
|
| description | string | No | Updated description |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Group updated.",
|
|
"data": { ...group }
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Deactivate Group
|
|
|
|
**`PATCH /api/admin/groups/:gid/deactivate`**
|
|
|
|
Soft deletes a group by setting `deletedAt` and `is_active: false`.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Group deactivated."
|
|
}
|
|
```
|
|
|
|
### Response `400`
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Group is already deactivated."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Bulk Deactivate Groups
|
|
|
|
**`DELETE /api/admin/groups/bulk`**
|
|
|
|
Soft deletes multiple groups at once.
|
|
Already-deactivated groups are skipped and reported.
|
|
|
|
### Request Body `application/json`
|
|
| Field | Type | Required | Description |
|
|
|-------|----------|----------|---------------------------|
|
|
| ids | number[] | Yes | Array of group IDs |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "3 group(s) deactivated successfully.",
|
|
"data": {
|
|
"deactivated_ids": [1, 2, 3],
|
|
"skipped_ids": [4]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Restore Group
|
|
|
|
**`PATCH /api/admin/groups/:gid/restore`**
|
|
|
|
Restores a soft-deleted group by clearing `deletedAt` and setting `is_active: true`.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Group restored."
|
|
}
|
|
```
|
|
|
|
### Response `400`
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Group is already active."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Bulk Restore Groups
|
|
|
|
**`POST /api/admin/groups/bulk/restore`**
|
|
|
|
Restores multiple soft-deleted groups at once.
|
|
Already-active groups are skipped and reported.
|
|
|
|
### Request Body `application/json`
|
|
| Field | Type | Required | Description |
|
|
|-------|----------|----------|---------------------------|
|
|
| ids | number[] | Yes | Array of group IDs |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "3 group(s) restored successfully.",
|
|
"data": {
|
|
"restored_ids": [1, 2, 3],
|
|
"skipped_ids": [4]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Get Archived Groups
|
|
|
|
**`GET /api/admin/groups/archived`**
|
|
|
|
Returns a paginated list of soft-deleted groups.
|
|
|
|
### Query Parameters
|
|
Same as [Get All Groups](#get-all-groups).
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Archived groups retrieved.",
|
|
"data": {
|
|
"rows": [ ...soft-deleted groups ],
|
|
"pagination": { ... }
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Get Group Field Values
|
|
|
|
**`GET /api/admin/groups/field-values`**
|
|
|
|
Returns distinct values for a given column — used to populate filter dropdowns in the DataTable.
|
|
Supports regular columns, date fields, and audit fields.
|
|
JSONB fields are not supported for groups.
|
|
|
|
### Query Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|----------|--------|----------|--------------------|
|
|
| field | string | Yes | Column name |
|
|
|
|
### Supported Field Types
|
|
| Type | Example | Returns |
|
|
|----------|-------------|--------------------------------|
|
|
| Regular | `is_active` | Distinct values |
|
|
| Date | `createdAt` | Distinct dates (no time) |
|
|
| Audit by | `createdBy` | Full names of referenced users |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Field values retrieved.",
|
|
"data": ["true", "false"]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Get Users In Group
|
|
|
|
**`GET /api/admin/groups/:gid/users`**
|
|
|
|
Returns all current members of a group with their `user_id` and `full_name`.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Group members fetched.",
|
|
"data": [
|
|
{ "user_id": 1, "full_name": "John Doe" },
|
|
{ "user_id": 2, "full_name": "Jane Smith" }
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Get Users Not In Group
|
|
|
|
**`GET /api/admin/groups/:gid/users/add`**
|
|
|
|
Returns all users who are **not** currently members of the group.
|
|
Used to populate the Add Members sheet.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Users fetched.",
|
|
"data": [
|
|
{ "user_id": 3, "full_name": "Alice Johnson" },
|
|
{ "user_id": 4, "full_name": "Bob Williams" }
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Add Users To Group
|
|
|
|
**`POST /api/admin/groups/:gid/users`**
|
|
|
|
Adds one or more users to a group.
|
|
If a user was previously removed (soft-deleted membership), their membership is restored instead of duplicated.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Request Body `application/json`
|
|
| Field | Type | Required | Description |
|
|
|---------|----------|----------|------------------------------|
|
|
| user_ids | number[] | Yes | Array of user IDs to add |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Users added to group."
|
|
}
|
|
```
|
|
|
|
### Response `404`
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Users not found: 5, 6"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Remove Users From Group
|
|
|
|
**`DELETE /api/admin/groups/:gid/users`**
|
|
|
|
Removes one or more users from a group via soft delete on the membership record.
|
|
|
|
### Path Parameters
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|--------|----------|-------------|
|
|
| gid | number | Yes | Group ID |
|
|
|
|
### Request Body `application/json`
|
|
| Field | Type | Required | Description |
|
|
|---------|----------|---------|---------------------------------|
|
|
| user_ids | number[] | Yes | Array of user IDs to remove |
|
|
|
|
### Response `200`
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Users removed from group."
|
|
}
|
|
```
|
|
|
|
### Response `404`
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Memberships not found for users: 5, 6"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Error Responses
|
|
|
|
All endpoints return the following on server error:
|
|
|
|
```json
|
|
{
|
|
"status": "error",
|
|
"message": "Internal server error."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Notes
|
|
|
|
- **Soft delete** — deactivation sets `deletedAt` + `is_active: false`. Groups are excluded from all queries unless explicitly queried with `paranoid: false`.
|
|
- **Membership soft delete** — removing a user from a group soft-deletes the membership record. Re-adding the user restores the record rather than creating a duplicate.
|
|
- **Audit fields** — `createdBy`, `updatedBy`, `deletedBy` store the `user_id` of the admin who performed the action.
|
|
- **JSONB** — group fields do not support JSONB dot-notation filtering unlike users. |