docs/SPECIFICATION.md
Markov 223be901aa Add comprehensive project specification
- Complete system architecture
- All repositories and components
- Data models with UUID
- API endpoints
- WebSocket events
- Agent system (Picogent)
- Frontend architecture
- Infrastructure setup
- Current features and roadmap
2026-03-13 15:08:27 +01:00

803 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Team Board — Полная Спецификация
Версия: 1.0
Дата: 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-дорожная-карта)
---
## 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
---
*Документ поддерживается Авророй. Последнее обновление: 2026-03-13*