diff --git a/tradein-mvp/backend/app/services/estimator.py b/tradein-mvp/backend/app/services/estimator.py index b12dcc8b..ba0e9d3a 100644 --- a/tradein-mvp/backend/app/services/estimator.py +++ b/tradein-mvp/backend/app/services/estimator.py @@ -965,8 +965,8 @@ def _load_sber_index_series(db: Session, *, region: str) -> dict[date, float]: .all() ) except Exception as exc: - logger.warning("sber_price_index lookup failed (graceful, no-op): %s", exc) - return {} + logger.warning("sber_price_index lookup failed for %s (graceful): %s", dash, exc) + continue if rows: return {r["period_month"]: float(r["index_value_rub_m2"]) for r in rows} return {} diff --git a/tradein-mvp/backend/app/services/sber_index.py b/tradein-mvp/backend/app/services/sber_index.py index 7cbe48ba..3554a0a7 100644 --- a/tradein-mvp/backend/app/services/sber_index.py +++ b/tradein-mvp/backend/app/services/sber_index.py @@ -380,32 +380,35 @@ async def pull_sber_indices( latest_month.isoformat(), latest_val, ) - # Task B: best-effort reconciliation to our scrape-median asking ppm² - try: - our_median = db.execute( - text(""" - SELECT percentile_cont(0.5) - WITHIN GROUP (ORDER BY price_per_m2) AS m - FROM listings - WHERE is_active = true - AND price_per_m2 BETWEEN 50000 AND 800000 - """) - ).scalar() - if our_median is not None and latest_val: - sber_latest = latest_val - divergence_pct = (our_median - sber_latest) / sber_latest * 100 - logger.info( - "sber_index benchmark [asking vs our median]: " - "sber=%.0f our_median=%.0f divergence=%+.1f%% " - "(data-quality signal)", - sber_latest, - our_median, - divergence_pct, + # our listings median is ЕКБ-only → + # compare only against Свердловская обл. (REF_AREA 66) + if ref_area == "66": + # Task B: best-effort reconciliation to our scrape-median asking ppm² + try: + our_median = db.execute( + text(""" + SELECT percentile_cont(0.5) + WITHIN GROUP (ORDER BY price_per_m2) AS m + FROM listings + WHERE is_active = true + AND price_per_m2 BETWEEN 50000 AND 800000 + """) + ).scalar() + if our_median is not None and latest_val: + sber_latest = latest_val + divergence_pct = (our_median - sber_latest) / sber_latest * 100 + logger.info( + "sber_index benchmark [asking vs our median]: " + "sber=%.0f our_median=%.0f divergence=%+.1f%% " + "(data-quality signal)", + sber_latest, + our_median, + divergence_pct, + ) + except Exception as exc: + logger.debug( + "sber benchmark reconciliation skipped (graceful): %s", exc ) - except Exception as exc: - logger.debug( - "sber benchmark reconciliation skipped (graceful): %s", exc - ) except httpx.HTTPStatusError as exc: logger.error(