feat(web): перевести браузерные URL курсов на courseNo

- teacher/admin course pages, content, gradebook, profile, downloads
- courseNo -> UUID только на границе REST API
- обновлены e2e, шаблоны, тесты и docs
- LDD-UI-002; baseline 59 claims / 385 тестов
This commit is contained in:
2026-10-29 19:51:03 +03:00
parent b57a5ffbce
commit 65ed08f5c2
45 changed files with 1058 additions and 352 deletions

View File

@@ -92,7 +92,7 @@ progress `:8083`, web `:8090`. Интерфейс: `http://localhost:8090`.
отдельной CI VM: Woodpecker Docker backend, nested dind, Java 21,
Docker Compose v2, Python 3, Node и Chromium/Firefox/WebKit. Установка —
[`deploy/WOODPECKER.md`](deploy/WOODPECKER.md).
Baseline: **58 claims, 368 тестов, 18/18 browser E2E**.
Baseline: **59 claims, 385 тестов, 18/18 browser E2E**.
## Запуск в Docker (для сервера)
@@ -152,16 +152,16 @@ cp .env.prod.example .env.prod # заполнить LMS_DB_PASSWORD
с одноразовым паролем; преподаватель видит только назначенные курсы
(`/teacher`), их группы, студентов и профили. Курсы и лабораторные
фильтруются по роли, внутренние вызовы identity защищены `LMS_INTERNAL_TOKEN`.
- **Профиль студента курса**: `/teacher/courses/{id}/students/{id}` и админский
- **Профиль студента курса**: `/teacher/courses/{courseNo}/students/{studentId}` и админский
маршрут показывают сводку, оценки, комментарии с авторами, защиты и все
попытки сдачи со скачиванием ZIP; студенту API отдаёт только его профиль
и опубликованные данные.
- **Работа преподавателя**: ведомость группы переиспользует
`/admin/groups/{groupId}?courseId=...` без админских контролов — оценки и
`/admin/groups/{groupId}?courseNo=...` без админских контролов — оценки и
комментарии, публикация, уровни/варианты и раздача, защиты (код/reset),
скачивание попыток и ZIP группы; лабораторные/уровни/варианты своего курса,
привязка/отвязка групп на `/teacher/courses/{id}`, авторские материалы на
`/teacher/courses/{id}/content`. Чужой курс отклоняется на сервисах.
привязка/отвязка групп на `/teacher/courses/{courseNo}`, авторские материалы на
`/teacher/courses/{courseNo}/content`. Чужой курс отклоняется на сервисах.
- **Аудит**: чувствительные действия (профили, скачивания, оценки, защиты,
курсы, группы, материалы, преподаватели, жизненный цикл) пишутся в
`identity.audit_events`; админ смотрит `/admin/audit` с фильтром по действию,