fix(estimator): топ-5 фиксов аудита «Мера» (anchor gate, analog_tier, freshness, MAD-order, data-age) #1836

Merged
lekss361 merged 6 commits from feat/estimator-audit-top5 into main 2026-06-20 12:27:14 +00:00

6 commits

Author SHA1 Message Date
daa2edfac3 test(estimator): unit tests для audit fixes #audit-1..5 + empty-series guard
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
18 тестов покрывают все 5 фиксов: low-conf gate, analog_tier enum,
price_trend freshness, sigma=0 guard, sber staleness, thin-market flag.
Попутный fix: _load_sber_index_series — guard 'if not series: continue'
предотвращает max() на пустом dict при MagicMock rows (truthy=True).
2026-06-20 15:06:59 +03:00
a6ef2c73e1 fix(estimator): data-age guards — sber staleness + IMV thin-market (#audit-5)
5a: _load_sber_index_series логирует warning если latest месяц серии
старее sber_index_max_age_days (дефолт 35) — расчёт не блокируется.
5b: AvitoImvSummary.thin_market (bool, дефолт False) — True когда
market_count < avito_imv_thin_market_threshold (дефолт 10). Все три
точки конструирования AvitoImvSummary обновлены. Warning при thin.
2026-06-20 15:03:19 +03:00
5b2a39cd5e fix(estimator): MAD-clip после similarity-weighting + sigma=0 guard (#audit-4)
sigma=0 guard: safe_area_sigma2/safe_floor_sigma2 предотвращает div/0 при
нулевом sigma из конфига. Post-weight MAD-clip (estimate_sb_clip_after_weight,
дефолт True) выполняется ПОСЛЕ Gaussian weighting — видовые/топ-юниты
с высоким ppm² больше не выкидываются до учёта similarity. За флагом.
2026-06-20 15:01:36 +03:00
17edac532b fix(estimator): Yandex history freshness filter в price_trend (#audit-3)
_fetch_price_trend(freshness_months) — новый параметр, дефолт из
settings.estimate_price_trend_max_age_months (6 мес).
WHERE scraped_at > now() - N months исключает устаревшие items
(yandex_valuation 2024 и т.д.) из house_placement_history fallback.
houses_price_dynamics (Source 1) не затронут. psycopg v3 CAST syntax.
2026-06-20 15:00:55 +03:00
6b99f7d238 fix(estimator): структурный analog_tier + address_precision в API (#audit-2)
Добавляет AggregatedEstimate.analog_tier — стабильный enum для фронта:
same_building (Tier A), micro_radius (Tier C), district (S/H/0), city (W),
null (нет данных). Фронт не парсит tier из explanation.
address_precision уже был в схеме (подтверждено: line 208). Explanation не
удаляется — фронт fallback'ает на него.
2026-06-20 15:00:12 +03:00
55c7bc2c72 fix(estimator): anchor low-confidence gate (#audit-1)
Якорь с confidence=low ИЛИ (n<gate_min_n И FSD>gate_max_fsd) не заменяет
headline — fallback на radius-median. Дефолты (min_n=3, max_fsd=0.20) не
режут здоровые якоря (n≥4, FSD<0.15 проходят). За флагом
estimate_sb_low_conf_gate_enabled (дефолт True). Логируется с причиной.
2026-06-20 14:59:05 +03:00