init
This commit is contained in:
988
ARCHITECTURE.md
Normal file
988
ARCHITECTURE.md
Normal file
@ -0,0 +1,988 @@
|
||||
# Архитектура Team Planner
|
||||
|
||||
---
|
||||
|
||||
## 1. C4 Model
|
||||
|
||||
### 1.1 Level 1: System Context
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph external [" "]
|
||||
User["👤 Пользователь<br/><i>Член команды разработки</i>"]
|
||||
AI["🤖 AI Proxy Service<br/><i>LLM для оценки задач</i>"]
|
||||
end
|
||||
|
||||
subgraph system ["Team Planner"]
|
||||
TP["🎯 Team Planner<br/><i>Приложение для управления<br/>бэклогом идей команды</i>"]
|
||||
end
|
||||
|
||||
User -->|"Управляет идеями,<br/>командой, комментариями<br/>[HTTPS]"| TP
|
||||
TP -->|"Запросы на оценку<br/>трудозатрат<br/>[HTTPS/REST]"| AI
|
||||
|
||||
style TP fill:#1168bd,color:#fff
|
||||
style User fill:#08427b,color:#fff
|
||||
style AI fill:#999,color:#fff
|
||||
```
|
||||
|
||||
### 1.2 Level 2: Container Diagram
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
User["👤 Пользователь<br/><i>Член команды разработки</i>"]
|
||||
|
||||
subgraph TeamPlanner ["Team Planner"]
|
||||
SPA["📱 Frontend SPA<br/><i>React, TypeScript, MUI</i><br/><br/>Веб-интерфейс для<br/>работы с идеями"]
|
||||
API["⚙️ Backend API<br/><i>NestJS, TypeScript</i><br/><br/>REST API + WebSocket"]
|
||||
DB[("🗄️ Database<br/><i>PostgreSQL</i><br/><br/>Хранение идей,<br/>команды, комментариев")]
|
||||
end
|
||||
|
||||
AI["🤖 AI Proxy Service<br/><i>LLM для оценки задач</i>"]
|
||||
|
||||
User -->|"Использует<br/>[HTTPS]"| SPA
|
||||
SPA -->|"API запросы<br/>[REST/WebSocket]"| API
|
||||
API -->|"Читает/пишет<br/>[TypeORM]"| DB
|
||||
API -->|"Оценка трудозатрат<br/>[HTTPS/REST]"| AI
|
||||
|
||||
style SPA fill:#438dd5,color:#fff
|
||||
style API fill:#438dd5,color:#fff
|
||||
style DB fill:#438dd5,color:#fff
|
||||
style User fill:#08427b,color:#fff
|
||||
style AI fill:#999,color:#fff
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Sequence Diagrams
|
||||
|
||||
### 2.1 Создание идеи
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as Пользователь
|
||||
participant FE as Frontend<br/>(React)
|
||||
participant BE as Backend<br/>(NestJS)
|
||||
participant DB as PostgreSQL
|
||||
|
||||
User->>FE: Заполняет форму идеи
|
||||
FE->>FE: Валидация на клиенте
|
||||
FE->>BE: POST /api/ideas
|
||||
BE->>BE: Валидация DTO
|
||||
BE->>DB: INSERT INTO ideas
|
||||
DB-->>BE: idea record
|
||||
BE-->>FE: 201 Created { idea }
|
||||
FE->>FE: Добавляет в store
|
||||
FE-->>User: Показывает новую идею в списке
|
||||
```
|
||||
|
||||
### 2.2 Inline-редактирование идеи
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as Пользователь
|
||||
participant FE as Frontend<br/>(React)
|
||||
participant BE as Backend<br/>(NestJS)
|
||||
participant DB as PostgreSQL
|
||||
|
||||
User->>FE: Double-click на ячейку
|
||||
FE->>FE: Переключает в режим редактирования
|
||||
User->>FE: Изменяет значение, blur/Enter
|
||||
FE->>FE: Оптимистичное обновление store
|
||||
FE->>BE: PATCH /api/ideas/:id
|
||||
BE->>BE: Валидация DTO
|
||||
BE->>DB: UPDATE ideas SET ...
|
||||
DB-->>BE: updated idea
|
||||
BE-->>FE: 200 OK { idea }
|
||||
FE->>FE: Подтверждает изменение в store
|
||||
|
||||
alt Ошибка
|
||||
BE-->>FE: 4xx/5xx error
|
||||
FE->>FE: Откат оптимистичного обновления
|
||||
FE-->>User: Показывает ошибку
|
||||
end
|
||||
```
|
||||
|
||||
### 2.3 Drag & Drop (изменение порядка)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as Пользователь
|
||||
participant FE as Frontend<br/>(React)
|
||||
participant BE as Backend<br/>(NestJS)
|
||||
participant DB as PostgreSQL
|
||||
|
||||
User->>FE: Перетаскивает идею
|
||||
FE->>FE: dnd-kit обновляет UI
|
||||
FE->>FE: Оптимистичное обновление порядка
|
||||
FE->>BE: PATCH /api/ideas/reorder
|
||||
Note right of FE: { ids: [id1, id2, ...] }
|
||||
BE->>DB: UPDATE ideas SET position = ...
|
||||
DB-->>BE: OK
|
||||
BE-->>FE: 200 OK
|
||||
FE-->>User: Порядок сохранён
|
||||
```
|
||||
|
||||
### 2.4 AI-оценка трудозатрат
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as Пользователь
|
||||
participant FE as Frontend<br/>(React)
|
||||
participant BE as Backend<br/>(NestJS)
|
||||
participant AI as AI Proxy
|
||||
participant DB as PostgreSQL
|
||||
|
||||
User->>FE: Нажимает "Оценить"
|
||||
FE->>FE: Показывает loader
|
||||
FE->>BE: POST /api/ai/estimate
|
||||
Note right of FE: { ideaId }
|
||||
BE->>DB: SELECT idea, team_members
|
||||
DB-->>BE: idea + team data
|
||||
BE->>BE: Формирует промпт
|
||||
BE->>AI: POST /chat/completions
|
||||
Note right of BE: prompt с описанием идеи<br/>и составом команды
|
||||
AI-->>BE: LLM response
|
||||
BE->>BE: Парсит ответ
|
||||
BE->>DB: UPDATE ideas SET estimate = ...
|
||||
DB-->>BE: OK
|
||||
BE-->>FE: 200 OK { estimate }
|
||||
FE->>FE: Обновляет store
|
||||
FE-->>User: Показывает оценку
|
||||
```
|
||||
|
||||
### 2.5 Добавление комментария
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as Пользователь
|
||||
participant FE as Frontend<br/>(React)
|
||||
participant BE as Backend<br/>(NestJS)
|
||||
participant DB as PostgreSQL
|
||||
|
||||
User->>FE: Пишет комментарий
|
||||
FE->>BE: POST /api/ideas/:id/comments
|
||||
Note right of FE: { text, parentId? }
|
||||
BE->>BE: Валидация
|
||||
BE->>DB: INSERT INTO comments
|
||||
DB-->>BE: comment record
|
||||
BE-->>FE: 201 Created { comment }
|
||||
FE->>FE: Добавляет в store
|
||||
FE-->>User: Показывает комментарий
|
||||
```
|
||||
|
||||
### 2.6 Загрузка списка идей с фильтрами
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as Пользователь
|
||||
participant FE as Frontend<br/>(React)
|
||||
participant BE as Backend<br/>(NestJS)
|
||||
participant DB as PostgreSQL
|
||||
|
||||
User->>FE: Открывает страницу / меняет фильтры
|
||||
FE->>FE: Показывает skeleton loader
|
||||
FE->>BE: GET /api/ideas?status=...&priority=...
|
||||
BE->>DB: SELECT * FROM ideas WHERE ... ORDER BY ...
|
||||
DB-->>BE: ideas[]
|
||||
BE-->>FE: 200 OK { data, total, page }
|
||||
FE->>FE: Сохраняет в store
|
||||
FE-->>User: Отображает таблицу
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. API Contracts
|
||||
|
||||
### 3.1 Ideas
|
||||
|
||||
#### GET /api/ideas
|
||||
Получение списка идей с пагинацией и фильтрами.
|
||||
|
||||
**Query Parameters:**
|
||||
```typescript
|
||||
{
|
||||
page?: number; // default: 1
|
||||
limit?: number; // default: 50
|
||||
status?: IdeaStatus; // фильтр по статусу
|
||||
priority?: Priority; // фильтр по приоритету
|
||||
module?: Module; // фильтр по модулю
|
||||
color?: string; // фильтр по цвету
|
||||
search?: string; // поиск по тексту
|
||||
sortBy?: string; // поле для сортировки
|
||||
sortOrder?: 'asc' | 'desc';
|
||||
}
|
||||
```
|
||||
|
||||
**Response 200:**
|
||||
```typescript
|
||||
{
|
||||
data: Idea[];
|
||||
meta: {
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
totalPages: number;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/ideas
|
||||
Создание новой идеи.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
title: string; // обязательное
|
||||
description?: string;
|
||||
status: IdeaStatus; // default: 'new'
|
||||
priority: Priority; // default: 'medium'
|
||||
module: Module[];
|
||||
targetAudience?: string;
|
||||
painPoint?: string;
|
||||
aiRole?: string;
|
||||
validationMethod?: string;
|
||||
color?: string;
|
||||
position?: number;
|
||||
}
|
||||
```
|
||||
|
||||
**Response 201:**
|
||||
```typescript
|
||||
{
|
||||
id: string;
|
||||
title: string;
|
||||
description: string | null;
|
||||
status: IdeaStatus;
|
||||
priority: Priority;
|
||||
module: Module[];
|
||||
targetAudience: string | null;
|
||||
painPoint: string | null;
|
||||
aiRole: string | null;
|
||||
validationMethod: string | null;
|
||||
color: string | null;
|
||||
position: number;
|
||||
estimate: Estimate | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### PATCH /api/ideas/:id
|
||||
Обновление идеи (partial update).
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
Partial<{
|
||||
title: string;
|
||||
description: string;
|
||||
status: IdeaStatus;
|
||||
priority: Priority;
|
||||
module: Module[];
|
||||
targetAudience: string;
|
||||
painPoint: string;
|
||||
aiRole: string;
|
||||
validationMethod: string;
|
||||
color: string;
|
||||
}>
|
||||
```
|
||||
|
||||
**Response 200:** `Idea`
|
||||
|
||||
#### DELETE /api/ideas/:id
|
||||
Удаление идеи.
|
||||
|
||||
**Response 204:** No Content
|
||||
|
||||
#### PATCH /api/ideas/reorder
|
||||
Изменение порядка идей.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
ids: string[]; // ID идей в новом порядке
|
||||
}
|
||||
```
|
||||
|
||||
**Response 200:**
|
||||
```typescript
|
||||
{
|
||||
success: true;
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Comments
|
||||
|
||||
#### GET /api/ideas/:ideaId/comments
|
||||
Получение комментариев к идее.
|
||||
|
||||
**Response 200:**
|
||||
```typescript
|
||||
{
|
||||
data: Comment[];
|
||||
}
|
||||
|
||||
// Comment
|
||||
{
|
||||
id: string;
|
||||
text: string;
|
||||
ideaId: string;
|
||||
parentId: string | null; // для тредов
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
replies?: Comment[]; // вложенные ответы
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/ideas/:ideaId/comments
|
||||
Добавление комментария.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
text: string;
|
||||
parentId?: string; // для ответа на комментарий
|
||||
}
|
||||
```
|
||||
|
||||
**Response 201:** `Comment`
|
||||
|
||||
#### DELETE /api/comments/:id
|
||||
Удаление комментария.
|
||||
|
||||
**Response 204:** No Content
|
||||
|
||||
### 3.3 Team
|
||||
|
||||
#### GET /api/team/members
|
||||
Получение списка членов команды.
|
||||
|
||||
**Response 200:**
|
||||
```typescript
|
||||
{
|
||||
data: TeamMember[];
|
||||
}
|
||||
|
||||
// TeamMember
|
||||
{
|
||||
id: string;
|
||||
name: string;
|
||||
role: TeamRole;
|
||||
productivity: {
|
||||
trivial: number; // часы
|
||||
easy: number;
|
||||
medium: number;
|
||||
hard: number;
|
||||
epic: number;
|
||||
};
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/team/members
|
||||
Добавление члена команды.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
name: string;
|
||||
role: TeamRole;
|
||||
productivity?: {
|
||||
trivial?: number;
|
||||
easy?: number;
|
||||
medium?: number;
|
||||
hard?: number;
|
||||
epic?: number;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**Response 201:** `TeamMember`
|
||||
|
||||
#### PATCH /api/team/members/:id
|
||||
Обновление члена команды.
|
||||
|
||||
**Request Body:** `Partial<TeamMember>`
|
||||
|
||||
**Response 200:** `TeamMember`
|
||||
|
||||
#### DELETE /api/team/members/:id
|
||||
Удаление члена команды.
|
||||
|
||||
**Response 204:** No Content
|
||||
|
||||
#### GET /api/team/summary
|
||||
Сводка по команде.
|
||||
|
||||
**Response 200:**
|
||||
```typescript
|
||||
{
|
||||
totalMembers: number;
|
||||
byRole: Record<TeamRole, number>;
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 AI
|
||||
|
||||
#### POST /api/ai/estimate
|
||||
AI-оценка трудозатрат для идеи.
|
||||
|
||||
**Request Body:**
|
||||
```typescript
|
||||
{
|
||||
ideaId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Response 200:**
|
||||
```typescript
|
||||
{
|
||||
ideaId: string;
|
||||
estimate: {
|
||||
totalHours: number;
|
||||
totalDays: number;
|
||||
complexity: 'trivial' | 'easy' | 'medium' | 'hard' | 'epic';
|
||||
breakdown: {
|
||||
role: TeamRole;
|
||||
hours: number;
|
||||
complexity: Complexity;
|
||||
description: string;
|
||||
}[];
|
||||
recommendations?: string[];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 Enums
|
||||
|
||||
```typescript
|
||||
enum IdeaStatus {
|
||||
NEW = 'new',
|
||||
DISCUSSING = 'discussing',
|
||||
APPROVED = 'approved',
|
||||
IN_PROGRESS = 'in_progress',
|
||||
DONE = 'done',
|
||||
REJECTED = 'rejected'
|
||||
}
|
||||
|
||||
enum Priority {
|
||||
CRITICAL = 'critical',
|
||||
HIGH = 'high',
|
||||
MEDIUM = 'medium',
|
||||
LOW = 'low'
|
||||
}
|
||||
|
||||
enum Module {
|
||||
FRONTEND = 'frontend',
|
||||
BACKEND = 'backend',
|
||||
AI = 'ai',
|
||||
MOBILE = 'mobile',
|
||||
INFRASTRUCTURE = 'infrastructure',
|
||||
OTHER = 'other'
|
||||
}
|
||||
|
||||
enum TeamRole {
|
||||
BACKEND = 'backend',
|
||||
FRONTEND = 'frontend',
|
||||
AI_ML = 'ai_ml',
|
||||
ANALYST = 'analyst',
|
||||
QA = 'qa',
|
||||
DEVOPS = 'devops',
|
||||
DESIGNER = 'designer',
|
||||
PM = 'pm'
|
||||
}
|
||||
|
||||
enum Complexity {
|
||||
TRIVIAL = 'trivial',
|
||||
EASY = 'easy',
|
||||
MEDIUM = 'medium',
|
||||
HARD = 'hard',
|
||||
EPIC = 'epic'
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. UI Prototypes
|
||||
|
||||
### 4.1 Главная страница - Список идей
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 🎯 Team Planner [Команда] [+ Идея] │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─ Фильтры ─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ [Статус ▼] [Приоритет ▼] [Модуль ▼] [Цвет ▼] [🔍 Поиск... ] │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Таблица идей ────────────────────────────────────────────────────────┐ │
|
||||
│ │ ⋮⋮ │ Статус │ ⚡ │ Модуль │ Идея │ Для кого │ Оценка │ │
|
||||
│ ├────┼───────────┼────┼──────────┼────────────────┼──────────┼─────────┤ │
|
||||
│ │ ⋮⋮ │ 🟢 Новая │ 🔴 │ Frontend │ Добавить темну │ Все поль │ 3д │ │
|
||||
│ │ ⋮⋮ │ 🟡 В обсу │ 🟡 │ Backend │ API кэширован │ Разработ │ 5д │ │
|
||||
│ │ ⋮⋮ │ 🔵 Одобре │ 🟢 │ AI │ Автоматическа │ Менеджер │ 10д │ │
|
||||
│ │ ⋮⋮ │ 🟣 В рабо │ 🔴 │ Backend │ Оптимизация з │ Все │ 7д │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Показано 4 из 24 [< Пред] 1 2 3 [След >] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
Легенда:
|
||||
⋮⋮ - drag handle для перетаскивания
|
||||
⚡ - приоритет (иконка молнии)
|
||||
🔴🟡🟢 - цветовые индикаторы приоритета
|
||||
```
|
||||
|
||||
### 4.2 Расширенная строка с комментариями
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ⋮⋮ │ 🟢 Новая │ 🔴 │ Frontend │ Добавить тёмную тему │ Все │ 3д [▼]│
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─ Детали ──────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Боль: Пользователи жалуются на яркий интерфейс вечером │ │
|
||||
│ │ AI роль: — │ │
|
||||
│ │ Проверка: A/B тест с 10% пользователей │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Комментарии (3) ─────────────────────────────────────────────────────┐ │
|
||||
│ │ 💬 Иван: Нужно согласовать палитру с дизайнером 2ч назад │ │
|
||||
│ │ └─ 💬 Мария: Уже в процессе, будет готово завтра 1ч назад │ │
|
||||
│ │ 💬 Петр: Предлагаю использовать CSS variables 30м назад │ │
|
||||
│ │ │ │
|
||||
│ │ [Написать комментарий... ] [Отправить] │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [🤖 Оценить AI] [✏️ Редактировать] [🗑️ Удалить] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.3 Модальное окно создания/редактирования идеи
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Новая идея [✕] │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Суть идеи * │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌──────────────────┐ │
|
||||
│ │ Статус │ │ Приоритет │ │ Модуль │ │
|
||||
│ │ [Новая ▼] │ │ [Средний ▼] │ │ [Frontend ▼] │ │
|
||||
│ └─────────────────────┘ └─────────────────────┘ └──────────────────┘ │
|
||||
│ │
|
||||
│ Для кого эта идея │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Какую боль решает │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Роль AI (если применимо) │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Быстрый способ проверить │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Цвет строки │
|
||||
│ [⬜][🟥][🟧][🟨][🟩][🟦][🟪] │
|
||||
│ │
|
||||
│ [Отмена] [💾 Сохранить] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.4 Страница управления командой
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 🎯 Team Planner [Команда] [+ Идея] │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ◀ Назад к идеям │
|
||||
│ │
|
||||
│ ┌─ Состав команды ──────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ 👨💻 Backend: 3 👩💻 Frontend: 2 🤖 AI/ML: 1 📊 Аналитик: 1 │ │
|
||||
│ │ 🧪 QA: 2 🔧 DevOps: 1 🎨 Дизайн: 1 📋 PM: 1 │ │
|
||||
│ │ │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Участники ───────────────────────────────────────────────────────────┐ │
|
||||
│ │ Имя │ Роль │ Trivial │ Easy │ Med │ Hard │ Epic │ │
|
||||
│ ├──────────────────┼────────────┼─────────┼──────┼─────┼──────┼────────┤ │
|
||||
│ │ Иван Петров │ Backend │ 1ч │ 4ч │ 16ч │ 40ч │ 80ч │ │
|
||||
│ │ Мария Сидорова │ Frontend │ 1ч │ 4ч │ 16ч │ 40ч │ 80ч │ │
|
||||
│ │ Алексей Козлов │ AI/ML │ 2ч │ 8ч │ 24ч │ 60ч │ 120ч │ │
|
||||
│ │ ... │ │ │ │ │ │ │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [+ Добавить участника] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4.5 Модальное окно AI-оценки
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 🤖 AI-оценка трудозатрат [✕] │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Идея: Добавить тёмную тему │
|
||||
│ │
|
||||
│ ┌─ Общая оценка ────────────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ ⏱️ 24 часа (~3 рабочих дня) │ │
|
||||
│ │ 📊 Сложность: Средняя │ │
|
||||
│ │ │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Разбивка по ролям ───────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ 👩💻 Frontend │ 16ч │ ████████████████░░░░ │ Средняя │ │
|
||||
│ │ 🎨 Дизайнер │ 4ч │ ████░░░░░░░░░░░░░░░░ │ Лёгкая │ │
|
||||
│ │ 🧪 QA │ 4ч │ ████░░░░░░░░░░░░░░░░ │ Лёгкая │ │
|
||||
│ │ │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Рекомендации ────────────────────────────────────────────────────────┐ │
|
||||
│ │ • Использовать CSS custom properties для цветовой схемы │ │
|
||||
│ │ • Добавить переключатель в настройки пользователя │ │
|
||||
│ │ • Учесть системные настройки (prefers-color-scheme) │ │
|
||||
│ └───────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [Сохранить оценку] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. UI Specification
|
||||
|
||||
### 5.1 Цветовая палитра
|
||||
|
||||
#### Основные цвета
|
||||
```
|
||||
Primary: #1976D2 (MUI Blue 700)
|
||||
Primary Light: #42A5F5 (MUI Blue 400)
|
||||
Primary Dark: #1565C0 (MUI Blue 800)
|
||||
|
||||
Secondary: #9C27B0 (MUI Purple 500)
|
||||
|
||||
Background: #FFFFFF
|
||||
Surface: #F5F5F5 (Grey 100)
|
||||
```
|
||||
|
||||
#### Статусы идей
|
||||
```
|
||||
New: #4CAF50 (Green 500) 🟢
|
||||
Discussing: #FF9800 (Orange 500) 🟡
|
||||
Approved: #2196F3 (Blue 500) 🔵
|
||||
In Progress: #9C27B0 (Purple 500) 🟣
|
||||
Done: #607D8B (Blue Grey 500) ⚫
|
||||
Rejected: #F44336 (Red 500) 🔴
|
||||
```
|
||||
|
||||
#### Приоритеты
|
||||
```
|
||||
Critical: #D32F2F (Red 700) фон: #FFEBEE
|
||||
High: #F57C00 (Orange 700) фон: #FFF3E0
|
||||
Medium: #FBC02D (Yellow 700) фон: #FFFDE7
|
||||
Low: #388E3C (Green 700) фон: #E8F5E9
|
||||
```
|
||||
|
||||
#### Цвета для маркировки строк
|
||||
```
|
||||
Без цвета: transparent
|
||||
Красный: #FFCDD2 (Red 100)
|
||||
Оранжевый: #FFE0B2 (Orange 100)
|
||||
Жёлтый: #FFF9C4 (Yellow 100)
|
||||
Зелёный: #C8E6C9 (Green 100)
|
||||
Голубой: #BBDEFB (Blue 100)
|
||||
Фиолетовый: #E1BEE7 (Purple 100)
|
||||
```
|
||||
|
||||
### 5.2 Типографика
|
||||
|
||||
```
|
||||
Font Family: 'Roboto', 'Helvetica', 'Arial', sans-serif
|
||||
|
||||
H1: 24px, weight 500, line-height 1.2
|
||||
H2: 20px, weight 500, line-height 1.3
|
||||
H3: 16px, weight 500, line-height 1.4
|
||||
Body1: 14px, weight 400, line-height 1.5
|
||||
Body2: 12px, weight 400, line-height 1.43
|
||||
Caption: 12px, weight 400, line-height 1.66, color: #757575
|
||||
```
|
||||
|
||||
### 5.3 Компоненты
|
||||
|
||||
#### Кнопки
|
||||
|
||||
| Тип | Использование | Стиль |
|
||||
|-----|---------------|-------|
|
||||
| Primary | Главное действие (Сохранить, Создать) | Filled, Primary color |
|
||||
| Secondary | Вторичные действия (Отмена) | Outlined, Grey |
|
||||
| Text | Третичные действия (Назад) | Text only |
|
||||
| Icon | Действия в строке таблицы | IconButton, 40x40px |
|
||||
| Danger | Удаление | Filled, Red |
|
||||
|
||||
```
|
||||
Border Radius: 4px
|
||||
Height: 36px (medium), 40px (large)
|
||||
Padding: 8px 16px
|
||||
```
|
||||
|
||||
#### Состояния кнопок
|
||||
```
|
||||
Default: opacity 1
|
||||
Hover: brightness 0.95, shadow elevation 2
|
||||
Active: brightness 0.9
|
||||
Disabled: opacity 0.38, cursor not-allowed
|
||||
Loading: показать CircularProgress (20px), disabled
|
||||
```
|
||||
|
||||
#### Инпуты
|
||||
|
||||
```
|
||||
Height: 40px
|
||||
Border: 1px solid #E0E0E0
|
||||
Border Radius: 4px
|
||||
Padding: 8px 12px
|
||||
|
||||
Focus: border-color: Primary, box-shadow: 0 0 0 2px Primary/20%
|
||||
Error: border-color: #D32F2F, helper text red
|
||||
Disabled: background: #F5F5F5, opacity 0.6
|
||||
```
|
||||
|
||||
#### Таблица
|
||||
|
||||
```
|
||||
Header:
|
||||
Background: #FAFAFA
|
||||
Font: 14px, weight 500
|
||||
Height: 48px
|
||||
Border: 1px solid #E0E0E0 (bottom)
|
||||
|
||||
Row:
|
||||
Height: 52px
|
||||
Border: 1px solid #E0E0E0 (bottom)
|
||||
Hover: background #F5F5F5
|
||||
|
||||
Row (colored):
|
||||
Background: соответствующий цвет из палитры маркировки
|
||||
Hover: darken 5%
|
||||
|
||||
Cell:
|
||||
Padding: 16px
|
||||
Vertical align: middle
|
||||
```
|
||||
|
||||
#### Dropdown/Select
|
||||
|
||||
```
|
||||
Trigger: как Input
|
||||
Menu:
|
||||
Background: #FFFFFF
|
||||
Shadow: 0 2px 8px rgba(0,0,0,0.15)
|
||||
Border Radius: 4px
|
||||
Max Height: 300px (scroll)
|
||||
|
||||
Item:
|
||||
Height: 40px
|
||||
Padding: 8px 16px
|
||||
Hover: background #F5F5F5
|
||||
Selected: background Primary/10%, color Primary
|
||||
```
|
||||
|
||||
#### Модальные окна
|
||||
|
||||
```
|
||||
Overlay: rgba(0, 0, 0, 0.5)
|
||||
Background: #FFFFFF
|
||||
Border Radius: 8px
|
||||
Shadow: 0 8px 32px rgba(0,0,0,0.2)
|
||||
Width: 480px (small), 640px (medium), 800px (large)
|
||||
Max Height: 90vh
|
||||
Padding: 24px
|
||||
|
||||
Header:
|
||||
Font: H2
|
||||
Border: 1px solid #E0E0E0 (bottom)
|
||||
Padding: 24px 24px 16px
|
||||
|
||||
Footer:
|
||||
Border: 1px solid #E0E0E0 (top)
|
||||
Padding: 16px 24px
|
||||
Justify: flex-end
|
||||
Gap: 12px
|
||||
```
|
||||
|
||||
### 5.4 Состояния загрузки
|
||||
|
||||
#### Skeleton Loader
|
||||
```
|
||||
Для таблицы:
|
||||
- Показать 5 строк skeleton
|
||||
- Анимация: shimmer effect (gradient slide)
|
||||
- Background: #E0E0E0
|
||||
- Highlight: #F5F5F5
|
||||
|
||||
Для карточек/полей:
|
||||
- Прямоугольники с закруглением 4px
|
||||
- Высота соответствует контенту
|
||||
```
|
||||
|
||||
#### Spinner (CircularProgress)
|
||||
```
|
||||
Size: 24px (в кнопках), 40px (в контенте)
|
||||
Color: Primary
|
||||
Thickness: 3.6
|
||||
```
|
||||
|
||||
#### Inline Loading (в ячейках таблицы)
|
||||
```
|
||||
Показать маленький spinner (16px) справа от текста
|
||||
Текст затемнить (opacity 0.5)
|
||||
```
|
||||
|
||||
### 5.5 Анимации
|
||||
|
||||
```
|
||||
Duration:
|
||||
Fast: 150ms (hover effects)
|
||||
Normal: 250ms (transitions)
|
||||
Slow: 350ms (modals, large elements)
|
||||
|
||||
Easing:
|
||||
Standard: cubic-bezier(0.4, 0, 0.2, 1)
|
||||
Enter: cubic-bezier(0.0, 0, 0.2, 1)
|
||||
Exit: cubic-bezier(0.4, 0, 1, 1)
|
||||
|
||||
Drag & Drop:
|
||||
Item lift: scale 1.02, shadow elevation 8
|
||||
Drop zone: border 2px dashed Primary, background Primary/5%
|
||||
```
|
||||
|
||||
### 5.6 Иконки
|
||||
|
||||
Использовать **Material Icons** (MUI Icons).
|
||||
|
||||
```
|
||||
Размеры:
|
||||
Small: 18px
|
||||
Medium: 24px (default)
|
||||
Large: 36px
|
||||
|
||||
Основные иконки:
|
||||
Добавить: Add (+)
|
||||
Редактировать: Edit (карандаш)
|
||||
Удалить: Delete (корзина)
|
||||
Drag: DragIndicator (⋮⋮)
|
||||
Фильтр: FilterList
|
||||
Поиск: Search (🔍)
|
||||
Комментарий: ChatBubbleOutline
|
||||
AI: AutoAwesome (✨) или SmartToy (🤖)
|
||||
Развернуть: ExpandMore
|
||||
Свернуть: ExpandLess
|
||||
```
|
||||
|
||||
### 5.7 Отступы и сетка
|
||||
|
||||
```
|
||||
Spacing unit: 8px
|
||||
|
||||
Margins/Paddings:
|
||||
xs: 4px
|
||||
sm: 8px
|
||||
md: 16px
|
||||
lg: 24px
|
||||
xl: 32px
|
||||
|
||||
Container:
|
||||
Max width: 1440px
|
||||
Padding: 24px (desktop), 16px (tablet), 12px (mobile)
|
||||
|
||||
Table:
|
||||
Min width: 1024px
|
||||
Horizontal scroll на меньших экранах
|
||||
```
|
||||
|
||||
### 5.8 Breakpoints
|
||||
|
||||
```
|
||||
xs: 0px
|
||||
sm: 600px
|
||||
md: 900px
|
||||
lg: 1200px
|
||||
xl: 1536px
|
||||
|
||||
Desktop-first approach:
|
||||
Основной дизайн для lg+ (1200px+)
|
||||
Адаптация для md (900-1199px)
|
||||
Горизонтальный скролл для sm и ниже
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Error States
|
||||
|
||||
### 6.1 Validation Errors
|
||||
|
||||
```
|
||||
Inline под полем:
|
||||
Color: #D32F2F
|
||||
Font: 12px
|
||||
Icon: ErrorOutline (слева от текста)
|
||||
Margin top: 4px
|
||||
```
|
||||
|
||||
### 6.2 API Errors
|
||||
|
||||
```
|
||||
Toast notification (Snackbar):
|
||||
Position: bottom-left
|
||||
Duration: 5000ms (auto-hide)
|
||||
Background: #D32F2F
|
||||
Color: #FFFFFF
|
||||
Action: "Повторить" (если применимо)
|
||||
```
|
||||
|
||||
### 6.3 Empty States
|
||||
|
||||
```
|
||||
Центрированный блок:
|
||||
Icon: 64px, Grey 400
|
||||
Title: H2, Grey 700
|
||||
Description: Body1, Grey 500
|
||||
Action: Primary Button
|
||||
|
||||
Примеры:
|
||||
Нет идей: "Список пуст. Создайте первую идею!"
|
||||
Нет команды: "Добавьте членов команды для AI-оценки"
|
||||
Нет результатов: "По вашему запросу ничего не найдено"
|
||||
```
|
||||
Reference in New Issue
Block a user