-- 139_ekb_genplan_functional_zone.sql
-- #1058 / #1067 (Site Finder v2, «GG-форсайт») — функциональные зоны генплана ЕКБ-2045.
--
-- Источник: ГИСОГД-СО WFS (gisogd66.midural.ru), слой
--   agate_ekbgo:agate_ekbgo_geo_urban_10_functional_zone_<hash>.
-- Harvest-воркер: tasks/genplan_zones_sync.py (Celery beat «genplan-zones-sync-weekly»).
-- Read-side: app/services/site_finder/functional_zone_lookup.py → parcel_functional_zones().
-- Analyze-врезка: follow-up после merge #1131 (чтобы не конфликтить с ird-analyze PR).
--
-- Grain: одна строка = одна зона (Polygon/MultiPolygon). Дедуп-ключ — globalid (UUID из ГИСОГД).
--
-- Deploy: auto-applied deploy.yml через _schema_migrations (ровно один раз по NN). Idempotent:
--   CREATE TABLE/INDEX IF NOT EXISTS + guarded DO-блок для UNIQUE (зеркаль м.132, м.125).
--   НИКАКИХ строк здесь не вставляется — данные приходят из harvest-воркера.

BEGIN;

-- ── 1. Таблица ekb_genplan_functional_zone ────────────────────────────────────
CREATE TABLE IF NOT EXISTS ekb_genplan_functional_zone (
    id            BIGSERIAL PRIMARY KEY,
    globalid      TEXT NOT NULL,              -- UUID из ГИСОГД (дедуп-ключ, UNIQUE ниже)
    zone_type     TEXT,                        -- читаемый тип зоны (full_name / urban10_classid_v)
    zone_class_code TEXT,                      -- числовой код класса (urban10_classid)
    status        TEXT,                        -- «Существующий» / «Планируемый» (urban10_status_v)
    area_ha       NUMERIC,                     -- площадь, га (urban10_area)
    doc_ref       TEXT,                        -- ссылка на документ генплана (info_set_key_ref)
    geom          geometry(Geometry, 4326) NOT NULL,  -- Polygon/MultiPolygon, EPSG:4326
    raw_props     JSONB,                       -- полный properties фичи (forward-compat / debug)
    fetched_at    timestamptz NOT NULL DEFAULT now()
);

COMMENT ON TABLE ekb_genplan_functional_zone IS
    'Функциональные зоны генплана ЕКБ-2045 (#1058, GG-форсайт). '
    'Источник: ГИСОГД-СО WFS (gisogd66.midural.ru). '
    'UPSERT harvest-воркером tasks/genplan_zones_sync.py по globalid. '
    'analyze читает overlap участка через ST_Intersects(geom). Пустая = 0 overlap.';

COMMENT ON COLUMN ekb_genplan_functional_zone.globalid IS
    'UUID объекта из ГИСОГД-СО (urban10_globalid); дедуп-ключ UPSERT';
COMMENT ON COLUMN ekb_genplan_functional_zone.zone_type IS
    'Читаемый тип зоны: full_name или urban10_classid_v («Жилые зоны» и т.д.)';
COMMENT ON COLUMN ekb_genplan_functional_zone.zone_class_code IS
    'Числовой код класса зоны (urban10_classid)';

-- ── 2. UNIQUE по globalid (дедуп для UPSERT) ─────────────────────────────────
-- Guard через pg_constraint — idempotent re-apply (зеркаль м.132 / м.125 / м.110).
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = 'uq_ekb_genplan_functional_zone_globalid'
    ) THEN
        ALTER TABLE ekb_genplan_functional_zone
            ADD CONSTRAINT uq_ekb_genplan_functional_zone_globalid
            UNIQUE (globalid);
    END IF;
END
$$;

-- ── 3. Индексы ────────────────────────────────────────────────────────────────
-- Read-path: ST_Intersects(parcel.geom, zone.geom) через GIST.
CREATE INDEX IF NOT EXISTS idx_ekb_genplan_fz_geom
    ON ekb_genplan_functional_zone USING GIST (geom);

-- Фильтрация по типу зоны (выборка «все жилые» / «все производственные»).
CREATE INDEX IF NOT EXISTS idx_ekb_genplan_fz_zone_type
    ON ekb_genplan_functional_zone (zone_type);

-- Фильтрация по статусу (существующие vs планируемые).
CREATE INDEX IF NOT EXISTS idx_ekb_genplan_fz_status
    ON ekb_genplan_functional_zone (status) WHERE status IS NOT NULL;

COMMIT;
