-- 182_eesk_heat_reserves.sql
-- Forgejo #2119 Phase B2 — АО «ЕЭСК» (Екатеринбургская электросетевая компания):
-- (а) резерв мощности по ЦП ПС 35-220 кВ → апдейт power_supply_centers (МВт);
-- (б) резерв ТП/РП напряжением ниже 35 кВ → UPSERT power_tp_rp_reserves;
-- (в) heat_system_reserves — задел под теплоснабжение (Gcal/ч), city-level.
--
-- Источник: eesk.ru «Наличие объёма свободной для технологического присоединения
-- мощности» — статический HTML-хаб со ссылками на xlsx (обычный SSL, БЕЗ гео-блока,
-- но лоадер всё равно RUN-ON-PROD рядом с rosseti/gas/vodokanal).
--
-- ЕЭСК резервы у ЦП измеряются в МВт (не МВА как у Россетей) → добавляем
-- reserve_unit на power_supply_centers (default 'МВА' для старых строк Россетей,
-- лоадер ЕЭСК проставляет 'МВт'). district — адм. район ЕКБ из xlsx ЕЭСК.
--
-- Refresh: weekly via tasks.connection_capacity_sync (отдельный воркер).
-- Порядок применения: миграция ПЕРЕД деплоем кода (schema-first, sql.md).

BEGIN;

-- ── power_supply_centers: единица резерва + адм. район ────────────────────────
-- reserve_unit: у Россетей резерв в МВА, у ЕЭСК ПС 35-220 — в МВт. default 'МВА'
-- сохраняет семантику существующих строк (заполнены Россетями), лоадер ЕЭСК
-- явно проставляет 'МВт'. district — административный район Екатеринбурга (колонка
-- B файла ЕЭСК); у Россети-строк остаётся NULL.
ALTER TABLE power_supply_centers
    ADD COLUMN IF NOT EXISTS reserve_unit TEXT DEFAULT 'МВА';

ALTER TABLE power_supply_centers
    ADD COLUMN IF NOT EXISTS district TEXT;

COMMENT ON COLUMN power_supply_centers.reserve_unit IS
    'Единица reserve_mva/installed_capacity_mva: ''МВА'' (Россети, default) или '
    '''МВт'' (ЕЭСК ПС 35-220, capacity_source=''eesk_35_220''). Forgejo #2119 B2.';

COMMENT ON COLUMN power_supply_centers.district IS
    'Административный район Екатеринбурга (из xlsx ЕЭСК ПС 35-220). NULL у '
    'Россети-строк. Forgejo #2119 Phase B2.';

-- ── heat_system_reserves ──────────────────────────────────────────────────────
-- Резервы тепловой мощности систем теплоснабжения (Gcal/ч), city-level, без geom.
-- sphere зафиксирована 'heat' (задел под другие сферы раскрытия одной таблицей).
-- reserve_gcal_h может быть отрицательным (дефицит) — знак сохраняем. raw jsonb —
-- сырая строка источника целиком (будущие колонки не теряются).
CREATE TABLE IF NOT EXISTS heat_system_reserves (
    id                SERIAL PRIMARY KEY,
    org               TEXT        NOT NULL,          -- организация-держатель (АО «ЕЭСК» и др.)
    sphere            TEXT        NOT NULL DEFAULT 'heat',
    system_name       TEXT        NOT NULL,          -- имя системы теплоснабжения
    reserve_gcal_h    NUMERIC,                       -- свободная мощность, Гкал/ч (может быть <0)
    applications_note TEXT,                          -- примечание о заявках на подключение
    period            TEXT,                          -- напр. '2026-Q2'
    source_guid       TEXT,                          -- хэш/идентификатор исходного файла
    raw               JSONB,                         -- сырая строка источника целиком
    fetched_at        TIMESTAMPTZ DEFAULT NOW(),

    -- NULLS NOT DISTINCT: period может быть NULL при неудачном разборе даты
    -- (те же грабли, что #140 / 180_connection_capacity.sql water_supply_reserves).
    UNIQUE NULLS NOT DISTINCT (org, sphere, system_name, period)
);

CREATE INDEX IF NOT EXISTS idx_heat_system_reserves_period
    ON heat_system_reserves (period);

CREATE INDEX IF NOT EXISTS idx_heat_system_reserves_sphere
    ON heat_system_reserves (sphere);

COMMENT ON TABLE heat_system_reserves IS
    'Резервы тепловой мощности систем теплоснабжения (Гкал/ч, city-level, без geom). '
    'reserve_gcal_h может быть отрицательным (дефицит). Forgejo #2119 Phase B2.';

COMMENT ON COLUMN heat_system_reserves.reserve_gcal_h IS
    'Свободная (резервная) тепловая мощность, Гкал/ч. Отрицательное = дефицит.';

COMMIT;
