[dx] Integration test для analyze hot-path с реальной PG — mock-БД не ловит SQL-keyword/cast ошибки (#1196 follow-up) #1198

Closed
opened 2026-06-13 04:15:46 +00:00 by bot-backend · 1 comment
Collaborator

Проблема

Mock-БД в tests/api/v1/test_*.py (MagicMock для db.execute()) не выполняет реальный SQL — keyword-конфликты, psycopg v3 :x::type antipattern и подобные SQL-уровневые ошибки не ловятся на CI.

Реальные incident'ы

  1. 2026-06-12: #1196 — мой PR #1195 ввёл CTE alias overlaps (PG keyword). Mock-БД зелёная, prod падал на каждом /analyze. Фронт получал пустой neighbors_summary и ird блок ~30 минут до hotfix.
  2. Ранее: psycopg v3 :x::type — recurring bug class задокументирован в .claude/rules/backend.md. Тоже не ловится моками.

Что сделать

  • Минимальный integration-suite для analyze hot-path: testcontainers с реальной PG (PostGIS-enabled) → выполняет POST /analyze на seeded cad → проверяет shape ответа (data_available, неэмпти секции).
  • Альтернатива: помечать в CI runtime — отдельный smoke job, который дёргает analyze на staging БД через docker exec backend python -c '...' (как я сделал в hotfix). Менее изолированно, но дёшево.
  • Объём: 1 fixture для PG-контейнера, 1-2 test'а на analyze. ~200-300 LoC.

Acceptance

SQL-уровневые ошибки в analyze hot-path должны падать в CI до мерджа в main.

scope/backend, dx, tests

## Проблема Mock-БД в `tests/api/v1/test_*.py` (`MagicMock` для `db.execute()`) не выполняет реальный SQL — keyword-конфликты, psycopg v3 `:x::type` antipattern и подобные SQL-уровневые ошибки **не ловятся** на CI. ## Реальные incident'ы 1. **2026-06-12: #1196** — мой PR #1195 ввёл CTE alias `overlaps` (PG keyword). Mock-БД зелёная, prod падал на каждом /analyze. Фронт получал пустой `neighbors_summary` и `ird` блок ~30 минут до hotfix. 2. **Ранее: psycopg v3 `:x::type`** — recurring bug class задокументирован в `.claude/rules/backend.md`. Тоже не ловится моками. ## Что сделать - Минимальный integration-suite для analyze hot-path: testcontainers с реальной PG (PostGIS-enabled) → выполняет `POST /analyze` на seeded cad → проверяет shape ответа (data_available, неэмпти секции). - Альтернатива: помечать в CI runtime — отдельный smoke job, который дёргает `analyze` на staging БД через `docker exec backend python -c '...'` (как я сделал в hotfix). Менее изолированно, но дёшево. - Объём: 1 fixture для PG-контейнера, 1-2 test'а на analyze. ~200-300 LoC. ## Acceptance SQL-уровневые ошибки в analyze hot-path должны падать в CI **до** мерджа в main. scope/backend, dx, tests
Author
Collaborator

Closed by PR #1200 (merged sha c8000d1)

backend/tests/integration/test_analyze_parcels_sql.py — 5 тестов:

  • 2 EXPLAIN-тесты (skip без TEST_DATABASE_URL, run в специальном CI job через SSH-туннель к prod-PG)
  • 2 compile-time guard'а: CTE alias ≠ PG keyword + запрет :bind::type antipattern
  • Поймал бы #1195 (CTE overlaps) на CI вместо прода. И recurring psycopg v3 :x::type тоже.

Заодно _NEIGHBORS_SUMMARY_SQL вынесен на module-level (паттерн _IRD_OVERLAP_SQL, _PARCEL_CENTROID_SQL).

Follow-up'ы (отдельные PR'ы):

  • CI job для EXPLAIN-тестов с docker-side postgis (devops-engineer material)
  • Покрытие остальных ~10 SQL в parcels.py по тому же паттерну
## ✅ Closed by PR #1200 (merged sha c8000d1) `backend/tests/integration/test_analyze_parcels_sql.py` — 5 тестов: - 2 EXPLAIN-тесты (skip без `TEST_DATABASE_URL`, run в специальном CI job через SSH-туннель к prod-PG) - 2 compile-time guard'а: CTE alias ≠ PG keyword + запрет `:bind::type` antipattern - Поймал бы #1195 (CTE `overlaps`) на CI вместо прода. И recurring psycopg v3 `:x::type` тоже. Заодно `_NEIGHBORS_SUMMARY_SQL` вынесен на module-level (паттерн `_IRD_OVERLAP_SQL`, `_PARCEL_CENTROID_SQL`). Follow-up'ы (отдельные PR'ы): - CI job для EXPLAIN-тестов с docker-side postgis (devops-engineer material) - Покрытие остальных ~10 SQL в parcels.py по тому же паттерну
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1198
No description provided.