📋 TaskTracker

Project management API with RBAC, sprint cycles, and task lifecycle management.

Overview

TaskTracker is a full project management API that simulates a real-world issue tracker. It supports multiple roles with different permission levels, task lifecycle management, time logging, attachments, sprint cycles, and an in-app notification system — all scoped per API key.

Base Path
/api/tasktracker
Auth Header
x-api-key: <your-key>
App URL
/tasktracker.html
Swagger
/tasktracker/docs
All data is scoped to your API key. Each user has a completely independent task space. The active role is also per-user and persists across sessions.

Quick Start

Step 1
Set Role
POST /roles/active with "User" or "QA"
Step 2
Create Task
POST /tasks with title, type, priority
Step 3
Progress Task
PUT /tasks/:id change status
Step 4
Log Time
POST /tasks/:id/time-logs
Step 5
Done
PUT /tasks/:id status: "done"
curl -X POST https://qacloud.dev/api/tasktracker/roles/active \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "QA"}'
curl -X POST https://qacloud.dev/api/tasktracker/tasks \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Login button unresponsive on mobile",
    "type": "bug",
    "priority": "high",
    "status": "todo",
    "labels": ["mobile", "regression"]
  }'

RBAC & Roles

Every request is evaluated against the caller's active role. Roles are per-user and can be changed at any time. The role determines which operations are permitted.

Guest
Read only. Cannot create or modify tasks.
User
Read + write tasks, labels, attachments.
QA
Same as User. Intended for test tracking.
Developer
Same as User. Dev-perspective on tasks.
Project Manager
Admin-level. Can delete tasks and reset data.
Admin
Full access including DELETE and reset.
Attempting to delete a task while active role is "User" returns 403 Forbidden. This is an intentional RBAC boundary for testing.

Available Role Values

Use these exact strings when setting a role:

Guest User QA Developer Project Manager Admin

Tasks

Task Types

bug story task epic

Task Statuses (flow)

backlog next_cycle todo in_progress review done blocked archived

Task Priorities

low medium high critical

Assignee Roles

The assignee_role field accepts: QA, Developer, Project Manager

Task Fields

FieldTypeNotes
titlestringRequired on create
typestringbug | story | task | epic
prioritystringlow | medium | high | critical
statusstringDefault: backlog
descriptionstringOptional markdown body
assignee_rolestringQA | Developer | Project Manager
labelsstring[]Label names (auto-created if new)
label_idsstring[]Existing label UUIDs
environmentsstring[]Environment names (auto-created)
story_pointsintegerPositive integer
cycle_idUUIDAssign to a sprint cycle

Labels & Environments

Labels are user-defined tags that can be attached to any task. When you pass a label by name that doesn't exist yet, it is automatically created.

Environments work the same way — they represent testing environments (e.g., staging, production, local) and are also auto-created on first use.

You can pass either labels (array of strings) or label_ids (array of UUIDs) or both. The API merges them.

Attachments & Time Logs

Attachments

Files can be attached to tasks as base64-encoded strings. Maximum file size: 5 MB. The attachment stores the filename, MIME type, and base64 content.

Exceeding the 5 MB limit returns 413 Payload Too Large. This is a deliberate test boundary.

Time Logs

Time logs record hours spent on a task. Each log entry has a minutes value and an optional note. The API tracks cumulative time per task.

Cycles (Sprint Cycles)

Cycles represent sprint iterations. Tasks can be assigned to a cycle via the cycle_id field. Each cycle has a name, start date, and end date.

Viewing a cycle by ID returns the cycle metadata along with its associated tasks.

Notifications

The notification system creates in-app alerts when tasks are created, updated, or reach key milestones. Notifications are per-user and have a read/unread state.

Roles API

GET /api/tasktracker/roles List all available roles

Returns the full list of role definitions. No role filtering required.

Response: [{ id, name }]

GET /api/tasktracker/roles/active Get the caller's active role

Returns the currently active role for the authenticated user. Defaults to User on first call.

Response: { role: "QA" }

POST /api/tasktracker/roles/active Set the caller's active role
FieldRequiredDescription
namerequiredOne of: Guest, User, QA, Developer, Project Manager, Admin

