# 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/` на дату создания спецификации.