Приложение для тестирования сотрудников клиники методом один вопрос - до пяти ответов один из которых правильный. Сотрудник должен выбрать правильный вариант ответа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

12 KiB

План спринтов

Дата: 2026-03-21 Статус: Согласовано


Принцип

Каждый спринт — это готовое работающее приложение (frontend + backend), которое можно запустить локально командой docker compose up и протестировать вручную в браузере.


Спринт 1 — Инфраструктура + Создание тестов

Результат: Поднят весь стек, можно зайти на страницу и создать тест. Статус: Завершён и протестирован вручную в браузере.

Инфраструктура

  • Структура репозитория: backend/, frontend/, nginx/, docker-compose.yml
  • docker-compose.yml: сервисы db, backend, frontend, nginx
  • PostgreSQL: контейнер, volume для данных
  • FastAPI: контейнер, GET /api/health{"status": "ok"}
  • Alembic: инициализирован, первая миграция (001_init)
  • React + Vite: контейнер, базовая страница открывается в браузере
  • Nginx: / → React SPA, /api/ → FastAPI

Создание тестов (без авторизации)

  • Модели БД: Test, Question, Answer
  • API: POST /api/tests — создать тест с вопросами и ответами
  • API: GET /api/tests — список тестов
  • API: GET /api/tests/{id} — детали теста
  • Фронт: страница создания теста (название, вопросы, варианты, настройки)
  • Фронт: список тестов
  • Фронт: страница просмотра теста

Настройки теста: порог зачёта (%), таймер (опционально), разрешить возврат к предыдущему вопросу

Баги, найденные и исправленные при тестировании

  • permission denied на entrypoint.sh — volume mount перекрывал chmod +x из Dockerfile → исправлено: CMD ["bash", "entrypoint.sh"]
  • No module named 'app' в Alembic — Python не видел /app → исправлено: ENV PYTHONPATH=/app в Dockerfile
  • host not found in upstream "backend" в nginx — nginx резолвил хост при старте, до поднятия backend → исправлено: Docker DNS resolver + set $backend
  • http://localhost/api/docs → 404 — FastAPI отдавал docs по /docs, а не /api/docs → исправлено: явные docs_url, redoc_url, openapi_url в FastAPI

Спринт 2 — Прохождение теста

Результат: Можно выбрать тест из списка и пройти его, увидеть результат и разбор ошибок. Статус: Завершён и протестирован вручную в браузере.

  • Модели БД: TestAttempt, AttemptAnswer
  • API: POST /api/attempts — начать попытку (фиксируем время начала)
  • API: POST /api/attempts/{id}/submit — завершить попытку, подсчитать результат
  • API: GET /api/attempts/{id}/result — результат с разбором ошибок
  • Фронт: страница прохождения теста
    • Случайный порядок вопросов
    • Таймер с обратным отсчётом (если задан) — автосабмит по истечении
    • Навигация назад (если разрешена настройкой теста)
  • Фронт: страница результата
    • Балл и процент
    • Сдал / Не сдал (относительно порога)
    • Разбор ошибок: вопрос, ответ сотрудника, правильный ответ
  • Фронт: кнопка «Пройти тест» прямо в строке таблицы списка тестов

Доработки после тестирования

  • Страница теста разделена на два вида:
    • /tests/:id — вид сотрудника: вопросы и варианты ответов без отметок правильных
    • /tests/:id/edit — вид автора: правильные ответы отмечены, жёлтый баннер, кнопка «Редактировать» (задизаблена до Спринта 4)
  • Список тестов: три кнопки действий заменены на выпадающее меню «⋯» — колонка с названием стала полноширинной

Баги, найденные и исправленные при тестировании

  • «Не удалось загрузить тест» × 2 при нажатии «Пройти тест» — миграция 002_attempts не применилась, т.к. --reload перезапускает только код приложения, но не entrypoint.sh → исправлено: docker compose restart backend

Спринт 3 — Редактирование теста + версионность

Результат: Тест можно редактировать. Если тест уже проходили — создаётся новая версия, старая сохраняется для истории. Статус: Завершён и протестирован вручную в браузере.

