feat: align UI with T-Bank design system, redesign landing page with bento layout, migrate shared utilities from SparkGuardian, standardize status chips and date formatters, remove explicit date inputs, and add project README

This commit is contained in:
Микаэл Оганесян
2026-04-16 03:31:48 +03:00
parent c99df2d86e
commit 44b80cd4b5
87 changed files with 14046 additions and 455 deletions

253
docs/INTEGRATION.md Normal file
View File

@@ -0,0 +1,253 @@
# Frontend Integration Guide
Этот документ нужен фронтенду как краткая рабочая инструкция по интеграции с `SparkGuardBackend`.
## Что использовать как основной контракт
Frontend-команде нужно отдать три файла:
1. `cmd/rest/controllers/docs/swagger.json` — машинно-читаемый OpenAPI/Swagger контракт.
2. `docs/api/README.md` — краткий REST-обзор по сценариям и смыслу ручек.
3. `docs/frontend/README.md` — этот документ с прикладными рекомендациями для экранов и polling flow.
## Базовые принципы
- frontend общается только с backend;
- frontend не ходит в `SparkGuardAntiplagiarism`, Kafka или MinIO;
- upload и check — это два разных шага;
- dashboards должны использовать `summary/stats` endpoints, а не `chunks`;
- `chunks` и `report.raw.json` — только debug/admin слой.
## Авторизация
### Вход
- `POST /auth/login`
Ответ:
```json
{
"user": {
"id": 1,
"name": "Admin",
"email": "admin@example.com",
"access_level": "Admin"
},
"token": "jwt"
}
```
### Текущий пользователь
- `GET /auth/me`
Передавать:
```http
Authorization: Bearer <jwt>
```
## Справочники и CRUD
Основные сущности:
- `users`
- `students`
- `groups`
- `events`
- `works`
- `reference-sets`
Для большинства таблиц frontend может опираться на стандартный CRUD:
- list: `GET`
- create: `POST`
- get one: `GET /:id`
- update: `PATCH` или `PUT`
- delete: `DELETE`
## Основной flow проверки работы
### 1. Создать work
- `POST /works`
### 2. Загрузить архив
- `PUT /works/:id/archive`
Поддерживаются:
- raw `application/octet-stream`
- `multipart/form-data`
Ответ:
```json
{
"message": "archive uploaded",
"status": "Stored",
"archive_object_key": "submissions/12/101.zip",
"archive_checksum": "sha256...",
"archive_size": 20480
}
```
### 3. Запустить проверку
- `POST /works/:id/check`
Ответ:
```json
{
"message": "analysis queued for current archive",
"analysis_run_id": "uuid",
"status": "Queued"
}
```
### 4. Poll статуса
- `GET /analysis-runs/:id`
Frontend должен ждать состояния:
- `Queued`
- `Processing`
- `Completed`
- `Failed`
Рекомендуемый polling:
- каждые `2-3` секунды первые `30` секунд;
- затем каждые `5` секунд;
- останавливать polling на `Completed` или `Failed`.
### 5. После завершения читать результат
- `GET /analysis-runs/:id/adoptions`
- `GET /analysis-runs/:id/report.json`
- `GET /analysis-runs/:id/report.html`
- `GET /analysis-runs/:id/report.pdf`
- `GET /works/:id/summary`
## Какие endpoints использовать для экранов
### Экран списка/карточки работы
- `GET /works`
- `GET /works/:id`
- `GET /works/:id/analysis-runs`
- `GET /works/:id/summary`
`GET /works/:id/summary` — основной endpoint для детального экрана работы.
Он уже отдаёт:
- `presentation_summary`
- `trust_score`
- `plagiarism_rate`
- strongest counterpart
- `counterparts`
- `graph`
- latest run metadata
### Экран события
- `GET /events`
- `GET /events/:id`
- `GET /events/:id/works`
- `GET /events/:id/summary`
### Экран группы
- `GET /groups`
- `GET /groups/:id`
- `GET /groups/:id/stats`
### Экран студента
- `GET /students`
- `GET /students/:id`
- `GET /students/:id/stats`
### Экран отчёта преподавателя
- основа: `GET /analysis-runs/:id/report.json`
- экспорт:
- `GET /analysis-runs/:id/report.html`
- `GET /analysis-runs/:id/report.pdf`
### Экран аудита
- `GET /audit-logs`
Фильтры:
- `actor_user_id`
- `action`
- `resource_type`
- `resource_id`
- `source`
- `limit`
Этот endpoint нужен только для admin UI.
## Что означает summary/statistics payload
Во всех `summary/stats` ручках frontend получает одинаковые строительные блоки:
- `presentation_summary`
- `works`
- `graph`
### `presentation_summary`
Основные поля:
- `works_total`
- `works_checked`
- `works_completed`
- `works_failed`
- `works_flagged`
- `counterparts_count`
- `connections_count`
- `plagiarism_rate`
- `trust_score`
- `risk_level`
- `headline`
### `graph`
- `nodes` — вершины графа работ;
- `edges` — связи между работами;
- использовать для экрана "`кто с кем совпадает`".
## Что не нужно использовать для продуктового UI
- `GET /analysis-runs/:id/chunks`
- `GET /analysis-runs/:id/report.raw.json`
Они нужны для:
- отладки пайплайна;
- технической диагностики;
- проверки Kafka/analyzer boundary.
## Ошибки
Формат ошибок стабилен:
```json
{
"message": "Краткое описание",
"error": "Технические детали"
}
```
Для UI обычно показывать:
- `message` пользователю;
- `error` — только в debug/admin mode.

