From 4b6d1cbc06e72049de84c7d028f4d20d675ac2cd Mon Sep 17 00:00:00 2001 From: bot-backend Date: Fri, 3 Jul 2026 00:31:25 +0000 Subject: [PATCH] =?UTF-8?q?fix(report):=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B5=D1=82=D1=80=D0=B0=D0=B9=20=C2=A77=20=D1=81=20densify=20?= =?UTF-8?q?=E2=80=94=20=C2=AB=D0=BD=D0=B5=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D0=BB=D0=B0=20=D0=BD=D0=B8=20=D0=BE=D0=B4=D0=BD=D0=BE?= =?UTF-8?q?=D0=B9=20=D1=81=D0=B5=D0=BA=D1=86=D0=B8=D0=B8=C2=BB=20=D0=B1?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20=D0=BD=D0=B5=20422=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B5?= =?UTF-8?q?=20(#2242)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../site-finder/analysis/Section7Concept.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/frontend/src/components/site-finder/analysis/Section7Concept.tsx b/frontend/src/components/site-finder/analysis/Section7Concept.tsx index b80c5228..883cb004 100644 --- a/frontend/src/components/site-finder/analysis/Section7Concept.tsx +++ b/frontend/src/components/site-finder/analysis/Section7Concept.tsx @@ -212,6 +212,14 @@ export function Section7Concept({ analysis }: Props) { //
via the summary; onToggle keeps `expanded` in sync when reopened. const [expanded, setExpanded] = useState(true); + // Одноразовый авторетрай (fix 2026-07-03): на узких/мелких участках дефолтная + // программа (3 корпуса comfort 21×18) честно не влезает — движок отвечает 422 + // «программа застройки не вместила ни одной секции». Показывать это ошибкой + // при ЗАГРУЗКЕ отчёта нельзя (прод-кейс 66:41:0702033:20) — пробуем один раз + // densify=true: greedy-раскладка сама вмещает, что физически влезает. + // Не влезло и так → честная ошибка остаётся. Ручные запуски не ретраятся. + const autoRetriedRef = useRef(false); + useEffect(() => { if (autoRanRef.current || !expanded) return; if (!polygon || catalog.length === 0) return; @@ -233,6 +241,27 @@ export function Section7Concept({ analysis }: Props) { }); }, [expanded, polygon, catalog, concept, seeded, handleGenerate]); + useEffect(() => { + if (!autoRanRef.current || autoRetriedRef.current) return; + if (!concept.isError || !polygon || catalog.length === 0) return; + if (!/не вместила/i.test(concept.error.message)) return; + const def = pickDefaultType(catalog); + if (!def) return; + autoRetriedRef.current = true; + handleGenerate({ + corpuses: CORPUSES_DEFAULT, + floors: def.default_floors > 0 ? def.default_floors : FLOORS_FALLBACK, + floor_height_m: 3.0, + section_type: def.section_type, + footprint_w_m: def.footprint_w_m, + footprint_d_m: def.footprint_d_m, + housing_class: seeded.housing_class, + development_type: seeded.development_type, + land_cost_rub: seeded.land_cost_rub, + densify: true, // greedy max-FAR: вместить, что физически влезает + }); + }, [concept, polygon, catalog, seeded, handleGenerate]); + const handleToggle = useCallback( (e: React.SyntheticEvent) => { if (e.currentTarget.open) setExpanded(true);