This commit is contained in:
2026-01-14 01:10:01 +03:00
parent 24c5581d7b
commit 2ce092aa59
40 changed files with 2001 additions and 297 deletions

View File

@ -11,6 +11,7 @@ flowchart TB
subgraph external [" "]
User["👤 Пользователь<br/><i>Член команды разработки</i>"]
AI["🤖 AI Proxy Service<br/><i>LLM для оценки задач</i>"]
KC["🔐 Keycloak<br/><i>auth.vigdorov.ru<br/>Identity Provider</i>"]
end
subgraph system ["Team Planner"]
@ -18,11 +19,14 @@ flowchart TB
end
User -->|"Управляет идеями,<br/>командой, комментариями<br/>[HTTPS]"| TP
User -->|"Авторизация<br/>[OIDC/PKCE]"| KC
KC -->|"JWT токены"| 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
style KC fill:#c92a2a,color:#fff
```
### 1.2 Level 2: Container Diagram
@ -30,6 +34,7 @@ flowchart TB
```mermaid
flowchart TB
User["👤 Пользователь<br/><i>Член команды разработки</i>"]
KC["🔐 Keycloak<br/><i>auth.vigdorov.ru</i>"]
subgraph TeamPlanner ["Team Planner"]
SPA["📱 Frontend SPA<br/><i>React, TypeScript, MUI</i><br/><br/>Веб-интерфейс для<br/>работы с идеями"]
@ -40,7 +45,9 @@ flowchart TB
AI["🤖 AI Proxy Service<br/><i>LLM для оценки задач</i>"]
User -->|"Использует<br/>[HTTPS]"| SPA
SPA -->|"API запросы<br/>[REST/WebSocket]"| API
User <-->|"OIDC Login<br/>[Redirect]"| KC
SPA -->|"API запросы<br/>[REST + Bearer JWT]"| API
API -.->|"Валидация JWT<br/>[JWKS]"| KC
API -->|"Читает/пишет<br/>[TypeORM]"| DB
API -->|"Оценка трудозатрат<br/>[HTTPS/REST]"| AI
@ -49,12 +56,49 @@ flowchart TB
style DB fill:#438dd5,color:#fff
style User fill:#08427b,color:#fff
style AI fill:#999,color:#fff
style KC fill:#c92a2a,color:#fff
```
---
## 2. Sequence Diagrams
### 2.0 Авторизация (Keycloak OIDC)
```mermaid
sequenceDiagram
autonumber
actor User as Пользователь
participant FE as Frontend<br/>(React)
participant KC as Keycloak<br/>(auth.vigdorov.ru)
participant BE as Backend<br/>(NestJS)
User->>FE: Открывает приложение
FE->>FE: keycloak.init({ onLoad: 'login-required' })
FE->>KC: Redirect на /auth (PKCE)
KC-->>User: Форма входа
User->>KC: Вводит логин/пароль
KC->>KC: Проверяет credentials
KC-->>FE: Redirect с authorization code
FE->>KC: POST /token (code + code_verifier)
KC-->>FE: { access_token, refresh_token }
FE->>FE: Сохраняет токены в памяти
FE-->>User: Показывает приложение
Note over FE,BE: Все последующие API запросы
FE->>BE: GET /api/ideas<br/>Authorization: Bearer {token}
BE->>KC: GET /certs (JWKS, кэшируется)
KC-->>BE: Public keys
BE->>BE: Валидация JWT подписи
BE-->>FE: 200 OK { data }
Note over FE,KC: Автообновление токена (каждые 10 сек)
FE->>KC: POST /token (refresh_token)
KC-->>FE: { new_access_token }
```
### 2.1 Создание идеи
```mermaid
@ -986,3 +1030,69 @@ Toast notification (Snackbar):
Нет команды: "Добавьте членов команды для AI-оценки"
Нет результатов: "По вашему запросу ничего не найдено"
```
---
## 7. Авторизация (Keycloak)
### 7.1 Конфигурация Keycloak
| Параметр | Значение |
|----------|----------|
| URL | https://auth.vigdorov.ru |
| Realm | `team-planner` |
| Client ID | `team-planner-frontend` |
| Client Type | Public (no secret) |
| Authentication Flow | Authorization Code + PKCE |
### 7.2 Настройка Client в Keycloak
```
Client authentication: OFF (public client)
Standard flow: ON
Direct access grants: OFF
Valid redirect URIs: http://localhost:4000/*
Web origins: http://localhost:4000
```
### 7.3 Environment Variables
**Backend (.env):**
```
KEYCLOAK_REALM_URL=https://auth.vigdorov.ru/realms/team-planner
```
**Frontend (.env):**
```
VITE_KEYCLOAK_URL=https://auth.vigdorov.ru
VITE_KEYCLOAK_REALM=team-planner
VITE_KEYCLOAK_CLIENT_ID=team-planner-frontend
```
### 7.4 JWT Validation (Backend)
```typescript
// Валидация через JWKS (публичные ключи)
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `${realmUrl}/protocol/openid-connect/certs`,
})
// Проверки
issuer: KEYCLOAK_REALM_URL
algorithms: ['RS256']
```
### 7.5 Защищённые и публичные endpoints
| Endpoint | Доступ | Декоратор |
|----------|--------|-----------|
| `GET /` | Public | `@Public()` |
| `GET /health` | Public | `@Public()` |
| `GET /api/ideas` | Protected | — |
| `POST /api/ideas` | Protected | — |
| `PATCH /api/ideas/:id` | Protected | — |
| `DELETE /api/ideas/:id` | Protected | — |
| Все остальные | Protected | — |