# Спринт 1 — Редактор тестов: версионирование (desktop web) **Формат:** отдельное веб desktop-приложение (согласно ТЗ `task.md`, этап 1; приёмка руководителями подразделений). **Граница спринта:** **до** готовой цепочки **версий** теста, **привязки попыток** к версии, **UI** списков/истории/смены активной версии и **деактивации** цепочки. **Детальная нарезка и правила приёмки:** [card1.md](card1.md) (части **V.x**, **A.x** по мере готовности). **Дизайн:** не отходить от визуального языка внутренних веб-экранов клиники (типографика, отступы, таблицы, модалки). **Стек (факт по репозиторию [TestingWebApp](../../README.md)):** **Node.js** (API в `backend/`), **PostgreSQL**, **Docker**; фронтенд **desktop-first** SPA. Интеграция с [HR_TG_Bot](../../../HR_TG_Bot/README.md) / экосистемой — по готовности API-контрактов, **не** обязана совпадать с FastAPI, если в этом репо бэкенд на Node. При переносе на Python — пересмотреть только слой API, **смысл** [card1.md](card1.md) не меняется. --- ## Цель спринта Реализовать **§4.1 ТЗ** (версионирование) end-to-end: модель данных, бизнес-правила, API, UI автора, поведение для сотрудника и разбора **старых** результатов. --- ## Функциональные критерии готовности (из ТЗ 4.1) 1. Пока по тесту **не было попыток** — автор редактирует **на месте**, номер версии **не** инкрементируется. 2. После **первой** попытки каждое сохранение изменений создаёт **новую** версию (`version + 1`, связь `parent_id`), предыдущая версия **неактивна**, данные **сохраняются**. 3. Попытки привязаны к **конкретной** версии; разбор старых попыток **валиден** после правок. 4. В списках — **только одна** активная версия цепочки. 5. **История версий** + **ручная** смена активной версии; остальные — неактивны. 6. Тест можно **деактивировать** целиком (скрыть из списков, **без** удаления данных). --- ## Технические подзадачи (этапы внутри спринта) | # | Задача | См. в card1 | | --- | --- | --- | | 1 | Миграция: `parent_id`, инвариант «одна активная версия на `test_id`», флаг цепочки (деактивация) | V.1, V.6 | | 2 | Сервис: «0 попыток — in-place; иначе — fork + копия вопросов» | V.2, V.3 | | 3 | Попытка: `test_version_id` фиксируется **на старте**; не перезаписывается | V.4 | | 4 | API: CRUD с версиями; переключение активной; деактивация; списки без дублей | V.5, V.6, V.10 | | 5 | UI: версия, история, смена активной, списки | V.7, V.8 | | 6 | Тесты: unit + integration, регресс разбора | V.9 | **Авторизация на БД [Postgres_TG_Bots](../../../Postgres_TG_Bots):** [card1.md](card1.md) **A.1**–**A.5** — **в рамке спринта 1**, если согласовано (иначе — отдельной задачей сразу после V.1). **Загрузка документа → тест:** [card1.md](card1.md) **D.1**–**D.5** — **вне** замыкания **только** на версии; может пойти **после** V.3 или параллельно, зависит от **LLM** (§4.2). --- ## Вне спринта 1 (как в ТЗ) - Полный **AI-**модуль (§4.2) сверх **импорта** из карточки, **медиа** (§4.3), **подсказки** (§4.4), **режимы** (§4.5), **дашборды** (этап 2). --- ## Документ тестирования Чек-лист: [sprint-01-testing.md](sprint-01-testing.md).