2 changed files with 85 additions and 7 deletions
@ -0,0 +1,73 @@ |
|||||||
|
# ШАГ 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`) была добавлена уже после первого запуска стека — поэтому она ни разу не применялась. |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
## Исправление |
||||||
|
|
||||||
|
```bash |
||||||
|
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` — принудительно пересоздаёт его. |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
## Следующие шаги |
||||||
|
|
||||||
|
- [x] Спринт 1: Инфраструктура + Создание тестов |
||||||
|
- [x] Спринт 2: Прохождение теста + результат |
||||||
|
- [ ] Спринт 3: Трекер результатов |
||||||
|
- [ ] Спринт 4: Авторизация и роли |
||||||
|
- [ ] Спринт 5: Уведомления в MAX |
||||||
Loading…
Reference in new issue