Tasks
Tasks are the primary work unit in Planner. They support a full lifecycle with status workflow, priorities, assignments, due dates, subtasks, threaded comments, change history, and a dedicated task chat.
Model
Task
├── title, description
├── status: todo | in_progress | in_review | done | cancelled | overdue
├── priority: low | medium | high | urgent
├── assigneeId?, dueDate?
├── parentId? (subtasks)
├── projectId (required, cascade delete)
├── comments (threaded with replies)
├── history (audit log)
└── chat (create or get task conversation)API Endpoints
Task CRUD (/projects/:id/tasks)
| Method | Path | Description |
|---|---|---|
GET | /api/projects/:id/tasks | List project tasks |
POST | /api/projects/:id/tasks | Create task |
GET | /api/projects/:id/tasks/:taskId | Get task with details |
PATCH | /api/projects/:id/tasks/:taskId | Update task |
PATCH | /api/projects/:id/tasks/:taskId/status | Update status only |
DELETE | /api/projects/:id/tasks/:taskId | Delete task |
My Tasks
| Method | Path | Description |
|---|---|---|
GET | /api/tasks/my | Tasks assigned to current user (dashboard) |
GET | /api/tasks/my/calendar | Tasks in date range (?from=&to=) |
Team Task Board
| Method | Path | Description |
|---|---|---|
GET | /api/teams/by-slug/:teamSlug/tasks | Convenience team endpoint |
Task Comments (/projects/:id/tasks/:taskId/comments)
| Method | Path | Description |
|---|---|---|
GET | /api/projects/:id/tasks/:taskId/comments | List comments (flat, with parentId for threading) |
POST | /api/projects/:id/tasks/:taskId/comments | Create comment (optional parentId for reply) |
PATCH | /api/projects/:id/tasks/:taskId/comments/:commentId | Edit comment |
DELETE | /api/projects/:id/tasks/:taskId/comments/:commentId | Delete comment (blocked if has replies) |
Task History (/projects/:id/tasks/:taskId/history)
| Method | Path | Description |
|---|---|---|
GET | /api/projects/:id/tasks/:taskId/history | Get task audit log |
Task Chat
| Method | Path | Description |
|---|---|---|
POST | /api/chats/task/:taskId | Create or get task conversation |
Reorder & Bulk Operations
| Method | Path | Description |
|---|---|---|
POST | /api/projects/:id/tasks/reorder | Reorder tasks (drag-and-drop) |
POST | /api/projects/:id/tasks/bulk | Bulk operations (status, assign, delete, priority) |
Task Attachments
| Method | Path | Description |
|---|---|---|
POST | /api/projects/:id/tasks/:taskId/attachments | Upload task attachments (up to 50MB) |
POST | /api/projects/:id/tasks/:taskId/attachments/remove | Remove attachment |
POST | /api/projects/:id/tasks/:taskId/comments/attachments | Upload comment attachments |
Task Dependencies (/tasks/:taskId/dependencies)
| Method | Path | Description |
|---|---|---|
GET | /api/tasks/:taskId/dependencies | List task dependencies |
POST | /api/tasks/:taskId/dependencies | Create dependency (dependsOnId, type?: blocks | relates_to) |
DELETE | /api/tasks/:taskId/dependencies/:id | Remove dependency |
Tags (/tags)
| Method | Path | Description |
|---|---|---|
GET | /api/orgs/:orgId/tags | List organization tags |
GET | /api/teams/:teamId/tags | List team tags |
GET | /api/tasks/:taskId/tags | List task tags |
POST | /api/tags | Create tag (name, color?, orgId?, teamId?) |
PATCH | /api/tags/:id | Update tag |
DELETE | /api/tags/:id | Delete tag |
POST | /api/tasks/:taskId/tags | Assign tags to task (tagIds: string[]) |
Status Workflow
todo ──► in_progress ──► in_review ──► done
│ │
└────────────────────────┘
cancelled
overdue (automatic, when due date passes)Task History (Audit Log)
Every change is automatically logged:
| Action | Trigger | Data |
|---|---|---|
CREATED | Task creation | Who created, when |
UPDATED | Field change | Field name, old value, new value |
STATUS_CHANGED | Status update | Old status, new status |
ASSIGNED | Assignee change | Old assignee, new assignee |
DELETED | Task deletion | Snapshot of deleted task |
History is displayed as a color-coded timeline.
Threaded Comments
Comments support replies via parentId:
- Top-level comment:
parentIdis null - Reply:
parentIdreferences the parent comment - Nesting: Unlimited (displayed with indentation)
- Deletion: Cannot delete a comment that has replies — delete replies first
- Notifications: Replying to a comment notifies the parent comment author
Frontend Component
The TaskComments.vue component builds a comment tree from the flat API response and renders it recursively via CommentNode.vue. Each comment has:
- Reply button (opens inline form)
- Edit button (own comments only)
- Delete button (own comments only, hidden if has replies)
Frontend Store
Tasks Store
typescript
const store = useTasksStore()
const { tasks, currentTask } = storeToRefs(store)
await store.fetchTasks(projectId)
await store.createTask(projectId, { title, status, priority, assigneeId, dueDate, parentId })
await store.updateTask(projectId, taskId, { title, status, priority, assigneeId, dueDate })
await store.updateTaskStatus(projectId, taskId, status)
await store.deleteTask(projectId, taskId)Comments Store
typescript
const store = useCommentsStore()
const { comments } = storeToRefs(store)
await store.fetchComments(projectId, taskId)
await store.createComment(projectId, taskId, { body, parentId, attachments })
await store.updateComment(projectId, taskId, commentId, { body })
await store.deleteComment(projectId, taskId, commentId)
await store.uploadAttachments(projectId, taskId, files)Task History Store
typescript
const store = useTaskHistoryStore()
const { history, loading } = storeToRefs(store)
await store.fetchHistory(projectId, taskId)Key Implementation Details
- Task chat is separate from comments — use
POST /api/chats/task/:taskIdto create or get a conversation - Chat automatically adds the requesting user as a participant
- Task history is served by a separate
TaskHistoryController(not embedded in task response) - Attachments are uploaded before creating a comment, then referenced by URL in the comment
- Tags are scoped to organizations or teams — assign via
POST /api/tasks/:taskId/tagswith{ tagIds: [] } - Task dependencies use
blockstype by default — a blocking task prevents the dependent task from being markeddone - Reorder items use
{ taskId, position }pairs for drag-and-drop persistence - Bulk operations support actions:
status,assignee,delete,priority