236
docs/REST-API.md Normal file
View File

@@ -0,0 +1,236 @@
# REST API
Этот документ описывает внешний REST-контракт `SparkGuardBackend`.
## Общие правила
- авторизация: `Authorization: Bearer <jwt>`;
- frontend работает только с backend, не с analyzer и не с MinIO;
- `upload` и `check` — разные действия;
- full report скачивается только через backend.
Формат ошибки:
```json
{
"message": "Краткое описание",
"error": "Технические детали"
}
```
## Основной сценарий
1. `POST /auth/login`
2. `GET /auth/me`
3. `GET /readyz`
4. `POST /students`
5. `POST /groups`
6. `POST /groups/:id/students/:student_id`
7. `POST /events`
8. `POST /works`
9. `PUT /works/:id/archive`
10. `POST /works/:id/check`
11. `GET /analysis-runs/:id`
12. дождаться `Queued -> Completed` или `Failed`
13. `GET /works/:id/summary`
14. `GET /events/:id/summary`
15. `GET /analysis-runs/:id/report.json`
16. `GET /analysis-runs/:id/report.html`
17. `GET /analysis-runs/:id/report.pdf`
18. `GET /audit-logs` — только для admin UI
## Works
- `GET /works`
- `POST /works`
- `GET /works/:id`
- `PUT /works/:id`
- `DELETE /works/:id`
- `PUT /works/:id/archive`
- `POST /works/:id/check`
- `GET /works/:id/archive`
- `GET /works/:id/analysis-runs`
- `GET /works/:id/summary`
- `GET /works/:id/adoptions`
- `GET /works/:id/adoptions/related`
- `GET /works/:id/adoptions/archive`
### `PUT /works/:id/archive`
Смысл:
- repack архива;
- сохранение текущего архива в MinIO;
- обновление archive metadata у `work`;
- без создания `analysis_run`.
- принимает и raw `application/octet-stream`, и `multipart/form-data`.
Пример ответа:
```json
{
"message": "archive uploaded",
"status": "Stored",
"archive_object_key": "submissions/12/101.zip",
"archive_checksum": "sha256...",
"archive_size": 20480
}
```
### `POST /works/:id/check`
Смысл:
- создать новый `analysis_run` по текущему архиву;
- записать outbox message;
- отправить задачу в Kafka.
Пример ответа:
```json
{
"message": "analysis queued for current archive",
"analysis_run_id": "uuid",
"status": "Queued"
}
```
## Analysis runs
- `GET /analysis-runs/:id`
- `GET /analysis-runs/:id/chunks`
- `GET /analysis-runs/:id/adoptions`
- `GET /analysis-runs/:id/report.raw.json`
- `GET /analysis-runs/:id/report.json`
- `GET /analysis-runs/:id/report.html`
- `GET /analysis-runs/:id/report.pdf`
- `POST /analysis-runs/:id/retry`
### Что важно понимать
- `POST /works/:id/check` — единственная обычная команда запуска новой проверки;
- `GET /works/:id/analysis-runs` — история попыток по работе;
- `GET /analysis-runs/:id` — статус конкретной попытки;
- `GET /analysis-runs/:id/adoptions` — материализованные suspicious findings конкретного run;
- `GET /analysis-runs/:id/report.json/html/pdf` — teacher-facing отчёт для UI;
- `GET /analysis-runs/:id/chunks` и `GET /analysis-runs/:id/report.raw.json` — debug/admin endpoints, не обязательны frontend dashboards;
- `POST /analysis-runs/:id/retry` — человекочитаемая обычная ручка retry;
### Dashboard summaries
- `GET /works/:id/summary`
- `GET /events/:id/summary`
- `GET /students/:id/stats`
- `GET /groups/:id/stats`
Они отдают:
- `presentation_summary` — агрегаты для frontend dashboards;
- `trust_score` и `plagiarism_rate`;
- список работ/контрагентов с highest risk;
- `graph.nodes`/`graph.edges` для сценария "кто с кем совпадает".
## System
- `GET /healthz`
- `GET /readyz`
`healthz` — дешёвая liveness probe.
`readyz` — readiness check backend API, который проверяет доступность базы данных.
## Audit
- `GET /audit-logs`
Доступно только `Admin`.
Фильтры:
- `actor_user_id`
- `action`
- `resource_type`
- `resource_id`
- `source`
- `limit`
Аудит покрывает:
- административные CRUD-операции;
- group memberships;
- upload/check/retry по работам;
- reference set changes;
- reference ingestion scheduling;
- system completion events для reference ingestion.
### Teacher report
Teacher report содержит:
- `context`:
- работа;
- студент;
- группа;
- событие;
- archive metadata;
- `summary`:
- plagiarism probability;
- risk level;
- strongest counterpart;
- strongest match;
- `counterparts`;
- `evidence`;
- `technical`.
### Retry
`POST /analysis-runs/:id/retry`:
- не требует повторного upload;
- использует snapshot archive metadata исходного run;
- создаёт новый `analysis_run`.
## Adoptions
- `GET /adoptions/:id/segment`
Этот endpoint сначала читает snapshot excerpt из БД. Если excerpt ещё не materialized, только тогда он обращается к архиву.
## Reference sets
- `GET /reference-sets`
- `POST /reference-sets`
- `GET /reference-sets/:id`
- `PATCH /reference-sets/:id`
- `DELETE /reference-sets/:id`
- `GET /reference-sets/:id/ingestions`
- `POST /reference-sets/:id/ingestions`
Пример создания:
```json
{
"name": "course-template",
"description": "Шаблон лабораторной работы",
"kind": "template"
}
```
Пример ingestion ответа:
```json
{
"message": "accepted",
"ingestion_id": "uuid",
"status": "Queued",
"object_key": "reference-sets/7/uuid-template.zip"
}
```
## Что смотреть при отладке
- `GET /analysis-runs/:id` — статусы и error message;
- `GET /analysis-runs/:id/chunks` — Kafka compatibility flow;
- `GET /analysis-runs/:id/report.raw.json` — исходный analyzer output;
- `GET /works/:id/summary` — агрегированный work-level view поверх bilateral adoptions;
- `GET /works/:id/adoptions/related` — новые двусторонние связи по уже проверенным работам.

4272
docs/swagger.json Normal file

File diff suppressed because it is too large Load Diff