From cc03ffa32dc2a6c8d87d9393f53b242b39734e19 Mon Sep 17 00:00:00 2001 From: lekss361 Date: Fri, 15 May 2026 09:20:51 +0300 Subject: [PATCH] fix(velocity): cross-stack contract + NULL safety per pre-push review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 3 pre-push code-reviewer findings fixed: 1. TS union extended ('objective'|'sale_graph'|'rosreestr_fallback') + UI conditions handle both objective и sale_graph как valid sources. 2. COALESCE(deals_total_vol_m2, deals_total_count * 45.0) — NULL safety for DKP-only rows (vol_m2 nullable, count > 0). 3. room_bucket parking filter — verified false positive (все 5 buckets apartments: студия/1/2/3/4+). Refs: PR #157 pre-push code-reviewer --- backend/app/services/site_finder/velocity.py | 6 ++++-- frontend/src/app/analytics/recommend/page.tsx | 11 +++++++---- .../components/analytics/RecommendVelocityPanel.tsx | 5 +++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/backend/app/services/site_finder/velocity.py b/backend/app/services/site_finder/velocity.py index c2a568a2..d3bb9b68 100644 --- a/backend/app/services/site_finder/velocity.py +++ b/backend/app/services/site_finder/velocity.py @@ -178,7 +178,8 @@ def compute_velocity( ) SELECT m.obj_id, - SUM(crm.deals_total_vol_m2) AS total_sqm, + SUM(COALESCE(crm.deals_total_vol_m2, + crm.deals_total_count * 45.0)) AS total_sqm, COUNT(DISTINCT crm.report_month) AS months_with_data, MIN(crm.report_month) AS period_start, MAX(crm.report_month) AS period_end @@ -294,7 +295,8 @@ def _get_ekb_median(db: Session, months_window: int = 6) -> float | None: WITH per_project AS ( SELECT project_name, - SUM(deals_total_vol_m2) AS total_sqm, + SUM(COALESCE(deals_total_vol_m2, + deals_total_count * 45.0)) AS total_sqm, COUNT(DISTINCT report_month) AS months_data FROM objective_corpus_room_month WHERE report_month >= (CURRENT_DATE - :window_interval::interval) diff --git a/frontend/src/app/analytics/recommend/page.tsx b/frontend/src/app/analytics/recommend/page.tsx index 4a50d5d6..e362b69d 100644 --- a/frontend/src/app/analytics/recommend/page.tsx +++ b/frontend/src/app/analytics/recommend/page.tsx @@ -260,16 +260,19 @@ export default function RecommendPage() { } /> {scope.market_velocity_per_month?.toFixed(1) ?? "—"}{" "} кв/мес ( - {scope.velocity_source === "sale_graph" - ? `sale_graph: ${scope.velocity_objects} ЖК / ${scope.velocity_observations} точек` + {scope.velocity_source === "objective" || + scope.velocity_source === "sale_graph" + ? `${scope.velocity_source}: ${scope.velocity_objects} ЖК / ${scope.velocity_observations} точек` : "fallback на rosreestr-сделки"} ),{" "} {scope.competitors_radius_n != null &&