fix(site-finder): обработка 202 (on-demand геометрия) + error boundaries — починка входа (#1001) #1073
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#1073
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/site-finder-entry-crash-1001"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что (🔴 демо-блокер)
Чинит белый экран на входе Site Finder. На стратегсессии ГГ (2026-06-01) анализ участка падал — теперь не падает.
Closes #1001 (958-B5). Часть EPIC #958.
Корень (подтверждён на проде)
POST /analyzeотдаёт HTTP 202{status:"fetching"}для участка, чья геометрия ещё не закеширована (#93 — on-demand НСПД-fetch).useParcelAnalyzeQueryтрактовал 202 как успех → заглушка (безscore/competitors) уходила в рендер →Section3 [...competitors]/Section4 score.toFixed()бросалиTypeError→ error boundary не было → белый экран. Прод-проба: некешированный кадастр → 202; кешированный → 200; кривой формат → 400.Правильная обработка 202 уже была в
hooks/useSiteAnalysis.ts(poll /fetch-status), но современная страница её не использовала.Фикс
useParcelAnalyzeQuery202-aware:apiFetchWithStatus→ на 202 поллитGET /fetch-status(2с, кап 2 мин), наreadyпере-POST/analyze(с проверкой статуса — не вернёт заглушку при гонке 202), наnot_in_nspd/failed/invalid_formatбросаетHTTPError(→ грейсфул-экран страницы).horizonсохранён в ОБОИХ POST (#996);retry: false;keepPreviousDataсохранён.useParcelForecastQueryне тронут.app/site-finder/analysis/[cad]/error.tsx+ глобальныйapp/error.tsx— белого экрана не будет НИКОГДА; в проде спокойное RU-сообщение, в dev — детали ошибки.competitors ?? []), Section4 (проверкаscoreна конечность) — частичный payload рендерит пустое состояние, а не падает.Карта (клик по участку) уже починена в
3cea915— не трогал.Качество
tech-analystдиагностика +code-reviewer: ✅ APPROVE (horizon в обоих URL, poll-кап, terminal-throws, boundary-placement, гварды — всё верно). Учтены минорные: симметрия пере-POST (status-checked) + RU-сообщение в проде.npm run buildзелёный. Без новых зависимостей, без codegen.Тест-план (post-deploy, обязательно на НЕкешированном участке)
/site-finder/analysis/<кадастр-не-в-БД>→ «Анализируем…» (поллинг) → либо подгрузка анализа, либо грейсфул-сообщение. Белого экрана нет.66:41:0702048:27→ полный рендер Секций 1-6.Critical demo-blocker: POST /analyze returns 202 {status:fetching} for parcels whose geometry isn't cached yet (#93 on-demand НСПД fetch). useParcelAnalyzeQuery treated 202 as success → the stub (no score/competitors) reached render → Section 3/4 threw TypeError → white screen (no error boundary). Repro confirmed on prod. - useParcelAnalyzeQuery: 202-aware — poll /fetch-status (2s, 2-min cap), re-POST on ready (status-checked, no stub on 202 race), throw HTTPError on not_in_nspd/failed/invalid_format; horizon preserved in both POSTs; retry: false - error boundaries: app/site-finder/analysis/[cad]/error.tsx + app/error.tsx — no white screen ever; calm RU message in prod, error detail in dev - Section3/Section4: guard competitors/score against partial payloads - CadInput: drop hardcoded default cad (empty + placeholder), raw hex → tokens Map parcel-select already fixed by3cea915. Part of EPIC #958.