From a572cf39d1716377b547966c77b4c7ed6452d8fa Mon Sep 17 00:00:00 2001 From: lekss361 Date: Fri, 15 May 2026 09:39:06 +0300 Subject: [PATCH 1/2] =?UTF-8?q?fix(velocity):=20:window=5Finterval::interv?= =?UTF-8?q?al=20cast=20syntax=20=E2=80=94=20same=20bug=20as=20PR=20#152?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SQLAlchemy text() parser confuses ':window_interval' (named param) followed by '::interval' (cast operator) — exactly как было в PR #152 с :weights::jsonb. Result: psycopg видит literal ':window_interval' в SQL → syntax error → exception caught by velocity catch → return None → UI shows null. ## Fix ':window_interval::interval' → 'CAST(:window_interval AS interval)' (2 мест: sales_rows query + _get_ekb_median percentile). Pre-push code-reviewer должен был catch — добавим в feedback что для каждого text() SQL grep ':[a-z]*::' before push. Refs: PR #158 deploy verify, e2e velocity = null root cause --- backend/app/services/site_finder/velocity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/app/services/site_finder/velocity.py b/backend/app/services/site_finder/velocity.py index d3bb9b68..0dd76d54 100644 --- a/backend/app/services/site_finder/velocity.py +++ b/backend/app/services/site_finder/velocity.py @@ -186,7 +186,7 @@ def compute_velocity( FROM objective_corpus_room_month crm JOIN mapped m ON m.objective_complex_name = crm.project_name - WHERE crm.report_month >= (CURRENT_DATE - :window_interval::interval) + WHERE crm.report_month >= (CURRENT_DATE - CAST(:window_interval AS interval)) AND crm.deals_total_count > 0 GROUP BY m.obj_id """ @@ -299,7 +299,7 @@ def _get_ekb_median(db: Session, months_window: int = 6) -> float | None: 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) + WHERE report_month >= (CURRENT_DATE - CAST(:window_interval AS interval)) AND deals_total_count > 0 GROUP BY project_name HAVING COUNT(DISTINCT report_month) >= 3 -- 2.45.3 From 46584d7c75534189b713386d1a36e80f7e265bcc Mon Sep 17 00:00:00 2001 From: lekss361 <47113017+lekss361@users.noreply.github.com> Date: Fri, 15 May 2026 09:46:01 +0300 Subject: [PATCH 2/2] =?UTF-8?q?fix(velocity):=20:window=5Finterval::interv?= =?UTF-8?q?al=20cast=20syntax=20=E2=80=94=20same=20bug=20as=20PR=20#152=20?= =?UTF-8?q?(#160)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SQLAlchemy text() parser confuses ':window_interval' (named param) followed by '::interval' (cast operator) — exactly как было в PR #152 с :weights::jsonb. Result: psycopg видит literal ':window_interval' в SQL → syntax error → exception caught by velocity catch → return None → UI shows null. ## Fix ':window_interval::interval' → 'CAST(:window_interval AS interval)' (2 мест: sales_rows query + _get_ekb_median percentile). Pre-push code-reviewer должен был catch — добавим в feedback что для каждого text() SQL grep ':[a-z]*::' before push. Refs: PR #158 deploy verify, e2e velocity = null root cause Co-authored-by: lekss361 --- backend/app/services/site_finder/velocity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/app/services/site_finder/velocity.py b/backend/app/services/site_finder/velocity.py index d3bb9b68..0dd76d54 100644 --- a/backend/app/services/site_finder/velocity.py +++ b/backend/app/services/site_finder/velocity.py @@ -186,7 +186,7 @@ def compute_velocity( FROM objective_corpus_room_month crm JOIN mapped m ON m.objective_complex_name = crm.project_name - WHERE crm.report_month >= (CURRENT_DATE - :window_interval::interval) + WHERE crm.report_month >= (CURRENT_DATE - CAST(:window_interval AS interval)) AND crm.deals_total_count > 0 GROUP BY m.obj_id """ @@ -299,7 +299,7 @@ def _get_ekb_median(db: Session, months_window: int = 6) -> float | None: 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) + WHERE report_month >= (CURRENT_DATE - CAST(:window_interval AS interval)) AND deals_total_count > 0 GROUP BY project_name HAVING COUNT(DISTINCT report_month) >= 3 -- 2.45.3