Appearance
Task Tracker
Назначение
Сервис управления задачами: заменяет внешние таск-трекеры внутри платформы. Задачи живут в пространствах (spaces), статусы и переходы задаются настраиваемым workflow пространства, а набор полей расширяется администратором без миграций и кода.
Порты
- HTTP: 8102
- БД:
tasks_db
Ключевые возможности
- CRUD задач с фиксированным набором полей: ключ (
TASK-42), заголовок, описание в формате TipTap, статус, приоритет, исполнитель, автор, сроки, даты создания и обновления - Типы задач:
task,bug,feature,documentation,review,epic(тип хранится строкой — пространство может завести свои) - Настраиваемый workflow на пространство или на отдельный тип задач: статусы, переходы, правила валидации перехода, автодействия
- Настраиваемые поля:
text,number,enum,checkbox,date,task_link,attachment(идентификаторы файлов Storage) - Наблюдатели (watchers) и связи задач (
relates,blocks/blocked_by,duplicates,caused_by) — связь пишется с обеих сторон - Подзадачи через
parent_id - Канбан-доска: колонки берутся из статусов workflow, каждая колонка пагинируется отдельно
- История изменений по задаче и лента активности пространства (
task_logs) - Поиск по ключу, заголовку и плоскому тексту описания; фильтры по статусу, типу, приоритету, исполнителю, автору, наблюдателю, родителю и срокам
- Soft delete (корзина) с восстановлением и hard delete
- Экспорт и импорт конфигурации workflow
- События NATS:
tasks.created,tasks.updated,tasks.status_changed,tasks.deleted,tasks.restored
Структура БД
Таблица tasks
| Колонка | Описание |
|---|---|
id | UUID PK |
space_id | UUID пространства (indexed) |
number / key | Порядковый номер в пространстве и его читаемая форма TASK-42 (уникальны в паре со space_id) |
title | Заголовок (varchar 512) |
description | Документ TipTap (jsonb) |
description_text | Плоский текст описания для поиска |
type | Тип задачи |
status | Идентификатор статуса из workflow |
priority | lowest / low / medium / high / critical |
assignee_id, reporter_id | Исполнитель и автор |
workflow_id | Workflow, по которому живёт задача (FK, RESTRICT) |
parent_id | Родительская задача (self-ref FK, SET NULL) |
due_date, completed_at | Срок и момент перехода в статус категории done |
position | Порядок внутри колонки доски |
deleted_at | Soft delete timestamp (indexed) |
Остальные таблицы
| Таблица | Назначение |
|---|---|
task_counters | Счётчик номеров и префикс ключа пространства; строка блокируется FOR UPDATE на время создания задачи |
workflows | Статусы, переходы, правила и автодействия (jsonb) |
task_fields | Объявления настраиваемых полей |
task_field_values | Значения настраиваемых полей у задач (уникально по task_id + field_id) |
task_watchers | Наблюдатели (PK task_id + user_id) |
task_links | Связи задач; обе стороны хранятся отдельными строками |
task_logs | История изменений и лента активности |
Workflow
У пространства всегда есть workflow по умолчанию: он создаётся при первом обращении и содержит To Do → In Progress → Done. Дополнительно объявляется workflow для отдельного типа задач — тогда задачи этого типа живут по нему, а остальные по умолчанию.
jsonc
{
"name": "Bugs",
"task_type": "bug",
"initial_status": "triage",
"statuses": [
{ "id": "triage", "name": "Triage", "category": "todo", "position": 0 },
{ "id": "fixing", "name": "Fixing", "category": "in_progress", "position": 1 },
{ "id": "verified", "name": "Verified", "category": "done", "position": 2 }
],
"transitions": [
{
"id": "start_fix",
"name": "Start fix",
"from": ["triage"],
"to": "fixing",
"rules": { "require_assignee": true, "required_fields": ["severity"] },
"actions": [{ "type": "notify" }]
},
{ "id": "cancel", "name": "Cancel", "from": ["*"], "to": "verified" }
]
}category(todo/in_progress/done) — группировка для досок и отчётов; переход в статус категорииdoneпроставляетcompleted_at.from: ["*"]— переход из любого статуса.rules:require_assignee,require_due_date,required_fields(ключи настраиваемых полей),allowed_roles.actions: реализованыnotify,assign,create_subtask.run_flowиrun_commandпринимаются в конфигурации, но пока только логируются — они появятся вместе с интеграцией Flow Manager и Command Manager.
Удаление статуса требует карты status_migration — куда переносить задачи. Без неё обновление workflow отклоняется, поэтому задача никогда не остаётся на несуществующем статусе.
Задача запоминает workflow_id при создании и живёт по нему до конца: объявление нового workflow для типа задач не переносит уже существующие задачи. Перевод на другой workflow происходит только через смену типа задачи, и тогда PATCH требует передать заодно статус из нового workflow.
API
Базовый путь — /api/v1/tasks/:space_id; требуются JWT и валидный space_id.
Задачи
| Метод | Путь | Описание |
|---|---|---|
| POST | / | создать задачу |
| GET | / | список с фильтрами, поиском, сортировкой и пагинацией |
| GET | /board | канбан-доска |
| GET | /activity | лента активности пространства |
| GET | /meta | словари, workflow и поля пространства |
| GET | /key/:key | задача по ключу |
| GET · PATCH · DELETE | /:id | чтение, частичное обновление, удаление в корзину |
| DELETE | /:id/hard | удалить навсегда |
| POST | /:id/restore | восстановить из корзины |
| POST | /:id/status | смена статуса через workflow |
| GET | /:id/transitions | доступные переходы |
| GET | /:id/history | история изменений |
| POST · DELETE | /:id/watchers[/:user_id] | наблюдатели |
| POST · DELETE | /:id/links[/:link_id] | связи задач |
Параметры списка: status, type, priority (повторяемые или через запятую), assignee_id, reporter_id, watcher_id, parent_id (none — без исполнителя / без родителя), q, due_before, due_after (RFC3339), deleted=true, sort_by, sort_order, page, per_page.
PATCH следует семантике JSON Merge Patch: отсутствующий ключ не меняет поле, ключ со значением null очищает его (assignee_id, due_date, parent_id).
Workflow и поля
| Метод | Путь | Описание |
|---|---|---|
| GET · POST | /workflows | список и создание |
| GET · PATCH · DELETE | /workflows/:workflow_id | чтение, изменение, удаление |
| GET | /workflows/:workflow_id/export | выгрузка конфигурации |
| POST | /workflows/import | загрузка конфигурации |
| GET · POST | /fields | список и объявление полей |
| GET · PATCH · DELETE | /fields/:field_id | чтение, изменение, удаление |
Swagger UI — http://localhost:8102/swagger/index.html.
События
| Subject | Когда публикуется |
|---|---|
tasks.created | создана задача |
tasks.updated | изменены поля задачи |
tasks.status_changed | выполнен переход по workflow |
tasks.deleted | задача удалена (в корзину или навсегда) |
tasks.restored | задача восстановлена |
В payload нет поля user_id — nats-bridge маршрутизирует события с ним в личный канал автора, а изменения задачи должны видеть все, кто открыл пространство. Поэтому инициатор передаётся как actor_id, а события уходят в канал tasks:broadcast (маппинг tasks.* → namespace tasks в nats-bridge).
Что ещё не сделано
- GraphQL API (REST готов)
- Веб-интерфейс (доски, список, календарь) в клиенте
web - Интеграции Flow Manager, Command Manager, AI Router, Scheduler