docs: актуализация под текущее состояние (Bootstrap вместо htmx, RestClient, интерцепторы, контроллеры, публикация по студентам, watch-опрос, автосейв без перезагрузки)
This commit is contained in:
@@ -146,6 +146,7 @@ sequenceDiagram
|
||||
P->>DB: INSERT/UPDATE variant_assignments (manual=false)
|
||||
P-->>W: DistributeResult(assigned, total)
|
||||
W-->>A: «Распределено: N из M»
|
||||
Note over A,W: UI — большая модалка «Выдача вариантов» на странице группы<br/>(фрагмент по fetch). Эндпоинт отвечает редиректом — это норма;<br/>модалка обновляется на месте, тост показывается поверх неё
|
||||
```
|
||||
|
||||
## 6. Сдача решения студентом
|
||||
@@ -214,13 +215,13 @@ sequenceDiagram
|
||||
P-->>W: DefenseDto
|
||||
W-->>S: «Работа сохранена»
|
||||
|
||||
Note over P,DB: DefenseService.syncTimeouts() переводит просроченные<br/>сессии в ready с ready_reason=timeout
|
||||
Note over P,DB: DefenseService.syncTimeouts() переводит просроченные<br/>сессии в ready с ready_reason=timeout; кнопка «Готов» даёт ready_reason=button.<br/>В UI: «Готов к сдаче» (button) / «Вышло время» (timeout)
|
||||
A->>W: «доп. задание: начать заново» → POST /admin/defenses/{id}/reset
|
||||
P->>DB: UPDATE status=waiting, code=NULL, started_at=NULL
|
||||
W-->>A: сессия снова ждёт кода
|
||||
```
|
||||
|
||||
## 8. Оценка, комментарии и публикация
|
||||
## 8. Оценка, комментарии и публикация (по студенту)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -235,19 +236,28 @@ sequenceDiagram
|
||||
W->>P: POST /api/v1/grades (GradeSetRequest)
|
||||
P->>DB: UPSERT lab_grades (student_id, lab_id, score)
|
||||
P->>DB: DELETE grade_comments по паре, затем INSERT новых
|
||||
P->>DB: UPSERT comment_templates (use_count++ для автоподсказок)
|
||||
Note over DB: comment_templates — подсказки; частота считается<br/>по актуальным grade_comments (не по use_count)
|
||||
P-->>W: GradeResponse
|
||||
Note over DB: Студент оценку пока НЕ видит
|
||||
|
||||
A->>W: «опубликовать оценки» → POST /admin/groups/{gid}/publish
|
||||
W->>P: POST /api/v1/grades/publish (labId, groupId, published=true)
|
||||
P->>DB: INSERT/DELETE grade_publications (group_id, lab_id)
|
||||
P-->>W: 200
|
||||
A->>W: чекбокс публикации в ячейке (student×lab) → POST /admin/groups/{gid}/publish-student
|
||||
W->>P: POST /api/v1/grades/publication {groupId, labId, studentIds[]} — заменяет набор
|
||||
P->>DB: DELETE/INSERT grade_publication_students<br/>(легаси grade_publications снимается)
|
||||
W-->>A: тост «Опубликовано: N из M», счётчик «глаза» обновлён
|
||||
|
||||
A->>W: «глаз» в шапке ЛР (всем / скрыть у всех) → POST /admin/groups/{gid}/publish (published=true|false)
|
||||
W->>P: POST /api/v1/grades/publication {studentIds = все | []}
|
||||
|
||||
A->>W: поиск подсказок → GET /admin/comment-templates?q=
|
||||
W->>P: GET /api/v1/comment-templates?q=
|
||||
P-->>W: [{text, tone, count}] — частота по текущим оценкам
|
||||
A->>W: удалить подсказку с частотой 0 → POST /admin/comment-templates/delete (text)
|
||||
W->>P: DELETE /api/v1/comment-templates?text= (400, если где-то используется)
|
||||
|
||||
S->>W: GET /student/labs/{labId}
|
||||
W->>P: GET /api/v1/me/grades?groupId=... (Bearer)
|
||||
P->>DB: SELECT lab_grades + grade_comments + grade_publications
|
||||
P-->>W: только опубликованные оценки группы
|
||||
P->>DB: SELECT lab_grades + grade_comments; фильтр isPublished(group, lab, student)
|
||||
P-->>W: только опубликованные этому студенту оценки
|
||||
W-->>S: оценка и комментарии списками: позитивный / негативный / нейтральный
|
||||
```
|
||||
|
||||
@@ -314,16 +324,18 @@ sequenceDiagram
|
||||
G->>ID: GroupService.detail (студенты по ФИО)
|
||||
W->>G: GET /api/v1/labs
|
||||
G->>AC: LabService.list (опубликованные ЛР)
|
||||
W->>G: GET /api/v1/assignments/group/{gid}
|
||||
G->>P: уровни и варианты всех студентов группы (bulk)
|
||||
loop по каждой лабораторной
|
||||
W->>G: GET /api/v1/assignments?labId
|
||||
G->>P: варианты студентов
|
||||
W->>G: GET /api/v1/submissions?labId
|
||||
G->>P: последние сдачи
|
||||
W->>G: GET /api/v1/defenses?labId
|
||||
G->>P: сессии защиты
|
||||
W->>G: GET /api/v1/grades/publication?groupId&labId
|
||||
G->>P: состояние публикации {all, studentIds}
|
||||
end
|
||||
W->>G: GET /api/v1/grades + /grades/publications?groupId
|
||||
G->>P: оценки
|
||||
W->>G: GET /api/v1/grades
|
||||
G->>P: все оценки (матрица)
|
||||
W->>W: сборка матрицы «студент × лабораторная»
|
||||
W-->>A: страница группы (оценки, защиты, поиск, фильтры, сортировка)
|
||||
```
|
||||
@@ -351,6 +363,32 @@ sequenceDiagram
|
||||
AC->>DB: UPDATE chapters.position,<br/>sections.chapter_id/position,<br/>articles.section_id/position
|
||||
AC-->>W: 200
|
||||
W-->>UI: {"ok": true}
|
||||
UI->>UI: location.reload() — страница из серверного состояния
|
||||
UI->>UI: без перезагрузки — DOM уже перестроен, статус «сохранено»
|
||||
Note over AC,DB: один запрос применяет и порядок, и перенос между родителями
|
||||
Note over UI: раскрытые разделы и позиция скролла сохраняются (localStorage / ui-state.js)
|
||||
```
|
||||
|
||||
## 12. Синхронизация таймеров защиты (опрос раз в 10 секунд)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor A as Преподаватель
|
||||
actor S as Студент
|
||||
participant W as web
|
||||
participant P as progress
|
||||
|
||||
loop каждые 10 c (страница группы)
|
||||
A->>W: GET /admin/defense-watch?labs=...
|
||||
W->>P: GET /api/v1/defenses/watch?labs=...
|
||||
P-->>W: статусы, secondsLeft, readyReason
|
||||
W-->>A: обновление ячеек; переход в ready → тост «ФИО — ЛР: Готов к сдаче / Вышло время»
|
||||
end
|
||||
|
||||
loop каждые 10 c (страница лабы студента)
|
||||
S->>W: GET /student/labs/{id}/defense-status
|
||||
W->>P: GET /api/v1/me/defenses/{labId}/status
|
||||
P-->>W: status / secondsLeft / readyReason
|
||||
W-->>S: подстройка таймера; при status != started — перезагрузка страницы
|
||||
end
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user