docs: Architecture Review
This commit is contained in:
parent
537fcfe09a
commit
1bb548ff3b
301
ARCHITECTURE-REVIEW.md
Normal file
301
ARCHITECTURE-REVIEW.md
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
# Architecture Review — Team Board
|
||||||
|
Дата: 2026-02-23
|
||||||
|
|
||||||
|
## 1. Соответствие PRD
|
||||||
|
|
||||||
|
### 4.1 Управление проектами ✅ ХОРОШО
|
||||||
|
- **Архитектура:** Полностью покрывает, модель Project с multi-repo поддержкой
|
||||||
|
- **Код:** Реализовано 100%, все API endpoints работают, UI компоненты созданы
|
||||||
|
- **Расхождения:** Нет
|
||||||
|
|
||||||
|
### 4.2 Управление задачами (Kanban) ⚠️ ЧАСТИЧНО
|
||||||
|
- **Архитектура:** Покрывает полностью, модель Task с подзадачами, зависимостями, watchers
|
||||||
|
- **Код:** Базовые CRUD есть, но отсутствуют специальные операции
|
||||||
|
- **Расхождения:**
|
||||||
|
- ❌ `POST /api/v1/tasks/{id}/take` — не реализован (БФФ проксирует, но в трекере нет)
|
||||||
|
- ❌ `POST /api/v1/tasks/{id}/reject` — не реализован
|
||||||
|
- ❌ `POST /api/v1/tasks/{id}/assign` — не реализован
|
||||||
|
- ❌ `POST /api/v1/tasks/{id}/watch` — не реализован
|
||||||
|
- ✅ Базовые CRUD работают
|
||||||
|
|
||||||
|
### 4.3 Чат и коммуникация ✅ ХОРОШО
|
||||||
|
- **Архитектура:** Unified Message модель реализована корректно
|
||||||
|
- **Код:** Message с chat_id/task_id работает, WS chat.send функционирует
|
||||||
|
- **Расхождения:**
|
||||||
|
- ⚠️ Голосовые сообщения (voice_url) — поле есть в модели, но API загрузки нет
|
||||||
|
|
||||||
|
### 4.4 AI агенты ⚠️ ПРОБЛЕМЫ
|
||||||
|
- **Архитектура:** Модель Member unified, AgentConfig детализирован
|
||||||
|
- **Код:** Модели реализованы, но проблемы с функциональностью
|
||||||
|
- **Расхождения:**
|
||||||
|
- ❌ Agent management UI — полностью отсутствует
|
||||||
|
- ❌ MCP Tools — не реализованы
|
||||||
|
- ❌ Фильтрация WS событий по capabilities — упрощена: humans получают ВСЁ
|
||||||
|
- ❌ REST API token auth для агентов — не работает (только WS auth)
|
||||||
|
|
||||||
|
### 4.5 Файлы и вложения ❌ НЕ РЕАЛИЗОВАНО
|
||||||
|
- **Архитектура:** Модель Attachment есть
|
||||||
|
- **Код:** Полностью отсутствует
|
||||||
|
- **Расхождения:**
|
||||||
|
- ❌ `POST /api/v1/messages/{id}/attachments` — не реализован
|
||||||
|
- ❌ `GET /api/v1/attachments/{id}` — не реализован
|
||||||
|
- ❌ Хранение файлов — не реализовано
|
||||||
|
|
||||||
|
### 4.6 Аутентификация и авторизация ⚠️ ЧАСТИЧНО
|
||||||
|
- **Архитектура:** JWT + Token auth описаны корректно
|
||||||
|
- **Код:** JWT через BFF работает, agent WS auth работает
|
||||||
|
- **Расхождения:**
|
||||||
|
- ❌ Token auth для REST API агентов — проверка не реализована
|
||||||
|
- ✅ BFF JWT auth работает
|
||||||
|
- ✅ WS token auth для агентов работает
|
||||||
|
|
||||||
|
### 4.7 WebSocket и реал-тайм ⚠️ ПРОБЛЕМЫ
|
||||||
|
- **Архитектура:** Подробно описан протокол, фильтрация событий
|
||||||
|
- **Код:** Базовые WS работают, но упрощённая архитектура
|
||||||
|
- **Расхождения:**
|
||||||
|
- ❌ Task события (task.created/updated/assigned) — не транслируются
|
||||||
|
- ⚠️ Упрощённая фильтрация: humans/bridges получают ВСЁ, agents — по подпискам
|
||||||
|
- ✅ auth, heartbeat, chat.send, project.subscribe работают
|
||||||
|
|
||||||
|
### 4.8 Steps (этапы задач) ✅ ХОРОШО
|
||||||
|
- **Архитектура:** Корректно описаны как чеклист внутри задачи
|
||||||
|
- **Код:** Полная реализация: модель, API, UI в TaskModal
|
||||||
|
- **Расхождения:** Нет
|
||||||
|
|
||||||
|
## 2. Архитектурные проблемы
|
||||||
|
|
||||||
|
### 2.1 WebSocket: Один слот на slug — КРИТИЧЕСКАЯ ПРОБЛЕМА
|
||||||
|
**Проблема:** `ConnectionManager.clients: dict[str, ConnectedClient]` — один слот на slug.
|
||||||
|
```python
|
||||||
|
# manager.py:15
|
||||||
|
self.clients: dict[str, ConnectedClient] = {} # slug → client
|
||||||
|
```
|
||||||
|
**Последствия:**
|
||||||
|
- Множественные вкладки одного пользователя вытесняют друг друга
|
||||||
|
- Агент при переподключении теряет предыдущую сессию
|
||||||
|
- Race conditions при одновременных подключениях
|
||||||
|
|
||||||
|
**Решение:** `dict[str, list[ConnectedClient]]` или уникальные session_id.
|
||||||
|
|
||||||
|
### 2.2 Task Events не транслируются
|
||||||
|
**Проблема:** В коде есть `broadcast_task_event`, но никто её не вызывает.
|
||||||
|
```python
|
||||||
|
# manager.py:47
|
||||||
|
async def broadcast_task_event(self, project_id: str, event_type: str, data: dict):
|
||||||
|
```
|
||||||
|
**Последствия:** Агенты не получают уведомления о создании/обновлении задач.
|
||||||
|
|
||||||
|
**Решение:** Интегрировать в REST API endpoints для задач.
|
||||||
|
|
||||||
|
### 2.3 REST API авторизация агентов не работает
|
||||||
|
**Проблема:** Токен проверяется только в WebSocket, REST API для агентов полностью открыт.
|
||||||
|
```python
|
||||||
|
# BFF проксирует агентские операции, но агенты не могут ходить напрямую к Tracker
|
||||||
|
```
|
||||||
|
**Последствия:** Агенты не могут делать REST вызовы без BFF.
|
||||||
|
|
||||||
|
**Решение:** Добавить token auth middleware в Tracker REST API.
|
||||||
|
|
||||||
|
### 2.4 BFF on_behalf_of создаёт collision risk
|
||||||
|
**Проблема:** Bridge может зарегистрировать любой `on_behalf_of` slug, даже несуществующий.
|
||||||
|
```python
|
||||||
|
# handler.py:88-95
|
||||||
|
if on_behalf_of and member.type == "bridge":
|
||||||
|
# Если пользователь не найден, используется синтетический slug
|
||||||
|
effective_slug = on_behalf_of
|
||||||
|
```
|
||||||
|
**Последствия:** Коллизии slug при подключении реального пользователя.
|
||||||
|
|
||||||
|
**Решение:** Строгая валидация on_behalf_of или префиксы для synthetic slugs.
|
||||||
|
|
||||||
|
### 2.5 Упрощённая фильтрация событий
|
||||||
|
**Проблема:** Humans/bridges получают ВСЕ события без фильтрации.
|
||||||
|
```python
|
||||||
|
# manager.py:36
|
||||||
|
if client.member_type in ("human", "bridge"):
|
||||||
|
await self.send_to(slug, {"type": "message.new", "data": message})
|
||||||
|
continue
|
||||||
|
```
|
||||||
|
**Последствия:** Лишний трафик, невозможность настроить подписки для людей.
|
||||||
|
|
||||||
|
**Решение:** Единая логика фильтрации для всех типов участников.
|
||||||
|
|
||||||
|
## 3. Расхождения документация ↔ код
|
||||||
|
|
||||||
|
### 3.1 TRACKER-PROTOCOL.md vs реальный протокол
|
||||||
|
**Документ описывает:**
|
||||||
|
- task.created/updated/assigned события
|
||||||
|
- Детальную фильтрацию по listen_mode и capabilities
|
||||||
|
- REST API endpoints для task operations
|
||||||
|
|
||||||
|
**Реальный код:**
|
||||||
|
- Task события не отправляются
|
||||||
|
- Упрощённая фильтрация (humans получают всё)
|
||||||
|
- Task API endpoints отсутствуют
|
||||||
|
|
||||||
|
### 3.2 ARCHITECTURE.md vs WS manager
|
||||||
|
**Документ описывает:**
|
||||||
|
- Фильтрацию по capabilities и listen modes
|
||||||
|
- Отдельные подписки для humans
|
||||||
|
|
||||||
|
**Реальный код:**
|
||||||
|
- Capabilities не используются в фильтрации
|
||||||
|
- Humans получают всё без подписок
|
||||||
|
|
||||||
|
### 3.3 CONCEPTS.md vs Agent REST auth
|
||||||
|
**Документ описывает:**
|
||||||
|
- REST API с token авторизацией для агентов
|
||||||
|
- MCP Tools полный набор
|
||||||
|
|
||||||
|
**Реальный код:**
|
||||||
|
- REST API открыт для всех
|
||||||
|
- MCP Tools отсутствуют
|
||||||
|
|
||||||
|
### 3.4 PRD vs отсутствующие features
|
||||||
|
**PRD объявляет реализованными:**
|
||||||
|
- Agent management UI
|
||||||
|
- Attachments API
|
||||||
|
- Task special operations
|
||||||
|
|
||||||
|
**Реальный код:**
|
||||||
|
- Эти features полностью отсутствуют
|
||||||
|
|
||||||
|
## 4. Рекомендации
|
||||||
|
|
||||||
|
### P0: Блокеры
|
||||||
|
|
||||||
|
#### P0.1 Исправить WebSocket collision
|
||||||
|
```python
|
||||||
|
# manager.py
|
||||||
|
class ConnectionManager:
|
||||||
|
def __init__(self):
|
||||||
|
self.clients: dict[str, list[ConnectedClient]] = {} # slug → clients[]
|
||||||
|
self.sessions: dict[str, ConnectedClient] = {} # session_id → client
|
||||||
|
```
|
||||||
|
**Без этого:** Система не работает корректно при multiple connections.
|
||||||
|
|
||||||
|
#### P0.2 Добавить REST token auth для агентов
|
||||||
|
```python
|
||||||
|
# tracker/api/middleware.py
|
||||||
|
async def verify_agent_token(request: Request):
|
||||||
|
auth = request.headers.get("Authorization")
|
||||||
|
if auth and auth.startswith("Bearer "):
|
||||||
|
token = auth[7:]
|
||||||
|
# Проверить в БД Member.token
|
||||||
|
```
|
||||||
|
**Без этого:** Агенты не могут использовать API напрямую.
|
||||||
|
|
||||||
|
#### P0.3 Реализовать task events
|
||||||
|
```python
|
||||||
|
# tracker/api/tasks.py после create/update/delete
|
||||||
|
await broadcast_task_event(task.project_id, "task.created", task_data)
|
||||||
|
```
|
||||||
|
**Без этого:** Агенты не видят изменения задач.
|
||||||
|
|
||||||
|
### P1: Важно
|
||||||
|
|
||||||
|
#### P1.1 Реализовать task special operations
|
||||||
|
- `POST /api/v1/tasks/{id}/take` — атомарное взятие задачи
|
||||||
|
- `POST /api/v1/tasks/{id}/reject` — отклонение с причиной
|
||||||
|
- `POST /api/v1/tasks/{id}/assign` — назначение
|
||||||
|
- `POST /api/v1/tasks/{id}/watch` — подписка на задачу
|
||||||
|
|
||||||
|
**Почему:** Это ключевые операции для работы агентов с задачами.
|
||||||
|
|
||||||
|
#### P1.2 Создать Agent Management UI
|
||||||
|
- Страница `/agents` с списком агентов
|
||||||
|
- Создание агентов с генерацией токенов
|
||||||
|
- Просмотр статусов и capabilities
|
||||||
|
|
||||||
|
**Почему:** Без UI управление агентами невозможно.
|
||||||
|
|
||||||
|
#### P1.3 Унифицировать фильтрацию событий
|
||||||
|
```python
|
||||||
|
async def should_receive_event(client: ConnectedClient, event_type: str, data: dict) -> bool:
|
||||||
|
# Единая логика для всех типов участников
|
||||||
|
# Проверка подписок, listen_mode, capabilities
|
||||||
|
```
|
||||||
|
**Почему:** Текущая архитектура не масштабируется.
|
||||||
|
|
||||||
|
#### P1.4 Исправить on_behalf_of логику
|
||||||
|
- Валидировать существование пользователя
|
||||||
|
- Использовать префиксы для synthetic slugs: `web-{slug}`
|
||||||
|
- Логировать все proxy подключения
|
||||||
|
|
||||||
|
**Почему:** Предотвращает коллизии и security issues.
|
||||||
|
|
||||||
|
### P2: Хорошо бы
|
||||||
|
|
||||||
|
#### P2.1 Реализовать Attachments API
|
||||||
|
- `POST /api/v1/messages/{id}/attachments` — загрузка
|
||||||
|
- `GET /api/attachments/{id}` — скачивание
|
||||||
|
- Хранение на диске по storage_path
|
||||||
|
|
||||||
|
**Почему:** Команды часто работают с файлами.
|
||||||
|
|
||||||
|
#### P2.2 Добавить MCP Tools для агентов
|
||||||
|
- create_task, take_task, update_task
|
||||||
|
- send_message, list_messages
|
||||||
|
- watch_task, unwatch_task
|
||||||
|
|
||||||
|
**Почему:** Агентам нужны инструменты для работы.
|
||||||
|
|
||||||
|
#### P2.3 Улучшить monitoring
|
||||||
|
- Health check endpoints `/health`
|
||||||
|
- Метрики WebSocket connections
|
||||||
|
- Логирование всех WS событий с timestamps
|
||||||
|
|
||||||
|
**Почему:** Проще дебажить и мониторить продакшен.
|
||||||
|
|
||||||
|
## 5. Обновлённая архитектурная диаграмма
|
||||||
|
|
||||||
|
### Текущая архитектура (как есть)
|
||||||
|
```
|
||||||
|
Web Client ——HTTP/JWT——→ BFF ——HTTP/Token——→ Tracker
|
||||||
|
↓ ↑ ↑
|
||||||
|
WS/JWT————————————————┘ │
|
||||||
|
│ WS/Token
|
||||||
|
Picogent Agent ———————————————————————————————————┘
|
||||||
|
(REST auth не работает)
|
||||||
|
|
||||||
|
ConnectionManager: dict[slug → client] ← ПРОБЛЕМА
|
||||||
|
Фильтрация: humans=ALL, agents=subscription ← УПРОЩЕНО
|
||||||
|
Task events: НЕ ОТПРАВЛЯЮТСЯ ← ПРОБЛЕМА
|
||||||
|
```
|
||||||
|
|
||||||
|
### Целевая архитектура (как должно быть)
|
||||||
|
```
|
||||||
|
Web Client ——HTTP/JWT——→ BFF ——HTTP/Token——→ Tracker
|
||||||
|
↓ ↑ ↑ ↑
|
||||||
|
WS/JWT————————————————┘ │ │ WS/Token
|
||||||
|
│ │
|
||||||
|
Picogent Agent ————HTTP/Token—————————————————┘ │
|
||||||
|
├————————WS/Token————————————————————────┘
|
||||||
|
└————————MCP Tools———————┘
|
||||||
|
|
||||||
|
ConnectionManager:
|
||||||
|
dict[slug → clients[]] ← ФИКС
|
||||||
|
dict[session_id → client] ← ФИКС
|
||||||
|
|
||||||
|
Фильтрация: unified для всех типов ← УЛУЧШЕНИЕ
|
||||||
|
Task events: все операции транслируются ← ФИКС
|
||||||
|
Agent REST: token auth работает ← ФИКС
|
||||||
|
```
|
||||||
|
|
||||||
|
### Компоненты как должны быть
|
||||||
|
| Компонент | Порт | Протоколы | Изменения |
|
||||||
|
|-----------|------|-----------|-----------|
|
||||||
|
| **Tracker** | 8100 | HTTP+WS (token auth) | + Task events, + Agent REST auth |
|
||||||
|
| **BFF** | 8200 | HTTP+WS (JWT auth) | + on_behalf_of validation |
|
||||||
|
| **Web Client** | 3100 | HTTP+WS через BFF | + Agent Management UI |
|
||||||
|
| **Picogent** | — | HTTP+WS к Tracker | + MCP Tools |
|
||||||
|
|
||||||
|
### Протоколы взаимодействия
|
||||||
|
- **Web ↔ BFF:** JWT auth, WS proxy с session management
|
||||||
|
- **BFF ↔ Tracker:** Token auth, on_behalf_of для web users
|
||||||
|
- **Agent ↔ Tracker:** Token auth для HTTP и WS, unified
|
||||||
|
- **Events:** Task+Message события через WS с единой фильтрацией
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Итог:** Архитектура в целом правильная, но много критических недоработок в реализации. Основная проблема — WebSocket connection management и отсутствие task events. После фиксов P0 система будет работать корректно.
|
||||||
Loading…
Reference in New Issue
Block a user