-- 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;
