docs: закрытие продуктовых рисков и новый LDD baseline
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
# 08. План реализации: группы, курсы, преподаватели
|
||||
|
||||
**Статус:** план согласован, этапы 0–6 выполнены. Этап 6 закрыт: права
|
||||
преподавателя на запись, аудит и CI добавлены; остаточные риски — § 9.1 и
|
||||
[16-stage6-report.md](16-stage6-report.md).
|
||||
преподавателя на запись, аудит и CI добавлены; продуктовые риски (legacy-активы,
|
||||
срок жизни JWT/сессии, пагинация аудита) закрыты 2026-10-28. Оставшиеся
|
||||
ограничения — § 9.1 и [16-stage6-report.md](16-stage6-report.md).
|
||||
**Основа:** [07-groups-courses.md](07-groups-courses.md).
|
||||
**Дата решений:** 2026-10-23.
|
||||
|
||||
@@ -195,10 +196,12 @@
|
||||
привязка групп, авторские материалы курса.
|
||||
- Полная security-матрица и negative-тесты «свой/чужой курс».
|
||||
- Upgrade-тест миграций.
|
||||
- Индексы; пагинация и N+1 — follow-up (§ 9.1).
|
||||
- Индексы; пагинация аудита и bulk-выдача групп с именами — выполнены;
|
||||
оставшийся N+1 в отдельных лабораторных списках — follow-up (§ 9.1).
|
||||
- Аудит скачиваний и чувствительных действий (`identity.audit_events`,
|
||||
`/admin/audit`).
|
||||
- CI merge gate: `test ktlintCheck detekt` на каждом push/MR.
|
||||
- CI merge gate: `test ktlintCheck detekt evidenceCheck` и smoke полного стека
|
||||
на каждом push/MR; полный `release-evidence` — для тегов/вручную.
|
||||
- Проверка backup: создание, retention, `verify`, restore на staging.
|
||||
- Документация, deploy/runbook, smoke.
|
||||
|
||||
@@ -208,11 +211,11 @@
|
||||
|
||||
Номера уточняются при реализации, чтобы не конфликтовать с максимумами master
|
||||
(identity V3, **academic V5**, progress V12). Максимумы этой ветки:
|
||||
identity V10, **academic V12**, progress V13.
|
||||
identity V11, **academic V12**, progress V13.
|
||||
|
||||
| Сервис | Миграции | Содержание |
|
||||
|---|---|---|
|
||||
| identity | V4–V10 | роли, поля групп, статусы студентов, `membership_history`, `promotion_runs/items`, `accounts.status`; `V10` — `audit_events` без внешних ключей и индексы по `occurred_at`/`action` |
|
||||
| identity | V4–V11 | роли, поля групп, статусы студентов, `membership_history`, `promotion_runs/items`, `accounts.status`; `V10` — `audit_events` без внешних ключей и индексы по `occurred_at`/`action`; `V11` — `refresh_tokens` (хеш, срок, отзыв, цепочка замен) |
|
||||
| academic | V6–V12 + post-bootstrap step | курсы, преподаватели, группы курса, `labs.course_id` (nullable), материалы курса/аудитории, частичные индексы, активы; `V10` — уникальный индекс `lower(title)` по курсам; `V11` — backfill `audience='ALL'` для глобальных глав; `V12` — backfill связей `article_assets` из markdown-ссылок; `SET NOT NULL` — post-bootstrap шаг вне Flyway |
|
||||
| progress | V13 | `grade_comments.author_account_id`, `lab_grades.updated_by_account_id`, индекс `lab_grades(lab_id)`; аудит реализован в identity `V10` |
|
||||
|
||||
@@ -291,11 +294,16 @@ identity V10, **academic V12**, progress V13.
|
||||
- **Межсервисная авторизация.** Самый сложный участок; ADR до кода.
|
||||
- **Перенос данных.** Нужны preflight и копия БД; группы с нестандартными именами
|
||||
и дубли номеров лаб могут заблокировать `NOT NULL`.
|
||||
- **Legacy-активы.** Связанные активы наследуют видимость статьи (миграция `V12`),
|
||||
но файлы без markdown-ссылки остаются публичными; нужна инвентаризация и
|
||||
привязка или удаление.
|
||||
- **JWT 30 дней.** Средний вариант блокировки оставляет остаточный риск для
|
||||
прямого API; фиксируем в документации.
|
||||
- **Legacy-активы.** Закрыто: связанные активы наследуют видимость статьи
|
||||
(миграция `V12`), а файлы без markdown-ссылки по умолчанию отдают `404`
|
||||
анониму/студенту/преподавателю. Админ перечисляет их через
|
||||
`GET /api/v1/content/legacy-assets` для привязки или удаления.
|
||||
- **JWT и сессии.** Закрыто: access-токен 15 минут, refresh 7 дней с ротацией
|
||||
и отзывом, web-сессия 7 дней sliding. Прямые API-клиенты используют
|
||||
`POST /api/v1/auth/refresh`; logout и смена пароля отзывают refresh.
|
||||
- **Оставшаяся производительность.** Аудит постраничный и группы курса
|
||||
отдаются одним вызовом, но N+1 в отдельных лабораторных списках и
|
||||
offset-пагинация аудита остаются лабораторными деталями.
|
||||
- **Комментарии без автора.** Старые записи останутся с «автор не указан».
|
||||
- **Архивные студенты.** Открывать ли профиль после отвязки группы — уточнить
|
||||
на этапе 3; по умолчанию история курса доступна, если студент был в курсе.
|
||||
@@ -326,24 +334,25 @@ identity V10, **academic V12**, progress V13.
|
||||
- **Этап 6 — выполнен.** Права преподавателя на запись (лабораторные,
|
||||
ведомость, группы, материалы), центральный аудит `identity.audit_events`
|
||||
с `/admin/audit`, CI merge gate и полный hardening. Проверены прогон
|
||||
тестов/линтеров (**267**), upgrade миграций с master-схемы (identity
|
||||
`V4–V10`, academic `V6–V12`, progress `V13`), security-матрица, gateway,
|
||||
видимость активов и deploy-runbook. Отчёт: [16-stage6-report.md](16-stage6-report.md).
|
||||
тестов/линтеров (**319**, 0 failures), upgrade миграций с master-схемы
|
||||
(identity `V4–V11`, academic `V6–V12`, progress `V13`), security-матрица,
|
||||
gateway, видимость активов и deploy-runbook. LDD baseline: **46 claims
|
||||
(25 P0 / 21 P1), 46/46 proven**, browser E2E 4/4. Отчёт:
|
||||
[16-stage6-report.md](16-stage6-report.md).
|
||||
|
||||
### 9.1. Известные пробелы после этапа 6
|
||||
|
||||
- **Legacy-активы без привязки.** Маршрут `/api/v1/content/assets/{name}`
|
||||
проверяет `article_assets → article → section → chapter`, а `V12`
|
||||
восстанавливает связи из markdown. Файлы без ссылок в статьях остаются
|
||||
публичными; нужна инвентаризация и привязка или удаление.
|
||||
- **Импорт.** Старый формат не поддерживается; ведущие нули номера группы
|
||||
нормализуются (`01` → `1`).
|
||||
- **JWT 30 дней.** Web перепроверяет статус каждые 45 секунд, но прямой API
|
||||
с уже выданным токеном живёт до истечения; нужны короткий TTL + refresh
|
||||
или revocation.
|
||||
- **Пагинация и N+1.** Журнал аудита ограничен `limit` без offset/keyset;
|
||||
часть списков групп, материалов и ведомости отдаётся целиком; на больших
|
||||
объёмах нужны пагинация и пакетные выборки.
|
||||
- **Импорт.** Старый формат не поддерживается, принимается только шаблон v2.
|
||||
Номер группы — числовой; отдельного требования к ведущим нулям нет.
|
||||
- **Пагинация и N+1.** `GET /api/v1/audit` поддерживает `page` + `limit`,
|
||||
в UI есть «Показать ещё»; `GET /api/v1/courses/{id}/groups` отдаёт
|
||||
привязанные группы с именами одним вызовом. Остаются offset-пагинация
|
||||
аудита и N+1 в отдельных лабораторных списках/ведомости на больших курсах.
|
||||
- **Абсолютный лимит сессии.** Web-сессия скользящая (7 дней) и отзывается
|
||||
при выходе/смене пароля/закрытии доступа, но при непрерывной активности
|
||||
может жить бессрочно; при необходимости нужен абсолютный `max-age`.
|
||||
- **Внешняя интеграция.** «Контингент»/`next.uniyar.ac.ru` остаётся заделом:
|
||||
отдельный anti-corruption слой и внешние идентификаторы — позже.
|
||||
|
||||
## 10. Definition of Done
|
||||
|
||||
@@ -354,8 +363,13 @@ identity V10, **academic V12**, progress V13.
|
||||
- Профиль показывает статистику, комментарии и все попытки; файлы скачиваются.
|
||||
- Повышение, академотпуск, выпуск и архив работают по ТЗ.
|
||||
- Аудит чувствительных действий пишется в `identity.audit_events` и доступен
|
||||
админу на `/admin/audit`.
|
||||
- Security-матрица и миграционный upgrade-тест зелёные.
|
||||
- CI на каждом push/MR прогоняет `test ktlintCheck detekt`.
|
||||
админу на `/admin/audit` с пагинацией.
|
||||
- Активы наследуют видимость материала; файлы без привязки не публичны и
|
||||
доступны только админу через инвентаризацию `legacy-assets`.
|
||||
- Access/refresh-токены и web-сессия работают по срокам 15 минут / 7 дней /
|
||||
7 дней; logout, смена пароля и закрытие доступа отзывают refresh.
|
||||
- Security-матрица и миграционный upgrade-тест зелёные (identity до `V11`).
|
||||
- CI на каждом push/MR прогоняет `test ktlintCheck detekt evidenceCheck` и
|
||||
smoke полного стека; полный release-evidence обязателен для тегов.
|
||||
- Backup перед деплоем обязателен; restore проверен на staging.
|
||||
- Документация, deploy/runbook и smoke обновлены.
|
||||
|
||||
Reference in New Issue
Block a user