fix(tradein/scraper): не помечать городом развёртки объявления соседних городов #2626
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#2626
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/tradein-city-stamp-geo-guard"
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?
Проблема
oblast city-sweep (avito/cian/yandex) проставлял ОДИН
cityна весь batchsave_listings(..., city=resolve_city_name(city_slug))— независимо от того, где объект физически. Верхняя Пышма (~15км от ЕКБ, yandexradius_m=25000) получала 97% лотов, физически лежащих в Екатеринбурге (замер на проде).listings.cityтеперь читаетсяapp/tasks/asking_to_sold_ratio.pyкак ценовой предиктор — неверная метка напрямую двигала выкупные цены.Фикс
save_listings(..., city_anchor=(lat, lon), city_radius_km=...)— гео-guard (haversine, без ST_DWithin round-trip): для лота С координатами дальшеcity_radius_kmот anchor'а города-целиcityНЕ проставляется (пишется NULL). Место правки:packages/scraper-kit/src/scraper_kit/base.py(сама проверка) +.../orchestration/pipeline.py(get_city_anchor_point,get_city_stamp_radius_km, wiring вrun_avito_city_sweep/run_yandex_city_sweep/run_cian_city_sweep).Три решения (обоснование)
NULL(не ближайший город из справочника, не drop лота). Честное «не знаем», не ломает существующую COALESCE-семантику ON CONFLICT, не выдумывает данные.Guard активен только для oblast-городов (
city_slugзадан) — ЕКБ-развёртка (city_slug=None) не имеет более крупного соседа в регионе и не проверяется (тестtest_save_listings_geo_guard_inactive_ekaterinburg_sweep_unaffected+ orchestration-level*_no_geo_guard_anchor_for_ekaterinburg).Замер масштаба (read-only, прод,
tradein-postgres)Правило применено к существующим строкам
listings(per-city anchor + мой радиус — 8км для В.Пышмы, 15км для остальных):Итого: 758 строк (всего) / 118 активных строк получили бы NULL вместо текущего города по этому правилу — оценка масштаба будущей backfill-очистки (отдельная задача, НЕ в этом PR). Активная утечка сосредоточена в yandex (В.Пышма 106, Первоуральск 9) + 3 avito-выброса в Серове — сходится по порядку величины с прод-замером из задачи (В.Пышма yandex 115/119≈97% по методике «расстояние до центра ЕКБ»; моя метрика «расстояние до anchor'а города-цели» даёт 106/119 — оба метода сходятся на одном выводе). Первоуральск/yandex (9/63), Каменск-Уральский/yandex (0/129), Нижний Тагил/yandex (0/87), Серов/avito active (3/150) — точное совпадение с числами из задачи.
Большая часть КУ/НТ avito-строк (209/387) уже
is_active=false— исторический мусор, не влияет на текущийasking_to_sold_ratio.Falsification
git stashimplementation-файлов (base.py+pipeline.py), тесты остаются применёнными → 9 новых тестов падают на pre-fix коде (TypeError: unexpected keyword argument 'city_anchor'/ImportError: get_city_anchor_point/KeyError: 'city_anchor'), 36 существующих проходят без изменений (backward-compat подтверждён).git stash pop→ все 45 проходят.Тесты
tests/test_listings_city_from_sweep.py— save_listings-уровень: ЕКБ-координаты в В.Пышма-развёртке → city=NULL; координаты anchor'а В.Пышмы → city сохранён; лот без координат → city сохранён; ЕКБ-развёртка без anchor/radius → не сломана.tests/test_scraper_kit_pipeline_parity.py+parity2.py— orchestration-уровень:run_avito_city_sweep/run_yandex_city_sweep/run_cian_city_sweepпередают правильныеcity_anchor/city_radius_kmдля oblast-города иNone/Noneдля ЕКБ.Полный
pytest -q --deselect "tests/test_search_api.py::test_search_cache_hit"(tradein-mvp/backend): 3091 passed, 9 skipped, 1 deselected (тот самый pre-existing 401 RBAC-фейл, не мой).Границы (не тронуто)
app/services/geocoder.py,proxy_pool.py,proxy_rotation.py, оценщик — не тронуты.radius_m) — не менялись.Refs #2594