# Tasks Controller Documentation **File:** `controllers/admin/task.controller.js` + `controllers/admin/task_completion.controller.js` **Base URL:** `/api/admin/task-lists` **Guards:** `authenticate → requireAdmin() → adminLimiter` --- ## Table of Contents - [Task Lists](#task-lists) - [Get All Task Lists](#get-all-task-lists) - [Get Single Task List](#get-single-task-list) - [Create Task List](#create-task-list) - [Update Task List](#update-task-list) - [Archive Task List](#archive-task-list) - [Restore Task List](#restore-task-list) - [Bulk Archive Task Lists](#bulk-archive-task-lists) - [Bulk Restore Task Lists](#bulk-restore-task-lists) - [Get Archived Task Lists](#get-archived-task-lists) - [Get Task List Field Values](#get-task-list-field-values) - [Task List Groups](#task-list-groups) - [Get Assigned Groups](#get-assigned-groups) - [Assign Groups](#assign-groups) - [Unassign Groups](#unassign-groups) - [Tasks](#tasks) - [Get All Tasks](#get-all-tasks) - [Get Single Task](#get-single-task) - [Create Task](#create-task) - [Update Task](#update-task) - [Archive Task](#archive-task) - [Restore Task](#restore-task) - [Bulk Archive Tasks](#bulk-archive-tasks) - [Bulk Restore Tasks](#bulk-restore-tasks) - [Get Archived Tasks](#get-archived-tasks) - [Get Task Field Values](#get-task-field-values) - [Completions](#completions) - [Get All Completions](#get-all-completions) - [Get Single Completion](#get-single-completion) - [Get Completions by User](#get-completions-by-user) - [Archive Completion](#archive-completion) - [Restore Completion](#restore-completion) - [Bulk Archive Completions](#bulk-archive-completions) - [Bulk Restore Completions](#bulk-restore-completions) --- ## Data Model ``` TaskList ──< Task ──< TaskRequirement │ └──< TaskListGroup >── UserGroup ``` - A **TaskList** is a named container of tasks, visible to assigned user groups. - A **Task** belongs to one TaskList and has 0-N requirements. - A **TaskRequirement** specifies what a user must do (visit a link, upload a file, or read a course/unit/lesson). - Completions are submitted by **clients only** — admins can view and archive/restore them. --- ## Task Requirement Types | `type` | Required Fields | Description | |--------|----------------|-------------| | `visit_link` | `link_url`, `link_label` | User must visit a URL | | `upload_file` | `allowed_file_types`, `max_file_count` | User must upload files | | `read_course` | `reference_id` (course UUID), `reference_label` | User must complete a course | | `read_unit` | `reference_id` (unit UUID), `reference_label` | User must complete a unit | | `read_lesson` | `reference_id` (lesson UUID), `reference_label` | User must complete a lesson | --- ## Task Lists ### Get All Task Lists **`GET /api/admin/task-lists`** Returns paginated active task lists. ### Query Parameters | Parameter | Type | Required | Description | |-----------|--------|----------|-------------| | `page` | number | No | Default: `1` | | `limit` | number | No | Default: `10` | | `filters` | array | No | JSON filter array | | `sort` | array | No | JSON sort array | ### Response `200` ```json { "status": "success", "message": "Task lists retrieved.", "data": [...], "pagination": { "page": 1, "limit": 10, "total": 5, "totalPages": 1 } } ``` --- ### Get Single Task List **`GET /api/admin/task-lists/:taskListId`** Returns a task list with its full task tree (tasks → requirements) and assigned groups. Includes archived items (`paranoid: false`). ### Response `200` ```json { "status": "success", "message": "Task list retrieved.", "data": { "task_list_id": "uuid-...", "name": "Onboarding Q1", "description": "...", "group_count": 2, "groups": [ { "group_id": 1, "name": "Engineering" } ], "tasks": [ { "task_id": "uuid-...", "name": "Read the handbook", "deadline": "2026-07-01T00:00:00.000Z", "status": "pending", "requirements": [ { "requirement_id": "uuid-...", "type": "read_lesson", "reference_id": "uuid-..." } ] } ], "createdAt": "...", "updatedAt": "..." } } ``` --- ### Create Task List **`POST /api/admin/task-lists`** Rate-limited. ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | **Yes** | Unique list name | | `description` | string | No | | ### Response `201` ```json { "status": "success", "message": "Task list created successfully.", "data": { ... } } ``` --- ### Update Task List **`PATCH /api/admin/task-lists/:taskListId`** Rate-limited. ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | No | | | `description` | string | No | | ### Response `200` ```json { "status": "success", "message": "Task list updated successfully.", "data": { ... } } ``` --- ### Archive Task List **`DELETE /api/admin/task-lists/:taskListId`** Rate-limited. Soft-deletes the task list. ### Response `200` ```json { "status": "success", "message": "Task list archived successfully." } ``` --- ### Restore Task List **`PATCH /api/admin/task-lists/:taskListId/restore`** Rate-limited. ### Response `200` ```json { "status": "success", "message": "Task list restored successfully.", "data": { ... } } ``` --- ### Bulk Archive Task Lists **`POST /api/admin/task-lists/bulk-archive`** Rate-limited. ### Request Body ```json { "ids": ["uuid-1", "uuid-2"] } ``` ### Response `200` ```json { "status": "success", "message": "2 task list(s) archived successfully.", "archived_ids": [...], "skipped_ids": [] } ``` --- ### Bulk Restore Task Lists **`POST /api/admin/task-lists/bulk-restore`** Rate-limited. Same body shape as bulk archive. --- ### Get Archived Task Lists **`GET /api/admin/task-lists/archived`** Returns paginated soft-deleted task lists. --- ### Get Task List Field Values **`GET /api/admin/task-lists/field-values`** Returns distinct filterable field values for task lists. --- ## Task List Groups ### Get Assigned Groups **`GET /api/admin/task-lists/:taskListId/groups`** Returns all user groups currently assigned to the task list, including assignment metadata. ### Response `200` ```json { "status": "success", "message": "Task list groups retrieved.", "data": [ { "id": "uuid-...", "task_list_id": "uuid-...", "group_id": 1, "assignedAt": "2026-06-01T00:00:00.000Z", "assignedBy": 1, "group": { "group_id": 1, "name": "Engineering" } } ] } ``` --- ### Assign Groups **`POST /api/admin/task-lists/:taskListId/groups/assign`** Rate-limited. Upsert-style — already-assigned groups are silently skipped. ### Request Body ```json { "group_ids": [1, 2, 3] } ``` ### Response `201` ```json { "status": "success", "message": "2 group(s) assigned.", "assigned_ids": [2, 3], "already_assigned_ids": [1], "invalid_ids": [] } ``` --- ### Unassign Groups **`POST /api/admin/task-lists/:taskListId/groups/unassign`** Rate-limited. Hard-deletes the junction rows (assignments are not soft-deleted). ### Request Body ```json { "group_ids": [2, 3] } ``` ### Response `200` ```json { "status": "success", "message": "2 group(s) unassigned.", "unassigned_ids": [2, 3], "skipped_ids": [] } ``` --- ## Tasks ### Get All Tasks **`GET /api/admin/task-lists/:taskListId/tasks`** Returns paginated tasks under a task list. ### Query Parameters Standard pagination + `filters` + `sort`. --- ### Get Single Task **`GET /api/admin/task-lists/:taskListId/tasks/:taskId`** Returns a task with its requirements and the parent task list (including assigned groups). ### Response `200` ```json { "status": "success", "message": "Task retrieved.", "data": { "task_id": "uuid-...", "task_list_id": "uuid-...", "name": "Complete orientation", "description": "...", "deadline": "2026-07-01T00:00:00.000Z", "status": "pending", "requirements": [ { "requirement_id": "uuid-...", "type": "upload_file", "allowed_file_types": ["application/pdf"], "max_file_count": 1, "order": 0 } ], "taskList": { "task_list_id": "...", "name": "Onboarding Q1", "groups": [...] } } } ``` --- ### Create Task **`POST /api/admin/task-lists/:taskListId/tasks`** Rate-limited. Creates a task and optionally its requirements in a single transaction. ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | **Yes** | Task name | | `description` | string | No | | | `deadline` | date | No | ISO date string | | `requirements` | array | No | Array of requirement objects (see Requirement Types above) | ### Response `201` ```json { "status": "success", "message": "Task created successfully.", "data": { "task_id": "uuid-...", "name": "...", "requirements": [...] } } ``` --- ### Update Task **`PATCH /api/admin/task-lists/:taskListId/tasks/:taskId`** Rate-limited. When `requirements` is provided, the full set is replaced (soft-delete + re-insert). > **Note:** Incoming requirement objects must **not** include `requirement_id` — the server always generates fresh IDs to avoid collisions with soft-deleted rows. ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | No | | | `description` | string | No | | | `deadline` | date | No | | | `status` | string | No | `pending`, `in_progress`, `completed`, `overdue` | | `requirements` | array | No | Full replacement set | --- ### Archive Task **`DELETE /api/admin/task-lists/:taskListId/tasks/:taskId`** Rate-limited. Soft-deletes the task. --- ### Restore Task **`PATCH /api/admin/task-lists/:taskListId/tasks/:taskId/restore`** Rate-limited. --- ### Bulk Archive Tasks **`POST /api/admin/task-lists/:taskListId/tasks/bulk-archive`** Rate-limited. ### Request Body ```json { "ids": ["uuid-1", "uuid-2"] } ``` --- ### Bulk Restore Tasks **`POST /api/admin/task-lists/:taskListId/tasks/bulk-restore`** Rate-limited. --- ### Get Archived Tasks **`GET /api/admin/task-lists/:taskListId/tasks/archived`** --- ### Get Task Field Values **`GET /api/admin/task-lists/:taskListId/tasks/field-values`** --- ## Completions Completions are created by clients only. Admins can view and archive/restore them. Each completion may have multiple attached files (`task_completion_files`). --- ### Get All Completions **`GET /api/admin/task-lists/:taskListId/tasks/:taskId/completions`** Returns paginated completions for a task, with submitting user info and files. ### Response `200` ```json { "status": "success", "message": "Completions retrieved.", "data": [ { "completion_id": "uuid-...", "task_id": "uuid-...", "user_id": 42, "note": "Attached the signed form.", "submitted_at": "2026-06-15T10:00:00.000Z", "user": { "user_id": 42, "email": "user@example.com", "name": "Jane Doe" }, "files": [ { "file_id": "uuid-...", "file_url": "https://...", "file_name": "signed_form.pdf", "file_size": 204800, "mime_type": "application/pdf" } ] } ], "pagination": { ... } } ``` --- ### Get Single Completion **`GET /api/admin/task-lists/:taskListId/tasks/:taskId/completions/:completionId`** Returns a single completion with user and files. --- ### Get Completions by User **`GET /api/admin/task-lists/:taskListId/tasks/:taskId/completions/user/:userId`** Returns all completions for a specific user on a specific task. --- ### Archive Completion **`DELETE /api/admin/task-lists/:taskListId/tasks/:taskId/completions/:completionId`** Rate-limited. Soft-deletes a completion. --- ### Restore Completion **`PATCH /api/admin/task-lists/:taskListId/tasks/:taskId/completions/:completionId/restore`** Rate-limited. --- ### Bulk Archive Completions **`POST /api/admin/task-lists/:taskListId/tasks/:taskId/completions/bulk-archive`** Rate-limited. ### Request Body ```json { "ids": ["uuid-1", "uuid-2"] } ``` --- ### Bulk Restore Completions **`POST /api/admin/task-lists/:taskListId/tasks/:taskId/completions/bulk-restore`** Rate-limited.