docs: Planning — epics and stories
This commit is contained in:
parent
1bb548ff3b
commit
96cc3b2b12
360
PLANNING.md
Normal file
360
PLANNING.md
Normal file
@ -0,0 +1,360 @@
|
||||
# Planning — Team Board
|
||||
Дата: 2026-02-23
|
||||
|
||||
## Принципы
|
||||
- Каждый эпик = самодостаточный блок, можно релизить независимо
|
||||
- Порядок = зависимости + приоритет из Architecture Review
|
||||
- Никаких параллельных эпиков — строго последовательно
|
||||
- Каждая story имеет чёткие критерии приёмки
|
||||
|
||||
## Эпик 1: WebSocket Foundation — Исправить критические баги
|
||||
Цель: Устранить P0 блокеры из Architecture Review — WS collision и отсутствие task events
|
||||
Зависимости: нет
|
||||
|
||||
### Story 1.1: Исправить WebSocket connection collision
|
||||
**Как** системный разработчик **я хочу** чтобы множественные подключения одного пользователя не вытесняли друг друга **чтобы** система работала корректно при multiple tabs/reconnect
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `ConnectionManager.clients` изменён с `dict[str, ConnectedClient]` на `dict[str, list[ConnectedClient]]`
|
||||
- [ ] Добавлен `sessions: dict[str, ConnectedClient]` с уникальными session_id
|
||||
- [ ] При подключении создаётся уникальный session_id
|
||||
- [ ] При отключении удаляется только конкретная сессия
|
||||
- [ ] Broadcast отправляется всем сессиям пользователя
|
||||
|
||||
**Компоненты:** Tracker
|
||||
**Оценка:** M
|
||||
|
||||
### Story 1.2: Добавить broadcast task events
|
||||
**Как** агент **я хочу** получать уведомления о создании/изменении задач **чтобы** реагировать на новую работу в проекте
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `POST /api/v1/tasks` вызывает `broadcast_task_event("task.created")`
|
||||
- [ ] `PATCH /api/v1/tasks/{id}` вызывает `broadcast_task_event("task.updated")`
|
||||
- [ ] `DELETE /api/v1/tasks/{id}` вызывает `broadcast_task_event("task.deleted")`
|
||||
- [ ] События содержат полную информацию о задаче
|
||||
- [ ] WebSocket клиент получает события в формате `{"type": "task.created", "data": task}`
|
||||
|
||||
**Компоненты:** Tracker
|
||||
**Оценка:** M
|
||||
|
||||
### Story 1.3: Добавить REST token auth для агентов
|
||||
**Как** агент **я хочу** аутентифицироваться через токен в REST API **чтобы** делать запросы напрямую к Tracker
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Middleware `verify_agent_token()` проверяет заголовок `Authorization: Bearer tb-xxxxx`
|
||||
- [ ] Токен валидируется по таблице Member.token
|
||||
- [ ] Защищены все эндпоинты кроме `/docs`, `/health`, `/ws`
|
||||
- [ ] При неверном токене возвращается 401
|
||||
- [ ] BFF продолжает работать (проксирует с токеном)
|
||||
|
||||
**Компоненты:** Tracker
|
||||
**Оценка:** S
|
||||
|
||||
## Эпик 2: Task Operations — Агентские операции с задачами
|
||||
Цель: Реализовать специальные операции для агентов из PRD
|
||||
Зависимости: Эпик 1
|
||||
|
||||
### Story 2.1: Реализовать take task API
|
||||
**Как** агент **я хочу** атомарно взять задачу в работу **чтобы** не было race condition с другими агентами
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `POST /api/v1/tasks/{id}/take` endpoint создан
|
||||
- [ ] Проверяется что задача в статусе backlog или todo
|
||||
- [ ] Атомарно устанавливается assignee_slug = текущий агент и status = in_progress
|
||||
- [ ] При конфликте возвращается 409 Conflict
|
||||
- [ ] Broadcast task.updated события после успешного взятия
|
||||
- [ ] BFF проксирует операцию
|
||||
|
||||
**Компоненты:** Tracker / BFF
|
||||
**Оценка:** M
|
||||
|
||||
### Story 2.2: Реализовать reject task API
|
||||
**Как** агент **я хочу** отклонить назначенную мне задачу **чтобы** вернуть её в backlog с объяснением
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `POST /api/v1/tasks/{id}/reject` с body `{"reason": "string"}`
|
||||
- [ ] Проверяется что assignee_slug = текущий агент
|
||||
- [ ] Устанавливается assignee_slug = null, status = backlog
|
||||
- [ ] Добавляется комментарий-сообщение "Задача отклонена: {reason}"
|
||||
- [ ] Broadcast task.updated события
|
||||
- [ ] BFF проксирует операцию
|
||||
|
||||
**Компоненты:** Tracker / BFF
|
||||
**Оценка:** M
|
||||
|
||||
### Story 2.3: Реализовать assign task API
|
||||
**Как** участник **я хочу** назначить задачу другому участнику **чтобы** делегировать работу
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `POST /api/v1/tasks/{id}/assign` с body `{"assignee_slug": "string"}`
|
||||
- [ ] Проверяется существование assignee в проекте
|
||||
- [ ] Устанавливается assignee_slug и status = todo (если был backlog)
|
||||
- [ ] Broadcast task.updated события
|
||||
- [ ] BFF проксирует операцию
|
||||
|
||||
**Компоненты:** Tracker / BFF
|
||||
**Оценка:** S
|
||||
|
||||
### Story 2.4: Реализовать watch/unwatch task API
|
||||
**Как** участник **я хочу** подписываться на уведомления по задаче **чтобы** отслеживать её прогресс
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `POST /api/v1/tasks/{id}/watch` добавляет текущий slug в watchers[]
|
||||
- [ ] `DELETE /api/v1/tasks/{id}/watch` удаляет slug из watchers[]
|
||||
- [ ] Дубликаты в watchers игнорируются
|
||||
- [ ] Broadcast task.updated события при изменении watchers
|
||||
- [ ] BFF проксирует операции
|
||||
|
||||
**Компоненты:** Tracker / BFF
|
||||
**Оценка:** S
|
||||
|
||||
## Эпик 3: WebSocket Events — Правильная фильтрация событий
|
||||
Цель: Унифицировать фильтрацию событий для всех типов участников
|
||||
Зависимости: Эпик 2
|
||||
|
||||
### Story 3.1: Реализовать project.subscribe для humans
|
||||
**Как** пользователь веб-клиента **я хочу** подписываться только на события нужных проектов **чтобы** не получать лишний трафик
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Humans/bridges могут отправлять `project.subscribe` сообщения
|
||||
- [ ] `connection.subscribed_projects` хранит список подписок
|
||||
- [ ] По умолчанию подписок нет (не "получать всё")
|
||||
- [ ] События фильтруются по подпискам для всех типов участников
|
||||
- [ ] Web Client автоматически подписывается на текущий проект
|
||||
|
||||
**Компоненты:** Tracker / Web
|
||||
**Оценка:** M
|
||||
|
||||
### Story 3.2: Унифицировать фильтрацию по listen_mode
|
||||
**Как** агент с chat_listen="mentions" **я хочу** получать только сообщения где меня упоминают **чтобы** снизить шум в канале
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Функция `should_receive_event(client, event_type, data)` для всех типов
|
||||
- [ ] chat_listen="mentions" → только сообщения с mentions[] содержащими агента
|
||||
- [ ] chat_listen="all" → все сообщения в подписанных проектах
|
||||
- [ ] task_listen="mentions" → только задачи где агент assignee/reviewer/watcher
|
||||
- [ ] task_listen="all" → все task события в подписанных проектах
|
||||
- [ ] Humans используют ту же логику с listen_mode="all" по умолчанию
|
||||
|
||||
**Компоненты:** Tracker
|
||||
**Оценка:** M
|
||||
|
||||
### Story 3.3: Исправить on_behalf_of validation
|
||||
**Как** BFF **я хочу** валидировать on_behalf_of пользователей **чтобы** предотвратить коллизии slug
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] При on_behalf_of проверяется существование Member с таким slug
|
||||
- [ ] Несуществующие users получают префикс `web-{slug}`
|
||||
- [ ] Все proxy подключения логируются с уровнем INFO
|
||||
- [ ] Bridge не может перехватить slug существующего агента
|
||||
- [ ] Добавлены unit тесты для collision cases
|
||||
|
||||
**Компоненты:** BFF
|
||||
**Оценка:** S
|
||||
|
||||
## Эпик 4: Agent Management — UI для управления агентами
|
||||
Цель: Создать интерфейс для создания и мониторинга агентов
|
||||
Зависимости: Эпик 3
|
||||
|
||||
### Story 4.1: Страница Agent Management
|
||||
**Как** администратор **я хочу** видеть список всех агентов с их статусами **чтобы** мониторить работу системы
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Страница `/agents` доступна в навигации
|
||||
- [ ] Таблица агентов с колонками: name, slug, status, capabilities, last_seen_at
|
||||
- [ ] Статусы показаны цветами: 🟢 online, 🔴 offline, 🟡 busy
|
||||
- [ ] Обновление статусов через WebSocket в реальном времени
|
||||
- [ ] Кнопка "Create Agent" ведёт на форму создания
|
||||
|
||||
**Компоненты:** Web
|
||||
**Оценка:** M
|
||||
|
||||
### Story 4.2: Форма создания агента
|
||||
**Как** администратор **я хочу** создать нового агента и получить его токен **чтобы** подключить к системе
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Форма с полями: name, slug, capabilities (чекбоксы), chat_listen, task_listen, model
|
||||
- [ ] Slug валидируется на уникальность
|
||||
- [ ] При создании генерируется токен формата `tb-{32 random chars}`
|
||||
- [ ] Токен показывается один раз с предупреждением "Сохраните токен"
|
||||
- [ ] После создания редирект на `/agents` со списком
|
||||
- [ ] Токен копируется в clipboard кнопкой
|
||||
|
||||
**Компоненты:** Web / BFF / Tracker
|
||||
**Оценка:** M
|
||||
|
||||
### Story 4.3: Agent configuration UI
|
||||
**Как** администратор **я хочу** редактировать настройки агента **чтобы** корректировать его поведение
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] В таблице агентов кнопка "Edit" открывает модальное окно
|
||||
- [ ] Поля: name, capabilities, chat_listen, task_listen, model, prompt
|
||||
- [ ] Slug не редактируется (readonly)
|
||||
- [ ] Кнопка "Regenerate Token" с подтверждением
|
||||
- [ ] Изменения сохраняются через PATCH API
|
||||
- [ ] Обновление конфигурации применяется без перезапуска агента
|
||||
|
||||
**Компоненты:** Web / BFF / Tracker
|
||||
**Оценка:** M
|
||||
|
||||
## Эпик 5: Task Steps UI — Интеграция steps в интерфейс
|
||||
Цель: Показывать прогресс задач через steps UI
|
||||
Зависимости: Эпик 4
|
||||
|
||||
### Story 5.1: Steps в TaskModal
|
||||
**Как** пользователь **я хочу** видеть этапы задачи в виде чеклиста **чтобы** отслеживать прогресс выполнения
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Секция Steps между описанием и комментариями в TaskModal
|
||||
- [ ] Список шагов с чекбоксами и заголовками
|
||||
- [ ] Прогресс-бар "3 из 7 выполнено" вверху секции
|
||||
- [ ] Чекбоксы интерактивны — клик отмечает/снимает выполнение
|
||||
- [ ] Обновления сохраняются через PATCH API
|
||||
- [ ] Live обновления через WebSocket
|
||||
|
||||
**Компоненты:** Web
|
||||
**Оценка:** M
|
||||
|
||||
### Story 5.2: Управление steps в TaskModal
|
||||
**Как** исполнитель задачи **я хочу** добавлять и удалять этапы **чтобы** планировать свою работу
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Кнопка "+ Add Step" в секции Steps
|
||||
- [ ] Инлайн добавление шага с автосохранением
|
||||
- [ ] Кнопка удаления у каждого шага (только для незавершённых)
|
||||
- [ ] Drag & drop для изменения порядка шагов
|
||||
- [ ] Завершённые шаги визуально отличаются (зачёркнутый текст)
|
||||
|
||||
**Компоненты:** Web
|
||||
**Оценка:** S
|
||||
|
||||
## Эпик 6: Files & Attachments — Загрузка файлов
|
||||
Цель: Реализовать upload/download файлов в сообщениях
|
||||
Зависимости: Эпик 5
|
||||
|
||||
### Story 6.1: Upload API для attachments
|
||||
**Как** пользователь **я хочу** прикреплять файлы к сообщениям **чтобы** делиться документами с командой
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `POST /api/v1/messages/{id}/attachments` принимает multipart/form-data
|
||||
- [ ] Файлы сохраняются в `/var/lib/team-board/attachments/{message_id}/`
|
||||
- [ ] Создаётся Attachment запись в БД с metadata
|
||||
- [ ] Поддерживаются файлы до 10MB
|
||||
- [ ] Валидация MIME типов (изображения, документы, код)
|
||||
- [ ] BFF проксирует загрузку с авторизацией
|
||||
|
||||
**Компоненты:** Tracker / BFF
|
||||
**Оценка:** M
|
||||
|
||||
### Story 6.2: Download API для attachments
|
||||
**Как** пользователь **я хочу** скачивать прикреплённые файлы **чтобы** просматривать их локально
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `GET /api/v1/attachments/{id}` отдаёт файл с правильными заголовками
|
||||
- [ ] Content-Type, Content-Length, Content-Disposition установлены
|
||||
- [ ] Проверка доступа — пользователь должен иметь доступ к сообщению
|
||||
- [ ] Обслуживание статичных файлов через FastAPI
|
||||
- [ ] BFF проксирует скачивание с авторизацией
|
||||
|
||||
**Компоненты:** Tracker / BFF
|
||||
**Оценка:** S
|
||||
|
||||
### Story 6.3: File preview в UI
|
||||
**Как** пользователь **я хочу** видеть превью файлов в чате **чтобы** не скачивать их для просмотра
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Изображения показываются как thumbnail в сообщении
|
||||
- [ ] Клик на thumbnail открывает полноразмерное изображение
|
||||
- [ ] Документы показываются как ссылки с иконками типов файлов
|
||||
- [ ] Код файлы (.js, .py, .md) показываются с syntax highlighting
|
||||
- [ ] Кнопка скачивания у каждого attachment
|
||||
|
||||
**Компоненты:** Web
|
||||
**Оценка:** M
|
||||
|
||||
## Эпик 7: MCP Tools — Инструменты для агентов
|
||||
Цель: Создать MCP Tools для взаимодействия агентов с системой
|
||||
Зависимости: Эпик 6
|
||||
|
||||
### Story 7.1: Базовые Task Tools
|
||||
**Как** агент **я хочу** создавать и управлять задачами через MCP **чтобы** автоматизировать workflow
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `create_task(title, description, project_slug, priority?, labels?)` → task_id
|
||||
- [ ] `take_task(task_id)` → success/error
|
||||
- [ ] `update_task(task_id, fields)` → updated task
|
||||
- [ ] `complete_task(task_id)` → устанавливает status=done
|
||||
- [ ] `list_tasks(project_slug?, status?, assignee?)` → task list
|
||||
- [ ] Все tools используют существующий REST API с токен авторизацией
|
||||
|
||||
**Компоненты:** Picogent
|
||||
**Оценка:** M
|
||||
|
||||
### Story 7.2: Communication Tools
|
||||
**Как** агент **я хочу** отправлять сообщения и читать чат **чтобы** участвовать в обсуждениях
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `send_message(content, chat_id?, task_id?, mentions?)` → message_id
|
||||
- [ ] `list_messages(chat_id?, task_id?, limit?)` → message list
|
||||
- [ ] `add_task_comment(task_id, content)` → comment message
|
||||
- [ ] `mention_user(slug, message)` → автодобавление в mentions[]
|
||||
- [ ] Все сообщения получают правильный author_slug агента
|
||||
|
||||
**Компоненты:** Picogent
|
||||
**Оценка:** S
|
||||
|
||||
### Story 7.3: Project & Member Tools
|
||||
**Как** агент **я хочу** получать информацию о проектах и участниках **чтобы** понимать контекст работы
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] `list_projects()` → project list с основными полями
|
||||
- [ ] `get_project(slug)` → детальная информация о проекте
|
||||
- [ ] `list_members(project_slug?)` → список участников
|
||||
- [ ] `get_member(slug)` → информация об участнике
|
||||
- [ ] `watch_task(task_id)` / `unwatch_task(task_id)` → управление подписками
|
||||
|
||||
**Компоненты:** Picogent
|
||||
**Оценка:** S
|
||||
|
||||
## Эпик 8: Advanced Features — Дополнительные возможности
|
||||
Цель: Реализовать отложенные features для полноценной работы
|
||||
Зависимости: Эпик 7
|
||||
|
||||
### Story 8.1: Telegram Bridge Foundation
|
||||
**Как** пользователь **я хочу** получать уведомления в Telegram **чтобы** не пропускать важные события проекта
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Bridge агент подключается как member типа "bridge"
|
||||
- [ ] Принимает все события проектов (listen_mode="all")
|
||||
- [ ] Фильтрует важные события: task.assigned на меня, mentions в чате
|
||||
- [ ] Отправляет уведомления в личный чат Telegram
|
||||
- [ ] Конфигурация через переменные окружения
|
||||
|
||||
**Компоненты:** Picogent (отдельный bridge agent)
|
||||
**Оценка:** L
|
||||
|
||||
### Story 8.2: Voice Messages Support
|
||||
**Как** пользователь **я хочу** отправлять голосовые сообщения **чтобы** быстро комментировать задачи
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] Web Client записывает аудио через MediaRecorder API
|
||||
- [ ] Upload аудио как attachment с типом audio/*
|
||||
- [ ] Message.voice_url ссылается на attachment
|
||||
- [ ] Аудио плеер в UI для воспроизведения
|
||||
- [ ] Агенты могут транскрибировать voice_url через STT
|
||||
|
||||
**Компоненты:** Web / Tracker / Picogent
|
||||
**Оценка:** L
|
||||
|
||||
### Story 8.3: Advanced Task Dependencies
|
||||
**Как** PM **я хочу** видеть граф зависимостей задач **чтобы** планировать последовательность работ
|
||||
|
||||
**Критерии приёмки:**
|
||||
- [ ] UI для добавления зависимостей в TaskModal (autocomplete других задач)
|
||||
- [ ] Валидация циклических зависимостей на бэкенде
|
||||
- [ ] Визуализация зависимостей в виде граф-диаграммы
|
||||
- [ ] Блокировка взятия задач с незавершёнными зависимостями
|
||||
- [ ] Автоматическое уведомление при разблокировке задачи
|
||||
|
||||
**Компоненты:** Web / Tracker
|
||||
**Оценка:** L
|
||||
Loading…
Reference in New Issue
Block a user