From 12030c4e76931f017d4c5da7272f1427492a1437 Mon Sep 17 00:00:00 2001 From: lekss361 Date: Mon, 18 May 2026 07:29:26 +0300 Subject: [PATCH] =?UTF-8?q?fix(sf-legacy):=20=D1=84=D0=B8=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D1=80=20=D1=81=D1=82=D0=B5=D0=B9=D0=BB=20competitors=20(?= =?UTF-8?q?>1=20=D0=B3=D0=BE=D0=B4=D0=B0=20=D0=A1=D0=B4=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=E2=86=92=20=D0=BD=D0=B5=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D0=BA=D1=83=D1=80=D0=B5=D0=BD=D1=82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User: 'плюс проверь какие данн чтобы было то что хочет макс хотя бы похожи что не старше года иначе жк не конкурент'. Анализ /analyze для 66:41:0204016:10: Total competitors: 20 Строящиеся: 6 Сданные: 14 (12 из них ready_dt >1y → стейл) Maxim spec: ЖК старше года не конкурент. Активные = строящиеся ИЛИ ready_dt в будущем ИЛИ сданы ≤1 года назад. MarketTab фильтрует data.competitors в relevantCompetitors: - site_status === 'Строящиеся' → активен - ready_dt в будущем → активен - ready_dt в пределах последнего года → активен - иначе скрыт activeCount + CompetitorTable теперь используют отфильтрованный список. Section label показывает 'N из M — фильтр' для прозрачности. После deploy для тестового cad: activeCount упадёт с 20 → 9 (6 строящихся + 1 future ≤1y + 2 past ≤1y). --- .../src/components/site-finder/MarketTab.tsx | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/site-finder/MarketTab.tsx b/frontend/src/components/site-finder/MarketTab.tsx index d44d4721..c6b4868e 100644 --- a/frontend/src/components/site-finder/MarketTab.tsx +++ b/frontend/src/components/site-finder/MarketTab.tsx @@ -56,9 +56,21 @@ export function MarketTab({ data }: Props) { data.competitors.length > 0; // ── Above-the-fold values ──────────────────────────────────────────────── - // Note: site_status field pending fix #2/#3 (backend PR). Using total - // competitors count as proxy for active (строящихся) count for now. - const activeCount = data.competitors.length; + // Maxim's spec: «ЖК старше года → не конкурент». Filter active competitors: + // - site_status === 'Строящиеся' → активен + // - либо ready_dt в будущем → активен (готовность ещё не наступила) + // - либо ready_dt в пределах последнего года → активен (свежие продажи) + // - иначе (Сданные >1y назад) → не конкурент, скрыт + const REL_MS = 365 * 24 * 60 * 60 * 1000; + const yearAgoTs = Date.now() - REL_MS; + const relevantCompetitors = data.competitors.filter((c) => { + if (c.site_status === "Строящиеся") return true; + if (!c.ready_dt) return false; + const ts = new Date(c.ready_dt).getTime(); + if (Number.isNaN(ts)) return false; + return ts >= yearAgoTs; + }); + const activeCount = relevantCompetitors.length; const radiusKm = getRadiusKm(data); // Treat zero velocity as "no data" — backend returns 0 when competitors // are unmapped to Objective ground truth (OBJ-3). Showing "0.0 м²/мес" @@ -241,11 +253,15 @@ export function MarketTab({ data }: Props) { {/* ── Main content blocks ───────────────────────────────────────────── */} {/* Competitors */} - {data.competitors.length > 0 && ( + {relevantCompetitors.length > 0 && (
- Конкуренты + + Конкуренты ({relevantCompetitors.length} из{" "} + {data.competitors.length} + {" — фильтр: строящиеся или сданы ≤1 года)"} +