# REST API Этот документ описывает внешний REST-контракт `SparkGuardBackend`. ## Общие правила - авторизация: `Authorization: Bearer `; - 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` — новые двусторонние связи по уже проверенным работам.