docs: план, ADR и контракты групп и курсов

This commit is contained in:
2026-10-26 15:47:01 +03:00
parent 920d96a0f5
commit cde04487e8
6 changed files with 945 additions and 18 deletions

91
docs/10-stage0-report.md Normal file
View File

@@ -0,0 +1,91 @@
# 10. Отчёт этапа 0: схема, контракты, preflight
**Дата:** 2026-10-23.
**Статус:** этап 0 выполнен на локальной копии БД; перед production нужен
повторный preflight на свежей копии.
## 1. Что сделано
- ADR с ключевыми решениями: [adr/0001-groups-courses-foundation.md](adr/0001-groups-courses-foundation.md).
- Контракт API профиля студента: [09-teacher-student-profile.md](09-teacher-student-profile.md).
- Миграции:
- identity `V4–V9`: роли, группы-когорты, статусы студентов, повышение,
история членства, статусы аккаунтов;
- academic `V6–V9`: курсы, преподаватели, группы курса, `labs.course_id`,
материалы курса/аудитории, индексы активов;
- progress `V10`: автор комментария и последнего изменения оценки.
- Preflight-скрипты:
- `deploy/preflight/groups-courses.sql` — до миграций;
- `deploy/preflight/groups-courses-post.sql` — после миграций/bootstrap.
- UI: статус защиты в ведомости различает «готова» и «кончилось время».
- Резервное копирование:
- `deploy/backup.sh` — БД + решения + материалы, checksums, retention,
`list`, `verify`, `restore`;
- `deploy/deploy.sh up` делает обязательный backup перед обновлением;
- systemd timer для ежедневного backup;
- инструкция `deploy/BACKUP.md`.
## 2. Проверка на пустой БД
Все миграции identity, academic и progress применены последовательно на чистой
БД PostgreSQL 18. Ошибок нет. Тесты сервисов на Testcontainers проходят.
## 3. Проверка на копии локальной БД
Скопирована локальная БД `lms` (41 аккаунт, 40 студентов, 2 группы, 1 лаба,
3 главы, 16 разделов, 35 статей, 6 комментариев).
Preflight до миграций:
- групп, не подходящих под шаблон, нет;
- конфликтующих кортежей когорт нет;
- дублей номеров лабораторных нет;
- дублей slug глав нет;
- студентов без группы нет.
Миграции применены успешно.
После миграций:
- `labs_without_course = 1` — ожидаемо до bootstrap;
- `chapters_without_course = 3` — ожидаемо до bootstrap;
- `courses = 0` — ожидаемо до bootstrap;
- `comments_without_author = 6` — ожидаемо для старых комментариев;
- группы разобраны полностью, `enrollment_year` заполнен.
## 4. Симуляция bootstrap
На копии вручную выполнено то, что будет делать bootstrap-сервис:
1. Создан курс C с владельцем-админом, `course_no = 1`.
2. Админ назначен преподавателем курса.
3. Обе активные группы привязаны к курсу.
4. Все лабы и главы получили `course_id`.
5. Выполнено `ALTER TABLE labs ALTER COLUMN course_id SET NOT NULL`.
Postflight:
- `labs_without_course = 0`;
- `chapters_without_course = 0`;
- курс C ровно один;
- `comments_without_author = 6` — старые данные, ожидаемо;
- группы без полного разбора отсутствуют.
## 5. Тесты и линтеры
- `./gradlew :services:identity-service:test :services:academic-service:test :services:progress-service:test :web:test` — успешно.
- `./gradlew ktlintCheck detekt` — успешно.
- `node --check web/src/main/resources/static/js/admin-group.js` — успешно.
- `bash -n deploy/backup.sh deploy/deploy.sh` — успешно.
- `./deploy/backup.sh backup` на локальной БД — успешно; `verify` проверил
`db.dump`, `submissions.tar.gz`, `assets.tar.gz` по SHA256.
- `git diff --check` — успешно.
## 6. Что осталось на этап 2
- Реализовать bootstrap-сервис курса C (создание курса, привязка групп,
назначение админа, перенос лаб/глав).
- Выбрать механизм post-bootstrap `SET NOT NULL` (CLI, admin endpoint или
отдельная Flyway-локация).
- Связать существующие активы со статьями при миграции контента.
- Повторить preflight на свежей копии production-БД перед деплоем.