878 lines
39 KiB
Markdown
878 lines
39 KiB
Markdown
# Team Board — Концепции системы v2.0
|
||
|
||
**Версия:** 2.0
|
||
**Дата:** 2026-02-23
|
||
**Статус:** Единая точка правды по всем концепциям Team Board на основе документации
|
||
|
||
---
|
||
|
||
## 1. Видение продукта
|
||
|
||
### Что такое Team Board
|
||
|
||
**Team Board** — платформа для совместной работы людей и AI-агентов над проектами. Канбан-доска, чат, файлы — где агенты являются полноценными участниками команды: берут задачи, общаются, создают подзадачи, ревьюят код.
|
||
|
||
### Для кого
|
||
|
||
- **Разработчики** — управление проектами с AI-помощью
|
||
- **Product Manager** — координация команды из людей и агентов
|
||
- **Solo разработчики** — масштабирование через AI-агентов
|
||
- **Команды** — прозрачная работа с AI как с коллегами
|
||
|
||
### Ключевое отличие
|
||
|
||
**Человек — участник процесса, а не наблюдатель.** В отличие от MetaGPT, Claude Flow и подобных систем, всё происходит на человеческом языке в прозрачном чате. Агенты работают рядом с людьми, а не вместо них.
|
||
|
||
### Философия агентов
|
||
|
||
- **Агент и человек — равны** (одна модель участника)
|
||
- **Всё прозрачно** — вся работа агентов видна в чате и задачах
|
||
- **Специализация** — каждый агент имеет роль и capabilities
|
||
- **Коллаборация** — агенты общаются друг с другом и людьми
|
||
- **Автономия** — агенты сами берут задачи, отклоняют неподходящие
|
||
|
||
---
|
||
|
||
## 2. Архитектура
|
||
|
||
### Принцип: Tracker-Centric
|
||
|
||
**Tracker — центральный хаб.** Всё остальное — клиенты, подключающиеся к нему.
|
||
|
||
```
|
||
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
|
||
│ Web Client │────▶│ BFF │────▶│ Tracker │
|
||
│ (Next.js) │ │ (FastAPI) │ │ (FastAPI) │
|
||
└─────────────┘ └──────────────┘ └──────┬───────┘
|
||
│
|
||
┌────────────────────────────────────────┤
|
||
│ │ │ │
|
||
┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌──▼───┐
|
||
│Picogent │ │Picogent │ │Telegram │ │ DB │
|
||
│ Кодер │ │Архитект │ │ Bridge │ │ Pg │
|
||
└─────────┘ └─────────┘ └─────────┘ └──────┘
|
||
```
|
||
|
||
### Компоненты
|
||
|
||
| Компонент | Технологии | Порт | Доступность | Описание |
|
||
|-----------|------------|------|-------------|----------|
|
||
| **Tracker** | Python, FastAPI, SQLAlchemy, PostgreSQL | 8100 | Внутренняя | Ядро системы. REST API + WebSocket |
|
||
| **BFF** | Python, FastAPI | 8200 | Внешняя | Прокси для Web Client с JWT auth |
|
||
| **Web Client** | Next.js 15, Tailwind CSS | 3100 | Внешняя | UI: канбан, чат, настройки |
|
||
| **PostgreSQL** | PostgreSQL 16 | 5433 | Внутренняя | База данных |
|
||
| **Redis** | Redis 7 | 6380 | Внутренняя | Кеш и очереди *(запланировано)* |
|
||
| **Picogent** | Node.js, TypeScript | — | Внутренняя | AI-агент процесс |
|
||
|
||
### Протоколы взаимодействия
|
||
|
||
- **Web Client ↔ BFF:** HTTPS REST API + WebSocket (JWT auth)
|
||
- **BFF ↔ Tracker:** HTTP REST API + WebSocket (Token auth)
|
||
- **Агенты ↔ Tracker:** HTTP REST API + WebSocket (Token auth)
|
||
- **База данных:** PostgreSQL connection pool через SQLAlchemy
|
||
|
||
### Принципы архитектуры
|
||
|
||
1. **Tracker не доступен извне** — только через BFF или nginx proxy
|
||
2. **Единая модель участников** — люди и агенты в одной таблице Member
|
||
3. **WebSocket для событий** — REST для мутаций
|
||
4. **Микросервисная готовность** — каждый компонент независим
|
||
5. **Event-driven** — всё через события *(Redis Streams — запланировано)*
|
||
|
||
---
|
||
|
||
## 3. Модели данных
|
||
|
||
### Member (Участники) — Ключевая модель
|
||
|
||
**Принцип:** Агенты и люди — единая модель. Различие только в `type` и методе авторизации.
|
||
|
||
```python
|
||
Member:
|
||
id: UUID (PK)
|
||
name: str # Отображаемое имя
|
||
slug: str (UNIQUE) # Уникальный идентификатор (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) # Для агентов/bridges
|
||
status: str # "online" | "offline" | "busy"
|
||
avatar_url: str?
|
||
created_at: timestamp
|
||
updated_at: timestamp
|
||
```
|
||
|
||
### AgentConfig (Конфигурация агентов)
|
||
|
||
```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 модель
|
||
```
|
||
|
||
### Project (Проекты)
|
||
|
||
```python
|
||
Project:
|
||
id: UUID (PK)
|
||
name: str # Отображаемое название
|
||
slug: str (UNIQUE) # Уникальный ID (для URLs)
|
||
description: str? # Описание (markdown)
|
||
repo_urls: str[] # Массив Git репозиториев
|
||
status: str # "active" | "archived"
|
||
task_counter: int # Счётчик для генерации номеров задач
|
||
created_at: timestamp
|
||
updated_at: timestamp
|
||
```
|
||
|
||
### Task (Задачи)
|
||
|
||
```python
|
||
Task:
|
||
id: UUID (PK)
|
||
project_id: UUID (FK → Project)
|
||
parent_id: UUID? (FK → Task) # Подзадача
|
||
number: int # Порядковый номер в проекте (1, 2, 3...)
|
||
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"]
|
||
assignee_slug: str? # Кому назначена (Member.slug)
|
||
reviewer_slug: str? # Кто ревьюит (Member.slug)
|
||
watchers: str[] # Наблюдатели (массив Member.slug) *запланировано*
|
||
depends_on: UUID[] # Зависимости от других задач *запланировано*
|
||
position: int # Позиция в колонке канбана
|
||
time_spent: int # Потраченное время (минуты)
|
||
created_at: timestamp
|
||
updated_at: timestamp
|
||
```
|
||
|
||
### Step (Шаги задачи)
|
||
|
||
```python
|
||
Step:
|
||
id: UUID (PK)
|
||
task_id: UUID (FK → Task)
|
||
title: str # Описание шага
|
||
done: bool # Выполнен ли
|
||
position: int # Порядок в списке
|
||
created_at: timestamp
|
||
updated_at: timestamp
|
||
```
|
||
|
||
**Подзадачи vs Этапы:**
|
||
- **Подзадачи** = полноценные задачи на канбан-доске (parent_id)
|
||
- **Этапы (steps)** = чеклист внутри задачи (прогресс агента, не на канбане)
|
||
|
||
### 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** — чат проекта (один на проект)
|
||
|
||
### Message (Сообщения) — Unified Model
|
||
|
||
**Ключевое решение:** Одна модель для чат-сообщений И комментариев к задачам.
|
||
|
||
```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? # URL голосового сообщения
|
||
created_at: timestamp
|
||
updated_at: timestamp
|
||
```
|
||
|
||
**Ограничения:** Ровно одно из `chat_id` или `task_id` должно быть заполнено.
|
||
|
||
### Attachment (Вложения)
|
||
|
||
```python
|
||
Attachment:
|
||
id: UUID (PK)
|
||
message_id: UUID (FK → Message)
|
||
filename: str # Оригинальное имя файла
|
||
mime_type: str? # MIME тип
|
||
size: int # Размер в байтах
|
||
storage_path: str # Путь к файлу на диске
|
||
created_at: timestamp
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Авторизация
|
||
|
||
### Типы авторизации
|
||
|
||
| Тип участника | Метод авторизации | Описание |
|
||
|---------------|-------------------|----------|
|
||
| **human (Web UI)** | JWT Token | Логин/пароль → JWT |
|
||
| **human (MCP Client)** | JWT Token | Логин/пароль → JWT *(запланировано)* |
|
||
| **agent** | Bearer Token | Статический токен в agent.json |
|
||
| **bridge** | Bearer Token | Статический токен для мостов |
|
||
|
||
### JWT Tokens (для людей)
|
||
|
||
- **Секрет:** `JWT_SECRET` (environment variable)
|
||
- **Алгоритм:** HS256
|
||
- **Payload:** `{"sub": member_id, "name": member_name, "exp": timestamp}`
|
||
- **Срок действия:** 30 дней (настраивается)
|
||
|
||
### Agent Tokens
|
||
|
||
- **Формат:** `tb-` + random string (32 символа)
|
||
- **Хранение:** `Member.token` (уникальное поле)
|
||
- **Генерация:** При создании агента через UI *(запланировано)*
|
||
- **Отзыв:** Через API `POST /api/v1/members/{slug}/revoke-token` *(запланировано)*
|
||
|
||
### Роли и права
|
||
|
||
| Роль | Описание | Права |
|
||
|------|----------|-------|
|
||
| `owner` | Владелец инстанса | Все права |
|
||
| `member` | Обычный участник | `send_messages`, `create_tasks`, `update_tasks` |
|
||
| `observer` | Наблюдатель | Только чтение |
|
||
| `bridge` | Мост в другую систему | `send_messages` |
|
||
|
||
### Процесс авторизации
|
||
|
||
**Web Client:**
|
||
1. POST /api/auth/login → JWT token
|
||
2. Сохранение в localStorage
|
||
3. Authorization: Bearer {jwt} в запросах
|
||
4. WebSocket: ?token={jwt} в query
|
||
|
||
**Agent:**
|
||
1. Статический токен из конфига
|
||
2. WS: `{"type": "auth", "token": "tb-xxx"}`
|
||
3. REST: Authorization: Bearer {token} *(запланировано — проверка не реализована)*
|
||
|
||
---
|
||
|
||
## 5. WebSocket Protocol
|
||
|
||
### Принцип разделения
|
||
|
||
- **WebSocket** = real-time: события (push) + отправка сообщений в чат
|
||
- **REST (MCP tools)** = все мутации: задачи, steps, файлы, статусы
|
||
|
||
### Подключение
|
||
|
||
**URL:** `ws://localhost:8100/ws` (прямое) или `wss://dev.team.uix.su/agent-ws` (через nginx)
|
||
|
||
### Сообщения: Клиент → Сервер
|
||
|
||
| Тип | Формат | Описание |
|
||
|-----|--------|----------|
|
||
| `auth` | `{"type": "auth", "token": "..."}` | Авторизация |
|
||
| `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", "mentions": []}` | Сообщение в чат |
|
||
| `ack` | `{"type": "ack"}` | Подтверждение получения |
|
||
|
||
### Сообщения: Сервер → Клиент
|
||
|
||
| Тип | Описание | Данные |
|
||
|-----|----------|--------|
|
||
| `auth.ok` | Успешная авторизация | `{slug, lobby_chat_id, projects[], online[]}` |
|
||
| `auth.error` | Ошибка авторизации | `{message}` |
|
||
| `message.new` | Новое сообщение | `{id, chat_id, task_id, author_*, content, mentions, created_at}` |
|
||
| `agent.status` | Изменение статуса агента | `{slug, status}` |
|
||
| `task.created` | Создана задача | `{...TaskData}` *(запланировано)* |
|
||
| `task.updated` | Обновлена задача | `{...TaskData}` *(запланировано)* |
|
||
| `task.assigned` | Задача назначена | `{...TaskData}` *(запланировано)* |
|
||
|
||
### Фильтрация событий
|
||
|
||
События фильтруются на сервере по настройкам агента:
|
||
|
||
**message.new:**
|
||
- `chat_listen: "all"` — все сообщения в подписанных проектах
|
||
- `chat_listen: "mentions"` — только сообщения с @упоминанием
|
||
|
||
**task.* (запланировано):**
|
||
- `task_listen: "all"` — все события задач в подписанных проектах
|
||
- `task_listen: "assigned"` — только задачи где агент assignee/reviewer/watcher
|
||
|
||
### Listen Modes (раздельные)
|
||
|
||
- `chat_listen: all` — слышит все сообщения в чатах проекта
|
||
- `chat_listen: mentions` — только при @упоминании
|
||
- `task_listen: all` — получает все события задач проекта
|
||
- `task_listen: assigned` — только свои задачи (assignee/reviewer/watcher) и @mentions
|
||
|
||
**Примеры:**
|
||
- Архитектор: chat=all, task=all
|
||
- Кодер: chat=mentions, task=assigned
|
||
- Тестер: chat=mentions, task=all
|
||
|
||
### Auth Flow
|
||
|
||
```
|
||
1. WebSocket Connect
|
||
2. Client → {"type": "auth", "token": "tb-xxx"}
|
||
3. Server validates token & creates session
|
||
4. Server → {"type": "auth.ok", "data": {...}}
|
||
5. Client → {"type": "project.subscribe", "project_id": "uuid"} (для каждого проекта)
|
||
6. Start heartbeat loop (каждые 30 секунд)
|
||
```
|
||
|
||
### Heartbeat
|
||
|
||
- **Интервал:** Каждые 30 секунд
|
||
- **Timeout:** 90 секунд без heartbeat → `status=offline`
|
||
- **Формат:** `{"type": "heartbeat", "status": "online|busy|idle"}`
|
||
- **Реакция сервера:** Обновление `Member.status`, уведомление `agent.status`
|
||
|
||
---
|
||
|
||
## 6. REST API
|
||
|
||
**Base URL:** `http://localhost:8100/api/v1` (прямой) или `https://dev.team.uix.su/agent-api/api/v1` (через nginx)
|
||
|
||
### Projects
|
||
|
||
| Метод | Путь | Описание | Параметры |
|
||
|-------|------|----------|-----------|
|
||
| GET | `/projects` | Список проектов | — |
|
||
| GET | `/projects/{slug}` | Проект по slug | — |
|
||
| POST | `/projects` | Создать проект | `{name, slug, description?, repo_urls?}` |
|
||
| PATCH | `/projects/{slug}` | Обновить проект | `{name?, description?, repo_urls?, status?}` |
|
||
| DELETE | `/projects/{slug}` | Удалить проект | — |
|
||
|
||
### Tasks
|
||
|
||
| Метод | Путь | Описание | Параметры |
|
||
|-------|------|----------|-----------|
|
||
| GET | `/tasks` | Список задач | `?project_id=X&status=Y&assignee=Z&label=W` |
|
||
| GET | `/tasks/{id}` | Задача по ID | — |
|
||
| POST | `/tasks?project_slug=X` | Создать задачу | `{title, description?, type?, status?, priority?, labels?, parent_id?, assignee_slug?, depends_on?}` |
|
||
| PATCH | `/tasks/{id}` | Обновить задачу | `{title?, description?, type?, status?, priority?, labels?, assignee_slug?, reviewer_slug?, position?}` |
|
||
| DELETE | `/tasks/{id}` | Удалить задачу | — |
|
||
|
||
**Специальные операции с задачами:**
|
||
|
||
| Метод | Путь | Описание | Параметры |
|
||
|-------|------|----------|-----------|
|
||
| POST | `/tasks/{id}/take?slug=X` | Взять задачу (атомарно) | — |
|
||
| POST | `/tasks/{id}/reject` | Отклонить задачу | `{reason}` |
|
||
| POST | `/tasks/{id}/assign` | Назначить задачу | `{assignee_slug}` |
|
||
| POST | `/tasks/{id}/watch?slug=X` | Подписаться на задачу | *(запланировано)* |
|
||
| DELETE | `/tasks/{id}/watch?slug=X` | Отписаться от задачи | *(запланировано)* |
|
||
|
||
### Steps
|
||
|
||
| Метод | Путь | Описание | Параметры |
|
||
|-------|------|----------|-----------|
|
||
| GET | `/tasks/{id}/steps` | Список шагов | — |
|
||
| POST | `/tasks/{id}/steps` | Создать шаг | `{title}` |
|
||
| PATCH | `/tasks/{tid}/steps/{sid}` | Обновить шаг | `{title?, done?}` |
|
||
| DELETE | `/tasks/{tid}/steps/{sid}` | Удалить шаг | — |
|
||
|
||
### Messages (Unified)
|
||
|
||
| Метод | Путь | Описание | Параметры |
|
||
|-------|------|----------|-----------|
|
||
| GET | `/messages` | Список сообщений | `?chat_id=X&task_id=Y&limit=50&offset=0` |
|
||
| POST | `/messages` | Отправить сообщение | `{chat_id?, task_id?, content, author_type?, author_slug?, mentions?}` |
|
||
| GET | `/messages/{id}/replies` | Треды сообщения | — |
|
||
|
||
### Members
|
||
|
||
| Метод | Путь | Описание | Параметры |
|
||
|-------|------|----------|-----------|
|
||
| GET | `/members` | Список участников | — |
|
||
| GET | `/members/{slug}` | Участник по slug | — |
|
||
| POST | `/members` | Создать участника | `{name, slug, type?, agent_config?}` |
|
||
| PATCH | `/members/{slug}` | Обновить участника | `{name?, role?, status?, agent_config?}` |
|
||
| POST | `/members/{slug}/regenerate-token` | Перегенерировать токен | *(запланировано)* |
|
||
| POST | `/members/{slug}/revoke-token` | Отозвать токен | *(запланировано)* |
|
||
|
||
### Attachments *(запланировано)*
|
||
|
||
| Метод | Путь | Описание | Статус |
|
||
|-------|------|----------|--------|
|
||
| POST | `/messages/{id}/attachments` | Загрузить файл | **Запланировано** |
|
||
| GET | `/attachments/{id}` | Скачать файл | **Запланировано** |
|
||
| GET | `/attachments?task_id=X` | Файлы задачи | **Запланировано** |
|
||
|
||
---
|
||
|
||
## 7. Агенты
|
||
|
||
### Концепция
|
||
|
||
- **Один процесс = один агент** (picogent)
|
||
- **Одна сессия на агента** — видит всё: задачи, чат, ответы
|
||
- **Роль = конфигурация** в agent.json
|
||
- **Автономность** — агент сам решает брать задачу или нет
|
||
|
||
### Конфигурация агента (agent.json)
|
||
|
||
```json
|
||
{
|
||
"name": "Кодер",
|
||
"slug": "coder",
|
||
"prompt": "Ты опытный разработчик...",
|
||
"model": "sonnet",
|
||
"capabilities": ["coding", "review"],
|
||
"chat_listen": "mentions",
|
||
"task_listen": "assigned",
|
||
"tracker_url": "http://localhost:8100",
|
||
"token": "tb-agent-xxx"
|
||
}
|
||
```
|
||
|
||
### Режимы прослушивания
|
||
|
||
**Chat Listen:**
|
||
- `all` — получает все сообщения в подписанных проектах
|
||
- `mentions` — только при @упоминании
|
||
- `none` — не получает чат-сообщения
|
||
|
||
**Task Listen:**
|
||
- `all` — получает все события задач в подписанных проектах
|
||
- `assigned` — только задачи где агент assignee/reviewer/watcher
|
||
- `none` — не получает task-события
|
||
|
||
### Capabilities (способности)
|
||
|
||
Массив строк, описывающих что умеет агент:
|
||
- `"coding"` — написание кода
|
||
- `"review"` — ревью кода
|
||
- `"testing"` — тестирование
|
||
- `"documentation"` — документация
|
||
- `"architecture"` — архитектурные решения
|
||
|
||
### Жизненный цикл агента
|
||
|
||
1. **Запуск:** Читает agent.json, подключается к Tracker
|
||
2. **Auth:** Отправляет токен, получает контекст
|
||
3. **Subscribe:** Подписывается на нужные проекты
|
||
4. **Listen:** Получает события по WebSocket
|
||
5. **Action:** Выполняет действия через REST API
|
||
6. **Heartbeat:** Каждые 30 секунд сообщает о статусе
|
||
7. **Disconnect:** При отключении статус → offline
|
||
|
||
### Checkpoint Pattern
|
||
|
||
**Проблема:** LLM блокирующий — агент не может получать события во время обдумывания.
|
||
|
||
**Решение:**
|
||
- Короткие задачи (5-10 минут)
|
||
- Проверка входящих событий между шагами
|
||
- Уведомления о статусе `busy` во время работы
|
||
|
||
### Назначение задач
|
||
|
||
1. Человек назначает вручную
|
||
2. Архитектор создаёт и назначает
|
||
3. Агент сам берёт из `todo` (`take_task` — атомарно)
|
||
4. Label matching: лейблы задачи ∩ capabilities агента
|
||
|
||
### Особенности
|
||
|
||
- Агент может **отклонить** задачу (`reject_task`) с причиной
|
||
- Автообнаружение блокеров (зависимость застряла → пинг в чат) *(запланировано)*
|
||
- Циклические зависимости запрещены *(запланировано)*
|
||
|
||
### Agent Home (запланировано)
|
||
|
||
```
|
||
agents/coder/
|
||
agent.json # конфиг
|
||
prompt.md # само-улучшаемый промпт
|
||
memory/ # per-project память
|
||
workspace/ # рабочие файлы
|
||
sessions/ # сессии (JSONL)
|
||
```
|
||
|
||
### Промпт-архитектура (запланировано)
|
||
|
||
Многослойный промпт:
|
||
1. System Prompt (agent.json) — базовая роль, неизменная
|
||
2. Agent Prompt (prompt.md) — агент сам улучшает
|
||
3. Project Context (docs) — документация
|
||
4. Skills — progressive loading
|
||
5. Tools (MCP) — автоматически
|
||
6. Guidelines — общие правила
|
||
7. Session History
|
||
8. Current Message
|
||
|
||
---
|
||
|
||
## 8. BFF (Backend for Frontend)
|
||
|
||
### Роль BFF
|
||
|
||
- **Прокси** между Web Client и Tracker
|
||
- **Авторизация** пользователей (JWT)
|
||
- **WebSocket прокси** с токен-аутентификацией
|
||
- **Трансформация данных** (при необходимости)
|
||
|
||
### Технологии
|
||
|
||
- Python, FastAPI
|
||
- JWT авторизация
|
||
- HTTP Client (httpx)
|
||
- WebSocket прокси
|
||
|
||
### Конфигурация (environment)
|
||
|
||
```bash
|
||
# Tracker
|
||
TRACKER_URL=http://localhost:8100
|
||
TRACKER_WS_URL=ws://localhost:8100/ws
|
||
TRACKER_TOKEN=tb-admin-xxx
|
||
|
||
# Auth
|
||
JWT_SECRET=secret-key
|
||
AUTH_USER=admin
|
||
AUTH_PASS=password
|
||
|
||
# Server
|
||
BFF_HOST=0.0.0.0
|
||
BFF_PORT=8200
|
||
```
|
||
|
||
### WebSocket прокси
|
||
|
||
1. **Client подключение:** `wss://dev.team.uix.su/ws?token={jwt}`
|
||
2. **Валидация JWT:** Проверка токена, извлечение user
|
||
3. **Tracker подключение:** `ws://localhost:8100/ws` с TRACKER_TOKEN
|
||
4. **Двусторонний relay:** Client ↔ BFF ↔ Tracker
|
||
|
||
### REST прокси
|
||
|
||
Все API запросы проксируются с добавлением:
|
||
- **Авторизация:** Проверка JWT
|
||
- **Трансформация:** Добавление `author_slug` в сообщения
|
||
- **Логирование:** Запросы и ответы
|
||
- **CORS:** Для фронтенда
|
||
|
||
---
|
||
|
||
## 9. Фронтенд (Web Client)
|
||
|
||
### Технологии
|
||
|
||
- **Framework:** Next.js 15 (App Router)
|
||
- **Styling:** Tailwind CSS
|
||
- **State:** React hooks (useState, useEffect)
|
||
- **HTTP:** fetch API
|
||
- **WebSocket:** Native WebSocket API
|
||
|
||
### Структура страниц
|
||
|
||
- `/login` — Авторизация
|
||
- `/` — Список проектов
|
||
- `/projects/[slug]` — Канбан доска проекта
|
||
- `/projects/[slug]/settings` — Настройки проекта *(запланировано)*
|
||
- `/agents` — Управление агентами *(запланировано)*
|
||
|
||
### Компоненты
|
||
|
||
| Компонент | Описание | Статус |
|
||
|-----------|----------|--------|
|
||
| `KanbanBoard` | Drag & drop доска + mobile tabs | ✅ Реализован |
|
||
| `TaskModal` | Модалка задачи (title, description, assignee, delete) | ✅ Базовая версия |
|
||
| `ChatPanel` | Чат (lobby) | ✅ Базовая версия |
|
||
| `CreateTaskModal` | Создание задачи | ✅ Реализован |
|
||
| `CreateProjectModal` | Создание проекта | ✅ Реализован |
|
||
| `AuthGuard` | Проверка авторизации | ✅ Реализован |
|
||
|
||
### Запланированные компоненты
|
||
|
||
| Компонент | Описание | Статус |
|
||
|-----------|----------|--------|
|
||
| Task comments в TaskModal | Комментарии к задаче | **Запланировано** |
|
||
| Task steps в TaskModal | Live progress агента | **Запланировано** |
|
||
| Agent management page | Создание, настройки агентов | **Запланировано** |
|
||
| Project dashboard | Метрики и активность | **Запланировано** |
|
||
| Project settings | Настройки проекта | **Запланировано** |
|
||
|
||
### API клиент (api.ts)
|
||
|
||
- **Base URL:** `process.env.NEXT_PUBLIC_API_URL`
|
||
- **Авторизация:** JWT из localStorage
|
||
- **Обработка ошибок:** 401 → редирект на /login
|
||
- **TypeScript типы** для всех моделей
|
||
|
||
### WebSocket клиент (ws.ts)
|
||
|
||
```typescript
|
||
class WSClient {
|
||
// Подключение через BFF с JWT токеном
|
||
connect() // ws://bff/ws?token=jwt
|
||
|
||
// Event handlers
|
||
on(type: string, handler: Function)
|
||
|
||
// Convenience methods
|
||
subscribeProject(projectId: string)
|
||
sendChat(chatId: string, content: string)
|
||
sendTaskComment(taskId: string, content: string)
|
||
heartbeat(status: string)
|
||
}
|
||
```
|
||
|
||
### Состояние приложения
|
||
|
||
- **Авторизация:** JWT в localStorage
|
||
- **Проекты:** Загружаются при входе в систему
|
||
- **Задачи:** Загружаются для каждого проекта
|
||
- **WebSocket:** Глобальный клиент, подписка по проектам
|
||
- **Real-time:** Обновления через WebSocket события
|
||
|
||
---
|
||
|
||
## 10. Деплой
|
||
|
||
### Docker Compose (разработка)
|
||
|
||
```yaml
|
||
services:
|
||
tracker:
|
||
build: ./tracker
|
||
ports: ["8100:8100"]
|
||
depends_on: [postgres, redis]
|
||
|
||
postgres:
|
||
image: postgres:16-alpine
|
||
ports: ["5433:5432"]
|
||
|
||
redis:
|
||
image: redis:7-alpine
|
||
ports: ["6380:6379"]
|
||
```
|
||
|
||
### Systemd сервисы (продакшен)
|
||
|
||
**Tracker:** Docker Compose + systemd unit
|
||
**BFF + Web Client:** systemd сервисы на хосте
|
||
**Picogent:** systemd unit на агента
|
||
|
||
### 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";
|
||
}
|
||
```
|
||
|
||
### SSL/HTTPS
|
||
|
||
- **Dev:** `dev.team.uix.su` (действующий)
|
||
- **Prod:** `team.uix.su` (placeholder)
|
||
- **Cертификаты:** Let's Encrypt через certbot
|
||
|
||
### База данных
|
||
|
||
- **Разработка:** PostgreSQL в Docker
|
||
- **Продакшен:** PostgreSQL на хосте
|
||
- **Миграции:** Нет (recreate from scratch) *(планируется Alembic)*
|
||
- **Бэкапы:** pg_dump *(запланировано)*
|
||
|
||
### Процесс деплоя
|
||
|
||
1. **Git push** → git.uix.su/team-board/docs
|
||
2. **Manual deploy** на сервере
|
||
3. **Restart services:** systemctl restart team-board-*
|
||
4. **Health check:** /health endpoints *(запланировано)*
|
||
|
||
**CI/CD:** Пока ручной деплой. В будущем — Gitea Actions.
|
||
|
||
---
|
||
|
||
## 11. Ключевые решения
|
||
|
||
### Архитектурные решения из brainstorm-ов
|
||
|
||
#### Unified Message Model
|
||
**Решение:** Одна модель `Message` для чат-сообщений И комментариев к задачам.
|
||
**Обоснование:** Проще API, единый компонент UI, треды работают везде.
|
||
**Статус:** Принято в BRAINSTORM-UI-2026-02-22.
|
||
|
||
#### Tracker-Centric Architecture
|
||
**Решение:** Tracker — центральный хаб, всё остальное — клиенты.
|
||
**Обоснование:** Простота, масштабируемость, единая точка правды.
|
||
**Статус:** Принято в ARCHITECTURE.md.
|
||
|
||
#### WebSocket для событий, REST для мутаций
|
||
**Решение:** Разделение протоколов — WS только для push-событий.
|
||
**Обоснование:** Агенты через MCP tools, WebSocket не перегружен.
|
||
**Статус:** Принято в BRAINSTORM-PROTOCOL-2026-02-20.
|
||
|
||
#### Раздельные Listen Modes
|
||
**Решение:** `chat_listen` и `task_listen` — независимо.
|
||
**Обоснование:** Гибкая настройка подписок для разных ролей агентов.
|
||
**Статус:** Принято в BRAINSTORM-WS-V2-2026-02-22.
|
||
|
||
#### Подзадачи vs Этапы (Steps)
|
||
**Решение:** Подзадачи = задачи на канбане, этапы = чеклист внутри.
|
||
**Обоснование:** Не засорять канбан, но показывать прогресс агента.
|
||
**Статус:** Принято в BRAINSTORM-PROJECTS-2026-02-20.
|
||
|
||
#### Checkpoint Pattern для агентов
|
||
**Решение:** Короткие задачи + проверка событий между шагами.
|
||
**Обоснование:** LLM блокирующий, нужно решать "глухой агент".
|
||
**Статус:** Принято в BRAINSTORM-AGENTS-2026-02-20.
|
||
|
||
#### Агенты могут отклонять задачи
|
||
**Решение:** `reject_task` с обоснованием.
|
||
**Обоснование:** Агент не безмолвный исполнитель, может не согласиться.
|
||
**Статус:** Принято в BRAINSTORM-TASKS-2026-02-20.
|
||
|
||
#### Multi-repo проекты
|
||
**Решение:** `repo_urls: string[]` — массив репозиториев.
|
||
**Обоснование:** Современные проекты = frontend + backend + docs.
|
||
**Статус:** Принято в BRAINSTORM-PROJECTS-2026-02-20.
|
||
|
||
#### Файлы как Attachments
|
||
**Решение:** Отдельного файлового сервиса нет, файлы = вложения к сообщениям.
|
||
**Обоснование:** Простота, единая модель для чата и задач.
|
||
**Статус:** Принято в разговоре 2026-02-22, противоречило ранним документам.
|
||
|
||
### Отклонённые решения
|
||
|
||
#### Redis Streams для Event Bus
|
||
**Решение:** НЕ реализовывать сейчас.
|
||
**Обоснование:** В BRAINSTORM-MICROSERVICES было принято, но хозяин сомневается. Пока WS достаточно.
|
||
**Статус:** Отклонено, оставлено как "идея на будущее".
|
||
|
||
#### HTTP Callback для агентов
|
||
**Решение:** Только WebSocket для агентов.
|
||
**Обоснование:** Усложняет архитектуру, нет реальной потребности.
|
||
**Статус:** Отклонено из WS-PROTOCOL.md.
|
||
|
||
#### Threads в комментариях задач
|
||
**Решение:** Threads только в чатах, в задачах — простая лента.
|
||
**Обоснование:** В задачах контекст и так понятен, треды избыточны.
|
||
**Статус:** Принято в BRAINSTORM-UI-2026-02-22.
|
||
|
||
#### Глобальные vs Per-project лейблы
|
||
**Статус:** Остается открытым вопросом.
|
||
|
||
#### Реакции в чатах
|
||
**Статус:** Остается открытым вопросом (токен burn vs UX).
|
||
|
||
### На будущее (запланированы)
|
||
|
||
#### Web MCP Server
|
||
**Описание:** Отдельный MCP Server для работы любого LLM-клиента с трекером.
|
||
**Статус:** Идея из BRAINSTORM-PROTOCOL-2026-02-20.
|
||
|
||
#### Session Compaction
|
||
**Описание:** Сжатие длинной истории сессии агента в summary.
|
||
**Статус:** Детали в AGENT-CONNECTION-RESEARCH.md.
|
||
|
||
#### Telegram Bridge
|
||
**Описание:** Бот дублирует сообщения project chats в Telegram с топиками.
|
||
**Статус:** MVP описан в BRAINSTORM-MISC-2026-02-21.
|
||
|
||
#### OAuth/Authentik интеграция
|
||
**Описание:** Мультипользовательский режим с SSO.
|
||
**Статус:** Упоминается в архитектуре.
|
||
|
||
#### Agent Home с self-improving промптами
|
||
**Описание:** Агент сам улучшает свой промпт на основе опыта.
|
||
**Статус:** Детали в BRAINSTORM-PROMPTS-2026-02-21.
|
||
|
||
---
|
||
|
||
## Нереализованные части
|
||
|
||
### Backend (запланировано)
|
||
|
||
- ❌ **Task events через WebSocket** — task.created/updated/assigned
|
||
- ❌ **Agent token auth для REST API** (только WS имеет проверку токенов)
|
||
- ❌ **Attachments API** — загрузка/скачивание файлов
|
||
- ❌ **Task dependencies** — валидация и уведомления о разблокировке
|
||
- ❌ **Watchers на задачах** — подписка на уведомления
|
||
- ❌ **Task watchers API** — POST/DELETE /tasks/{id}/watch
|
||
|
||
### Frontend (запланировано)
|
||
|
||
- ❌ **Task comments в TaskModal** — комментарии к задачам
|
||
- ❌ **Task steps в TaskModal** — live progress агентов
|
||
- ❌ **Agent management страница** — /agents с созданием и настройками
|
||
- ❌ **Project dashboard** — метрики и активность
|
||
- ❌ **Project settings** — настройки проекта
|
||
- ❌ **Mobile UI оптимизация** — полная адаптация под телефоны
|
||
|
||
### Infrastructure (запланировано)
|
||
|
||
- ❌ **Health check endpoints** — /health для мониторинга
|
||
- ❌ **Database migrations** — Alembic вместо recreate
|
||
- ❌ **CI/CD pipeline** — Gitea Actions автодеплой
|
||
- ❌ **Monitoring/metrics** — Grafana dashboard
|
||
- ❌ **Backup strategy** — автоматические бэкапы БД
|
||
|
||
### Agent System (запланировано)
|
||
|
||
- ❌ **MCP Tools полный набор** — для picogent агентов
|
||
- ❌ **Session resume** — восстановление контекста при переподключении
|
||
- ❌ **Agent home directory** — workspace, memory, sessions
|
||
- ❌ **Multi-instance агентов** — scaling одной роли
|
||
- ❌ **Self-improving промпты** — agent.prompt.md обновляется агентом
|
||
|
||
---
|
||
|
||
## Заключение
|
||
|
||
Этот документ v2.0 создан на основе полного анализа всех 24 файлов документации Team Board по состоянию на 2026-02-23. Он объединяет все принятые решения из brainstorm-ов, архитектурные концепции и текущее состояние реализации в единую точку правды.
|
||
|
||
**Принцип документа:** Описываем решения и концепции, а не текущее состояние кода. Если что-то запланировано но не реализовано — помечено как "Запланировано", а не TODO.
|
||
|
||
При расхождении между документацией и кодом — **приоритет у кода** (он правдивее), документ нужно обновить. |