Files
qa_test_app/DOC/СПРИНТЫ.md
T
Aleksey Razorvin 98049244ae docs: document Sprint 2 UX improvements
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 13:18:18 +05:00

168 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# План спринтов
**Дата:** 2026-03-21
**Статус:** Согласовано
---
## Принцип
Каждый спринт — это готовое работающее приложение (frontend + backend), которое можно запустить локально командой `docker compose up` и протестировать вручную в браузере.
---
## Спринт 1 — Инфраструктура + Создание тестов ✅
**Результат:** Поднят весь стек, можно зайти на страницу и создать тест.
**Статус:** Завершён и протестирован вручную в браузере.
### Инфраструктура
- [x] Структура репозитория: `backend/`, `frontend/`, `nginx/`, `docker-compose.yml`
- [x] `docker-compose.yml`: сервисы `db`, `backend`, `frontend`, `nginx`
- [x] PostgreSQL: контейнер, volume для данных
- [x] FastAPI: контейнер, `GET /api/health``{"status": "ok"}`
- [x] Alembic: инициализирован, первая миграция (`001_init`)
- [x] React + Vite: контейнер, базовая страница открывается в браузере
- [x] Nginx: `/` → React SPA, `/api/` → FastAPI
### Создание тестов (без авторизации)
- [x] Модели БД: `Test`, `Question`, `Answer`
- [x] API: `POST /api/tests` — создать тест с вопросами и ответами
- [x] API: `GET /api/tests` — список тестов
- [x] API: `GET /api/tests/{id}` — детали теста
- [x] Фронт: страница создания теста (название, вопросы, варианты, настройки)
- [x] Фронт: список тестов
- [x] Фронт: страница просмотра теста
**Настройки теста:** порог зачёта (%), таймер (опционально), разрешить возврат к предыдущему вопросу
### Баги, найденные и исправленные при тестировании
- [x] `permission denied` на `entrypoint.sh` — volume mount перекрывал `chmod +x` из Dockerfile → исправлено: `CMD ["bash", "entrypoint.sh"]`
- [x] `No module named 'app'` в Alembic — Python не видел `/app` → исправлено: `ENV PYTHONPATH=/app` в Dockerfile
- [x] `host not found in upstream "backend"` в nginx — nginx резолвил хост при старте, до поднятия backend → исправлено: Docker DNS resolver + `set $backend`
- [x] `http://localhost/api/docs` → 404 — FastAPI отдавал docs по `/docs`, а не `/api/docs` → исправлено: явные `docs_url`, `redoc_url`, `openapi_url` в FastAPI
---
## Спринт 2 — Прохождение теста ✅
**Результат:** Можно выбрать тест из списка и пройти его, увидеть результат и разбор ошибок.
**Статус:** Завершён и протестирован вручную в браузере.
- [x] Модели БД: `TestAttempt`, `AttemptAnswer`
- [x] API: `POST /api/attempts` — начать попытку (фиксируем время начала)
- [x] API: `POST /api/attempts/{id}/submit` — завершить попытку, подсчитать результат
- [x] API: `GET /api/attempts/{id}/result` — результат с разбором ошибок
- [x] Фронт: страница прохождения теста
- Случайный порядок вопросов
- Таймер с обратным отсчётом (если задан) — автосабмит по истечении
- Навигация назад (если разрешена настройкой теста)
- [x] Фронт: страница результата
- Балл и процент
- Сдал / Не сдал (относительно порога)
- Разбор ошибок: вопрос, ответ сотрудника, правильный ответ
- [x] Фронт: кнопка «Пройти тест» прямо в строке таблицы списка тестов
### Доработки после тестирования
- [x] Страница теста разделена на два вида:
- `/tests/:id` — вид сотрудника: вопросы и варианты ответов без отметок правильных
- `/tests/:id/edit` — вид автора: правильные ответы отмечены, жёлтый баннер, кнопка «Редактировать» (задизаблена до Спринта 4)
- [x] Список тестов: три кнопки действий заменены на выпадающее меню «⋯» — колонка с названием стала полноширинной
### Баги, найденные и исправленные при тестировании
- [x] «Не удалось загрузить тест» × 2 при нажатии «Пройти тест» — миграция `002_attempts` не применилась, т.к. `--reload` перезапускает только код приложения, но не `entrypoint.sh` → исправлено: `docker compose restart backend`
---
## Спринт 3 — Трекер результатов
**Результат:** Таблица всех попыток прохождения тестов.
- [ ] API: `GET /api/attempts` — все попытки (с фильтрами по тесту, дате)
- [ ] Фронт: страница трекера
- Таблица: сотрудник, тест, № попытки, начало, завершение, результат, зачёт
- Фильтрация по тесту и дате
- Пагинация
---
## Спринт 4 — Авторизация и управление пользователями
**Результат:** Вход по логину/паролю, роли ограничивают доступ. Можно создавать сотрудников и подразделения.
### Авторизация
- [ ] Модели БД: `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` — назначить тест (получатели, дедлайн, кол-во попыток)
- [ ] Фронт: форма назначения теста
- [ ] Фронт: дашборд сотрудника — список назначенных тестов со статусами (`Не начат`, `В процессе`, `Завершён`, `Просрочен`)
### Версионирование тестов
- [ ] При попытке редактировать назначенный тест — создаётся новая версия
- [ ] Результаты привязаны к конкретной версии теста
---
## Спринт 5 — Уведомления в 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/
```