Приложение для тестирования сотрудников клиники методом один вопрос - до пяти ответов один из которых правильный. Сотрудник должен выбрать правильный вариант ответа
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.
 
 
 
 
 
 

2.9 KiB

ШАГ 008 — Спринт 2: Баг «Не удалось загрузить тест»

Дата: 2026-03-21 Контекст: Мастер-класс по разработке системы тестирования сотрудников клиники.


Запрос

вот такой баг при нажатии кнопки «Пройти тест» — «Не удалось загрузить тест» × 2


Симптом

При нажатии кнопки «Пройти тест» фронт выполняет POST /api/attempts и получает ошибку. В консоли backend:

sqlalchemy.exc.ProgrammingError: (asyncpg.exceptions.UndefinedTableError)
relation "test_attempts" does not exist

Ошибка появляется дважды — из-за React StrictMode, который в dev-режиме намеренно монтирует компоненты дважды.


Причина

uvicorn --reload следит только за изменениями Python-файлов и перезапускает процесс приложения, но не перезапускает контейнер целиком и не выполняет entrypoint.sh повторно.

Миграция 002_attempts (создаёт таблицы test_attempts и attempt_answers) была добавлена уже после первого запуска стека — поэтому она ни разу не применялась.


Исправление

docker compose restart backend

При перезапуске контейнер выполняет entrypoint.sh заново:

Running migrations...
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade 001 -> 002, attempts
Starting server...
INFO:     Application startup complete.

Таблицы созданы — баг исчезает.


Правило для джуниора

uvicorn --reload ≠ перезапуск контейнера.

Если ты добавил новую миграцию Alembic и стек уже работает — выполни docker compose restart backend, чтобы миграция применилась.

docker compose up запускает контейнер только если он не запущен. restart — принудительно пересоздаёт его.


Следующие шаги

  • Спринт 1: Инфраструктура + Создание тестов
  • Спринт 2: Прохождение теста + результат
  • Спринт 3: Трекер результатов
  • Спринт 4: Авторизация и роли
  • Спринт 5: Уведомления в MAX