feat(sf): КРТ-реквизиты (ekb_krt_sites) в ИРД-блок analyze (#1060) #1131

Merged
bot-reviewer merged 1 commit from feat/krt-analyze-join into main 2026-06-07 11:50:30 +00:00
Owner

Что

block["krt_requisites"] в ИРД-блоке analyze: когда участок попадает в КРТ-площадку — отдаёт застройщика/цену торгов/градпотенциал из ekb_krt_sites (#1126). Завершает #1060.

Расследование ключа (важно)

  • ⚠️ ird_overlays.opportunity_krt оказался ККР (комплексные кадастровые работы) Роскадастра, НЕ КРТ-застройка (raw_props: contractNum/krcustomername — кадастровые работы). Геометрию КРТ для матча взял из planning_projects (ПМТ/ППТ полигоны, m.134).
  • Ключ: planning_projects.full_name ПАГЕ-№ ↔ ekb_krt_sites.paga_decisions[].number+yearconfidence='exact'.
  • Матч 3/15 площадок (Летчиков/Вилонова/Патриса Лумумбы — у них есть ПМТ). Остальные 12 → matched=False, confidence='none', реквизиты НЕ передаются (никакой ложной атрибуции застройщика).
  • При загрузке ПМТ для остальных 12 — матч заработает автоматически (SQL ищет по ПАГЕ-№), без правок кода.

Состав

  • krt_lookup.py::parcel_krt_requisites(db, parcel_wkt) — ST_Intersects к planning_projects + exact-матч к ekb_krt_sites, graceful.
  • врезка в build_ird_analyze_block.
  • 20/20 тестов (9 lookup + 2 ird_analyze + existing).

NB (follow-up)

Живой _krt_at (geoportal WFS portal_geo_oks_krt) в analyze остаётся отдельным geom-фактом, к ekb_krt_sites не привязан (нет общего ключа). Кандидат на harvest КРТ-геометрии в БД → закрывает и латентность (#1130).

Часть #1060/#1067.

## Что `block["krt_requisites"]` в ИРД-блоке analyze: когда участок попадает в КРТ-площадку — отдаёт застройщика/цену торгов/градпотенциал из `ekb_krt_sites` (#1126). Завершает #1060. ## Расследование ключа (важно) - ⚠️ `ird_overlays.opportunity_krt` оказался **ККР (комплексные кадастровые работы) Роскадастра**, НЕ КРТ-застройка (raw_props: contractNum/krcustomername — кадастровые работы). Геометрию КРТ для матча взял из **`planning_projects`** (ПМТ/ППТ полигоны, m.134). - Ключ: `planning_projects.full_name` ПАГЕ-№ ↔ `ekb_krt_sites.paga_decisions[].number+year` → `confidence='exact'`. - **Матч 3/15** площадок (Летчиков/Вилонова/Патриса Лумумбы — у них есть ПМТ). Остальные 12 → `matched=False, confidence='none'`, реквизиты НЕ передаются (никакой ложной атрибуции застройщика). - При загрузке ПМТ для остальных 12 — матч заработает **автоматически** (SQL ищет по ПАГЕ-№), без правок кода. ## Состав - `krt_lookup.py::parcel_krt_requisites(db, parcel_wkt)` — ST_Intersects к planning_projects + exact-матч к ekb_krt_sites, graceful. - врезка в `build_ird_analyze_block`. - 20/20 тестов (9 lookup + 2 ird_analyze + existing). ## NB (follow-up) Живой `_krt_at` (geoportal WFS `portal_geo_oks_krt`) в analyze остаётся отдельным geom-фактом, к `ekb_krt_sites` не привязан (нет общего ключа). Кандидат на harvest КРТ-геометрии в БД → закрывает и латентность (#1130). Часть #1060/#1067.
lekss361 added 1 commit 2026-06-07 11:43:28 +00:00
feat(sf): КРТ-реквизиты (ekb_krt_sites) в ИРД-блок analyze по geoportal-geom (#1060)
All checks were successful
CI / changes (push) Successful in 7s
CI / changes (pull_request) Successful in 6s
CI / backend-tests (push) Successful in 6m17s
CI / backend-tests (pull_request) Successful in 6m12s
ab5c9aabcb
lekss361 added the
GG-форсайт
scope/backend
site-finder
labels 2026-06-07 11:43:34 +00:00
bot-reviewer approved these changes 2026-06-07 11:50:23 +00:00
bot-reviewer left a comment
Collaborator

APPROVE — КРТ-реквизиты в analyze. Хорошее defensive-проектирование (no false attribution).

Verified:

  • Нет signature-change (build_ird_analyze_block только добавляет ключ krt_requisites в DB-дешёвой секции, рядом с planning/reservations) → callers/тесты не ломаются. _patch_overlay патчит parcel_krt_requisites.
  • Exact-match path корректен: ST_Intersects(planning_projects) ⋈ EXISTS jsonb_array_elements(paga_decisions) по ПАГЕ-№+год+title — confidence='exact', дедуп (pp_id,krt_id). psycopg v3: bind CAST(:parcel_wkt AS text) ✓; dmd_actual_year::text/split_part — column-cast, не bind, ОК.
  • Graceful: OperationalError/ProgrammingError/Exception → []. None-Decimal → None (тест есть). 9 lookup-тестов + 2 ird_analyze — годно.
  • Расследование opportunity_krt=ККР (Роскадастр, не КРТ-застройка) → матч через planning_projects ПМТ — корректный вывод, избегает ложного join. matched=False для непривязанных → нет ложной атрибуции застройщика. 👍

🟡 MINOR (actionable → follow-up #issue, НЕ блокер): в _PLANNING_NO_MATCH_SQL regex записан многострочным литералом — встроенные \n загрязняют alternation на концах строк. Проверил в Postgres: Краснофлотцев→match ✓, но Донбасской→False, Лумумбы→False (концевые токены строк склеены с \n |). Затрагивает ТОЛЬКО geom-only fallback-hint (matched=False) — не exact-данные, не падение, well-formed блок. Сейчас (ekb_krt_sites пуст) fallback — активный путь → 2 топонима молча без hint. Fix: схлопнуть regex в одну строку. Заодно: jsonb_array_elements упадёт на не-array paga_decisions (scraper всегда пишет array, но guard jsonb_typeof(...)='array' надёжнее) + хардкод-список топонимов хрупок к новым площадкам.

Данные: ekb_krt_sites пуст на проде (sync не прогнан) → exact-матчей пока 0, 3/15 заработают после наполнения (проверено автором локально; на проде не сверял — пустая таблица).

Merging (squash); regex → follow-up.

<!-- gendesign-review-bot: sha=ab5c9aa verdict=approve --> ✅ **APPROVE** — КРТ-реквизиты в analyze. Хорошее defensive-проектирование (no false attribution). **Verified:** - Нет signature-change (`build_ird_analyze_block` только добавляет ключ `krt_requisites` в DB-дешёвой секции, рядом с planning/reservations) → callers/тесты не ломаются. `_patch_overlay` патчит `parcel_krt_requisites`. - Exact-match path корректен: ST_Intersects(planning_projects) ⋈ EXISTS jsonb_array_elements(paga_decisions) по ПАГЕ-№+год+title — `confidence='exact'`, дедуп (pp_id,krt_id). psycopg v3: bind `CAST(:parcel_wkt AS text)` ✓; `dmd_actual_year::text`/`split_part` — column-cast, не bind, ОК. - Graceful: OperationalError/ProgrammingError/Exception → []. None-Decimal → None (тест есть). 9 lookup-тестов + 2 ird_analyze — годно. - Расследование `opportunity_krt`=ККР (Роскадастр, не КРТ-застройка) → матч через planning_projects ПМТ — корректный вывод, избегает ложного join. matched=False для непривязанных → нет ложной атрибуции застройщика. 👍 **🟡 MINOR (actionable → follow-up #issue, НЕ блокер):** в `_PLANNING_NO_MATCH_SQL` regex записан **многострочным литералом** — встроенные `\n ` загрязняют alternation на концах строк. Проверил в Postgres: `Краснофлотцев`→match ✓, но **`Донбасской`→False, `Лумумбы`→False** (концевые токены строк склеены с `\n |`). Затрагивает ТОЛЬКО geom-only fallback-hint (matched=False) — не exact-данные, не падение, well-formed блок. Сейчас (ekb_krt_sites пуст) fallback — активный путь → 2 топонима молча без hint. Fix: схлопнуть regex в одну строку. Заодно: `jsonb_array_elements` упадёт на не-array paga_decisions (scraper всегда пишет array, но guard `jsonb_typeof(...)='array'` надёжнее) + хардкод-список топонимов хрупок к новым площадкам. Данные: ekb_krt_sites пуст на проде (sync не прогнан) → exact-матчей пока 0, 3/15 заработают после наполнения (проверено автором локально; на проде не сверял — пустая таблица). Merging (squash); regex → follow-up.
bot-reviewer merged commit 97731a2b09 into main 2026-06-07 11:50:30 +00:00
bot-reviewer deleted branch feat/krt-analyze-join 2026-06-07 11:50:30 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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#1131
No description provided.