Files
LMS/docs/evidence/baseline-2026-10-27.md

143 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LDD baseline: 2026-10-27
Первый прогон доказательной проверки текущей функциональности LMS.
Код приложения в этом прогоне не менялся; добавлены реестр claims, gate
`evidenceCheck`, runtime- и migration-скрипты.
## 1. Что проверялось
Реестр: `docs/evidence/claims.json`, 31 утверждение.
| Критичность | Claims | Proven | Gaps |
|---|---:|---:|---:|
| P0 | 19 | 19 | 0 |
| P1 | 12 | 12 | 0 |
| **Итого** | **31** | **31** | **0** |
Домены:
- доступы: аноним/студент/преподаватель/админ, чужие курс/лаба/студент/группа,
внутренние API identity;
- повышение: dry-run, apply, идемпотентность, rollback, cancel;
- жизненный цикл: академ, возврат, отчисление, архив, восстановление, вход;
- профиль студента и скачивание сдач;
- материалы и активы;
- миграция V13 и полный upgrade с master-схемы;
- аудит: токен, admin-only, сохранность после удаления, representative-хуки;
- группы курса, авторство материалов, ведомость, UI/контракты, импорт, копирование лаб;
- runtime-smoke полного стека.
## 2. Команды и результаты
### 2.1. Автоматические тесты
```bash
./gradlew test --rerun-tasks
```
Результат: **267 тестов, 0 failures, 0 errors, 0 skipped**.
`ktlintCheck` и `detekt` — зелёные.
### 2.2. LDD gate
```bash
./gradlew evidenceCheck
```
Результат: **31/31 claims proven, P0 gaps = 0**.
Отчёт: `build/reports/evidence/index.md`.
Gate устроен так:
- каждый claim ссылается на конкретный JUnit-тест `Class#method`;
- P0 без зелёного теста валит сборку;
- P1-пробел показывается в отчёте;
- runtime-проверки читаются из `build/evidence/*.json` и тоже должны быть
`passed`, если claim на них ссылается.
### 2.3. Upgrade с master-схемы
```bash
./scripts/ldd-migration-upgrade.sh
```
Сценарий: одноразовая PostgreSQL 18, master identity `V1–V3`, academic
`V1–V5`, progress `V1–V9,V11,V12`, синтетические данные, затем ветка:
identity `V4–V10`, academic `V6–V12`, progress `V13`.
Проверено:
- `identity.audit_events` создана;
- `students`, `groups`, `membership_history` сохранились;
- `labs.course_id`, `chapters.course_id`, `article_assets` созданы;
- `grade_comments.author_account_id`, `lab_grades.updated_by_account_id` созданы;
- оценки и комментарии сохранились;
- повторное применение `V13` идемпотентно.
Результат: **PASS**, evidence: `build/evidence/migration.json`.
### 2.4. Runtime-smoke полного стека
```bash
./scripts/ldd-runtime.sh
```
Сценарий: одноразовая БД, `bootJar`, запуск identity/academic/progress/gateway/web,
реальные HTTP-вызовы через gateway.
Проверено:
- health всех пяти сервисов = `UP`;
- `adminExists=false` до setup, создание админа, `/auth/me` = `ADMIN`;
- создание группы, курса, преподавателя, привязка группы, создание лабы;
- преподаватель входит и видит свой курс, лабу и состав группы;
- чужой преподаватель получает `403` на курс, лабу и аудит;
- админ видит audit-события `COURSE_CREATE`, `TEACHER_CREATE`,
`COURSE_TEACHER_ASSIGN`, `COURSE_GROUP_ATTACH`, `LAB_CREATE`;
- web `/login` отдаёт `200`, публичное дерево материалов доступно, курсовая
материалы анонимно — `401`.
Результат: **PASS**, evidence: `build/evidence/runtime.json`.
Стек и одноразовая БД после прогона остановлены/удалены.
## 3. Что это доказывает
- Критичные P0-инварианты доступа, повышения, жизненного цикла, профиля,
материалов, миграции и аудита имеют зелёные автоматические свидетельства.
- Приложение собирается, мигрируется с master-схемы и поднимается полным
стеком на чистой БД.
- Ключевой доменный поток «админ → группа → курс → преподаватель → лаба»
проходит через реальные HTTP/gateway/БД, а не только через mock.
- Чужой преподаватель не получает доступ к курсу/лабе/аудиту на реальном стеке.
- Аудит пишется и читается; upgrade не теряет синтетические данные.
## 4. Чего это не доказывает
1. **Нет браузерного E2E.** Thymeleaf-тесты проверяют HTML, но не реальные
клики/JS/CSRF/редиректы в браузере.
2. **Нет нагрузочных и конкурентных испытаний.** Advisory locks и гонки
проверены кодом и unit/integration-тестами, но не под нагрузкой.
3. **Нет mutation testing.** Сила тестов измерена косвенно; следующий шаг —
PIT на `CourseAccessService`, `PromotionService`, `StudentProfileService`.
4. **Нет property-based/model-based проверки повышения.** Один сценарный тест
не покрывает все комбинации курсов, степеней и академ-переходов.
5. **Legacy-активы без `article_assets` остаются публичными.**
6. **JWT живёт до 30 дней.** Web перепроверяет статус, прямой API — нет.
7. **Ведущие нули номера группы нормализуются** (`01` → `1`).
8. **Нет пагинации/keyset** для части списков и N+1 в отдельных экранах.
9. **Runtime-smoke не входит в unit-CI**; он запускается отдельным скриптом
перед релизом.
## 5. Вывод
Текущая функциональность прошла первый LDD-контур: **P0 gaps = 0**,
полный стек и upgrade работают. Это достаточное основание продолжать
доработки, но не «формальное доказательство всей системы». Следующий цикл
LDD должен добавить:
1. mutation testing для критичных пакетов;
2. property-based тесты повышения и матрицы доступа;
3. браузерный E2E (Playwright) для ведомости, профиля и материалов;
4. нагрузочный smoke на чтение ведомости/профиля;
5. автоматический runtime-smoke в release-пайплайне.