Три honesty/correctness-фикса из audit-issue #1871 (🟠 P2). Все факты подтверждены prod-DB + разведкой. ETL не трогаем (отдельная задача). velocity.py: - _EKB_MEDIAN_FALLBACK 4500→750 (audit-verified медиана ЕКБ 593-766; 4500 завышало знаменатель нормализации 7.6× → занижало velocity_score при DB-error fallback, latent). Консервативно 750 (верх диапазона). - VelocityResult + as_dict() раскрывают: objective_coverage_pct, proxy_used, proxy_sqm_per_deal — теперь видно что объём rosreestr-пути фабрикуется count×45 м²/сделка при низком покрытии Objective (<50%). Проброшено во все 4 конструктора, additive. parcels.py (market_trend producer): - Различать «источник устарел» от «нет сделок». rosreestr_deals MAX(period_start_date)=2026-01-01 (stale 5.5 мес) → recent-окно пусто → раньше голый null. Теперь status ∈ {ok, source_stale, no_deals} + as_of_date + label + recent_deals_count. MAX(deal_date) добавлен в CTE. Consumer scoring читает recent_deals_count защищённо (без регрессии). frontend (types + MarketTrendBlock + VelocityBlock + ptica market-drawer + Section3 verdict + legacy guard): - staleness/no_deals → честный caveat вместо фейкового тренда. - velocity → caption «объём оценочный (прокси N м²/сделка, покрытие P%)». - formatAsOfMonth парсит YYYY-MM напрямую (TZ-safe). - Типы MarketTrend/Velocity расширены (optional, backward-compat; отсутствие status = "ok"). Тесты: +3 velocity unit + extended as_dict contract. 17 velocity passed, 138 frontend vitest passed. Refs #1871 |
||
|---|---|---|
| .. | ||
| analysis_runs | ||
| analytics | ||
| cadastre | ||
| chat | ||
| etl | ||
| exporters | ||
| forecasting | ||
| generative | ||
| llm | ||
| photos | ||
| scrapers | ||
| site_finder | ||
| __init__.py | ||
| analytics_queries.py | ||
| analytics_refresh.py | ||
| forecast_request_cache.py | ||
| insights.py | ||
| job_settings.py | ||
| objective_etl.py | ||
| objective_sync_config.py | ||
| own_projects.py | ||
| weather_cache.py | ||