Bulk cadastre ingest ЕКБ — 2408 кварталов через NSPD #168

Closed
opened 2026-05-15 09:27:30 +00:00 by lekss361 · 2 comments
lekss361 commented 2026-05-15 09:27:30 +00:00 (Migrated from github.com)

Контекст

После live HAR-audit NSPD API (2026-05-15) подтверждены два рабочих эндпоинта:

  • GET /api/geoportal/v2/search/geoportal?thematicSearchId=1&query={quarter} — snapshot первых 20 features per category + meta.totalCount (5+ категорий)
  • GET /api/aeggis/v4/{layerId}/wms?REQUEST=GetFeatureInfo&...&I=&J= — точечный feature lookup (для grid-walk discovery)

Цель: one-time bulk-ingest всех кадастровых данных ЕКБ (66:41:*) в БД для использования в Site Finder analyze, scoring, gate verdict, generative design.

См. полный план: research/Bulk_Cadastre_Ingest_Plan_May15.md в Obsidian.

Скоп

Регион ЕКБ-город (cad prefix 66:41:*, ~2 408 кварталов)
Помещения НЕТ (deferred — separate task для per-flat ДДУ cross-check)
Existing data Drop + re-scrape cad_parcels_geom (610) + cad_buildings (10 590)
Pilot 50 quarter → metrics → go/no-go full 2 408
Concurrency 3 req/s sustained (verified 5/5 burst OK)
Refresh One-time + manual re-run раз в квартал через admin UI
Analyze integration Не сразу — bulk работает sandbox'но, cutover в отдельном PR после verification

Architecture

DB tables (7 new + 1 jobs):
  cad_parcels          — 36368 ЗУ ЕГРН
  cad_buildings        — 36369 (replace existing, add objdoc_id)
  cad_constructions    — 36383 Сооружения + ЕГРН (flag is_egrn)
  cad_oncs             — 36384 ОНС
  cad_enk              — 39663 ЕНК
  cad_zouit            — 36940/469039/469040/469042 → 1 таблица, dedup reg_numb_border
  cad_quarter_stats    — enrichment для cad_quarters_geom
  cadastre_jobs        — saga state per harvest run (клон geo_jobs)

Celery tasks:
  bulk_harvest_quarter(quarter, job_id)  — phase 1: snapshot + phase 2: overflow detect
  grid_walk_quarter(quarter, layer)      — phase 3: WMS GetFeatureInfo 15×15

Backend:
  POST /api/v1/admin/scrape/cadastre
  GET  /api/v1/admin/scrape/cadastre/jobs
  GET  /api/v1/admin/scrape/cadastre/jobs/{id}
  POST /api/v1/admin/scrape/cadastre/jobs/{id}/cancel

Frontend:
  /admin/scrape/cadastre — клон /admin/scrape/geo

Sequential PR plan

PR Описание Owner Effort
#1 Schema data/sql/92_cad_bulk_layers.sql — 7 таблиц + cadastre_jobs + индексы database-expert 0.5 дня
#2 NSPDClient search_by_quarter, wms_feature_info, list_objects_in_building backend-engineer 1 день
#3 Worker bulk_harvest_quarter Celery task + grid_walker + saga state backend-engineer 1.5 дня
#4 Admin UI /admin/scrape/cadastre — клон scrape/geo + adapter frontend-engineer 0.5 дня
#5 Pilot Run 50 quarter → metrics → go/no-go full 2408 (~5ч elapsed) manual + analyst 0.5 дня

Resumable saga

  • cadastre_jobs.phase_state JSONB: {phase, snapshot_at, parcels_total_meta, parcels_fetched, ...}
  • Celery acks_late=True + idempotent upsert (ON CONFLICT (cad_num) DO UPDATE)
  • Redeploy mid-run → task resumes от точки падения

Risks + mitigations

Risk Mitigation
NSPD WAF при sustained 3 req/s Pilot detect early; fallback 1 req/s при 429
Grid-walk пропускает мелкие ЗУ при step=50м FEATURE_COUNT=10 + fallback step=25м для overflow quarters
Redeploy mid-harvest acks_late + idempotent upsert + saga state в DB
Storage growth >100MB Pilot extrapolation

Acceptance per PR

  • PR 1: миграция применилась, 8 таблиц created, existing data migrated
  • PR 2: pytest e2e — search_by_quarter("66:41:0303161") → 502 объекта + meta
  • PR 3: bulk_harvest_quarter ВЫДЕРЖИВАЕТ redeploy mid-run, идемпотентен
  • PR 4: /admin/scrape/cadastre доступен, кнопка "Запустить pilot 50" работает
  • PR 5: pilot 50 quarter завершён, метрики собраны, go/no-go decision

