773 lines
32 KiB
Markdown
773 lines
32 KiB
Markdown
# 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. Является единой точкой правды для всех концепций системы.* |