epic(infra): NSPD unify — Вариант B consolidation (cadastre as single scraper) #263

Closed
opened 2026-05-17 07:21:22 +00:00 by lekss361 · 1 comment
Owner

Контекст

Сейчас 3 разных NSPD scraper'а с overlapping функциональностью:

Pipeline Endpoint Status Tables
cadastre /admin/scrape/cadastre работает cad_parcels (39k), cad_buildings (37k), cad_zouit (3k), cad_constructions, cad_oncs, cad_enk, cad_quarter_stats
geo /admin/scrape/geo ⚠️ bootstrap-only cad_quarters_geom (9k from geo, 1.7k from cadastre auto-heal)
nspd_sync /admin/scrape/nspd/harvest-quarter broken (WMS bug #126) nspd_quarter_dumps (1 row)

User-decision (2026-05-17): унифицировать на cadastre (Вариант B).

Полный план (5 phases)

Phase 1 — Подготовка (БЕЗ удаления)

  • Создать новые таблицы для NSPD overlay данных:
    • cad_territorial_zones (ПЗЗ) — layer 875838
    • cad_red_lines — layer 879243
    • cad_engineering_structures — layer 36328 (для #115)
    • cad_risk_zones — 11 risk layers (872xxx)
    • cad_opportunity_parcels — 5 layers (37294, 37298, 37299, 36473, 875845)
  • Migration data/sql/NN_cad_nspd_overlay_tables.sql (idempotent, GIST indices)

Phase 2 — Расширить cadastre (главная работа)

  • backend/app/scrapers/nspd_bulk_client.py — добавить grid-walk WMS методы для layers:
    • 875838 territorial_zones (zone_code, zone_name)
    • 879243 red_lines (geom polygon/linestring)
    • 36328 engineering_structures (name, type, raw_props)
    • 11 risk layers (subcategory, severity)
    • 5 opportunity layers (lot info, auction status)
  • backend/app/services/cadastre/bulk_harvest.py — orchestration: при harvest квартала writes в новые таблицы
  • Tests: mocks + integration (smoke на тестовом quarter)

Phase 3 — Refactor downstream

  • backend/app/services/site_finder/quarter_dump_lookup.py — переключить читателей с nspd_quarter_dumps.features_json на новые cad_* таблицы:
    • _get_nspd_zoning → SELECT from cad_territorial_zones
    • _get_zouit_overlaps → уже использует cad_zouit (через PR #248 fallback)
    • _get_engineering_nearby → SELECT from cad_engineering_structures
    • _get_risk_zones → SELECT from cad_risk_zones
    • _get_opportunity_parcels → SELECT from cad_opportunity_parcels
    • _get_red_lines → SELECT from cad_red_lines
  • Удалить ссылки на nspd_quarter_dumps
  • backend/app/services/site_finder/get_connection_points.py (#115) — переключить на cad_engineering_structures + cad_zouit
  • Tests: regression на analyze_parcel response shape (не должна сломаться)

Phase 4 — Минимизировать geo

  • /admin/scrape/geo — удалить thematic_id=1 (parcels) и thematic_id=5 (buildings) paths (cadastre полностью покрывает)
  • Оставить только thematic_id=2 (quarters bootstrap) → переименовать endpoint в /admin/scrape/quarter-bootstrap?
  • Удалить cad_parcels_geom view if not used после Phase 3 (Grep!)
  • Удалить parcels/buildings UPSERT logic из nspd_geo.py:_save_parcel, _save_building

Phase 5 — Cleanup nspd_sync

  • Удалить:
    • backend/app/api/v1/admin_scrape.py/nspd/harvest-quarter endpoint (+ HarvestQuarterRequest)
    • backend/app/workers/tasks/nspd_sync.py
    • backend/app/services/scrapers/nspd_client.py (если только nspd_sync его использует — проверить grep)
    • backend/app/services/scrapers/nspd_denorm.py (пустые nspd_parcels, nspd_buildings)
  • Migration data/sql/NN_drop_nspd_legacy_tables.sql:
    • DROP nspd_quarter_dumps, nspd_parcels, nspd_buildings, nspd_scrape_runs, nspd_scrape_log
  • Удалить beat schedule entry для harvest_stale_quarters (уже закомментирован 2026-05-14)
  • Удалить frontend /admin/scrape/nspd/* UI (если есть)
  • Сlose old issues #126, #256 (resolved by unification)

Dependency graph

Phase 1 (schemas) ──┐
                    ├──► Phase 2 (cadastre extension) ──► Phase 3 (quarter_dump_lookup refactor) ──┐
                    │                                                                                ├──► Phase 5 (delete nspd_sync)
                    └──► Phase 4 (minimize geo)                                                    ──┘

Sub-PRs

  • #264 — Phase 1: new cad_* overlay tables migration
  • #265 — Phase 2: cadastre extension (WMS layers for ПЗЗ/red_lines/engineering/risks/opportunity)
  • #266 — Phase 3: refactor quarter_dump_lookup + get_connection_points
  • #267 — Phase 4: minimize /admin/scrape/geo to quarters-only bootstrap
  • #268 — Phase 5: delete nspd_sync + nspd_quarter_dumps + cleanup

Acceptance

  • /analyze response identical в shape (нет regression на frontend)
  • ПЗЗ (nspd_zoning) для cad из ЕКБ — non-null после cadastre harvest квартала
  • Engineering structures (#115 точки подключения) — non-empty
  • All existing tests pass + new tests для cad_* readers
  • nspd_quarter_dumps/nspd_sync полностью удалены
  • /admin/scrape/cadastre остаётся единственным NSPD scraper (+ minimal /quarter-bootstrap для cad_quarters_geom)

Estimated effort

Phase Effort Risk
Phase 1 0.5д Low
Phase 2 3-5д Medium (новые WMS layers + grid-walk performance)
Phase 3 1-2д High (analyze_parcel — central, регрессия = пилот)
Phase 4 Low
Phase 5 0.5д Low
Total 6-9 дней

Rollback plan

После Phase 3 — keep nspd_quarter_dumps writes из nspd_sync на 1 неделю (parallel writing) чтобы можно было откатить Phase 3 без data loss. Phase 5 cleanup делать только после stable verify Phase 3.

  • Analysis report: ранее в этой сессии (2026-05-17 ~06:50 UTC) — общий план Variant B
  • #126, #256 — старые NSPD WMS bugs, resolved by unification (нет нужды fix grid sampling в nspd_sync если он удаляется)
  • #259 — pzz_sync deprecated (PKK6→NSPD), resolved by Phase 2 (ПЗЗ через cadastre extension)
  • #115 KILLER (точки подключения) — resolved by Phase 2+3 (cadastre будет качать layer 36328)
  • #232/#248 — cad_zouit fallback уже работает, останется после consolidation
  • audits/issues_audit_2026_05_16.md — context
## Контекст Сейчас 3 разных NSPD scraper'а с overlapping функциональностью: | Pipeline | Endpoint | Status | Tables | |---|---|---|---| | **cadastre** | `/admin/scrape/cadastre` | ✅ работает | `cad_parcels` (39k), `cad_buildings` (37k), `cad_zouit` (3k), `cad_constructions`, `cad_oncs`, `cad_enk`, `cad_quarter_stats` | | **geo** | `/admin/scrape/geo` | ⚠️ bootstrap-only | `cad_quarters_geom` (9k from geo, 1.7k from cadastre auto-heal) | | **nspd_sync** | `/admin/scrape/nspd/harvest-quarter` | ❌ broken (WMS bug #126) | `nspd_quarter_dumps` (1 row) | User-decision (2026-05-17): **унифицировать на cadastre** (Вариант B). ## Полный план (5 phases) ### Phase 1 — Подготовка (БЕЗ удаления) - Создать новые таблицы для NSPD overlay данных: - `cad_territorial_zones` (ПЗЗ) — layer 875838 - `cad_red_lines` — layer 879243 - `cad_engineering_structures` — layer 36328 (для #115) - `cad_risk_zones` — 11 risk layers (872xxx) - `cad_opportunity_parcels` — 5 layers (37294, 37298, 37299, 36473, 875845) - Migration `data/sql/NN_cad_nspd_overlay_tables.sql` (idempotent, GIST indices) ### Phase 2 — Расширить cadastre (главная работа) - `backend/app/scrapers/nspd_bulk_client.py` — добавить grid-walk WMS методы для layers: - `875838` territorial_zones (zone_code, zone_name) - `879243` red_lines (geom polygon/linestring) - `36328` engineering_structures (name, type, raw_props) - 11 risk layers (subcategory, severity) - 5 opportunity layers (lot info, auction status) - `backend/app/services/cadastre/bulk_harvest.py` — orchestration: при harvest квартала writes в новые таблицы - Tests: mocks + integration (smoke на тестовом quarter) ### Phase 3 — Refactor downstream - `backend/app/services/site_finder/quarter_dump_lookup.py` — переключить читателей с `nspd_quarter_dumps.features_json` на новые cad_* таблицы: - `_get_nspd_zoning` → SELECT from `cad_territorial_zones` - `_get_zouit_overlaps` → уже использует `cad_zouit` (через PR #248 fallback) ✅ - `_get_engineering_nearby` → SELECT from `cad_engineering_structures` - `_get_risk_zones` → SELECT from `cad_risk_zones` - `_get_opportunity_parcels` → SELECT from `cad_opportunity_parcels` - `_get_red_lines` → SELECT from `cad_red_lines` - Удалить ссылки на `nspd_quarter_dumps` - `backend/app/services/site_finder/get_connection_points.py` (#115) — переключить на cad_engineering_structures + cad_zouit - Tests: regression на analyze_parcel response shape (не должна сломаться) ### Phase 4 — Минимизировать geo - `/admin/scrape/geo` — удалить `thematic_id=1` (parcels) и `thematic_id=5` (buildings) paths (cadastre полностью покрывает) - Оставить **только** `thematic_id=2` (quarters bootstrap) → переименовать endpoint в `/admin/scrape/quarter-bootstrap`? - Удалить `cad_parcels_geom` view if not used после Phase 3 (Grep!) - Удалить parcels/buildings UPSERT logic из `nspd_geo.py:_save_parcel`, `_save_building` ### Phase 5 — Cleanup nspd_sync - Удалить: - `backend/app/api/v1/admin_scrape.py` — `/nspd/harvest-quarter` endpoint (+ `HarvestQuarterRequest`) - `backend/app/workers/tasks/nspd_sync.py` - `backend/app/services/scrapers/nspd_client.py` (если только nspd_sync его использует — проверить grep) - `backend/app/services/scrapers/nspd_denorm.py` (пустые `nspd_parcels`, `nspd_buildings`) - Migration `data/sql/NN_drop_nspd_legacy_tables.sql`: - DROP `nspd_quarter_dumps`, `nspd_parcels`, `nspd_buildings`, `nspd_scrape_runs`, `nspd_scrape_log` - Удалить beat schedule entry для harvest_stale_quarters (уже закомментирован 2026-05-14) - Удалить frontend `/admin/scrape/nspd/*` UI (если есть) - Сlose old issues #126, #256 (resolved by unification) ## Dependency graph ``` Phase 1 (schemas) ──┐ ├──► Phase 2 (cadastre extension) ──► Phase 3 (quarter_dump_lookup refactor) ──┐ │ ├──► Phase 5 (delete nspd_sync) └──► Phase 4 (minimize geo) ──┘ ``` ## Sub-PRs - [ ] **#264** — Phase 1: new cad_* overlay tables migration - [ ] **#265** — Phase 2: cadastre extension (WMS layers for ПЗЗ/red_lines/engineering/risks/opportunity) - [ ] **#266** — Phase 3: refactor quarter_dump_lookup + get_connection_points - [ ] **#267** — Phase 4: minimize /admin/scrape/geo to quarters-only bootstrap - [ ] **#268** — Phase 5: delete nspd_sync + nspd_quarter_dumps + cleanup ## Acceptance - [ ] `/analyze` response **identical** в shape (нет regression на frontend) - [ ] ПЗЗ (`nspd_zoning`) для cad из ЕКБ — non-null после cadastre harvest квартала - [ ] Engineering structures (#115 точки подключения) — non-empty - [ ] All existing tests pass + new tests для cad_* readers - [ ] `nspd_quarter_dumps`/`nspd_sync` полностью удалены - [ ] `/admin/scrape/cadastre` остаётся единственным NSPD scraper (+ minimal `/quarter-bootstrap` для cad_quarters_geom) ## Estimated effort | Phase | Effort | Risk | |---|---|---| | Phase 1 | 0.5д | Low | | Phase 2 | 3-5д | Medium (новые WMS layers + grid-walk performance) | | Phase 3 | 1-2д | High (analyze_parcel — central, регрессия = пилот) | | Phase 4 | 1д | Low | | Phase 5 | 0.5д | Low | | **Total** | **6-9 дней** | — | ## Rollback plan После Phase 3 — keep `nspd_quarter_dumps` writes из nspd_sync на 1 неделю (parallel writing) чтобы можно было откатить Phase 3 без data loss. Phase 5 cleanup делать только после stable verify Phase 3. ## Links / context - Analysis report: ранее в этой сессии (2026-05-17 ~06:50 UTC) — общий план Variant B - #126, #256 — старые NSPD WMS bugs, **resolved by unification** (нет нужды fix grid sampling в nspd_sync если он удаляется) - #259 — pzz_sync deprecated (PKK6→NSPD), **resolved by Phase 2** (ПЗЗ через cadastre extension) - #115 KILLER (точки подключения) — **resolved by Phase 2+3** (cadastre будет качать layer 36328) - #232/#248 — cad_zouit fallback уже работает, останется после consolidation - `audits/issues_audit_2026_05_16.md` — context
Collaborator

Superseded by ird_overlays (ground-truth 2026-06-13). Epic NSPD unify (Вариант B): Sub-A merged (cad_* overlay-схемы, #265), но Phase 2 (harvest в cad_red_lines/cad_risk_zones — на prod 0 строк) заброшен в пользу ird_overlays (13621 строк) который реально питает analyze red-lines/risk/opportunity. Cad_*-overlay таблицы остались формальными пустышками (read-path есть, наполнение через ird_overlays). Epic-цель (унифицированный NSPD-слой) достигнута через ird_overlays + bulk cadastre (cad_parcels 40190). Закрываю как superseded.

**Superseded by ird_overlays (ground-truth 2026-06-13).** Epic NSPD unify (Вариант B): Sub-A merged (cad_* overlay-схемы, #265), но Phase 2 (harvest в cad_red_lines/cad_risk_zones — на prod 0 строк) заброшен в пользу `ird_overlays` (13621 строк) который реально питает analyze red-lines/risk/opportunity. Cad_*-overlay таблицы остались формальными пустышками (read-path есть, наполнение через ird_overlays). Epic-цель (унифицированный NSPD-слой) достигнута через ird_overlays + bulk cadastre (cad_parcels 40190). Закрываю как superseded.
Sign in to join this conversation.
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#263
No description provided.