-- 151_cad_parcels_geom_unavailable.sql -- --------------------------------------------------------------------------- -- Контекст (issue #200): -- На prod ~964 строки cad_parcels с geom IS NULL. Ground-truth (измерено -- 2026-06-13): 930/964 — реальные участки ЕКБ 66:41:NNNNNN:NN, все -- source='search'. NSPD search-эндпоинт для квартала возвращает участок без -- полигона (только центроид/Point ИЛИ вовсе без geometry → upsert_parcel -- пишет geom=NULL, см. bulk_harvest.py). Остаток (34) — кросс-региональные -- артефакты поиска (последний сегмент :41 / :66 — это номер участка из -- ДРУГОГО квартала, попавший в выдачу), у которых полигона в WMS-слое -- 36368 нет вовсе. -- -- Полигон для большинства восстановим grid-walk'ом слоя 36368 (WMS -- GetFeatureInfo по bbox квартала — Phase 2-3 bulk_harvest). Но для -- систематически недоступных (кросс-региональные артефакты) бесконечный -- ретрай вреден: каждый прогон бэкфилла снова бы их дёргал. -- -- Действие: -- Добавить флаг geom_unavailable BOOLEAN. Backfill-task -- (tasks.cadastre.backfill_parcel_geom) выставляет его в TRUE, когда после -- grid-walk слоя участок ВСЁ ЕЩЁ без полигона — значит geom систематически -- недоступен, перестаём ретраить. Дефолт FALSE — обычные участки и новые -- inserts не затрагиваются; пересчёт делает только бэкфилл. -- -- Partial-индекс под выборку «кого ещё докачивать» -- (geom IS NULL AND NOT geom_unavailable) — узкий, индексирует только -- рабочую очередь, не всю таблицу (40k строк). -- -- Идемпотентность: ADD COLUMN IF NOT EXISTS + CREATE INDEX IF NOT EXISTS. -- Apply order: чистая схема, без зависимости от кода. Backend-код с -- backfill-task деплоится после (правило sql.md: схема → код). -- --------------------------------------------------------------------------- BEGIN; ALTER TABLE cad_parcels ADD COLUMN IF NOT EXISTS geom_unavailable BOOLEAN NOT NULL DEFAULT FALSE; COMMENT ON COLUMN cad_parcels.geom_unavailable IS 'issue #200: TRUE — geom систематически недоступен в НСПД (grid-walk слоя ' '36368 не вернул полигон). Выставляется backfill-task' ' (tasks.cadastre.backfill_parcel_geom), чтобы не ретраить докачку вечно. ' 'FALSE (дефолт) — geom либо есть, либо ещё не пробовали докачать.'; -- Рабочая очередь бэкфилла: участки без геометрии, которые ещё имеет смысл -- докачивать. Partial WHERE держит индекс компактным. CREATE INDEX IF NOT EXISTS cad_parcels_geom_backfill_queue ON cad_parcels (cad_num) WHERE geom IS NULL AND geom_unavailable = FALSE; COMMIT;