fix(tradein): cadastre ЖКХ-fallback + COALESCE merge-key + median-floors guard #2090

Merged
lekss361 merged 1 commit from feat/tradein-zhkh-cadastre-plus into main 2026-06-28 22:34:16 +00:00
Owner

Три фикса в серии sale-share data-quality (по находкам юзера в этой сессии).

1. COALESCE merge-key (house_dedup_merge.py) — фиксит Вайнера 66

P4c-мерж схлопнул 2674 дубля, но Вайнера 66 НЕ схлопнулась: house 11320 address=«улица Вайнера, 66 · р-н Центр» — tradein_canon_addr не стрипает trailing-район → canon вайнера66рнцентрвайнера66. Но short_address=«улица Вайнера, 66» чистый. → cluster_key теперь tradein_canon_addr(COALESCE(short_address, full_address, address)). Re-run мержа после деплоя поймает Вайнера + ещё район-noise дубли.

2. Cadastre ЖКХ-fallback (zhkh_flats_loader.py + CLI --cadastre)

Guid-лоадер промахивается, когда наш gar_house_guid ≠ ЖКХ houseGuid (Переходный 6: наш guid → ЖКХ total 0; но cadastre 66:41:0604007:747 → 165). searchByAddress принимает cadastreNumber — guid-независимо. Наши listings.building_cadastral_number дают cadastre. Новый match_houses_to_zhkh_by_cadastre (UPDATE по house.id, т.к. ЖКХ-guid ≠ наш). 736 домов без ЖКХ имеют cadastre.

⚠️ Cadastre троттлится жёстко (~11 запросов/окно vs батч ~15×100) → полный прогон медленный (~часы). Запускаю paced после деплоя; гард (#3) держит метрику честной независимо.

3. Median-floors плаузибилити-гард (мигр.153)

Башни с gar-недосчётом без ЖКХ давали ложные доли (Переходный 6 до фикса: gar=9, листинги 19-26 эт → 77.8%). Гейт усилен: denom >= GREATEST(total_floors, median(listings.total_floors), 8). Медиана (не max) устойчива к одному чужому листингу. gar=9 < median(24) → NULL (честно «нет данных»). Переходный 6 (уже zhkh=165) проходит.

Проверки

  • ruff clean; pytest test_house_dedup_merge + test_zhkh_flats_loader36 passed.
  • Cadastre-рецепт verified живьём (Переходный 6 → 165).

После мержа (делаю сам)

  1. Deploy (мигр.153 авто-применится; гард сразу чистит башни-недосчёты).
  2. Re-run merge_duplicate_houses → Вайнера 66 схлопнется.
  3. Paced cadastre-батч (--cadastre) → дорезолвить часть из 736.
  4. Verify Вайнера / Переходный-тип / coverage.
Три фикса в серии sale-share data-quality (по находкам юзера в этой сессии). ## 1. COALESCE merge-key (`house_dedup_merge.py`) — фиксит Вайнера 66 P4c-мерж схлопнул 2674 дубля, но Вайнера 66 НЕ схлопнулась: house 11320 `address`=«улица Вайнера, 66 **· р-н Центр**» — `tradein_canon_addr` не стрипает trailing-район → canon `вайнера66рнцентр` ≠ `вайнера66`. Но `short_address`=«улица Вайнера, 66» чистый. → cluster_key теперь `tradein_canon_addr(COALESCE(short_address, full_address, address))`. Re-run мержа после деплоя поймает Вайнера + ещё район-noise дубли. ## 2. Cadastre ЖКХ-fallback (`zhkh_flats_loader.py` + CLI `--cadastre`) Guid-лоадер промахивается, когда наш `gar_house_guid` ≠ ЖКХ `houseGuid` (Переходный 6: наш guid → ЖКХ `total 0`; но **cadastre `66:41:0604007:747` → 165**). `searchByAddress` принимает `cadastreNumber` — guid-независимо. Наши `listings.building_cadastral_number` дают cadastre. Новый `match_houses_to_zhkh_by_cadastre` (UPDATE по house.id, т.к. ЖКХ-guid ≠ наш). **736** домов без ЖКХ имеют cadastre. > ⚠️ Cadastre троттлится жёстко (~11 запросов/окно vs батч ~15×100) → полный прогон медленный (~часы). Запускаю paced после деплоя; гард (#3) держит метрику честной независимо. ## 3. Median-floors плаузибилити-гард (мигр.153) Башни с gar-недосчётом без ЖКХ давали ложные доли (Переходный 6 до фикса: gar=9, листинги 19-26 эт → 77.8%). Гейт усилен: `denom >= GREATEST(total_floors, median(listings.total_floors), 8)`. Медиана (не max) устойчива к одному чужому листингу. gar=9 < median(24) → NULL (честно «нет данных»). Переходный 6 (уже zhkh=165) проходит. ## Проверки - ruff clean; pytest `test_house_dedup_merge` + `test_zhkh_flats_loader` → **36 passed**. - Cadastre-рецепт verified живьём (Переходный 6 → 165). ## После мержа (делаю сам) 1. Deploy (мигр.153 авто-применится; гард сразу чистит башни-недосчёты). 2. Re-run `merge_duplicate_houses` → Вайнера 66 схлопнется. 3. Paced cadastre-батч (`--cadastre`) → дорезолвить часть из 736. 4. Verify Вайнера / Переходный-тип / coverage.
lekss361 added 1 commit 2026-06-28 22:33:25 +00:00
fix(tradein): cadastre ЖКХ-fallback + COALESCE merge-key + median-floors guard
All checks were successful
CI / changes (pull_request) Successful in 7s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
078dadc440
Серия sale-share data-quality (по находкам юзера):
- house_dedup_merge: cluster_key → tradein_canon_addr(COALESCE(short_address,
  full_address, address)) — ловит дубли с район-noise в address (Вайнера 66).
- zhkh_flats_loader: cadastre-fallback (searchByAddress по cadastreNumber,
  guid-независимо) — резолвит дома где gar_house_guid ≠ ЖКХ houseGuid
  (Переходный 6: guid→0, cadastre→165). CLI --cadastre.
- мигр.153: плаузибилити-гард по медиане этажности листингов — denom >=
  GREATEST(total_floors, median(listings.total_floors), 8); отсекает gar-недосчёт
  башен без ЖКХ (gar=9 vs листинги 19-26 эт → NULL).

ruff clean, pytest 36 green.
lekss361 merged commit cbe56cab0e into main 2026-06-28 22:34:16 +00:00
lekss361 deleted branch feat/tradein-zhkh-cadastre-plus 2026-06-28 22:34:16 +00:00
Sign in to join this conversation.
No reviewers
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#2090
No description provided.