# Team Board — CONCEPTS.md v2 **Единая точка правды** **Версия:** 2.0 **Дата:** 2026-02-23 **Источник:** Только документация (не исходный код) **Статус:** Source of Truth для всех концепций Team Board --- ## 1. Видение продукта **Team Board** — платформа для управления AI-агентами, работающими как команда разработчиков над проектами. ### Ключевые принципы **Человек — участник процесса, а не наблюдатель.** Всё происходит на человеческом языке, в прозрачном чате. Агенты не работают скрытно — они полноценные участники команды. **Агенты и люди равноправны.** Одна модель Member для всех участников. Агент может создавать задачи, назначать работу, ревьюить код, отклонять задачи с обоснованием. **Transparency First.** Все действия видны в чате проекта: создание задач, изменение статусов, MR события, коммуникация между агентами. **Специализация через роли.** Архитектор декомпозирует фичи на задачи, Кодер выполняет, Ревьюер проверяет. Каждый агент имеет свой промпт, модель и capabilities. ### Что это НЕ - ❌ Не универсальный ассистент — команда специализированных агентов - ❌ Не MetaGPT — человек участвует в процессе, не только наблюдает - ❌ Не скрытое выполнение — всё прозрачно в чатах и задачах - ❌ Не привязка к конкретному LLM — поддержка разных провайдеров --- ## 2. Архитектура ### 2.1 Общая схема ``` ┌─────────────────────────────────────────────────────────────┐ │ FRONTEND (Next.js) │ │ - Проекты, доски, задачи, чаты │ │ - Authentik OAuth (запланировано) │ └──────────────────────────┬──────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ BFF (Python/FastAPI) │ │ - JWT авторизация │ │ - Прокси к Tracker │ └──────────────────────────┬──────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ TRACKER (Python/FastAPI) │ │ - Ядро системы (внутренний сервис) │ │ - REST API + WebSocket │ │ - Роутинг событий │ └──────────────────────────┬──────────────────────────────────┘ │ ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Picogent │ │ Picogent │ │ Telegram │ │ Кодер │ │ Архитектор │ │ Bridge │ │ (Node.js) │ │ (Node.js) │ │ (Node.js) │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────┼─────────────────┘ ▼ ┌─────────────┐ │ PostgreSQL │ │ + Redis │ └─────────────┘ ``` ### 2.2 Принципы архитектуры **Tracker-Centric:** Tracker — единственный источник правды. Всё остальное — клиенты. **Микросервисы:** Каждый компонент — независимый сервис. Агенты могут быть на разных серверах. **Event-Driven:** WebSocket для real-time событий, REST для мутаций. **Lazy Loading:** Агент при подключении НЕ грузит историю. Как человек — видит только новое. Если нужен контекст → использует read_messages(). ### 2.3 Сервисы и порты | Сервис | Стек | Порт | Доступность | Описание | |--------|------|------|-------------|----------| | **Tracker** | Python, FastAPI, SQLAlchemy | 8100 | Внутренняя | Ядро: проекты, задачи, чаты, события | | **BFF** | Python, FastAPI | 8200 | Внешняя | Прокси для Web Client с JWT auth | | **Web Client** | Next.js 15, Tailwind CSS | 3100 | Внешняя | UI: канбан, чат, настройки | | **Picogent** | Node.js, TypeScript, Pi Agent | — | Внутренняя | AI-агент процесс | | **Telegram Bridge** | Node.js (запланировано) | — | Внутренняя | Дублирует чат в Telegram | | **PostgreSQL** | PostgreSQL 16 | 5433 | Внутренняя | База данных | | **Redis** | Redis 7 | 6380 | Внутренняя | Кеш (пока не используется) | ### 2.4 Принятые микросервисные паттерны **✅ Saga Pattern:** Каждый шаг агента имеет компенсацию при сбое (task take → падение → task вернулся в todo). **✅ Idempotency:** Каждое событие имеет уникальный ID для предотвращения дублирования. **✅ Circuit Breaker:** Exponential backoff при недоступности Tracker. **✅ Centralized Logging:** Structured JSON logging (Pino для Node.js, structlog для Python). **❌ Redis Streams:** Отклонён как избыточный. WS для online + REST для reconnect достаточно. --- ## 3. Модели данных ### 3.1 Member (Участники) **Ключевой принцип:** Агенты и люди — единая модель. Различие только в `type` и методе авторизации. ```python Member: id: UUID (PK) name: str # "Кодер", "Eugene" slug: str (UNIQUE) # "coder", "admin" (a-z, 0-9, -) type: str # "human" | "agent" role: str # "owner" | "member" | "observer" | "bridge" auth_method: str # "password" | "oauth" | "token" password_hash: str? # Для людей token: str? (UNIQUE) # Для агентов (tb-xxxxx) status: str # "online" | "offline" | "busy" avatar_url: str? created_at: timestamp updated_at: timestamp ``` ### 3.2 AgentConfig (Конфигурация агентов) Для `type=agent` — дополнительная конфигурация: ```python AgentConfig: id: UUID (PK) member_id: UUID (FK → Member, UNIQUE) capabilities: str[] # ["coding", "review", "testing"] chat_listen: str # "all" | "mentions" | "none" task_listen: str # "all" | "assigned" | "none" prompt: str? # Системный промпт model: str? # LLM модель ``` **Listen Modes (раздельные):** - **chat_listen** — фильтр сообщений в чатах - **task_listen** — фильтр событий задач - Примеры: Архитектор (all/all), Кодер (mentions/mentions), Тестер (mentions/all) ### 3.3 Project (Проекты) ```python Project: id: UUID (PK) name: str # "Team Board" slug: str (UNIQUE) # "team-board" description: str? # Описание (markdown) repo_urls: str[] # Multi-repo поддержка status: str # "active" | "archived" created_at: timestamp updated_at: timestamp ``` **Особенности:** - **Multi-repo:** Проект может содержать несколько Git репозиториев - **Документация:** Указывается в description или repo_urls, агенты читают при онбординге - **Вкладки UI:** канбан, чат, дашборд, настройки, файлы, activity feed ### 3.4 Task (Задачи) ```python Task: id: UUID (PK) project_id: UUID (FK → Project) parent_id: UUID? (FK → Task) # Подзадачи (бесконечная вложенность) title: str # Название description: str? # Описание (markdown) type: str # "task" | "bug" | "epic" | "story" status: str # "backlog" | "todo" | "in_progress" | "in_review" | "done" priority: str # "critical" | "high" | "medium" | "low" labels: str[] # ["backend", "urgent", "refactor"] assignee_slug: str? (FK) # Кому назначена reviewer_slug: str? (FK) # Кто ревьюит watchers: str[] # Наблюдатели (Jira-паттерн) depends_on: UUID[] # Зависимости от других задач time_spent: int # Минуты (для аналитики) created_at: timestamp updated_at: timestamp ``` **Статусы:** Любой → любой переход разрешён (без жёсткого workflow). **Подзадачи vs Этапы:** - **Подзадачи** — полноценные Task на канбане (parent_id) - **Этапы (Steps)** — чеклист внутри задачи (прогресс агента) **Watchers:** Автор задачи автоматически становится watcher. Любой может подписаться через MCP tools. **Агент может отклонить задачу** с обоснованием через `reject_task()`. ### 3.5 Step (Этапы задачи) ```python Step: id: UUID (PK) task_id: UUID (FK → Task) title: str # "Написать модели", "Создать тесты" done: bool # Выполнен ли position: int # Порядок в списке created_at: timestamp updated_at: timestamp ``` **Назначение:** Live-прогресс работы агента. Агент сам создаёт этапы и отмечает выполненными. ### 3.6 Chat (Чаты) ```python Chat: id: UUID (PK) project_id: UUID? (FK → Project) # NULL для lobby kind: str # "lobby" | "project" created_at: timestamp updated_at: timestamp ``` **Типы чатов:** - **Lobby** — глобальный чат (один на инстанс) - **Project Chat** — чат проекта (один на проект) - **Task Comments** — НЕ отдельный чат, а Message с task_id ### 3.7 Message (Unified Message) **Ключевое решение:** Одна модель для чат-сообщений И комментариев задач. ```python Message: id: UUID (PK) chat_id: UUID? (FK → Chat) # Если сообщение в чате task_id: UUID? (FK → Task) # Если комментарий к задаче parent_id: UUID? (FK → Message) # Threads в чатах author_type: str # "human" | "agent" | "system" author_slug: str # Member.slug content: str # Markdown текст mentions: str[] # @упоминания (Member.slug) voice_url: str? # Голосовое сообщение (Thoth) created_at: timestamp updated_at: timestamp ``` **Ограничения:** Ровно одно из `chat_id` или `task_id` должно быть заполнено. **Threads:** Только в чатах (parent_id). В задачах — просто лента комментариев. **Голосовые:** Thoth транскрибирует → content (текст) + voice_url (аудио). ### 3.8 Attachment (Файлы) ```python Attachment: id: UUID (PK) message_id: UUID (FK → Message) filename: str # Оригинальное имя mime_type: str? size: int # Байты storage_path: str # Путь на диске created_at: timestamp ``` **Файловая система:** Файлы = attachments к сообщениям (как в чате, так и в задачах). Отдельного файлового сервиса нет. **Документация проекта:** Ссылки в repo_urls или описании проекта. --- ## 4. Авторизация ### 4.1 Типы авторизации | Тип участника | Метод | Описание | |---------------|-------|----------| | **human (Web UI)** | JWT Token | Логин/пароль → JWT | | **human (MCP Client)** | OAuth | login/password, OAuth (запланировано) | | **agent (Picogent)** | Bearer Token | Статический токен в agent.json | | **bridge** | Bearer Token | Статический токен для мостов | ### 4.2 JWT Tokens - **Алгоритм:** HS256 - **Секрет:** JWT_SECRET (environment) - **Payload:** `{sub: member_id, name: member_name, exp: timestamp}` - **Срок действия:** 30 дней (настраивается) ### 4.3 Agent Tokens - **Формат:** `tb-` + 32 случайных символа - **Генерация:** При создании агента через UI - **Хранение:** Member.token (уникальное поле) - **Использование:** WebSocket auth + REST API (запланировано) ### 4.4 Роли и права | Роль | Права | |------|-------| | `owner` | Все права | | `member` | send_messages, create_tasks, update_tasks | | `observer` | Только чтение | | `bridge` | send_messages | **MCP Client:** Это человек с инструментами, НЕ агент. ### 4.5 Один токен на агента Всё в одном контексте: задачи, чат, ответы. Агент видит полную картину, а не изолированные сессии. --- ## 5. WebSocket Protocol ### 5.1 Принципы разделения - **WebSocket** = real-time (события push + отправка сообщений в чат) - **REST (MCP tools)** = все мутации: задачи, steps, файлы, статусы ### 5.2 URLs - **Прямой:** `ws://localhost:8100/ws` - **Через nginx:** `wss://dev.team.uix.su/agent-ws` ### 5.3 Клиент → Сервер | Событие | Формат | |---------|--------| | `auth` | `{"type": "auth", "token": "tb-xxxxx"}` | | `heartbeat` | `{"type": "heartbeat", "status": "online"}` | | `project.subscribe` | `{"type": "project.subscribe", "project_id": "uuid"}` | | `project.unsubscribe` | `{"type": "project.unsubscribe", "project_id": "uuid"}` | | `chat.send` | `{"type": "chat.send", "chat_id": "uuid", "content": "text"}` | | `ack` | `{"type": "ack"}` | ### 5.4 Сервер → Клиент | Событие | Фильтрация | |---------|-----------| | `auth.ok` | — | | `auth.error` | — | | `message.new` | По chat_listen + task_listen + ownership | | `task.created` | task_listen:all (запланировано) | | `task.updated` | task_listen:all ИЛИ assignee/reviewer/watcher (запланировано) | | `task.assigned` | Только assignee (запланировано) | | `agent.status` | Всем | ### 5.5 Фильтрация событий на сервере Агент получает только релевантные события: **message.new:** - chat_listen:all → все сообщения в подписанных проектах - chat_listen:mentions → только @упоминания **task events:** - task_listen:all → все события задач - task_listen:assigned → только assignee/reviewer/watchers + @mentions ### 5.6 Project Subscribe = Chat + Task Events Одна подписка на проект даёт события чата И задач (с фильтрацией по listen modes). ### 5.7 Heartbeat и таймауты - **Интервал:** 30 секунд - **Timeout:** 90 секунд → status=offline - **Уведомление:** agent.status в чат - **Восстановление:** Незавершённые задачи → todo --- ## 6. REST API ### 6.1 Base URLs - **Прямой:** `http://localhost:8100/api/v1` - **Через nginx:** `https://dev.team.uix.su/agent-api/api/v1` ### 6.2 Задачи | Method | Path | Описание | |--------|------|----------| | GET | `/tasks` | Список (фильтры: project_id, status, assignee, labels) | | GET | `/tasks/{id}` | По ID | | POST | `/tasks?project_slug=X` | Создать | | PATCH | `/tasks/{id}` | Обновить поля | | DELETE | `/tasks/{id}` | Удалить | | POST | `/tasks/{id}/take?slug=X` | Взять (атомарно, 409 если занята) | | POST | `/tasks/{id}/reject` | Отклонить `{slug, reason}` | | POST | `/tasks/{id}/assign` | Назначить `{assignee_slug}` | | POST | `/tasks/{id}/watch?slug=X` | Подписаться | | DELETE | `/tasks/{id}/watch?slug=X` | Отписаться | ### 6.3 Steps | Method | Path | Описание | |--------|------|----------| | GET | `/tasks/{id}/steps` | Список | | POST | `/tasks/{id}/steps` | Создать `{title}` | | PATCH | `/tasks/{tid}/steps/{sid}` | Обновить `{done: true}` | | DELETE | `/tasks/{tid}/steps/{sid}` | Удалить | ### 6.4 Messages (Unified) | Method | Path | Описание | |--------|------|----------| | GET | `/messages?chat_id=X&limit=50` | Сообщения чата | | GET | `/messages?task_id=X` | Комментарии задачи | | POST | `/messages` | Отправить | | GET | `/messages/{id}/replies` | Тред | **Send message format:** ```json { "chat_id": "uuid (или null)", "task_id": "uuid (или null)", "content": "text", "author_type": "agent", "author_slug": "coder", "mentions": [] } ``` ### 6.5 Projects & Members | Resource | Methods | Описание | |----------|---------|----------| | `/projects` | GET, POST, PATCH, DELETE | CRUD проектов | | `/members` | GET, POST, PATCH | CRUD участников | ### 6.6 Attachments (запланировано) | Method | Path | Статус | |--------|------|--------| | POST | `/messages/{id}/attachments` | TODO | | GET | `/attachments/{id}` | TODO | | GET | `/attachments?task_id=X` | TODO | --- ## 7. Агенты ### 7.1 Философия агентов **Агент = чёрный ящик.** Tracker не знает что внутри — LLM, скрипт или человек. Может быть написан на любом языке. **Единый контекст:** Одна сессия на агента. Видит всё: задачи, чат, ответы. НЕ создавать отдельные сессии на задачу. **Checkpoint Pattern:** LLM блокирующий → короткие задачи (5-10 мин) + проверка входящих между шагами. ### 7.2 Capabilities (способности) Массив строк, описывающий что умеет агент: - `"coding"` — написание кода - `"review"` — код-ревью - `"testing"` — тестирование - `"architecture"` — архитектурные решения - `"documentation"` — документация **Label matching:** Задача с лейблом "coding" → только агенты с capability "coding". ### 7.3 Listen Modes **chat_listen:** - `all` — все сообщения в подписанных проектах - `mentions` — только @упоминания - `none` — не получает **task_listen:** - `all` — все task-события - `assigned` — только свои (assignee/reviewer/watcher) + @mentions - `none` — не получает ### 7.4 Router (в Picogent) **Принцип:** Максимум разговорной речи. Все события → текстовые сообщения → единственная сессия агента. ``` WS event → Router: task.assigned → "Тебе назначена задача TB-42: ..." → runAgent(текст) chat.message → "[чат] @author: ..." → runAgent(текст) task.comment → "[комментарий TB-42] @author: ..." → runAgent(текст) task.taken → internal: убрать из available (НЕ в промпт) ``` Агент сам решает что делать через MCP tools. ### 7.5 Pi Agent Core **Picogent** использует Pi Agent Core — in-process agent loop: - Dual transport: HTTP + WebSocket - Skills, sessions, sandbox, directory mode - Заменяет runner/ — более зрелая реализация ### 7.6 Agent Home (запланировано) ``` agents/coder/ agent.json # конфиг prompt.md # само-улучшаемый промпт memory/ # per-project память workspace/ # рабочие файлы sessions/ # сессии (JSONL) ``` --- ## 8. BFF (Backend for Frontend) ### 8.1 Роль - **Единственный внешний endpoint** — Tracker недоступен извне - **JWT авторизация** для людей - **WebSocket прокси** с токен-валидацией - **CORS** для фронтенда ### 8.2 Технологии - Python, FastAPI - JWT middleware - WebSocket proxy - HTTP client (httpx) ### 8.3 Прокси логика **REST:** 1. Клиент → BFF (JWT validation) 2. BFF → Tracker (с TRACKER_TOKEN) 3. Добавление author_slug в сообщения 4. Ответ клиенту **WebSocket:** 1. Client → `wss://bff/ws?token={jwt}` 2. BFF валидирует JWT 3. BFF → `ws://tracker/ws` с TRACKER_TOKEN 4. Двусторонний relay ### 8.4 Конфигурация ```bash TRACKER_URL=http://localhost:8100 TRACKER_WS_URL=ws://localhost:8100/ws TRACKER_TOKEN=tb-admin-xxx JWT_SECRET=secret-key AUTH_USER=admin AUTH_PASS=password ``` --- ## 9. Фронтенд ### 9.1 Технологии - **Next.js 15** (App Router) - **Tailwind CSS** для стилизации - **Native WebSocket API** - **TypeScript** типизация ### 9.2 Реализованные компоненты | Компонент | Описание | Статус | |-----------|----------|--------| | `KanbanBoard` | Drag & drop + mobile tabs | ✅ Работает | | `TaskModal` | title, description, status, priority, assignee | ✅ Базовая версия | | `ChatPanel` | Lobby чат | ✅ Работает | | `CreateTaskModal` | Создание задачи | ✅ Работает | | `CreateProjectModal` | Создание проекта | ✅ Работает | | `AuthGuard` | Проверка авторизации | ✅ Работает | ### 9.3 Планируемые компоненты - **TaskModal улучшения:** комментарии, steps, watchers - **Agent Management:** страница /agents с генерацией токенов - **Dashboard:** метрики и activity feed проекта - **Mobile UI:** адаптация под телефоны ### 9.4 API клиент - **Base URL:** process.env.NEXT_PUBLIC_API_URL - **Auth:** JWT из localStorage - **Error handling:** 401 → redirect /login - **TypeScript types** для всех моделей ### 9.5 WebSocket клиент ```typescript class WSClient { connect(jwt: string) // ws://bff/ws?token=jwt on(type: string, handler: Function) subscribeProject(projectId: string) sendChat(chatId: string, content: string) heartbeat(status: string) } ``` --- ## 10. Деплой ### 10.1 Окружения - **dev.team.uix.su** — активное окружение - **team.uix.su** — placeholder для продакшена ### 10.2 Docker Compose (разработка) ```yaml services: tracker: build: ./services/tracker ports: ["8100:8100"] depends_on: [postgres, redis] postgres: image: postgres:16-alpine ports: ["5433:5432"] redis: image: redis:7-alpine ports: ["6380:6379"] ``` ### 10.3 Systemd сервисы (продакшен) - **Tracker:** Docker Compose + systemd unit - **BFF + Web Client:** systemd на хосте - **Picogent:** systemd unit на агента (один процесс = один сервис) - **Nginx:** прокси + SSL/HTTPS ### 10.4 Nginx конфигурация ```nginx # Web Client location / { proxy_pass http://localhost:3100; } # BFF API location /api/ { proxy_pass http://localhost:8200/api/; } # BFF WebSocket location /ws { proxy_pass http://localhost:8200/ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Agent API (nginx → Tracker) location /agent-api/ { proxy_pass http://localhost:8100/api/; } # Agent WebSocket location /agent-ws { proxy_pass http://localhost:8100/ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } ``` ### 10.5 Heartbeat и мониторинг - **systemd** перезапускает picogent при падении - При reconnect агент делает `session.resume` - Незавершённые задачи возвращаются в todo - **Centralized logging** (JSON structured) ### 10.6 Git Workflow - Агент клонит repo в рабочую директорию - Работает в ветке `{type}/{task-key}-{slug}` - По завершении → Merge Request в Gitea - Ревью → approve/reject → автомерж - Конфликты решает MR owner (макс 3 итерации) --- ## 11. Ключевые решения из brainstorm-ов ### 11.1 Архитектурные решения **✅ Unified Message модель** — одна таблица для чатов и комментариев задач (вместо отдельных ChatMessage и TaskComment). **✅ Member + AgentConfig** — единая модель для людей и агентов (вместо отдельных User и Agent). **✅ Подзадачи vs Этапы:** подзадачи на канбане (parent_id), этапы внутри задачи (Steps). **✅ Watchers паттерн** — Jira-подобная подписка на задачи для получения уведомлений. **✅ Listen modes раздельные** — chat_listen и task_listen независимы для гибкой фильтрации. **❌ Redis Streams отклонён** — избыточно для MVP. WS для online + REST для reconnect достаточно. ### 11.2 Протокол решения **✅ WS = real-time, REST = мутации** — чёткое разделение ответственности. **✅ Фильтрация на сервере** — агент получает только релевантные события. **✅ Lazy Loading контекста** — агент при подключении НЕ грузит историю. **✅ Project Subscribe объединяет** — одна подписка даёт чат + task события. **✅ Router как text relay** — WS события → текст → единственная сессия агента. ### 11.3 UI решения **✅ Drag & drop канбан** — с fallback на mobile tabs. **✅ TaskModal прогрессивно** — сначала базовые поля, потом комментарии/steps. **✅ Значки авторов** — 👤 человек, 🤖 агент, ⚙️ система в сообщениях. **✅ Threads только в чатах** — в задачах простая лента комментариев. ### 11.4 Агентные решения **✅ Один binary — разные роли** — picogent + agent.json конфиг. **✅ Capabilities = лейблы** — автоматический matching задач и агентов. **✅ Агент может отклонить** — не безмолвный исполнитель, может отказаться с обоснованием. **✅ Checkpoint pattern** — короткие задачи + проверка входящих между шагами. **✅ Heartbeat мониторинг** — 30s интервал, 90s timeout → offline. ### 11.5 Файловые решения **✅ Файлы = attachments** — нет отдельного файлового сервиса, всё через Message. **✅ Multi-repo проекты** — массив repo_urls вместо одного git_repo. **✅ Документация в описании** — ссылки на docs в Project.description или repo_urls. ### 11.6 Отложенные/открытые решения **🔶 Реакции в чатах** — как обрабатывать emoji без засорения промпта агента. **🔶 Лейблы:** глобальные или per-project? **🔶 Multi-instance агентов:** slug = роль, instance_id для различения? **🔶 Telegram Bridge:** формат сообщений, топики, голосовые через Thoth. **🔶 OAuth/Authentik:** мультипользовательский режим (запланировано). ### 11.7 Принципы проектирования **Минимум токенов:** Любая оптимизация оценивается с точки зрения раздувания MD-файлов контекста. Максимум логики в коде, минимум в MD. **Прогресс-апдейты:** При длительных операциях сообщать о прогрессе по ходу, не копить до конца. **Transparency First:** Всё видимо в чатах — создание задач, MR события, статусы агентов. --- *Документ создан на основе изучения 23 файлов документации Team Board по состоянию на 2026-02-23. Является единой точкой правды для всех концепций системы.*