Backend

  • Миграция 003: добавить поле parent_id в таблицу tests
  • PUT /api/tests/{id} — редактировать тест:
    • Нет попыток → обновить на месте
    • Есть попытки → создать новый тест (version + 1, parent_id = id), вернуть {test, is_new_version: true}
  • GET /api/tests — показывать только активные версии (is_active = True)
  • GET /api/tests/{id}/versions — цепочка всех версий теста
  • POST /api/tests/{id}/activate — сделать версию активной (деактивирует остальные в цепочке)

Frontend

  • Страница /tests/:id/edit разделена на режим просмотра и режим редактирования
  • Форма редактирования с предзаполненными данными (общий компонент TestForm)
  • При сохранении с новой версией — редирект + уведомление «Создана новая версия v2»
  • Кнопка «← К просмотру теста» в форме редактирования
  • Секция «История версий»: таблица с версиями, статусом, датой, кнопкой «Сделать активной»
  • Активная версия — единственная видимая в списке тестов

Баги, найденные и исправленные при тестировании

  • ForeignKeyViolationError при сохранении — bulk DELETE questions не каскадирует на answers → исправлено: сначала удаляем answers, потом questions
  • Обе версии показывались «Активными» при создании до введения логики деактивации → исправлено: кнопка «Сделать активной» в шапке и в строке таблицы

Спринт 4 — Трекер результатов

Результат: Таблица всех попыток прохождения тестов.

  • API: GET /api/attempts — все попытки (с фильтрами по тесту, дате)
  • Фронт: страница трекера
    • Таблица: тест, версия, дата начала, дата завершения, результат, зачёт
    • Фильтрация по тесту и дате
    • Пагинация

Спринт 5 — Авторизация и управление пользователями

Результат: Вход по логину/паролю, роли ограничивают доступ. Можно создавать сотрудников и подразделения.

Авторизация

  • Модели БД: User, Department
  • API: POST /api/auth/login → JWT access token
  • API: POST /api/auth/logout
  • API: GET /api/auth/me
  • Middleware: проверка JWT на защищённых эндпоинтах
  • Фронт: страница входа
  • Фронт: защищённые роуты (редирект на логин если нет токена)

Роли и права

Роль Тесты Трекер
HR-менеджер / Директор Создаёт и редактирует все тесты Вся клиника
Руководитель подразделения Создаёт и редактирует свои тесты Только свой отдел
Сотрудник Проходит назначенные тесты Только свои результаты

Управление пользователями

  • API: CRUD подразделений
  • API: CRUD пользователей (создание, редактирование, деактивация)
  • Фронт: страница управления подразделениями (HR)
  • Фронт: страница управления сотрудниками (HR / руководитель)

Назначение тестов

  • Модели БД: TestAssignment
  • API: POST /api/assignments — назначить тест (получатели, дедлайн, кол-во попыток)
  • Фронт: форма назначения теста
  • Фронт: дашборд сотрудника — список назначенных тестов со статусами (Не начат, В процессе, Завершён, Просрочен)

Спринт 6 — Уведомления в MAX

Результат: Сотрудники получают уведомления в мессенджер MAX.

  • Изучить документацию MAX API
  • Реализовать сервис уведомлений в backend
  • Уведомление при назначении теста сотруднику
  • Уведомление за N дней до дедлайна (настраивается)
  • Поле max_user_id в профиле пользователя
  • Фронт: в профиле пользователя — поле для MAX ID

Структура репозитория (целевая после Спринта 1)

qa_test_app/
├── backend/
│   ├── app/
│   │   ├── api/          ← роутеры FastAPI
│   │   ├── models/       ← SQLAlchemy модели
│   │   ├── schemas/      ← Pydantic схемы
│   │   ├── services/     ← бизнес-логика
│   │   └── main.py
│   ├── alembic/
│   ├── Dockerfile
│   └── requirements.txt
├── frontend/
│   ├── src/
│   │   ├── api/          ← Axios + TanStack Query
│   │   ├── components/   ← переиспользуемые компоненты
│   │   ├── pages/        ← страницы
│   │   └── main.tsx
│   ├── Dockerfile
│   └── package.json
├── nginx/
│   └── nginx.conf
├── docker-compose.yml
└── DOC/