fix(estimator): #1774 Tier A admits same-building novostroyki resales (secondary-dominant gate) #1776

Merged
lekss361 merged 1 commit from fix/1774-tier-a-same-building-primary into main 2026-06-19 09:28:16 +00:00
Collaborator

Проблема (#1774)

Пользователь оценивает «Евгения Савкова 29» (ЕКБ, Широкая Речка) и видит на cian объявления в том же доме, но оценщик их не учитывает.

Корень (диагностика на проде): в том же доме «29» — 6 вторичных комплов (avito+yandex, vtorichka) и 4 cian-объявления, помеченных listing_segment='novostroyki' (включая ссылку юзера 330047129). Same-building anchor (Tier A) фильтровал (listing_segment IS NULL OR ='vtorichka') — гард #1186 — и выкидывал 4 cian-объявления. Но их sale_type='free' (свободная продажа собственником) → это вторичные перепродажи/переуступки в сданном доме; cian клеит «новостройка» как таксономию ЖК. Цены идентичны вторичке (153–185k vs 138–188k). Плюс дубль source_id=330047129 (2 active-строки) раздувал вес.

Решение (за reversible-флагом, Tier A ONLY)

Ослабление гарда #1186 только в Tier A и только при secondary-dominant доме: впускаем novostroyki, если в том же доме secondary_count >= 1 AND secondary_count >= primary_count. Чисто-первичный или primary-dominated дом → гард #1186 сохраняется (не якорим перепродажу на ценах застройщика). Флаг estimate_sb_tier_a_allow_primary_if_secondary_present (default True) — Леха может выключить без редеплоя кода.

  • Дедуп комплов по (source, source_id) (канон кодовой базы) — схлопывает дубль 330047129 даже при отличии source_url слешем/параметром.

Не тронуты: Tier C, радиусный median, asking_to_sold_ratio — гарды #1186 там целы.

Почему secondary-dominant, а не «≥1 вторичка»

Code-review поймал money-кейс: 1 одинокая вторичка + кластер дорогих novostroyki → MAD-clip выкинул бы редкую вторичку как выброс → якорь на застройщике (~27% переоценка). Гейт secondary_count >= primary_count это исключает.

Остаточный риск (для трекинга)

При parity (sec==prim) MAD-clip теоретически может сместить якорь; на практике защищён band-guard + comp_min floor. Возможный follow-up: тюнить порог / sale_type-aware классификация переуступок.

Тесты

84 unit-теста зелёные (test_tier_a_primary_1774 — новый: secondary-dominant include / primary-dominated exclude / pure-primary exclude / flag-off / dedup same-id-diff-url; test_segment_guard_1186 — Tier C гард цел; test_same_building_anchor; test_anchor_watchdog; backtest+pure_units). ruff чист. Миграций нет.

⚠️ Golden 55-case backtest гоняется офлайн против БД — не покрыт unit-сьютом; релаксация только ДОБАВЛЯет комплы в mixed-домах, так что ранее якорившиеся pure-secondary кейсы не сдвигаются.

Связано

Часть разбора жалобы «не учитывает тот же дом» (Евгения Савкова 29). Соседние: #1773 (avito de-glue адресов — PR #1775; cian newbuilding house-number — зона Лехи), #1772 (кадастровая унификация — data-blocked: кадастр ~0% на домах, FDW cad_buildings без геометрии).

## Проблема (#1774) Пользователь оценивает «Евгения Савкова 29» (ЕКБ, Широкая Речка) и видит на cian объявления **в том же доме**, но оценщик их не учитывает. **Корень (диагностика на проде):** в том же доме «29» — 6 вторичных комплов (avito+yandex, `vtorichka`) и 4 cian-объявления, помеченных `listing_segment='novostroyki'` (включая ссылку юзера 330047129). Same-building anchor (Tier A) фильтровал `(listing_segment IS NULL OR ='vtorichka')` — гард #1186 — и **выкидывал 4 cian-объявления**. Но их `sale_type='free'` (свободная продажа собственником) → это вторичные перепродажи/переуступки в **сданном** доме; cian клеит «новостройка» как таксономию ЖК. Цены идентичны вторичке (153–185k vs 138–188k). Плюс дубль `source_id=330047129` (2 active-строки) раздувал вес. ## Решение (за reversible-флагом, Tier A ONLY) Ослабление гарда #1186 **только в Tier A** и **только при secondary-dominant доме**: впускаем novostroyki, если в том же доме `secondary_count >= 1 AND secondary_count >= primary_count`. Чисто-первичный или primary-dominated дом → гард #1186 сохраняется (не якорим перепродажу на ценах застройщика). Флаг `estimate_sb_tier_a_allow_primary_if_secondary_present` (default True) — Леха может выключить без редеплоя кода. + Дедуп комплов по `(source, source_id)` (канон кодовой базы) — схлопывает дубль 330047129 даже при отличии source_url слешем/параметром. **Не тронуты:** Tier C, радиусный median, asking_to_sold_ratio — гарды #1186 там целы. ## Почему secondary-dominant, а не «≥1 вторичка» Code-review поймал money-кейс: 1 одинокая вторичка + кластер дорогих novostroyki → MAD-clip выкинул бы редкую вторичку как выброс → якорь на застройщике (~27% переоценка). Гейт `secondary_count >= primary_count` это исключает. ## Остаточный риск (для трекинга) При parity (sec==prim) MAD-clip теоретически может сместить якорь; на практике защищён band-guard + comp_min floor. Возможный follow-up: тюнить порог / sale_type-aware классификация переуступок. ## Тесты 84 unit-теста зелёные (test_tier_a_primary_1774 — новый: secondary-dominant include / primary-dominated exclude / pure-primary exclude / flag-off / dedup same-id-diff-url; test_segment_guard_1186 — Tier C гард цел; test_same_building_anchor; test_anchor_watchdog; backtest+pure_units). ruff чист. Миграций нет. ⚠️ Golden 55-case backtest гоняется офлайн против БД — не покрыт unit-сьютом; релаксация только ДОБАВЛЯет комплы в mixed-домах, так что ранее якорившиеся pure-secondary кейсы не сдвигаются. ## Связано Часть разбора жалобы «не учитывает тот же дом» (Евгения Савкова 29). Соседние: #1773 (avito de-glue адресов — PR #1775; cian newbuilding house-number — зона Лехи), #1772 (кадастровая унификация — **data-blocked**: кадастр ~0% на домах, FDW cad_buildings без геометрии).
bot-backend added 1 commit 2026-06-19 09:00:54 +00:00
fix(estimator): #1774 Tier A admits same-building novostroyki resales when secondary-dominant
All checks were successful
CI / changes (pull_request) Successful in 6s
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
07d9cc8e8b
Tier A (same building) dropped cian listings tagged listing_segment='novostroyki'
even in delivered buildings where that tag marks owner resales/переуступки
(sale_type=free). Gated relaxation of the #1186 guard, Tier A ONLY: include
novostroyki rows iff the same house has secondary (vtorichka/NULL) listings AND
secondary_count >= primary_count — secondary-dominant signal of a delivered house.
Prevents a lone vtorichka + clustered developer-priced novostroyki from anchoring
on застройщик prices after MAD-clip drops the rare secondary (~27% overvaluation).
Pure-primary / primary-dominated houses keep the #1186 guard. Behind
estimate_sb_tier_a_allow_primary_if_secondary_present (default True).

Dedup duplicate active rows by (source, source_id) primary key (codebase canon,
namespaced id/url tags, source_url fallback) — collapses rows whose source_url
differs only by trailing slash / query-param (e.g. cian source_id=330047129 ×2).

Tier C / radius / asking_to_sold_ratio paths untouched. 84 unit tests pass.
lekss361 merged commit ee2703419b into main 2026-06-19 09:28:16 +00:00
lekss361 deleted branch fix/1774-tier-a-same-building-primary 2026-06-19 09:28:17 +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#1776
No description provided.