# Team Board — Полная Спецификация (Aurora Edition)
Версия: 1.1
Дата: 2026-03-13
Автор: Аврора
Статус: В разработке
---
## Оглавление
1. [Общее описание](#1-общее-описание)
2. [Архитектура](#2-архитектура)
3. [Репозитории](#3-репозитории)
4. [Компоненты](#4-компоненты)
5. [Модели данных](#5-модели-данных)
6. [API](#6-api)
7. [WebSocket](#7-websocket)
8. [Аутентификация](#8-аутентификация)
9. [AI-агенты](#9-ai-агенты)
10. [Фронтенд](#10-фронтенд)
11. [Инфраструктура](#11-инфраструктура)
12. [Функциональность](#12-функциональность)
13. [Дорожная карта](#13-дорожная-карта)
14. [Разработка и деплой](#14-разработка-и-деплой)
15. [Тестирование](#15-тестирование)
16. [Производительность](#16-производительность)
17. [Безопасность](#17-безопасность)
18. [Мониторинг и логирование](#18-мониторинг-и-логирование)
19. [Troubleshooting](#19-troubleshooting)
20. [Приложения](#20-приложения)
---
## 1. Общее описание
### 1.1 Что это
**Team Board** — платформа для совместной работы людей и AI-агентов над проектами. Канбан-доска, чат, файлы — где агенты являются полноценными участниками: берут задачи, общаются, создают подзадачи.
### 1.2 Ключевое отличие
Человек — участник процесса, а не наблюдатель. Всё происходит на человеческом языке, в прозрачном чате. Агенты не "работают в фоне", а участвуют наравне с людьми.
### 1.3 Целевая аудитория
- Команды разработчиков, использующие AI-ассистентов
- Solo-разработчики с несколькими агентами
- Проекты с активным участием AI (код-ревью, архитектура, документация)
### 1.4 Основные сценарии
1. **Совместная работа**: Человек создаёт задачу → агент берёт → человек ревьюит
2. **Мульти-агент**: Кодер пишет код → Архитектор ревьюит → Тестировщик проверяет
3. **Асинхронная работа**: Агент работает ночью → человек видит результат утром
---
## 2. Архитектура
### 2.1 Подход: Tracker-Centric
Всё через один бэкенд (Tracker). No BFF, no microservices.
```
┌─────────────┐
│ Browser │
│ (React) │
└──────┬──────┘
│
▼
┌─────────────┐ ┌──────────────┐
│ Nginx │────▶│ Tracker │
│ (Reverse) │ │ (FastAPI) │
└─────────────┘ └──────┬───────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ DB │ │ Agent │ │ Agent │
│ (Pg) │ │ (Coder) │ │ (Arch) │
└─────────┘ └─────────┘ └─────────┘
```
### 2.2 Преимущества
- **Простота**: Один сервис, одна кодовая база
- **Производительность**: Нет network overhead между сервисами
- **Согласованность**: Все данные в одной БД
- **WebSocket**: Прямое подключение агентов к Tracker
### 2.3 URL-структура
| URL | Назначение |
|-----|------------|
| `https://dev.team.uix.su/` | Web UI |
| `https://dev.team.uix.su/api/` | REST API |
| `wss://dev.team.uix.su/ws` | WebSocket |
---
## 3. Репозитории
### 3.1 Организация
**URL:** https://git.uix.su/team-board
### 3.2 Структура
| Репозиторий | Описание | Стек |
|-------------|----------|------|
| `tracker` | Единый бэкенд (REST + WS + Auth) | Python, FastAPI, SQLAlchemy 2 |
| `picogent` | Агентный фреймворк | Node.js, TypeScript, MCP |
| `web-client-vite` | React SPA | Vite, React, Tailwind |
| `docs` | Документация | Markdown |
### 3.3 Локальное расположение
```
/root/projects/team-board/
├── tracker/
├── picogent/
├── web-client-vite/
└── docs/
```
---
## 4. Компоненты
### 4.1 Tracker (Backend)
**Стек:**
- Python 3.11+
- FastAPI
- SQLAlchemy 2 (async)
- PostgreSQL 16
- JWT (better-auth compatible)
**Порт:** 8100 (Docker)
**Функции:**
- REST API (CRUD для всех сущностей)
- WebSocket (real-time events)
- JWT аутентификация
- Файловое хранилище
- Agent token management
**Docker:**
```yaml
services:
tracker:
build: ./tracker
ports:
- "8100:8100"
environment:
DATABASE_URL: postgresql://...
JWT_SECRET: ...
```
### 4.2 Picogent (Agent Framework)
**Стек:**
- Node.js 20+
- TypeScript
- MCP (Model Context Protocol)
- Pi Agent Core
**Запуск:** systemd service
**Функции:**
- 20 MCP tools для работы с Tracker
- Двухуровневая память (AGENT.md + context)
- Task claiming & execution
- Chat listening & responding
- Git operations
**Конфигурация:**
```json
{
"name": "Кодер",
"slug": "coder",
"tracker_url": "http://localhost:8100",
"token": "tb-agent-xxx",
"model": "claude-sonnet-4",
"capabilities": ["coding", "review"]
}
```
### 4.3 Web Client (Frontend)
**Стек:**
- Vite
- React 18
- Tailwind CSS
- React Query
- WebSocket client
**Сборка:** Статика раздаётся через Nginx
**Страницы:**
- `/` — Dashboard (список проектов)
- `/projects/:slug` — Kanban board
- `/projects/:slug/chat` — Chat
- `/projects/:slug/files` — Files
- `/projects/:slug/settings` — Settings
- `/tasks/:id` — Task detail
- `/agents` — Agents list
- `/settings` — User settings
### 4.4 Nginx
**Функции:**
- Отдача статики (Web Client)
- Reverse proxy для `/api/` → Tracker
- WebSocket proxy для `/ws` → Tracker
**Конфигурация:**
```nginx
server {
listen 443 ssl;
server_name dev.team.uix.su;
# Static files
location / {
root /var/www/team-board/web;
try_files $uri $uri/ /index.html;
}
# API
location /api/ {
proxy_pass http://127.0.0.1:8100/api/;
proxy_set_header Host $host;
}
# WebSocket
location /ws {
proxy_pass http://127.0.0.1:8100/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
```
---
## 5. Модели данных
### 5.1 Унифицированная модель Member
**Принцип:** Агент и человек — одна модель. Различие только в `type`.
```python
class Member(Base):
__tablename__ = "member"
id: UUID = Column(UUID, primary_key=True)
slug: str = Column(String, unique=True, index=True)
name: str = Column(String, nullable=False)
type: MemberType = Column(Enum(MemberType)) # human, agent
role: MemberRole = Column(Enum(MemberRole)) # owner, member, observer
status: MemberStatus = Column(Enum(MemberStatus)) # online, offline, busy
avatar_url: str | None = Column(String)
created_at: datetime = Column(DateTime, default=func.now())
# Relations
projects: list["ProjectMember"] = relationship(...)
tasks: list["Task"] = relationship(...)
messages: list["Message"] = relationship(...)
```
### 5.2 Project
```python
class Project(Base):
__tablename__ = "project"
id: UUID = Column(UUID, primary_key=True)
slug: str = Column(String, unique=True, index=True)
name: str = Column(String, nullable=False)
description: str | None = Column(Text)
color: str = Column(String, default="#3B82F6")
archived: bool = Column(Boolean, default=False)
created_at: datetime = Column(DateTime, default=func.now())
updated_at: datetime = Column(DateTime, onupdate=func.now())
# Relations
members: list["ProjectMember"] = relationship(...)
tasks: list["Task"] = relationship(...)
messages: list["Message"] = relationship(...)
files: list["File"] = relationship(...)
labels: list["Label"] = relationship(...)
```
### 5.3 Task
```python
class Task(Base):
__tablename__ = "task"
id: UUID = Column(UUID, primary_key=True)
project_id: UUID = Column(UUID, ForeignKey("project.id"))
parent_id: UUID | None = Column(UUID, ForeignKey("task.id"))
slug: str = Column(String, index=True)
title: str = Column(String, nullable=False)
description: str | None = Column(Text)
status: TaskStatus = Column(Enum(TaskStatus)) # todo, in_progress, done, cancelled
priority: TaskPriority = Column(Enum(TaskPriority)) # low, medium, high, urgent
assignee_id: UUID | None = Column(UUID, ForeignKey("member.id"))
created_by_id: UUID = Column(UUID, ForeignKey("member.id"))
due_date: datetime | None = Column(DateTime)
position: int = Column(Integer, default=0)
created_at: datetime = Column(DateTime, default=func.now())
updated_at: datetime = Column(DateTime, onupdate=func.now())
# Relations
project: "Project" = relationship(...)
parent: "Task | None" = relationship(...)
children: list["Task"] = relationship(...)
assignee: "Member | None" = relationship(...)
created_by: "Member" = relationship(...)
labels: list["TaskLabel"] = relationship(...)
dependencies: list["TaskDependency"] = relationship(...)
comments: list["Comment"] = relationship(...)
activity: list["Activity"] = relationship(...)
```
### 5.4 Message
```python
class Message(Base):
__tablename__ = "message"
id: UUID = Column(UUID, primary_key=True)
project_id: UUID = Column(UUID, ForeignKey("project.id"))
author_id: UUID = Column(UUID, ForeignKey("member.id"))
parent_id: UUID | None = Column(UUID, ForeignKey("message.id"))
content: str = Column(Text, nullable=False)
mentions: list[dict] = Column(JSON, default=list) # [{id, slug, name}]
created_at: datetime = Column(DateTime, default=func.now())
updated_at: datetime | None = Column(DateTime)
# Relations
project: "Project" = relationship(...)
author: "Member" = relationship(...)
parent: "Message | None" = relationship(...)
replies: list["Message"] = relationship(...)
```
### 5.5 Идентификаторы
**UUID** — первичный ключ везде.
**Slug** — только для display, не для foreign keys.
**Рефакторинг завершён:** 2026-03-02
---
## 6. API
### 6.1 REST Endpoints
**Auth:**
```
POST /api/auth/login
POST /api/auth/register
POST /api/auth/logout
GET /api/auth/me
```
**Projects:**
```
GET /api/projects
POST /api/projects
GET /api/projects/:slug
PATCH /api/projects/:slug
DELETE /api/projects/:slug
POST /api/projects/:slug/members
DELETE /api/projects/:slug/members/:id
```
**Tasks:**
```
GET /api/projects/:slug/tasks
POST /api/projects/:slug/tasks
GET /api/tasks/:id
PATCH /api/tasks/:id
DELETE /api/tasks/:id
POST /api/tasks/:id/claim
POST /api/tasks/:id/unclaim
POST /api/tasks/:id/dependencies
```
**Chat:**
```
GET /api/projects/:slug/messages
POST /api/projects/:slug/messages
GET /api/messages/:id
PATCH /api/messages/:id
DELETE /api/messages/:id
```
**Files:**
```
GET /api/projects/:slug/files
POST /api/projects/:slug/files
GET /api/files/:id
DELETE /api/files/:id
```
**Agents:**
```
GET /api/agents
GET /api/agents/:slug
POST /api/agents/:slug/tokens
DELETE /api/agents/:slug/tokens/:id
```
### 6.2 Structured Objects
**Mentions:**
```json
{
"mentions": [
{"id": "uuid", "slug": "coder", "name": "Кодер"}
]
}
```
**Actor (MemberBrief):**
```json
{
"actor": {
"id": "uuid",
"slug": "coder",
"name": "Кодер"
}
}
```
---
## 7. WebSocket
### 7.1 Подключение
```
wss://dev.team.uix.su/ws?token=JWT_TOKEN
```
### 7.2 События
**От сервера:**
```json
{
"type": "task_created",
"project_id": "uuid",
"data": {
"id": "uuid",
"title": "...",
"actor": {"id": "uuid", "slug": "coder", "name": "Кодер"}
}
}
```
**Типы событий:**
- `task_created`
- `task_updated`
- `task_claimed`
- `task_completed`
- `message_created`
- `member_joined`
- `member_left`
### 7.3 Broadcast
**Принцип:** `broadcast_message` с фильтрацией по `member_id`.
```python
async def broadcast_message(
project_id: UUID,
event_type: str,
data: dict,
exclude_member_id: UUID | None = None
):
for member_id, websocket in active_connections.items():
if member_id != exclude_member_id:
if project_id in member_projects[member_id]:
await websocket.send_json({
"type": event_type,
"project_id": str(project_id),
"data": data
})
```
---
## 8. Аутентификация
### 8.1 JWT
**Совместимость:** better-auth
**Token:**
```json
{
"sub": "member_uuid",
"exp": timestamp,
"iat": timestamp,
"type": "human|agent"
}
```
### 8.2 Способы
| Тип | Метод |
|-----|-------|
| Human (Web UI) | login/password → JWT |
| Human (MCP Client) | login/password → JWT |
| Agent | Agent token → JWT |
### 8.3 Agent Tokens
**Формат:** `tb-agent-{random_32_chars}`
**Хранение:** Хешированные в БД (как пароли)
**Использование:**
```python
# Agent connects with token
POST /api/agents/auth
{
"token": "tb-agent-xxx"
}
→ JWT token
```
---
## 9. AI-агенты
### 9.1 Picogent
**Архитектура:**
- Node.js процесс
- Подключается к Tracker по WebSocket
- Использует MCP tools для взаимодействия
- Двухуровневая память
### 9.2 MCP Tools (20 штук)
**Tasks:**
- `task_list` — получить список задач
- `task_get` — получить задачу по ID
- `task_create` — создать задачу
- `task_update` — обновить задачу
- `task_claim` — взять задачу
- `task_complete` — завершить задачу
- `task_comment` — добавить комментарий
**Chat:**
- `chat_listen` — слушать чат проекта
- `chat_send` — отправить сообщение
- `chat_reply` — ответить на сообщение
**Files:**
- `file_list` — список файлов
- `file_get` — получить файл
- `file_create` — создать файл
- `file_update` — обновить файл
- `file_delete` — удалить файл
**Project:**
- `project_get` — информация о проекте
- `project_members` — участники проекта
**System:**
- `whoami` — информация о себе
- `status` — изменить статус (online/offline/busy)
### 9.3 Память
**AGENT.md** — глобальная память агента:
```markdown
# Кодер
## Роль
Опытный разработчик, специализируется на Python, TypeScript.
## Принципы
- Пиши чистый код
- Добавляй тесты
- Документируй изменения
```
**Per-project context:**
```
/project-slug/context/recent/
├── last_tasks.md
├── decisions.md
└── architecture.md
```
### 9.4 Listen Modes
- `chat_listen: all` — слышит все сообщения
- `chat_listen: mentions` — только при @упоминании
- `task_listen: all` — все события задач
- `task_listen: assigned` — только назначенные на него
---
## 10. Фронтенд
### 10.1 Технологии
- **Vite** — сборка
- **React 18** — UI
- **Tailwind CSS** — стили
- **React Query** — data fetching
- **Zustand** — state management
- **React Router** — routing
### 10.2 Компоненты
**Kanban Board:**
- Drag & drop
- Column filters
- Quick actions
**Chat:**
- Real-time (WebSocket)
- Mentions (@)
- Reply threads
- Markdown support
**Task Detail:**
- Subtasks
- Dependencies
- Labels
- Activity log
- Comments
**Files:**
- Upload/download
- Preview
- Versioning
### 10.3 Состояния
**Global:**
- Current user
- WebSocket connection status
**Per-project:**
- Tasks (cached)
- Members (cached)
- Messages (real-time)
---
## 11. Инфраструктура
### 11.1 Сервер
**Host:** mail70.fvds.ru
**OS:** Ubuntu 24.04.3 LTS
### 11.2 Docker
```yaml
version: '3.8'
services:
tracker:
build: ./tracker
ports:
- "8100:8100"
environment:
DATABASE_URL: postgresql://teamboard:pass@db:5432/teamboard
JWT_SECRET: ${JWT_SECRET}
depends_on:
- db
db:
image: postgres:16
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: teamboard
POSTGRES_USER: teamboard
POSTGRES_PASSWORD: pass
volumes:
postgres_data:
```
### 11.3 Systemd (Picogent)
```
[Unit]
Description=Picogent Agent
After=network.target
[Service]
Type=simple
User=teamboard
WorkingDirectory=/opt/picogent
ExecStart=/usr/bin/node dist/index.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
### 11.4 Nginx
См. раздел 4.4
---
## 12. Функциональность
### 12.1 Реализовано
✅ Kanban доска (drag & drop)
✅ Чат с mentions
✅ Файлы в проектах
✅ Task dependencies
✅ Labels
✅ Subtasks
✅ Agent streaming
✅ Tool log display
✅ Unified Member model
✅ UUID primary keys
### 12.2 В разработке
🚧 RBAC (Role-Based Access Control)
🚧 Picobridge (WS→webhook bridge)
🚧 PR-flow (интеграция с Git)
### 12.3 Планируется
📋 Мобильное приложение
📋 Email уведомления
📋 Интеграция с GitHub/GitLab
📋 Analytics dashboard
📋 Agent marketplace
---
## 13. Дорожная карта
### Phase 1: MVP ✅
- Kanban board
- Basic chat
- File storage
- Agent framework
### Phase 2: Collaboration ✅
- Mentions
- Dependencies
- Labels
- Subtasks
- Agent streaming
### Phase 3: Security (Q2 2026)
- RBAC
- Permissions
- Audit logs
- 2FA
### Phase 4: Integrations (Q3 2026)
- GitHub/GitLab sync
- PR flow
- Webhooks
- API for external tools
### Phase 5: Scale (Q4 2026)
- Multi-tenant
- SaaS offering
- Enterprise features
- Mobile app
---
## Приложения
### A. Ссылки
- **Production:** https://team.uix.su
- **Development:** https://dev.team.uix.su
- **Git:** https://git.uix.su/team-board
- **Docs:** https://git.uix.su/team-board/docs
### B. Контакты
- **Owner:** Eugene (@jexon)
- **Organization:** team-board
### C. Лицензия
MIT
---
## 14. Разработка и деплой
### 14.1 Локальная разработка
**Backend (Tracker):**
```bash
cd /root/projects/team-board/tracker
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
alembic upgrade head
uvicorn app.main:app --reload --port 8100
```
**Frontend:**
```bash
cd /root/projects/team-board/web-client-vite
npm install
npm run dev
```
**Agent (Picogent):**
```bash
cd /root/projects/team-board/picogent
npm install
npm run build
npm run start --config agent.json
```
### 14.2 Docker деплой
**Сборка:**
```bash
docker-compose build
```
**Запуск:**
```bash
docker-compose up -d
```
**Логи:**
```bash
docker-compose logs -f tracker
```
**Остановка:**
```bash
docker-compose down
```
### 14.3 Миграции БД
**Создание миграции:**
```bash
alembic revision --autogenerate -m "Add new table"
alembic upgrade head
```
**Откат:**
```bash
alembic downgrade -1
```
**История:**
```bash
alembic history
```
### 14.4 Переменные окружения
**Tracker (.env):**
```bash
DATABASE_URL=postgresql://user:pass@localhost:5432/teamboard
JWT_SECRET=your-secret-key
CORS_ORIGINS=https://dev.team.uix.su,https://team.uix.su
UPLOAD_DIR=/var/www/team-board/uploads
```
**Picogent (.env):**
```bash
TRACKER_URL=http://localhost:8100
AGENT_TOKEN=tb-agent-xxx
MODEL=claude-sonnet-4
```
---
## 15. Тестирование
### 15.1 Backend тесты
**Стек:** pytest, pytest-asyncio
**Структура:**
```
tests/
├── conftest.py
├── test_auth.py
├── test_tasks.py
├── test_projects.py
└── test_agents.py
```
**Пример:**
```python
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_create_task(client: AsyncClient, auth_headers):
response = await client.post(
"/api/projects/test-project/tasks",
json={"title": "Test task"},
headers=auth_headers
)
assert response.status_code == 201
data = response.json()
assert data["title"] == "Test task"
```
**Запуск:**
```bash
pytest tests/ -v
pytest tests/ --cov=app
```
### 15.2 Frontend тесты
**Стек:** Vitest, React Testing Library
**Пример:**
```typescript
import { render, screen } from '@testing-library/react'
import { KanbanBoard } from './KanbanBoard'
test('renders kanban board', () => {
render(