[Fable 5][P2] EGRN-контракт сломан: фронт ждёт vri/category/owner_type, бэкенд шлёт permitted_use_text/land_category — таблица ЕГРН пустая в prod #1217

Closed
opened 2026-06-13 04:49:45 +00:00 by bot-backend · 0 comments
Collaborator

Из армейского ревью Claude Fable 5 (2026-06-11)

Confirmed by 2/2 адверсариальных верификатора, severity P2 (api-contract), confidence 0.85.

Файл

frontend/src/components/site-finder/analysis/Section1ParcelInfo.tsx:188

Evidence (цитата кода)

// EGRN: use response field if B5-extended is deployed, else fallback stub
const egrn: ParcelEgrn =
  data.egrn != null ? (data.egrn as ParcelEgrn) : buildFallbackEgrn(cad);

Why bug

Бэкенд /analyze собирает egrn_block с ключами permitted_use_text/land_category/ownership_type/parcel_status/last_egrn_update_date (parcels.py:2151-2171), а ParcelEgrn (site-finder-api.ts:255) ждёт cad_num/vri/category/owner_type/encumbrance/status/last_updated. Mock-фикстура имеет старую форму — в dev ок, в prod 6 из 10 строк таблицы ЕГРН пустые при наличии данных; CSV-экспорт (ExportButtons.tsx:41-52) пишет литеральный «undefined». При отсутствии строки в cad_parcels бэкенд шлёт {} → fallback «—» не срабатывает. OverviewTab корректно читает permitted_use_text — подтверждение реальной формы.

Suggested fix

Адаптер backend-egrn → ParcelEgrn (permitted_use_text→vri, land_category→category, ownership_type→owner_type, parcel_status→status, last_egrn_update_date→last_updated), пустой объект считать отсутствием данных; обновить mock-фикстуру.

Verify notes

  • [real/P2] Трасса: /analyze шлёт egrn passthrough (schemas/parcel.py:556 dict[str,Any], extra=allow) с ключами permitted_use_text/land_category/ownership_type/parcel_status; hook отдаёт body без маппинга; каст as ParcelEgrn глушит TS. buildRows читает vri/category/owner_type/encumbrance/status/cad_num → 6/10 строк пустые. Нет строки в cad_parcels → egrn={} (truthy) → fallback мёртв, CSV пишет String(undefined). Mock — старая форма; OverviewTab подтверждает реальную.
  • [real/P2] Защиты нет: AnalyzeResponse.egrn = dict[str,Any] + extra="allow" (без ремапа), хук возвращает body as-is, в prod MOCK_ANALYZE=false, страница живая (AnalysisPageContent.tsx:161). Ключи бэка и фронта расходятся → 6 из 10 строк таблицы ЕГРН пустые; egrn={} != null → fallback «—» не срабатывает. Фикстура старой формы маскирует баг в dev; OverviewTab читает permitted_use_text — реальная форма. Неточность: CSV пишет пустые ячейки, не литерал «undefined» (join коэрсит в ""). P2 подтверждён.

Provenance

  • Finders: fe-sitefinder
  • Confidence: 0.85
  • Originally batched at: main@d796027
## Из армейского ревью Claude Fable 5 (2026-06-11) Confirmed by 2/2 адверсариальных верификатора, severity **P2** (api-contract), confidence 0.85. ## Файл [`frontend/src/components/site-finder/analysis/Section1ParcelInfo.tsx:188`](frontend/src/components/site-finder/analysis/Section1ParcelInfo.tsx:188) ## Evidence (цитата кода) ``` // EGRN: use response field if B5-extended is deployed, else fallback stub const egrn: ParcelEgrn = data.egrn != null ? (data.egrn as ParcelEgrn) : buildFallbackEgrn(cad); ``` ## Why bug Бэкенд /analyze собирает egrn_block с ключами permitted_use_text/land_category/ownership_type/parcel_status/last_egrn_update_date (parcels.py:2151-2171), а ParcelEgrn (site-finder-api.ts:255) ждёт cad_num/vri/category/owner_type/encumbrance/status/last_updated. Mock-фикстура имеет старую форму — в dev ок, в prod 6 из 10 строк таблицы ЕГРН пустые при наличии данных; CSV-экспорт (ExportButtons.tsx:41-52) пишет литеральный «undefined». При отсутствии строки в cad_parcels бэкенд шлёт {} → fallback «—» не срабатывает. OverviewTab корректно читает permitted_use_text — подтверждение реальной формы. ## Suggested fix Адаптер backend-egrn → ParcelEgrn (permitted_use_text→vri, land_category→category, ownership_type→owner_type, parcel_status→status, last_egrn_update_date→last_updated), пустой объект считать отсутствием данных; обновить mock-фикстуру. ## Verify notes - [real/P2] Трасса: /analyze шлёт egrn passthrough (schemas/parcel.py:556 dict[str,Any], extra=allow) с ключами permitted_use_text/land_category/ownership_type/parcel_status; hook отдаёт body без маппинга; каст as ParcelEgrn глушит TS. buildRows читает vri/category/owner_type/encumbrance/status/cad_num → 6/10 строк пустые. Нет строки в cad_parcels → egrn={} (truthy) → fallback мёртв, CSV пишет String(undefined). Mock — старая форма; OverviewTab подтверждает реальную. - [real/P2] Защиты нет: AnalyzeResponse.egrn = dict[str,Any] + extra="allow" (без ремапа), хук возвращает body as-is, в prod MOCK_ANALYZE=false, страница живая (AnalysisPageContent.tsx:161). Ключи бэка и фронта расходятся → 6 из 10 строк таблицы ЕГРН пустые; egrn={} != null → fallback «—» не срабатывает. Фикстура старой формы маскирует баг в dev; OverviewTab читает permitted_use_text — реальная форма. Неточность: CSV пишет пустые ячейки, не литерал «undefined» (join коэрсит в ""). P2 подтверждён. ## Provenance - Finders: `fe-sitefinder` - Confidence: 0.85 - Originally batched at: main@d796027
bot-backend added the
Fable 5 ревью
label 2026-06-13 04:49:45 +00:00
Sign in to join this conversation.
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#1217
No description provided.