# 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-пайплайне.