feat(#126): Sub-PR B — интегрировать grid sampling в harvest_quarter (single-pixel WMS fix) #256

Closed
opened 2026-05-17 06:29:24 +00:00 by lekss361 · 1 comment
Owner

Контекст

Sub-PR A для #126 уже merged (PR #247) — добавил NSPDClient.get_features_in_bbox_grid(layer_id, bbox, *, grid_n=7, step_m=50) с deduplication. Это foundation.

Sub-PR B — заменить вызовы get_features_in_bbox (single-pixel WMS GetFeatureInfo, 0-3 features) на get_features_in_bbox_grid в harvest_quarter.

Доказательство bug'а

После PR #246 (CAST fix) harvest_quarter работает без exception. Manual trigger для 66:41:0204016:

quarter_cad: 66:41:0204016
fetched_at_utc: 2026-05-17 06:26 UTC
harvest_duration_ms: 7380
harvest_error: None
parcels_count: 1
zouit_count: 0     ← должно быть ~10-30 для города
engineering_count: 0 ← должно быть несколько structures
total_features: 2  ← должно быть ~30-80

Известное ограничение задокументировано в vault fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md.

Что нужно

Backend изменения в harvest_quarter

backend/app/workers/tasks/nspd_sync.py:

  1. Заменить client.get_features_in_bbox(layer_id, bbox)client.get_features_in_bbox_grid(layer_id, bbox, grid_n=7, step_m=50) для non-search-by-quarter layers:

    • territorial_zones (875838)
    • red_lines (879243)
    • engineering_structures (36328)
    • zouit_* (37577-37581)
    • risk_zones (872xxx) — если include_risks=True
    • opportunity_* — если include_opportunity=True
  2. НЕ менять search_by_quarter для parcels/buildings — там REST endpoint работает корректно.

  3. Performance budget: grid_n=7 = 49 WMS calls per layer × ~20 layers = ~1000 calls per quarter. С Semaphore(3) и rate limit 333ms = ~3 RPS → quarter dump ~5-7 минут. Это OK для weekly beat schedule, но slow для manual demo trigger.

  4. Adaptive option: grid_n=3 (9 calls) для tighter bbox + grid_n=7 для wider → save calls. Не обязательно для MVP.

Tests

  • Mock NSPDClient.get_features_in_bbox_grid → return list of features
  • Verify harvest_quarter calls grid version not pixel version
  • Smoke: harvest_quarter("66:41:0204016", 66)total_features > 10 (~значительно больше чем сейчас 2)

Acceptance

  • Manual trigger harvest_quarter("66:41:0204016", 66) дает total_features >= 30 (вместо 2 сейчас)
  • zouit_count >= 5 для cad в развитой части города
  • engineering_count >= 1 для cad с инжкоммуникациями
  • Test pass + tests in nspd_sync.py mock'ают grid client correctly

Severity / Effort

🟠 P1 — разблокирует:

  • #115 KILLER полностью (точки подключения видны на проде)
  • Полные ЗОУИТ overlaps в nspd_quarter_dumps (сейчас fallback на cad_zouit через PR #248, но NSPD dump имеет больше категорий + актуальнее)
  • Engineering structures для analyze block

Effort: ~1-2 дня (backend integration 1д + tests + verify)

Beat schedule re-enable

После Sub-PR B — раскомментировать nspd-harvest-stale-quarters в backend/app/workers/beat_schedule.py:229 (заморожен 2026-05-14 из-за bug'а). После этого weekly Monday 04:00 МСК будет наполнять stale quarters автоматически.

  • #126 (parent) — NSPD WMS grid sampling
  • PR #247 — Sub-PR A (foundation: get_features_in_bbox_grid + classify_engineering_kind)
  • PR #246 — fix(#244) CAST AmbiguousParameter (unblocked harvest)
  • Vault fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md
  • Vault code/modules/NSPD_Bulk_Client.md

(QA discovery 2026-05-17: manual trigger harvest_quarter работает но grabs только 2 features)

## Контекст Sub-PR A для #126 уже merged (PR #247) — добавил `NSPDClient.get_features_in_bbox_grid(layer_id, bbox, *, grid_n=7, step_m=50)` с deduplication. Это **foundation**. **Sub-PR B** — заменить вызовы `get_features_in_bbox` (single-pixel WMS GetFeatureInfo, 0-3 features) на `get_features_in_bbox_grid` в `harvest_quarter`. ## Доказательство bug'а После PR #246 (CAST fix) `harvest_quarter` работает без exception. Manual trigger для `66:41:0204016`: ``` quarter_cad: 66:41:0204016 fetched_at_utc: 2026-05-17 06:26 UTC harvest_duration_ms: 7380 harvest_error: None parcels_count: 1 zouit_count: 0 ← должно быть ~10-30 для города engineering_count: 0 ← должно быть несколько structures total_features: 2 ← должно быть ~30-80 ``` Известное ограничение задокументировано в vault `fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md`. ## Что нужно ### Backend изменения в `harvest_quarter` `backend/app/workers/tasks/nspd_sync.py`: 1. Заменить `client.get_features_in_bbox(layer_id, bbox)` → `client.get_features_in_bbox_grid(layer_id, bbox, grid_n=7, step_m=50)` для **non-search-by-quarter layers**: - territorial_zones (875838) - red_lines (879243) - engineering_structures (36328) - zouit_* (37577-37581) - risk_zones (872xxx) — если `include_risks=True` - opportunity_* — если `include_opportunity=True` 2. **НЕ менять** `search_by_quarter` для parcels/buildings — там REST endpoint работает корректно. 3. **Performance budget:** grid_n=7 = 49 WMS calls per layer × ~20 layers = ~1000 calls per quarter. С `Semaphore(3)` и rate limit 333ms = ~3 RPS → quarter dump ~5-7 минут. Это OK для weekly beat schedule, но **slow для manual demo trigger**. 4. **Adaptive option:** `grid_n=3` (9 calls) для tighter bbox + `grid_n=7` для wider → save calls. Не обязательно для MVP. ### Tests - Mock NSPDClient.get_features_in_bbox_grid → return list of features - Verify `harvest_quarter` calls grid version not pixel version - Smoke: `harvest_quarter("66:41:0204016", 66)` → `total_features > 10` (~значительно больше чем сейчас 2) ## Acceptance - Manual trigger `harvest_quarter("66:41:0204016", 66)` дает `total_features >= 30` (вместо 2 сейчас) - `zouit_count >= 5` для cad в развитой части города - `engineering_count >= 1` для cad с инжкоммуникациями - Test pass + tests in nspd_sync.py mock'ают grid client correctly ## Severity / Effort 🟠 **P1** — разблокирует: - #115 KILLER полностью (точки подключения видны на проде) - Полные ЗОУИТ overlaps в `nspd_quarter_dumps` (сейчас fallback на cad_zouit через PR #248, но NSPD dump имеет больше категорий + актуальнее) - Engineering structures для analyze block **Effort:** ~1-2 дня (backend integration 1д + tests + verify) ## Beat schedule re-enable После Sub-PR B — раскомментировать `nspd-harvest-stale-quarters` в `backend/app/workers/beat_schedule.py:229` (заморожен 2026-05-14 из-за bug'а). После этого weekly Monday 04:00 МСК будет наполнять stale quarters автоматически. ## Links - #126 (parent) — NSPD WMS grid sampling - PR #247 — Sub-PR A (foundation: get_features_in_bbox_grid + classify_engineering_kind) - PR #246 — fix(#244) CAST AmbiguousParameter (unblocked harvest) - Vault `fixes/Bug_NSPD_WMS_NotBulk_2026_May14.md` - Vault `code/modules/NSPD_Bulk_Client.md` (QA discovery 2026-05-17: manual trigger harvest_quarter работает но grabs только 2 features)
Collaborator

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

Sub-PR B (grid sampling в harvest) merged: fdced94/8ebcd15 #260 — search_by_quarter диспатчит AREA_LAYERS на get_features_in_bbox_grid. Beat nspd-harvest-stale-quarters re-enabled (#267). Closed.

**DRIFT — реализовано (ground-truth 2026-06-13), трекер отставал.** Sub-PR B (grid sampling в harvest) merged: fdced94/8ebcd15 #260 — search_by_quarter диспатчит AREA_LAYERS на get_features_in_bbox_grid. Beat nspd-harvest-stale-quarters re-enabled (#267). Closed.
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#256
No description provided.