fix(tradein): оценка исключает Avito из радиусного поиска аналогов

У Avito-объявлений «координаты» = якорь cron-скрейпа ± jitter (DOM
Avito реальных coords не отдаёт). Фейковые точки кучкуются плотными
кластерами на 5 якорях ЕКБ — tier-1 радиус (1 км) набирался почти
целиком из них: оценка для центра давала sources_used=['avito'],
18 аналогов все Avito, при 1400 живых cian/yandex/n1 в БД.

_fetch_analogs теперь исключает source='avito'. Трёхтирный fallback
по радиусу доходит до реальных cian/yandex/n1 с настоящей геопривязкой
— оценка считается по корректным аналогам.
This commit is contained in:
Light1YT 2026-05-22 14:26:29 +05:00
parent c3df202d8a
commit 8bef0fd872

View file

@ -5,7 +5,8 @@
Алгоритм:
1. Geocode address (lat, lon)
2. SELECT listings с фильтрами:
- PostGIS ST_DWithin (geom, point, 800m) радиус поиска
- PostGIS ST_DWithin (geom, point, 1000m) радиус поиска
- source avito (у Avito фейковые anchor-jitter координаты не гео-аналог)
- rooms = target_rooms (точное совпадение)
- area_m2 BETWEEN target × 0.85 AND target × 1.15
- scraped_at > NOW() - 14 days (свежие)
@ -362,6 +363,12 @@ def _fetch_analogs(
AND is_active = true
AND scraped_at > NOW() - (:fresh_days || ' days')::interval
AND price_rub > 0
-- Avito исключён из радиусного поиска: его «координаты» это
-- якорь cron-скрейпа ± jitter (DOM Avito реальных coords не
-- отдаёт). Фейковые точки кучкуются на 5 якорях и вытесняют
-- реальные cian/yandex/n1 оценка считалась почти целиком по
-- Avito. Реальные источники дают честный гео-радиус.
AND source <> 'avito'
ORDER BY (
-- distance_m это SELECT-алиас. В ORDER BY-ВЫРАЖЕНИИ (не голым
-- термом) PostgreSQL трактует имя как входную колонку listings,