Задачи
Задачи — основной рабочий элемент в Planner. Они поддерживают полный жизненный цикл с workflow статусов, приоритетами, назначениями, сроками, подзадачами, комментариями с ветвлением, историей изменений и отдельным чатом задачи.
Модель
Task
├── title, description
├── status: todo | in_progress | in_review | done | cancelled | overdue
├── priority: low | medium | high | urgent
├── assigneeId?, dueDate?
├── parentId? (подзадачи)
├── projectId (обязательно, каскадное удаление)
├── comments (с ветвлением и ответами)
├── history (журнал аудита)
└── chat (создание или получение беседы задачи)API Endpoints
CRUD задач (/projects/:id/tasks)
| Метод | Путь | Описание |
|---|---|---|
GET | /api/projects/:id/tasks | Список задач проекта |
POST | /api/projects/:id/tasks | Создать задачу |
GET | /api/projects/:id/tasks/:taskId | Получить задачу с деталями |
PATCH | /api/projects/:id/tasks/:taskId | Обновить задачу |
PATCH | /api/projects/:id/tasks/:taskId/status | Обновить только статус |
DELETE | /api/projects/:id/tasks/:taskId | Удалить задачу |
Мои задачи
| Метод | Путь | Описание |
|---|---|---|
GET | /api/tasks/my | Задачи, назначенные текущему пользователю (дашборд) |
GET | /api/tasks/my/calendar | Задачи в диапазоне дат (?from=&to=) |
Доска задач команды
| Метод | Путь | Описание |
|---|---|---|
GET | /api/teams/by-slug/:teamSlug/tasks | Удобный эндпоинт команды |
Комментарии к задачам (/projects/:id/tasks/:taskId/comments)
| Метод | Путь | Описание |
|---|---|---|
GET | /api/projects/:id/tasks/:taskId/comments | Список комментариев (плоский, с parentId для ветвления) |
POST | /api/projects/:id/tasks/:taskId/comments | Создать комментарий (опциональный parentId для ответа) |
PATCH | /api/projects/:id/tasks/:taskId/comments/:commentId | Редактировать комментарий |
DELETE | /api/projects/:id/tasks/:taskId/comments/:commentId | Удалить комментарий (заблокировано, если есть ответы) |
История задач (/projects/:id/tasks/:taskId/history)
| Метод | Путь | Описание |
|---|---|---|
GET | /api/projects/:id/tasks/:taskId/history | Получить журнал аудита задачи |
Чат задачи
| Метод | Путь | Описание |
|---|---|---|
POST | /api/chats/task/:taskId | Создать или получить беседу задачи |
Вложения
| Метод | Путь | Описание |
|---|---|---|
POST | /api/projects/:id/tasks/:taskId/attachments | Загрузить вложения к задаче (до 50MB) |
POST | /api/projects/:id/tasks/:taskId/attachments/remove | Удалить вложение |
POST | /api/projects/:id/tasks/:taskId/comments/attachments | Загрузить вложения к комментарию |
Переупорядочивание и массовые операции
| Метод | Путь | Описание |
|---|---|---|
POST | /api/projects/:id/tasks/reorder | Переупорядочить задачи (drag-and-drop) |
POST | /api/projects/:id/tasks/bulk | Массовые операции (статус, назначение, удаление, приоритет) |
Зависимости задач (/tasks/:taskId/dependencies)
| Метод | Путь | Описание |
|---|---|---|
GET | /api/tasks/:taskId/dependencies | Список зависимостей задачи |
POST | /api/tasks/:taskId/dependencies | Создать зависимость (dependsOnId, type?: blocks | relates_to) |
DELETE | /api/tasks/:taskId/dependencies/:id | Удалить зависимость |
Теги (/tags)
| Метод | Путь | Описание |
|---|---|---|
GET | /api/orgs/:orgId/tags | Список тегов организации |
GET | /api/teams/:teamId/tags | Список тегов команды |
GET | /api/tasks/:taskId/tags | Список тегов задачи |
POST | /api/tags | Создать тег (name, color?, orgId?, teamId?) |
PATCH | /api/tags/:id | Обновить тег |
DELETE | /api/tags/:id | Удалить тег |
POST | /api/tasks/:taskId/tags | Назначить теги задаче (tagIds: string[]) |
Workflow статусов
todo ──► in_progress ──► in_review ──► done
│ │
└────────────────────────┘
cancelled
overdue (автоматически, при просрочке срока)История задач (журнал аудита)
Каждое изменение автоматически логируется:
| Действие | Триггер | Данные |
|---|---|---|
CREATED | Создание задачи | Кто создал, когда |
UPDATED | Изменение поля | Имя поля, старое значение, новое значение |
STATUS_CHANGED | Обновление статуса | Старый статус, новый статус |
ASSIGNED | Изменение исполнителя | Старый исполнитель, новый исполнитель |
DELETED | Удаление задачи | Снимок удалённой задачи |
История отображается в виде временной шкалы с цветовой кодировкой.
Комментарии с ветвлением
Комментарии поддерживают ответы через поле parentId:
- Комментарий верхнего уровня:
parentIdравен null - Ответ:
parentIdссылается на родительский комментарий - Вложенность: Без ограничений (отображается с отступами)
- Удаление: Нельзя удалить комментарий, у которого есть ответы — сначала удалите ответы
- Уведомления: Ответ на комментарий уведомляет автора родительского комментария
Компонент фронтенда
Компонент TaskComments.vue строит дерево комментариев из плоского API-ответа и рекурсивно отображает его через CommentNode.vue. Каждый комментарий имеет:
- Кнопку ответа (открывает встроенную форму)
- Кнопку редактирования (только свои комментарии)
- Кнопку удаления (только свои комментарии, скрыта если есть ответы)
Store фронтенда
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)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)Store истории задач
typescript
const store = useTaskHistoryStore()
const { history, loading } = storeToRefs(store)
await store.fetchHistory(projectId, taskId)Ключевые детали реализации
- Чат задачи отделён от комментариев — используйте
POST /api/chats/task/:taskIdдля создания или получения беседы - Чат автоматически добавляет запрашивающего пользователя как участника
- История задач обслуживается отдельным
TaskHistoryController(не встроена в ответ задачи) - Вложения загружаются до создания комментария, затем ссылаются по URL в комментарии
- Теги привязаны к организациям или командам — назначение через
POST /api/tasks/:taskId/tagsс{ tagIds: [] } - Зависимости задач используют тип
blocksпо умолчанию — блокирующая задача не позволяет зависимой перейти в статусdone - Элементы переупорядочивания используют пары
{ taskId, position }для сохранения drag-and-drop - Массовые операции поддерживают действия:
status,assignee,delete,priority