Tasks API

GET /api/tasktracker/tasks List all tasks for the current user

Returns all tasks scoped to the current API key. Supports query filters:

Query ParamDescription
statusFilter by status (e.g. in_progress)
priorityFilter by priority
typeFilter by type
cycle_idFilter by sprint cycle
POST /api/tasktracker/tasks Create a new task
FieldRequiredDescription
titlerequiredTask title
typeoptionalbug | story | task | epic
priorityoptionallow | medium | high | critical
statusoptionalDefault: backlog
descriptionoptionalMarkdown text
labelsoptionalArray of label name strings
environmentsoptionalArray of environment strings
story_pointsoptionalPositive integer
assignee_roleoptionalQA | Developer | Project Manager

Roles required: User, QA, Developer, Project Manager, Admin

GET /api/tasktracker/tasks/:id Get a single task with full details

Returns a task by UUID including its labels, environments, attachments count, and time log total.

PUT /api/tasktracker/tasks/:id Update a task

Partial update — include only the fields you want to change. Labels and environments are merged unless you pass the full replacement set.

FieldDescription
statusChange task status (e.g. todo → in_progress)
priorityChange priority
titleRename the task
labelsReplace label set by name
environmentsReplace environment set

Roles required: User, QA, Developer, Project Manager, Admin

DELETE /api/tasktracker/tasks/:id Delete a task (Admin/PM only)

Permanently deletes the task and all associated labels, time logs, and attachments.

Roles required: Project Manager, Admin. Returns 403 for lower roles.

POST /api/tasktracker/reset Delete all data and reload template (Admin/PM only)

Wipes all tasks, labels, environments, time logs, and cycles, then populates with a default template dataset.

⚠ Destructive. Roles required: Project Manager, Admin.

Labels API

GET /api/tasktracker/labels List all labels for the current user

Returns [{ id, name, color }]

POST /api/tasktracker/labels Create a label
FieldRequiredDescription
namerequiredLabel display name
coloroptionalHex color string e.g. #3b82f6
DELETE /api/tasktracker/labels/:id Delete a label

Removes the label and detaches it from all tasks.

Environments API

GET /api/tasktracker/environments List all environments

Returns all environments defined by the current user.

POST /api/tasktracker/environments Create an environment
FieldRequiredDescription
namerequirede.g. staging, production, local
DELETE /api/tasktracker/environments/:id Delete an environment

Detaches this environment from any tasks before deletion.

Attachments API

GET /api/tasktracker/tasks/:id/attachments List attachments for a task

Returns all attachments for the specified task.

POST /api/tasktracker/tasks/:id/attachments Upload an attachment (base64)
FieldRequiredDescription
filenamerequiredOriginal filename with extension
content_typerequiredMIME type e.g. image/png
datarequiredBase64-encoded file content (max 5 MB)
DELETE /api/tasktracker/attachments/:id Delete an attachment

Removes the attachment record. The UUID is the attachment's own ID, not the task ID.

Time Logs API

GET /api/tasktracker/tasks/:id/time-logs List time log entries for a task

Returns all time log entries for the task in reverse chronological order.

POST /api/tasktracker/tasks/:id/time-logs Add a time log entry
FieldRequiredDescription
minutesrequiredPositive integer — minutes spent
noteoptionalWhat was worked on
logged_atoptionalISO date string; defaults to now
PUT /api/tasktracker/time-logs/:id Update a time log entry

Update minutes or note. The UUID is the time-log entry's own ID.

DELETE /api/tasktracker/time-logs/:id Delete a time log entry

Removes a single time log entry by its UUID.

Cycles API

GET /api/tasktracker/cycles List all sprint cycles

Returns all cycles for the current user.

POST /api/tasktracker/cycles Create a sprint cycle
FieldRequiredDescription
namerequiredSprint name e.g. "Sprint 4"
start_dateoptionalISO date string
end_dateoptionalISO date string
GET /api/tasktracker/cycles/:id Get a cycle with its tasks

Returns the cycle metadata and all tasks assigned to it.

Notifications API

GET /api/tasktracker/notifications List all notifications

