# Team Board — Frontend спецификация
## Общие сведения
**Технологии:**
- React 19.2.0
- TypeScript (~5.9.3)
- Vite 7.3.1 (bundler + dev server)
- React Router DOM 7.13.1 (роутинг)
- Tailwind CSS 4.2.1 (стили)
**Файл конфигурации:** `package.json`
**Архитектура:** SPA (Single Page Application)
---
## Структура проекта
```
src/
├── App.tsx # Главный компонент с роутингом
├── pages/ # Страницы приложения
│ ├── HomePage.tsx # Главная страница (список проектов)
│ ├── LoginPage.tsx # Страница входа
│ ├── ProjectPage.tsx # Страница проекта (канбан + чат)
│ ├── CreateProjectPage.tsx # Создание проекта
│ └── settings/ # Настройки
│ ├── SettingsLayout.tsx # Layout для настроек
│ ├── SettingsPage.tsx # Общие настройки
│ ├── LabelsPage.tsx # Управление лейблами
│ └── AgentsPage.tsx # Управление агентами
├── components/ # Переиспользуемые компоненты
│ ├── AuthGuard.tsx # Защита роутов авторизацией
│ ├── Sidebar.tsx # Боковая панель навигации
│ ├── KanbanBoard.tsx # Канбан доска задач
│ ├── TaskModal.tsx # Модальное окно задачи
│ ├── CreateTaskModal.tsx # Создание задачи
│ ├── CreateProjectModal.tsx # Создание проекта
│ ├── CreateAgentModal.tsx # Создание агента
│ ├── AgentModal.tsx # Просмотр/редактирование агента
│ ├── ProjectSettings.tsx # Настройки проекта
│ ├── ProjectFiles.tsx # Файлы проекта
│ └── ChatPanel.tsx # Панель чата
├── lib/ # Библиотеки и утилиты
│ ├── api.ts # REST API клиент
│ ├── ws.ts # WebSocket клиент
│ └── auth-client.ts # Авторизация
└── assets/ # Статические ресурсы
```
---
## Роуты и страницы
### Публичные роуты:
- `/login` — **LoginPage** — вход в систему
### Защищённые роуты (AuthGuard):
- `/` — **HomePage** — список проектов
- `/projects/:id` — **ProjectPage** — страница проекта с канбаном и чатом
- `/projects/new` — **CreateProjectPage** — создание нового проекта
- `/settings` — **SettingsLayout** — настройки (nested routes)
- `/settings` — **SettingsPage** — общие настройки
- `/settings/labels` — **LabelsPage** — управление лейблами
- `/settings/agents` — **AgentsPage** — управление агентами
### Роутинг:
```tsx
} />
} />
} />
} />
}>
} />
} />
} />
```
---
## Основные компоненты
### AuthGuard
**Файл:** `components/AuthGuard.tsx`
**Назначение:** проверяет авторизацию, перенаправляет на /login если токена нет
### KanbanBoard
**Файл:** `components/KanbanBoard.tsx`
**Назначение:** канбан доска с drag & drop задач между колонками
**Колонки:**
- Backlog (#737373)
- TODO (#3b82f6)
- In Progress (#f59e0b)
- Review (#a855f7)
- Done (#22c55e)
**Функции:**
- Drag & drop задач между статусами
- Фильтрация по исполнителю/лейблам
- Real-time обновления через WebSocket
- Создание задач в определённой колонке
### TaskModal
**Файл:** `components/TaskModal.tsx`
**Назначение:** полное отображение и редактирование задачи
**Секции:**
- Заголовок и описание
- Метаданные (статус, приоритет, лейблы, исполнитель)
- Steps (чеклист этапов)
- Комментарии и обсуждения
- Файловые вложения
### ChatPanel
**Файл:** `components/ChatPanel.tsx`
**Назначение:** панель чата проекта с real-time сообщениями
**Функции:**
- Отправка сообщений
- Упоминания участников (@username)
- Загрузка файлов
- Real-time обновления через WebSocket
### Sidebar
**Файл:** `components/Sidebar.tsx`
**Назначение:** боковая панель навигации
**Элементы:**
- Список проектов
- Общий чат (Lobby)
- Настройки
- Онлайн участники
---
## State Management
**Подход:** Локальный state с React hooks
**Глобального стора нет** — каждый компонент управляет своим состоянием
### Паттерны управления состоянием:
#### Загрузка данных:
```tsx
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function load() {
try {
const result = await apiCall();
setData(result);
} finally {
setLoading(false);
}
}
load();
}, [dependency]);
```
#### Real-time обновления:
```tsx
useEffect(() => {
const unsubscribe = wsClient.on("event.type", (data) => {
setItems(prev => prev.map(item =>
item.id === data.id ? data : item
));
});
return unsubscribe;
}, []);
```
#### Оптимистичные обновления:
```tsx
const handleUpdate = async (id: string, changes: Partial) => {
// Оптимистично обновляем UI
setItems(prev => prev.map(item =>
item.id === id ? {...item, ...changes} : item
));
try {
await updateItem(id, changes);
} catch {
// Откат в случае ошибки
loadItems();
}
};
```
---
## API интеграция
**Файл:** `lib/api.ts`
**Базовый URL:** определяется через `VITE_API_URL` environment variable
### HTTP клиент:
```typescript
async function request(path: string, options: RequestInit = {}): Promise {
const token = getToken();
const headers = {
"Content-Type": "application/json",
...(token && { "Authorization": `Bearer ${token}` })
};
const res = await fetch(`${API_BASE}${path}`, { ...options, headers });
if (!res.ok) {
if (res.status === 401) {
localStorage.removeItem("tb_token");
window.location.href = "/login";
}
throw new Error(await res.json().error);
}
return res.json();
}
```
### API методы по категориям:
#### Auth:
- `login(login, password)` — вход в систему
#### Projects:
- `getProjects()` — список проектов
- `getProject(id)` — получить проект
- `createProject(data)` — создать проект
- `updateProject(id, data)` — обновить проект
- `deleteProject(id)` — удалить проект
#### Tasks:
- `getTasks(projectId)` — задачи проекта
- `getTask(id)` — получить задачу
- `createTask(projectId, data)` — создать задачу
- `updateTask(id, data)` — обновить задачу
- `deleteTask(id)` — удалить задачу
- `takeTask(id)` — взять задачу (для агентов)
- `rejectTask(id, reason)` — отклонить задачу
- `assignTask(id, assigneeId)` — назначить задачу
- `watchTask(id)` / `unwatchTask(id)` — подписки на задачу
#### Steps:
- `getTaskSteps(taskId)` — этапы задачи
- `createTaskStep(taskId, data)` — создать этап
- `updateTaskStep(taskId, stepId, data)` — обновить этап
- `deleteTaskStep(taskId, stepId)` — удалить этап
#### Messages:
- `getMessages(params)` — сообщения чата/задачи
- `createMessage(data)` — отправить сообщение
#### Members:
- `getMembers()` — список участников
- `getMember(id)` — получить участника
- `createMember(data)` — создать участника/агента
- `updateMember(id, data)` — обновить участника
- `regenerateMemberToken(id)` — новый токен агента
- `revokeMemberToken(id)` — отозвать токен
#### Labels:
- `getLabels()` — глобальные лейблы
- `createLabel(data)` — создать лейбл
- `updateLabel(id, data)` — обновить лейбл
- `deleteLabel(id)` — удалить лейбл
#### Files:
- `uploadFile(file)` — загрузить временный файл
- `downloadAttachment(id)` — скачать вложение
- `getProjectFiles(projectId)` — файлы проекта
- `uploadProjectFile(projectId, file, description)` — загрузить файл проекта
- `deleteProjectFile(projectId, fileId)` — удалить файл проекта
---
## WebSocket интеграция
**Файл:** `lib/ws.ts`
**URL:** определяется через `VITE_WS_URL` environment variable
### WSClient класс:
```typescript
class WSClient {
connect() // подключение с токеном из localStorage
disconnect() // отключение
on(type, handler) // подписка на события
send(data) // отправка сообщения
// Convenience методы:
subscribeProject(projectId)
unsubscribeProject(projectId)
sendChat(chatId, content, mentions)
sendTaskComment(taskId, content, mentions)
heartbeat(status)
}
```
### Обработка событий:
```typescript
useEffect(() => {
const unsubscribe = wsClient.on("message.new", (message) => {
setMessages(prev => [...prev, message]);
});
return unsubscribe;
}, []);
```
### Поддерживаемые события:
- `auth.ok` — успешная авторизация
- `auth.error` — ошибка авторизации
- `message.new` — новое сообщение
- `task.created` — задача создана
- `task.updated` — задача обновлена
- `task.assigned` — задача назначена
- `task.deleted` — задача удалена
- `agent.status` — изменение статуса участника
- `agent.stream.*` — streaming от агентов
### Auto-reconnect:
- При разрыве соединения автоматический переподключение через 3 секунды
- Heartbeat каждые 30 секунд для поддержания соединения
- Очередь сообщений до подключения и авторизации
---
## Авторизация
**Файл:** `lib/auth-client.ts`
### Токены:
- Хранение: `localStorage.getItem("tb_token")`
- Формат: JWT токен
- Автоматическое добавление в заголовки API запросов
- Автоматический redirect на /login при 401 ошибке
### AuthGuard компонент:
```tsx
function AuthGuard({ children }: { children: React.ReactNode }) {
const token = localStorage.getItem("tb_token");
if (!token) return ;
return <>{children}>;
}
```
---
## Стили и UI
### Tailwind CSS 4.2.1:
- Utility-first подход
- CSS переменные для темизации
- Responsive дизайн
### Цветовая схема:
```css
:root {
--background: #ffffff;
--foreground: #0f0f0f;
--muted: #6b7280;
--border: #e5e7eb;
--primary: #3b82f6;
--destructive: #ef4444;
}
```
### Компоненты UI:
- Модальные окна
- Drag & drop интерфейсы
- Kanban колонки
- Формы с валидацией
- Файл загрузчики
- Chat интерфейс
---
## Environment переменные
**Файл:** `.env`
```bash
VITE_API_URL=http://localhost:8100 # Базовый URL REST API
VITE_WS_URL=ws://localhost:8100 # Базовый URL WebSocket
```
**Использование:**
```typescript
const API_BASE = import.meta.env.VITE_API_URL!;
const WS_BASE = import.meta.env.VITE_WS_URL!;
```
---
## Типизация
### TypeScript конфигурация:
- Строгий режим
- Path mapping (`@/` → `src/`)
- DOM типы
### API типы:
Все типы синхронизированы с backend Pydantic схемами:
- `Member`, `AgentConfig`, `MemberBrief`
- `Project`, `ProjectMember`
- `Task`, `Step`, `SubtaskBrief`
- `Message`, `Attachment`
- `Label`
---
## Производительность
### Оптимизации:
- Lazy loading компонентов
- Мемоизация через React.memo для тяжёлых компонентов
- Дебаунсинг поисковых запросов
- Пагинация сообщений чата
- Оптимистичные обновления UI
### Bundle размер:
- Tree shaking неиспользуемого кода
- Code splitting по роутам
- Минификация в production
---
## Особенности архитектуры
### Real-time синхронизация:
- WebSocket для мгновенных обновлений
- Оптимистичные обновления с откатом при ошибках
- Автоматическая подписка на события проекта
### Drag & Drop:
- Нативный HTML5 drag & drop API
- Визуальная обратная связь при перетаскивании
- Оптимистичное обновление с откатом
### Файловая система:
- Поддержка загрузки файлов через drag & drop
- Preview для изображений
- Скачивание файлов через API
### Offline-first:
- Кэширование в localStorage (токен авторизации)
- Graceful degradation при отсутствии сети
- Очередь WebSocket сообщений
Этот документ описывает фронтенд на основе исходного кода в `/root/projects/team-board/web-client-vite/src/` на дату создания спецификации.