Q3 deferred (помещения 37163 + парковка 37159)

Когда понадобятся для per-flat ДДУ cross-check:

  • iterate cad_buildingstab-group-data → batch fetch search per помещение
  • ~100K req для ЕКБ × 3 req/s = ~9ч harvest
  • Отдельный bulk_harvest_flats task + cad_flats + cad_parking tables

Vault refs

  • research/NSPD_API_Map_May12.md — полный API audit (1613 lines)
  • research/Bulk_Cadastre_Ingest_Plan_May15.md — этот план
  • research/Engineering_Networks_Schema_191FZ_May12.md — pattern для альт-источников
  • fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md — closed когда grid-walk works в PR 3
## Контекст После live HAR-audit NSPD API (2026-05-15) подтверждены два рабочих эндпоинта: - `GET /api/geoportal/v2/search/geoportal?thematicSearchId=1&query={quarter}` — snapshot первых 20 features per category + `meta.totalCount` (5+ категорий) - `GET /api/aeggis/v4/{layerId}/wms?REQUEST=GetFeatureInfo&...&I=&J=` — точечный feature lookup (для grid-walk discovery) Цель: one-time bulk-ingest всех кадастровых данных ЕКБ (66:41:*) в БД для использования в Site Finder analyze, scoring, gate verdict, generative design. См. полный план: `research/Bulk_Cadastre_Ingest_Plan_May15.md` в Obsidian. ## Скоп | | | |---|---| | Регион | ЕКБ-город (cad prefix `66:41:*`, ~2 408 кварталов) | | Помещения | ❌ НЕТ (deferred — separate task для per-flat ДДУ cross-check) | | Existing data | Drop + re-scrape `cad_parcels_geom` (610) + `cad_buildings` (10 590) | | Pilot | 50 quarter → metrics → go/no-go full 2 408 | | Concurrency | 3 req/s sustained (verified 5/5 burst OK) | | Refresh | One-time + manual re-run раз в квартал через admin UI | | Analyze integration | ❌ Не сразу — bulk работает sandbox'но, cutover в отдельном PR после verification | ## Architecture ``` DB tables (7 new + 1 jobs): cad_parcels — 36368 ЗУ ЕГРН cad_buildings — 36369 (replace existing, add objdoc_id) cad_constructions — 36383 Сооружения + ЕГРН (flag is_egrn) cad_oncs — 36384 ОНС cad_enk — 39663 ЕНК cad_zouit — 36940/469039/469040/469042 → 1 таблица, dedup reg_numb_border cad_quarter_stats — enrichment для cad_quarters_geom cadastre_jobs — saga state per harvest run (клон geo_jobs) Celery tasks: bulk_harvest_quarter(quarter, job_id) — phase 1: snapshot + phase 2: overflow detect grid_walk_quarter(quarter, layer) — phase 3: WMS GetFeatureInfo 15×15 Backend: POST /api/v1/admin/scrape/cadastre GET /api/v1/admin/scrape/cadastre/jobs GET /api/v1/admin/scrape/cadastre/jobs/{id} POST /api/v1/admin/scrape/cadastre/jobs/{id}/cancel Frontend: /admin/scrape/cadastre — клон /admin/scrape/geo ``` ## Sequential PR plan | PR | Описание | Owner | Effort | |---|---|---|---| | **#1 Schema** | `data/sql/92_cad_bulk_layers.sql` — 7 таблиц + cadastre_jobs + индексы | database-expert | 0.5 дня | | **#2 NSPDClient** | `search_by_quarter`, `wms_feature_info`, `list_objects_in_building` | backend-engineer | 1 день | | **#3 Worker** | `bulk_harvest_quarter` Celery task + grid_walker + saga state | backend-engineer | 1.5 дня | | **#4 Admin UI** | `/admin/scrape/cadastre` — клон scrape/geo + adapter | frontend-engineer | 0.5 дня | | **#5 Pilot** | Run 50 quarter → metrics → go/no-go full 2408 (~5ч elapsed) | manual + analyst | 0.5 дня | ## Resumable saga - `cadastre_jobs.phase_state JSONB`: `{phase, snapshot_at, parcels_total_meta, parcels_fetched, ...}` - Celery `acks_late=True` + idempotent upsert (`ON CONFLICT (cad_num) DO UPDATE`) - Redeploy mid-run → task resumes от точки падения ## Risks + mitigations | Risk | Mitigation | |---|---| | NSPD WAF при sustained 3 req/s | Pilot detect early; fallback 1 req/s при 429 | | Grid-walk пропускает мелкие ЗУ при step=50м | FEATURE_COUNT=10 + fallback step=25м для overflow quarters | | Redeploy mid-harvest | acks_late + idempotent upsert + saga state в DB | | Storage growth >100MB | Pilot extrapolation | ## Acceptance per PR - [ ] PR 1: миграция применилась, 8 таблиц created, existing data migrated - [ ] PR 2: pytest e2e — `search_by_quarter("66:41:0303161")` → 502 объекта + meta - [ ] PR 3: `bulk_harvest_quarter` ВЫДЕРЖИВАЕТ redeploy mid-run, идемпотентен - [ ] PR 4: `/admin/scrape/cadastre` доступен, кнопка "Запустить pilot 50" работает - [ ] PR 5: pilot 50 quarter завершён, метрики собраны, go/no-go decision ## Q3 deferred (помещения 37163 + парковка 37159) Когда понадобятся для per-flat ДДУ cross-check: - iterate `cad_buildings` → `tab-group-data` → batch fetch search per помещение - ~100K req для ЕКБ × 3 req/s = ~9ч harvest - Отдельный bulk_harvest_flats task + cad_flats + cad_parking tables ## Vault refs - `research/NSPD_API_Map_May12.md` — полный API audit (1613 lines) - `research/Bulk_Cadastre_Ingest_Plan_May15.md` — этот план - `research/Engineering_Networks_Schema_191FZ_May12.md` — pattern для альт-источников - `fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md` — closed когда grid-walk works в PR 3
Owner