Returns all notifications with is_read, message, task_id, and timestamp.

PATCH /api/tasktracker/notifications/:id/read Mark a notification as read

Sets is_read: true for the specified notification.

PATCH /api/tasktracker/notifications/read-all Mark all notifications as read

Bulk operation — sets is_read: true on all notifications for the current user.

Test Cases

TC-TT-001 Create task as User role — succeeds PASS

Steps: Set role to "User" → POST /tasks with title and type "bug" → expect 201 with task object including id and owner_id.

TC-TT-002 Delete task as User role — returns 403 FAIL

Steps: Set role to "User" → create a task → attempt DELETE /tasks/:id → expect 403 Forbidden. User role cannot delete.

TC-TT-003 Delete task as Admin role — succeeds PASS

Steps: Set role to "Admin" → DELETE /tasks/:id → expect 200. Confirm task is gone with GET /tasks/:id returning 404.

TC-TT-004 Guest role cannot create tasks FAIL

Steps: POST /roles/active with name "Guest" → POST /tasks → expect 403 Forbidden.

TC-TT-005 Invalid status value returns 400 FAIL

Steps: POST /tasks with status "pending" (invalid) → expect 400 Bad Request with validation message.

TC-TT-006 Labels auto-created on task creation PASS

Steps: POST /tasks with labels: ["regression", "critical-path"] → GET /labels → confirm both labels appear in the list.

TC-TT-007 Attachment exceeds 5 MB limit — returns 413 FAIL

Steps: POST /tasks/:id/attachments with base64 content exceeding 5 MB → expect 413 Payload Too Large.

TC-TT-008 Time log added and cumulative time updates PASS

Steps: POST /tasks/:id/time-logs with minutes: 90 → GET /tasks/:id → verify time tracking fields reflect the added log.

TC-TT-009 Notifications created on task events PASS

Steps: Create a task → GET /notifications → verify at least one notification exists with a task_id matching the created task.

TC-TT-010 Role switch persists across requests PASS

Steps: POST /roles/active with "Developer" → GET /roles/active → verify response shows "Developer".

TC-TT-011 Task assigned to cycle appears in cycle view PASS

Steps: POST /cycles → POST /tasks with cycle_id → GET /cycles/:id → verify task appears in cycle response.

TC-TT-012 Reset as PM wipes all tasks PASS

Steps: Set role to "Project Manager" → create several tasks → POST /reset → GET /tasks → verify task list matches the template (original tasks gone).

QA Tasks

1. RBAC Boundary Matrix
Test every write/delete endpoint with all 6 roles. Build a matrix of expected vs actual HTTP status codes. Verify Guest/User cannot delete, Guest cannot write.
2. Status Transition Coverage
Create a task and move it through every valid status in order: backlog → next_cycle → todo → in_progress → review → done. Then try "blocked" and "archived" from various states.
3. Label Auto-Creation Idempotency
Create two tasks with the same label name. Verify only one label is created in GET /labels (no duplicates for the same name).
4. Attachment Size Boundary
Upload attachments at 4.9 MB, exactly 5 MB, and 5.1 MB. Verify 4.9 MB succeeds, 5.1 MB returns 413.
5. Notification Read Flow
Create multiple tasks to generate notifications. Mark one as read, verify count decrements. Then use read-all and verify all show is_read: true.
6. Sprint Cycle Assignment
Create a cycle, create 5 tasks assigning them to it, then GET /cycles/:id and verify all 5 tasks appear in the response.
7. Empty Title Validation
POST /tasks with title: "" or title missing entirely. Verify the API returns 400 with a descriptive error — not 500.
8. Time Log Negative/Zero Minutes
POST /tasks/:id/time-logs with minutes: 0 and minutes: -30. Both should return 400. Verify the validation message indicates the constraint.
9. Cascade Delete Verification
Create a task with labels, time logs, and attachments. Delete the task as Admin. Verify all child records (labels junction, time logs, attachments) are also removed.
10. Multi-User Isolation
Using two different API keys, create tasks on both. Verify that API key A's GET /tasks does not include API key B's tasks (data is fully isolated).