# Team Board — Концепции системы (Source of Truth) **Версия:** 1.0 **Дата:** 2026-02-23 **Статус:** Единая точка правды по всем концепциям Team Board --- ## 1. Архитектура ### 1.1 Общая схема ``` ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │ Web Client │────▶│ BFF │────▶│ Tracker │ │ (Next.js) │ │ (FastAPI) │ │ (FastAPI) │ └─────────────┘ └──────────────┘ └──────┬───────┘ │ ┌────────────────────────────────────────┤ │ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌──▼───┐ │Picogent │ │Picogent │ │Telegram │ │ DB │ │ Кодер │ │Архитект │ │ Bridge │ │ Pg │ └─────────┘ └─────────┘ └─────────┘ └──────┘ ``` ### 1.2 Компоненты и порты | Компонент | Технологии | Порт | Доступность | Описание | |-----------|------------|------|-------------|----------| | **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-агент процесс | ### 1.3 Протоколы взаимодействия - **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 --- ## 2. Модели данных ### 2.1 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 ``` ### 2.2 AgentConfig (Конфигурация агентов) ```python AgentConfig: id: UUID (PK) member_id: UUID (FK → Member, UNIQUE) capabilities: str[] # ["coding", "review", "testing"] chat_listen: str # "all" | "mentions" task_listen: str # "all" | "mentions" prompt: str? # Системный промпт model: str? # LLM модель ``` ### 2.3 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 ``` ### 2.4 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 ``` **Связи:** - Task.project → Project (многие к одному) - Task.parent → Task (самоссылка для подзадач) - Task.subtasks ← Task (обратная связь) ### 2.5 Step (Шаги задачи) ```python Step: id: UUID (PK) task_id: UUID (FK → Task) title: str # Описание шага done: bool # Выполнен ли position: int # Порядок в списке created_at: timestamp updated_at: timestamp ``` ### 2.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** — чат проекта (один на проект) ### 2.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? # URL голосового сообщения created_at: timestamp updated_at: timestamp ``` **Ограничения:** Ровно одно из `chat_id` или `task_id` должно быть заполнено. ### 2.8 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 ``` --- ## 3. Авторизация ### 3.1 Типы авторизации | Тип участника | Метод авторизации | Описание | |---------------|-------------------|----------| | **human (Web UI)** | JWT Token | Логин/пароль → JWT | | **human (MCP Client)** | JWT Token | Логин/пароль → JWT (будущее) | | **agent** | Bearer Token | Статический токен в agent.json | | **bridge** | Bearer Token | Статический токен для мостов | ### 3.2 JWT Tokens (для людей) - **Секрет:** `JWT_SECRET` (environment variable) - **Алгоритм:** HS256 - **Payload:** `{"sub": member_id, "name": member_name, "exp": timestamp}` - **Срок действия:** 30 дней (настраивается) ### 3.3 Agent Tokens - **Формат:** `tb-` + random string (32 символа) - **Хранение:** `Member.token` (уникальное поле) - **Генерация:** При создании агента через UI - **Отзыв:** Через API `POST /api/v1/members/{slug}/revoke-token` ### 3.4 Роли и права | Роль | Описание | Права | |------|----------|-------| | `owner` | Владелец инстанса | Все права | | `member` | Обычный участник | `send_messages`, `create_tasks`, `update_tasks` | | `observer` | Наблюдатель | Только чтение | | `bridge` | Мост в другую систему | `send_messages` | ### 3.5 Процесс авторизации **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} (TODO: не реализовано) --- ## 4. WebSocket Protocol ### 4.1 Подключение **URL:** `ws://localhost:8100/ws` (прямое) или `wss://dev.team.uix.su/agent-ws` (через nginx) ### 4.2 Сообщения: Клиент → Сервер | Тип | Формат | Описание | |-----|--------|----------| | `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"}` | Подтверждение получения | ### 4.3 Сообщения: Сервер → Клиент | Тип | Описание | Данные | |-----|----------|--------| | `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}` (TODO: не реализовано) | | `task.updated` | Обновлена задача | `{...TaskData}` (TODO: не реализовано) | | `task.assigned` | Задача назначена | `{...TaskData}` (TODO: не реализовано) | ### 4.4 Фильтрация событий События фильтруются на сервере по настройкам агента: **message.new:** - `chat_listen: "all"` — все сообщения в подписанных проектах - `chat_listen: "mentions"` — только сообщения с @упоминанием **task.* (будущее):** - `task_listen: "all"` — все события задач в подписанных проектах - `task_listen: "mentions"` — только задачи где агент assignee/reviewer/watcher ### 4.5 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 секунд) ``` ### 4.6 Heartbeat - **Интервал:** Каждые 30 секунд - **Timeout:** 90 секунд без heartbeat → `status=offline` - **Формат:** `{"type": "heartbeat", "status": "online|busy|idle"}` - **Реакция сервера:** Обновление `Member.status`, уведомление `agent.status` --- ## 5. REST API **Base URL:** `http://localhost:8100/api/v1` (прямой) или `https://dev.team.uix.su/agent-api/api/v1` (через nginx) ### 5.1 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}` | Удалить проект | — | ### 5.2 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` | Отписаться от задачи | — | ### 5.3 Steps | Метод | Путь | Описание | Параметры | |-------|------|----------|-----------| | GET | `/tasks/{id}/steps` | Список шагов | — | | POST | `/tasks/{id}/steps` | Создать шаг | `{title}` | | PATCH | `/tasks/{tid}/steps/{sid}` | Обновить шаг | `{title?, done?}` | | DELETE | `/tasks/{tid}/steps/{sid}` | Удалить шаг | — | ### 5.4 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` | Треды сообщения | — | ### 5.5 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` | Отозвать токен | — | ### 5.6 Attachments (TODO) | Метод | Путь | Описание | Статус | |-------|------|----------|--------| | POST | `/messages/{id}/attachments` | Загрузить файл | **TODO** | | GET | `/attachments/{id}` | Скачать файл | **TODO** | | GET | `/attachments?task_id=X` | Файлы задачи | **TODO** | --- ## 6. Агенты ### 6.1 Концепция - **Один процесс = один агент** (picogent) - **Одна сессия на агента** — видит всё: задачи, чат, ответы - **Роль = конфигурация** в agent.json ### 6.2 Конфигурация агента (agent.json) ```json { "name": "Кодер", "slug": "coder", "prompt": "Ты опытный разработчик...", "model": "sonnet", "capabilities": ["coding", "review"], "chat_listen": "mentions", "task_listen": "mentions", "tracker_url": "http://localhost:8100", "token": "tb-agent-xxx" } ``` ### 6.3 Режимы прослушивания **Chat Listen:** - `all` — получает все сообщения в подписанных проектах - `mentions` — только при @упоминании **Task Listen:** - `all` — получает все события задач в подписанных проектах - `mentions` — только задачи где агент assignee/reviewer/watcher ### 6.4 Capabilities (способности) Массив строк, описывающих что умеет агент: - `"coding"` — написание кода - `"review"` — ревью кода - `"testing"` — тестирование - `"documentation"` — документация - `"architecture"` — архитектурные решения ### 6.5 Жизненный цикл агента 1. **Запуск:** Читает agent.json, подключается к Tracker 2. **Auth:** Отправляет токен, получает контекст 3. **Subscribe:** Подписывается на нужные проекты 4. **Listen:** Получает события по WebSocket 5. **Action:** Выполняет действия через REST API 6. **Heartbeat:** Каждые 30 секунд сообщает о статусе 7. **Disconnect:** При отключении статус → offline ### 6.6 Checkpoint Pattern **Проблема:** LLM блокирующий — агент не может получать события во время обдумывания. **Решение:** - Короткие задачи (5-10 минут) - Проверка входящих событий между шагами - Уведомления о статусе `busy` во время работы --- ## 7. BFF (Backend for Frontend) ### 7.1 Роль BFF - **Прокси** между Web Client и Tracker - **Авторизация** пользователей (JWT) - **WebSocket прокси** с токен-аутентификацией - **Трансформация данных** (при необходимости) ### 7.2 Технологии - Python, FastAPI - JWT авторизация - HTTP Client (httpx) - WebSocket прокси ### 7.3 Конфигурация (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 ``` ### 7.4 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 ### 7.5 REST прокси Все API запросы проксируются с добавлением: - **Авторизация:** Проверка JWT - **Трансформация:** Добавление `author_slug` в сообщения - **Логирование:** Запросы и ответы - **CORS:** Для фронтенда --- ## 8. Фронтенд (Web Client) ### 8.1 Технологии - **Framework:** Next.js 15 (App Router) - **Styling:** Tailwind CSS - **State:** React hooks (useState, useEffect) - **HTTP:** fetch API - **WebSocket:** Native WebSocket API ### 8.2 Структура страниц - `/login` — Авторизация - `/` — Список проектов - `/projects/[slug]` — Канбан доска проекта - `/projects/[slug]/settings` — Настройки проекта (TODO) - `/agents` — Управление агентами (TODO) ### 8.3 Компоненты | Компонент | Описание | Статус | |-----------|----------|--------| | `KanbanBoard` | Drag & drop доска + mobile tabs | ✅ Реализован | | `TaskModal` | Модалка задачи (title, description, assignee, delete) | ✅ Базовая версия | | `ChatPanel` | Чат (lobby) | ✅ Базовая версия | | `CreateTaskModal` | Создание задачи | ✅ Реализован | | `CreateProjectModal` | Создание проекта | ✅ Реализован | | `AuthGuard` | Проверка авторизации | ✅ Реализован | ### 8.4 API клиент (api.ts) - **Base URL:** `process.env.NEXT_PUBLIC_API_URL` - **Авторизация:** JWT из localStorage - **Обработка ошибок:** 401 → редирект на /login - **TypeScript типы** для всех моделей ### 8.5 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) } ``` ### 8.6 Состояние приложения - **Авторизация:** JWT в localStorage - **Проекты:** Загружаются при входе в систему - **Задачи:** Загружаются для каждого проекта - **WebSocket:** Глобальный клиент, подписка по проектам - **Real-time:** Обновления через WebSocket события --- ## 9. Деплой ### 9.1 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"] ``` ### 9.2 Systemd сервисы (продакшен) **Tracker:** Docker Compose + systemd unit **BFF + Web Client:** systemd сервисы на хосте **Picogent:** systemd unit на агента ### 9.3 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"; } ``` ### 9.4 SSL/HTTPS - **Dev:** `dev.team.uix.su` (действующий) - **Prod:** `team.uix.su` (placeholder) - **Cертификаты:** Let's Encrypt через certbot ### 9.5 База данных - **Разработка:** PostgreSQL в Docker - **Продакшен:** PostgreSQL на хосте - **Миграции:** Нет (recreate from scratch) - **Бэкапы:** pg_dump (TODO) ### 9.6 Процесс деплоя 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. --- ## 10. Нереализованные части (TODO) ### 10.1 Backend TODO - ❌ **Attachments API** — загрузка/скачивание файлов - ❌ **Task events** через WebSocket — task.created/updated/assigned - ❌ **Agent token auth** для REST API (только WS) - ❌ **Chat threads** — parent_id поддержка в UI - ❌ **Task dependencies** — визуализация и валидация - ❌ **БД миграции** — пока только recreate ### 10.2 Frontend TODO - ❌ **Task comments** в TaskModal - ❌ **Task steps** (live progress) в TaskModal - ❌ **Task watchers** — подписка/отписка - ❌ **Agent management** — страница /agents - ❌ **Project dashboard** — метрики и активность - ❌ **Mobile UI** — адаптация под телефоны ### 10.3 Agent TODO - ❌ **MCP Tools** — полный набор инструментов для picogent - ❌ **Session resume** — восстановление контекста при переподключении - ❌ **Multi-instance** — несколько экземпляров одного агента - ❌ **Agent home** — workspace, memory, sessions ### 10.4 Infrastructure TODO - ❌ **Telegram Bridge** — дублирование чата в Telegram - ❌ **OAuth/Authentik** — мультипользовательский режим - ❌ **Redis integration** — event bus и кеширование - ❌ **CI/CD pipeline** — автоматический деплой - ❌ **Monitoring** — метрики и логи - ❌ **Backup strategy** — регулярные бэкапы БД --- ## Заключение Этот документ является единой точкой правды для всех концепций Team Board. Он основан на реальном коде и документации по состоянию на 2026-02-23. **Версионирование:** При значимых изменениях в архитектуре или API обновляется версия документа и дата. **Обратная связь:** Если код не соответствует документу — приоритет у кода (он правдивее), документ нужно обновить.