gendesign/tradein-mvp/backend/app/tasks
bot-backend abe559cf8f fix(mera): витрина больше не отсеивает промахи оценщика, счётчики едут на фронт
Ревью MAJOR по честности, два пункта.

1. Убран MAX_ABS_ERR_PCT = 40 из build_row. Докстринг модуля сам запрещает
отбор по величине ошибки, но запрет был реализован только в _sort_key, а
фильтр — тот же отбор ступенькой раньше, и злее: строка не попадала даже в
кандидаты. Обоснование «отклонение >40% — почти всегда занижение ДКП ради
налога» не держится: _load_sample уже режет выборку санитарным диапазоном
₽/м² (для ЕКБ это глобальные PPM2_MIN=30k / PPM2_MAX=600k — город намеренно
не заведён в deal_city_price_bands), то есть грубые занижения вырезаны выше
по потоку и ПО СВОЙСТВУ САМОЙ СДЕЛКИ. Всё, что после этого дало большую
ошибку, — работа оценщика, и посетитель обязан её видеть. Честность про
заниженные ДКП перенесена в note каждой строки.

Заодно убраны MIN_FACT_PPM2=30k (дублировал уже применённый фильтр) и
MAX_FACT_PPM2=1.2M (недостижим при потолке выборки 600k): из трёх отбраковок
в проде срабатывала ровно одна — та, что льстила витрине, а два мёртвых
порога читались как работающие. Осталась только структурная отбраковка «нет
прогноза / квартала / площади».

2. Счётчики прогона выведены в ответ ручки. Итог пересчёта пишется в
landing_showcase_runs (миграция 277) и уезжает в ShowcaseResponse.stats
вместе с правилом отбраковки: показано 20 из N годных, рассмотрено M сделок.
Отдельная таблица, а не колонки в строках, — иначе в самом важном случае
(показывать нечего) счётчики исчезли бы вместе со строками. Ручка теперь
берёт и строки, и числа ИЗ ОДНОГО прогона: иначе пустой прогон показал бы
вчерашние строки под сегодняшними счётчиками.

Тесты двусторонние и проверены на сломанном коде: возврат любого порога по
ошибке → красный с величиной отклонения в сообщении; возврат любой границы
₽/м² → красная своя половина; stats=None при живом прогоне → красный.
2026-08-29 19:20:04 +05:00
..
__init__.py feat(tradein): search matview + indexes (Phase 3.1) (#469) 2026-05-23 14:01:18 +00:00
asking_to_sold_ratio.py fix(tradein/estimate): фильтр свежести в якоре дома и знаменателе коэффициента выкупа (#2656) 2026-08-05 21:27:38 +05:00
avito_detail_backfill.py fix(tradein/scrapers): ABORT-лог называл серию блоков, хотя рвал прогон по доле 2026-08-28 23:04:07 +03:00
backfill_house_coords_from_listings.py fix(tradein/houses): вернуть координаты объявлений в дом, когда объявления согласны (#2771) (#2780) 2026-08-07 09:08:06 +00:00
backfill_listings_coords_geoportal.py fix(tradein/geocode): прошить city_hint в deals-скрипт + развести счётчики гейта (#2603) 2026-08-05 17:36:07 +05:00
cadastral_geo_match.py fix(tradein/matching): честность тиров сопоставления домов (#2674) 2026-08-06 04:37:12 +05:00
cian_history_backfill.py fix(tradein/scrapers): диагноз блока брался из текстовых маркеров чужой площадки, а не из HTTP-статуса (#3196) 2026-08-28 23:21:54 +03:00
deactivate_stale_avito.py feat(tradein/deactivate-stale): страховочные рельсы объёма снятия (#3066) 2026-08-24 08:44:32 +00:00
deal_city_price_bands_refresh.py feat(tradein/db): авто-refresh ценовых бэндов по городам + порог для малых городов (#2576) 2026-07-31 16:33:20 +03:00
deals_freshness_monitor.py fix(tradein): сигналы о сбоях наконец становятся событиями, а протухание кук предупреждает заранее (#2674) 2026-08-06 02:29:11 +05:00
domclick_detail_backfill.py fix(tradein/domclick): backfill ходил в сайдкар мимо прокси-пула (#3197 ч.1) 2026-08-29 15:26:14 +03:00
domrf_kapremont_load.py feat(tradein): fill houses.year_built/material_walls from ДОМ.РФ КР1.1/1.2 + zhkh_year, propagate to listings (#2013) (#2476) 2026-07-12 13:12:07 +00:00
ekb_geoportal_ingest.py feat(tradein/scraper-kit): migrate backfill-task imports to kit, Group C (#2310) 2026-07-04 01:19:34 +03:00
gar_flats_load.py feat(tradein): канонический матч ГАР↔houses (0%→41% yield) + tradein_canon_addr + --match-only (#2063) 2026-06-28 15:50:07 +00:00
geocode_missing.py fix(tradein/geocode): бюджет прогона не был потолком — проверялся только между батчами 2026-08-27 19:10:53 +03:00
landing_showcase_deals.py fix(mera): витрина больше не отсеивает промахи оценщика, счётчики едут на фронт 2026-08-29 19:20:04 +05:00
landing_stats.py test(mera/b2c): гейт на сам SQL доли снижений + чистка протухших метрик 2026-08-29 19:10:04 +05:00
listing_source_snapshot.py fix(tradein): убрать невыводимые события, развести «снято» и «протухло» (#2674) 2026-08-06 03:01:05 +05:00
newbuilding_enrich_backfill.py fix(tradein/scrapers): убрать оставшиеся обходы пула прокси (#2830) (#2833) 2026-08-12 10:53:36 +00:00
osm_poi_ekb_refresh.py fix(tradein/location): заменить сломанный коэффициент локации на калиброванный индекс (#2531) 2026-07-26 21:48:15 +00:00
purge_expired_trade_in_data.py fix(tradein/payments): миграция 234 → 240 — номер снова занят на main 2026-08-07 15:31:01 +03:00
refresh_search_matview.py feat(tradein): premium_houses MV + premium_building flag (#2002) 2026-06-27 16:40:39 +00:00
rosreestr_quarter_poll.py feat(tradein): scheduled monthly Rosreestr new-quarter poll → ingest alert (#888) (#894) 2026-05-31 13:13:55 +00:00
sber_freshness_monitor.py fix(tradein/sber): сторож мерит отставание загрузки, а не календарь (#2846) (#2849) 2026-08-12 19:36:20 +00:00
sber_index_pull.py feat(tradein): СберИндекс monthly city-level price index pull (#887, data-layer) (#890) 2026-05-31 12:44:56 +00:00
yandex_address_backfill.py style(tradein): уложить перенесённые строки в лимит 100 символов 2026-08-27 18:24:09 +03:00
yandex_detail_backfill.py fix(tradein/scrapers): диагноз блока брался из текстовых маркеров чужой площадки, а не из HTTP-статуса (#3196) 2026-08-28 23:21:54 +03:00
yandex_newbuilding_sweep.py fix(tradein): неудача резолва yandex_jk_slug помечает дом — очередь не упирается в одни и те же пять (#2924) 2026-08-21 14:38:22 +05:00
zhkh_flats_load.py fix(tradein): cadastre ЖКХ-fallback + COALESCE merge-key + median-floors guard 2026-06-29 01:32:48 +03:00