# ШАГ 006 — Спринт 1: Инфраструктура + Создание тестов **Дата:** 2026-03-21 **Контекст:** Мастер-класс по разработке системы тестирования сотрудников клиники. --- ## Запрос > готов. поехали (начинаем Спринт 1) --- ## Ответ Реализован Спринт 1 в полном объёме: инфраструктура + создание тестов без авторизации. --- ## Структура проекта после спринта ``` qa_test_app/ ├── docker-compose.yml ← поднимает весь стек одной командой ├── .env.example ├── nginx/ │ └── nginx.conf ← / → frontend, /api/ → backend ├── backend/ │ ├── Dockerfile │ ├── entrypoint.sh ← ждёт БД, запускает миграции, стартует сервер │ ├── requirements.txt │ ├── alembic.ini │ ├── alembic/ │ │ ├── env.py ← async alembic, берёт URL из settings │ │ ├── script.py.mako │ │ └── versions/ │ │ └── 001_init.py ← создаёт таблицы tests, questions, answers │ └── app/ │ ├── config.py ← настройки через pydantic-settings │ ├── database.py ← async SQLAlchemy engine + session │ ├── main.py ← FastAPI app, /api/health │ ├── models/test.py ← ORM модели: Test, Question, Answer │ ├── schemas/test.py ← Pydantic схемы с валидацией │ └── api/tests.py ← REST эндпоинты └── frontend/ ├── Dockerfile ├── package.json ├── vite.config.ts ├── index.html └── src/ ├── App.tsx ← роутер + провайдеры ├── api/ │ ├── client.ts ← axios с baseURL=/api │ └── tests.ts ← типы + функции запросов └── pages/ ├── TestList/ ← список тестов + кнопка создать ├── TestCreate/ ← форма создания теста └── TestDetail/ ← просмотр теста с вопросами ``` --- ## API эндпоинты | Метод | URL | Описание | |-------|-----|----------| | GET | `/api/health` | Проверка работы сервера | | GET | `/api/tests` | Список тестов | | GET | `/api/tests/{id}` | Детали теста с вопросами и ответами | | POST | `/api/tests` | Создать тест | --- ## Схема БД ``` tests id, title, description, passing_score, time_limit, allow_navigation_back, is_active, version, created_at questions id, test_id → tests.id, text, order answers id, question_id → questions.id, text, is_correct ``` --- ## Валидация **Backend (Pydantic):** - Тест: минимум 7 вопросов, passing_score 0–100 - Вопрос: минимум 3 варианта ответа, хотя бы 1 правильный **Frontend (Ant Design Form):** - Те же правила воспроизведены на клиенте - Nested Form.List для динамических вопросов и ответов - Таймер показывается только при включённом переключателе (shouldUpdate) --- ## Как запустить ```bash docker compose up --build ``` Открыть браузер: `http://localhost` - Список тестов → кнопка «Создать тест» - Заполнить форму → нажать «Создать тест» - Перейти к созданному тесту и увидеть все вопросы и ответы - `http://localhost/api/health` → `{"status": "ok"}` - `http://localhost/api/docs` → Swagger UI FastAPI --- ## Ключевые решения для джуниора **Async SQLAlchemy 2.0:** - `async_sessionmaker` + `AsyncSession` — не блокируем event loop при запросах к БД - `selectinload` для жадной загрузки связей (вместо N+1 запросов) **Alembic async:** - `async_engine_from_config` + `connection.run_sync(do_run_migrations)` - URL берётся из `app.config.settings` — одно место для конфига **Docker Compose healthcheck:** - `db` объявляет `healthcheck`, `backend` ждёт `condition: service_healthy` - Дополнительно `entrypoint.sh` вызывает `pg_isready` для надёжности **TanStack Query:** - `useQuery` для чтения данных — кэш, loading state, error state из коробки - `useMutation` для создания — `invalidateQueries` обновляет список после успеха --- ## Следующие шаги - [x] Спринт 1: Инфраструктура + Создание тестов - [ ] Спринт 2: Прохождение теста + результаты - [ ] Спринт 3: Трекер результатов - [ ] Спринт 4: Авторизация и роли - [ ] Спринт 5: Уведомления в MAX