# ШАГ 007 — Спринт 2: Прохождение теста + результат **Дата:** 2026-03-21 **Контекст:** Мастер-класс по разработке системы тестирования сотрудников клиники. --- ## Запрос > запускай реализацию спринта 2 --- ## Ответ Реализован Спринт 2: прохождение теста с таймером и навигацией, результат с разбором ошибок. --- ## Новые файлы ``` backend/app/models/attempt.py ← TestAttempt, AttemptAnswer backend/app/schemas/attempt.py ← схемы для старта, сдачи и результата backend/app/api/attempts.py ← 3 эндпоинта backend/alembic/versions/002_attempts.py ← миграция frontend/src/api/attempts.ts ← типы и запросы frontend/src/pages/TestTake/ ← страница прохождения теста frontend/src/pages/AttemptResult/ ← страница результата ``` --- ## API эндпоинты (новые) | Метод | URL | Описание | |-------|-----|----------| | POST | `/api/attempts` | Начать попытку → возвращает вопросы перемешанные, без правильных ответов | | POST | `/api/attempts/{id}/submit` | Сдать тест → подсчитать и вернуть результат | | GET | `/api/attempts/{id}/result` | Получить результат сохранённой попытки | --- ## Схема БД (добавлено) ``` test_attempts id, test_id → tests.id, started_at, finished_at, score, passed, correct_count, total_count, status attempt_answers id, attempt_id → test_attempts.id, question_id → questions.id, answer_id → answers.id ``` Одна строка `attempt_answers` = один выбранный вариант ответа. Для вопросов с несколькими правильными ответами — несколько строк. --- ## Логика прохождения теста **Старт попытки:** - Создаётся запись `TestAttempt` со статусом `in_progress` - Вопросы и ответы внутри каждого вопроса перемешиваются случайно - Поле `is_correct` **не передаётся** на фронт — нельзя смошенничать через DevTools - Поле `is_multiple: bool` говорит фронту: показывать радио-кнопки или чекбоксы **Сдача теста:** - Фронт отправляет `[{ question_id, answer_ids[] }]` для каждого вопроса - Вопрос засчитывается правильным только если `selected_ids == correct_ids` (точное совпадение) - Балл = (правильных / всего) × 100 - Зачёт: балл ≥ порогу из теста **Разбор ошибок:** - Для каждого вопроса: `is_answered_correctly` - Для каждого варианта: `is_correct` + `is_selected` → фронт показывает что выбрал и что было правильно --- ## UX прохождения теста - Вопросы по одному, прогресс-бар сверху - Таймер: если задан — обратный отсчёт, при `< 60 сек` — предупреждение, при `0` — автосабмит - Кнопка «Назад» заблокирована если `allow_navigation_back = false` - Чекбоксы для `is_multiple`, радио-кнопки для одиночного ответа --- ## Следующие шаги - [x] Спринт 1: Инфраструктура + Создание тестов - [x] Спринт 2: Прохождение теста + результат - [ ] Спринт 3: Трекер результатов - [ ] Спринт 4: Авторизация и роли - [ ] Спринт 5: Уведомления в MAX