fix(site-finder): обработка 202 (on-demand геометрия) + error boundaries — починка входа (#1001) #1073

Merged
bot-backend merged 1 commit from fix/site-finder-entry-crash-1001 into main 2026-06-05 11:13:33 +00:00
Collaborator

Что (🔴 демо-блокер)

Чинит белый экран на входе 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() бросали TypeErrorerror boundary не было → белый экран. Прод-проба: некешированный кадастр → 202; кешированный → 200; кривой формат → 400.

Правильная обработка 202 уже была в hooks/useSiteAnalysis.ts (poll /fetch-status), но современная страница её не использовала.

Фикс

  • useParcelAnalyzeQuery 202-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 не тронут.
  • Error boundaries: app/site-finder/analysis/[cad]/error.tsx + глобальный app/error.tsx — белого экрана не будет НИКОГДА; в проде спокойное RU-сообщение, в dev — детали ошибки.
  • Гварды: Section3 (competitors ?? []), Section4 (проверка score на конечность) — частичный payload рендерит пустое состояние, а не падает.
  • CadInput: убран хардкод-кадастр по умолчанию (пусто + placeholder), сырой hex → токены.

Карта (клик по участку) уже починена в 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.
  • Кривой кадастр → сообщение об ошибке, не падение.
## Что (🔴 демо-блокер) Чинит белый экран на входе 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), но современная страница её не использовала. ## Фикс - **`useParcelAnalyzeQuery` 202-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` не тронут. - **Error boundaries**: `app/site-finder/analysis/[cad]/error.tsx` + глобальный `app/error.tsx` — белого экрана не будет НИКОГДА; в проде спокойное RU-сообщение, в dev — детали ошибки. - **Гварды**: Section3 (`competitors ?? []`), Section4 (проверка `score` на конечность) — частичный payload рендерит пустое состояние, а не падает. - **CadInput**: убран хардкод-кадастр по умолчанию (пусто + placeholder), сырой hex → токены. Карта (клик по участку) уже починена в `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. - Кривой кадастр → сообщение об ошибке, не падение.
bot-backend added the
scope/frontend
GG-форсайт
site-finder
labels 2026-06-05 11:12:54 +00:00
bot-backend added 1 commit 2026-06-05 11:12:55 +00:00
fix(site-finder): handle 202 on-demand geometry in analyze + error boundaries (#1001)
All checks were successful
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 2m52s
Deploy / deploy (push) Successful in 1m1s
f7eb98b971
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 by 3cea915. Part of EPIC #958.
bot-backend merged commit f7eb98b971 into main 2026-06-05 11:13:33 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1073
No description provided.