fix(tradein/estimator): гео-ограничение якорного тира — не брать чужие города (#2581) #2586
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2586
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/tradein-anchor-geo-scope"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #2581. Критический дефект: цена завышалась в 4-5 раз, помеченная самым доверенным тиром.
Якорный тир «тот же дом» подбирал объявления по всей области без географического ограничения. «Серов, ул. Ленина, 5» матчился с екатеринбургской улицей Ленина (из ~40 200 активных объявлений ~40 191 — Екатеринбург) → 8-9 млн вместо ~1.7 млн, с текстом «по аналогам из того же дома». Все страховки — коридор сделок, минимальный радиус, понижение за грубую геолокацию, MAD-отсечка — отключены структурно именно при
anchor_tier == 'A'. Хуже: сработавший якорь глушил честный областной путь по сделкам Росреестра, который требуетanchor_tier is None.Решение:
ST_DWithin(geom::geography, ..., 1000м)— та же константа, что уже одобрена для Tier S (f9ae6f0c). Строковый матч по улице и номеру дома уже задаёт «тот же дом»; радиус нужен лишь чтобы отсечь межгородские коллизии (Серов↔ЕКБ — сотни километров), а не для внутридомовой точности.house_id_fkнамеренно не используется — Tier A его избегает, один дом дробится на несколько записей.Объявления без координат исключены (
geom IS NOT NULL), не берутся вслепую: координаты есть у >99.97% (см.f9ae6f0c), а слепое включение вернуло бы часть риска._normalize_building_keyне тронут — городской токен в ключе сломал бы матчинг адресов без города в тексте (анонимные объявления Авито) и внёс бы риск разночтений в написании. Коллизия закрыта на уровне SQL, что надёжнее.Починен слепой тест-страж:
db=MagicMock()не был сконфигурирован для якорного запроса, иdb.execute(...).mappings().all()тривиально возвращал[]— поэтому тир 'A' никогда не активировался и регрессия была невидима. Плюс два новых теста, которые не мокают якорный запрос, а гоняют реальную логику через фейковыйdb.executeс настоящей фильтрацией по расстоянию.Доказательство регрессии (откат только фикса, тесты новые):
186 400 ₽/м² — ровно диапазон «150-190 тыс» из issue. После восстановления фикса 12/12 зелёные.
Екатеринбург не деградировал: контрольный тест — 4 объявления в одном доме ЕКБ по-прежнему формируют якорь, headline ~145 тыс ₽/м², одинаково на старом и новом коде.
Также исправлен ложный комментарий
:1900-1908(«same-building anchor pool для oblast не формируется») — он был неверен и до фикса.uv run pytest -q: 2842 passed, 1 pre-existing fail. ruff чисто.