Status update — bulk cadastre почти complete:

Merged PRs:

  • PR #169 — schema 92_cad_bulk_layers.sql (7 таблиц + cadastre_jobs)
  • PR #170 — NSPDBulkClient + schemas (b7889d1)
  • PR #171 — bulk_harvest_quarter Celery task + grid-walker (5da66bb)
  • PR #178 — CAST :geom AS text psycopg fix
  • PR #179 — skip grid-walk для broken quarter geom
  • PR #180 — per-category NSPD snapshot (ZOUIT/ENK) Phase 1.5
  • PR #181 — auto-heal cad_quarters_geom
  • PR #183/#184/#185/#186/#187 — fixes для cadastre + grid-walk performance

Pilot + full run: job cadastre_ekb_full #20 успешно прогнан 2026-05-16, загружено 39287 parcels / 37624 buildings.

Residual: 932 parcels без geom (371 квартал) — выделено в #200 для retry/explain.

PR #4 admin UI (scrape/cadastre) тоже merged раньше. Этот umbrella issue можно закрыть после resolve #200.

Status update — bulk cadastre почти complete: **Merged PRs:** - PR #169 — schema `92_cad_bulk_layers.sql` (7 таблиц + cadastre_jobs) - PR #170 — NSPDBulkClient + schemas (b7889d1) - PR #171 — bulk_harvest_quarter Celery task + grid-walker (5da66bb) - PR #178 — CAST :geom AS text psycopg fix - PR #179 — skip grid-walk для broken quarter geom - PR #180 — per-category NSPD snapshot (ZOUIT/ENK) Phase 1.5 - PR #181 — auto-heal cad_quarters_geom - PR #183/#184/#185/#186/#187 — fixes для cadastre + grid-walk performance **Pilot + full run:** job `cadastre_ekb_full` #20 успешно прогнан 2026-05-16, загружено 39287 parcels / 37624 buildings. **Residual:** 932 parcels без geom (371 квартал) — выделено в #200 для retry/explain. PR #4 admin UI (scrape/cadastre) тоже merged раньше. Этот umbrella issue можно закрыть после resolve #200.
Collaborator

DRIFT — реализовано (ground-truth 2026-06-13), трекер отставал.

Bulk cadastre построен и прогнан до конца: admin_cadastre.py + scrape_cadastre.py (saga+grid_walk) + cadastre/bulk_harvest.py. Prod: cadastre_jobs #20/#22 ekb_full status=done, cad_parcels 40190 (2852 квартала > 2408 цель). Commits #168/#179/#180/#182/#187. Closed.

**DRIFT — реализовано (ground-truth 2026-06-13), трекер отставал.** Bulk cadastre построен и прогнан до конца: admin_cadastre.py + scrape_cadastre.py (saga+grid_walk) + cadastre/bulk_harvest.py. Prod: cadastre_jobs #20/#22 ekb_full status=done, cad_parcels 40190 (2852 квартала > 2408 цель). Commits #168/#179/#180/#182/#187. Closed.
Sign in to join this conversation.
No milestone
No project
No assignees
3 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#168
No description provided.