Skip to content

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

КолонкаОписание
idUUID PK
space_idUUID пространства (indexed)
number / keyПорядковый номер в пространстве и его читаемая форма TASK-42 (уникальны в паре со space_id)
titleЗаголовок (varchar 512)
descriptionДокумент TipTap (jsonb)
description_textПлоский текст описания для поиска
typeТип задачи
statusИдентификатор статуса из workflow
prioritylowest / low / medium / high / critical
assignee_id, reporter_idИсполнитель и автор
workflow_idWorkflow, по которому живёт задача (FK, RESTRICT)
parent_idРодительская задача (self-ref FK, SET NULL)
due_date, completed_atСрок и момент перехода в статус категории done
positionПорядок внутри колонки доски
deleted_atSoft 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