Commit graph

3 commits

Author SHA1 Message Date
c336f91182 fix(site-finder): align competitor flats_sold to objective_lots.contract_date (#1926)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m50s
CI / backend-tests (pull_request) Successful in 11m17s
Audit #1871/#1926: competitor block computed flats_sold from
domrf_kn_flats.status (LIKE '%прод%'/'sold'), populated in only ~0.2% of
rows (99.8% NULL) -> massive undercount (~1600 units in reported case) and
divergence from MarketMetrics, which counts sold via objective_lots.contract_date
(100% populated for sold lots).

Fix: new _SOLD_COUNT_SQL counts sold lots from objective_lots.contract_date
IS NOT NULL, bridged domrf obj_id -> objective_complex_mapping.domrf_obj_id ->
objective_complex_mapping.objective_complex_name == objective_lots.project_name
(same 1:1 mapping pattern as _OBJECTIVE_PRICE_FALLBACK_SQL primary_price CTE).
This is the exact source MarketMetrics._STOCK_SQL uses, so the two paths agree.
Dropped the domrf_kn_flats.status count from _AVG_PRICE_SQL (price-only now).

No schema/Pydantic field change (flats_sold/sold_pct already existed) ->
codegen not needed. psycopg v3 CAST style preserved.

Tests: updated mock DB ordering (+ sold-count execute), added
test_competitors_flats_sold_from_contract_date (120/200 -> 60% sold) and
phantom-column EXPLAIN check for _SOLD_COUNT_SQL.
2026-06-26 23:03:13 +05:00
c8000d1089 test(parcels): integration EXPLAIN-gate для analyze hot-path SQL (#1198)
All checks were successful
CI / changes (push) Successful in 7s
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (pull_request) Has been skipped
CI / backend-tests (push) Successful in 6m24s
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Successful in 1m46s
Deploy / build-worker (push) Successful in 2m55s
CI / backend-tests (pull_request) Successful in 6m20s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy (push) Successful in 1m10s
PR #1195 ввёл CTE alias `overlaps` (PG keyword для time-period operator)
→ каждый POST /analyze падал с syntax error ~10ч до hotfix PR #1197. Mock-БД
в tests/api/v1/test_*.py не поймала: MagicMock на db.execute() не парсит SQL.

Расширяет существующий phantom-column gate (tests/integration/) на
_neighbors_summary и parcel_ird_overlaps SQL:

1. _NEIGHBORS_SUMMARY_SQL вынесен из inline-text в module-level constant
   в parcels.py (паттерн как в best_layouts/ird_overlay_lookup/krt_lookup).
   Заодно сконвертирован на canonical CAST(:wkt AS text) — backend.md rule.
2. EXPLAIN-тесты через phantom_check_session (SSH-туннель к prod-PG) —
   skip без TEST_DATABASE_URL, run в спец CI job.
3. Compile-time guards (всегда работают, без БД):
   - CTE-alias не должен быть PG-keyword (overlaps/user/current_date/select/where)
   - SQL не должен содержать :bind::type (psycopg v3 antipattern)

Поймал бы:
- #1195 (CTE alias overlaps) — оба EXPLAIN-тест + compile-time keyword guard
- :type recurring class — compile-time parametrized guard
- Phantom column / typo PostGIS function — EXPLAIN parses + plans

Refactor backward-compatible: _neighbors_summary использует ту же константу,
behavior идентичен. 26 unit-тестов parcels analyze продолжают зелёные.

Refs #1198
2026-06-13 09:43:49 +05:00
76b1f8673f test(infra): integration phantom column gate (#197) (#216)
All checks were successful
Deploy / changes (push) Successful in 5s
Deploy / build-backend (push) Successful in 2m48s
Deploy / build-frontend (push) Has been skipped
Deploy / build-worker (push) Successful in 4m11s
Deploy / deploy (push) Successful in 53s
2026-05-16 13:07:13 +00:00