diff --git a/data/sql/181_gas_grs_capacity.sql b/data/sql/181_gas_grs_capacity.sql new file mode 100644 index 00000000..ac40ac09 --- /dev/null +++ b/data/sql/181_gas_grs_capacity.sql @@ -0,0 +1,75 @@ +-- 181_gas_grs_capacity.sql +-- Forgejo #2119 Phase B1 — газовая вертикаль «свободная мощность ГРС» для ПТИЦА §3. +-- +-- Одна таблица gas_grs_capacity: свободная мощность ГРС (газораспределительная +-- станция) из раскрытия «Газпром трансгаз Екатеринбург» (ГТЕ): +-- https://ekaterinburg-tr.gazprom.ru/about/informatsiya-o-tekhnicheskoj-vozmo/ +-- — инлайн HTML-таблица «Информация о технической возможности…». +-- +-- Источник ГЕО-БЛОКИРУЕТ non-RU IP → загрузчик РАБОТАЕТ НА ПРОДЕ (Celery / manual +-- docker exec) — как rosseti-/vodokanal-лоадеры (180). Код не должен предполагать +-- локальный сетевой доступ. +-- +-- У ГРС бывает несколько выходов («выход 1/2/3») — тогда одна ГРС = N строк с +-- разным output_name; output_name IS NULL = вся ГРС целиком (одна строка). +-- grs_name_norm — нормализованное имя для матча (lower, ё→е, пробелы/дефисы +-- схлопнуты; префиксы «ГРС»/«АРП» СОХРАНЯЮТСЯ, т.к. различают станции). +-- +-- Refresh: weekly via tasks.connection_capacity_sync.sync_gas_grs_capacity. +-- Порядок применения: миграция ПЕРЕД деплоем кода (schema-first, sql.md). + +BEGIN; + +-- ── gas_grs_capacity ───────────────────────────────────────────────────────── +-- geom NULL до Фазы C (геокод ГРС). raw jsonb — сырые ячейки строки целиком +-- (неизвестные/будущие колонки таблицы ГТЕ не теряются, а падают в raw). +CREATE TABLE IF NOT EXISTS gas_grs_capacity ( + id SERIAL PRIMARY KEY, + grs_name TEXT NOT NULL, -- исходное имя ГРС + grs_name_norm TEXT NOT NULL, -- нормализованное для матча + output_name TEXT, -- «выход 1/2/3»; NULL = вся ГРС + region TEXT, -- область (Свердловская и др.) + design_capacity_th_m3_h NUMERIC, -- проектная, тыс. м³/ч + current_load_th_m3_h NUMERIC, -- текущая загрузка, тыс. м³/ч + free_capacity_th_m3_h NUMERIC, -- свободная мощность, тыс. м³/ч + free_capacity_pct NUMERIC, -- свободная, % + upgrade_due TEXT, -- срок расшивки (как в источнике) + asof DATE, -- дата актуальности данных + geom GEOMETRY(POINT, 4326), -- NULL до Фазы C геокода + raw JSONB, -- сырая строка таблицы целиком + fetched_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + + -- NULLS NOT DISTINCT: output_name nullable (у ГРС без разбивки по выходам — + -- одна строка с output_name IS NULL). Без этого ON CONFLICT не матчит строку + -- с NULL-выходом → weekly-прогон плодит дубли (те же грабли, что #140 / + -- 180_connection_capacity.sql power_tp_rp_reserves). + UNIQUE NULLS NOT DISTINCT (grs_name_norm, output_name) +); + +CREATE INDEX IF NOT EXISTS idx_gas_grs_capacity_name_norm + ON gas_grs_capacity (grs_name_norm); + +CREATE INDEX IF NOT EXISTS gist_gas_grs_capacity_geom + ON gas_grs_capacity USING GIST (geom); + +COMMENT ON TABLE gas_grs_capacity IS + 'Свободная мощность ГРС (газораспределительных станций) из раскрытия «Газпром ' + 'трансгаз Екатеринбург». Один output_name на строку («выход 1/2/3»; NULL = вся ' + 'ГРС). geom NULL до Фазы C геокода. Refresh: weekly via ' + 'tasks.connection_capacity_sync.sync_gas_grs_capacity. Forgejo #2119 Phase B1.'; + +COMMENT ON COLUMN gas_grs_capacity.grs_name_norm IS + 'Нормализованное имя ГРС для матча/дедупа (lower, ё→е, пробелы/дефисы схлопнуты; ' + 'префиксы «ГРС»/«АРП» СОХРАНЯЮТСЯ — различают станции).'; + +COMMENT ON COLUMN gas_grs_capacity.output_name IS + 'Выход ГРС («выход 1/2/3»). NULL = вся ГРС целиком (нет разбивки по выходам).'; + +COMMENT ON COLUMN gas_grs_capacity.free_capacity_th_m3_h IS + 'Свободная (резервная) мощность ГРС, тыс. м³/ч. Может быть 0 при полной загрузке.'; + +COMMENT ON COLUMN gas_grs_capacity.upgrade_due IS + 'Срок расшивки (планового увеличения пропускной способности), как в источнике ' + '(свободный текст: год / «после 2027» / пусто).'; + +COMMIT; diff --git a/frontend/src/components/site-finder/analysis/StageDetails.tsx b/frontend/src/components/site-finder/analysis/StageDetails.tsx index e31f6a60..277bcaf3 100644 --- a/frontend/src/components/site-finder/analysis/StageDetails.tsx +++ b/frontend/src/components/site-finder/analysis/StageDetails.tsx @@ -13,7 +13,9 @@ export function StageDetails({ openLabel = "Раскрыть всё", closeLabel = "Свернуть", }: StageDetailsProps) { - const [open, setOpen] = useState(false); + // Изначально РАСКРЫТО (запрос Anton 2026-07-02): полный отчёт виден сразу, + // «Свернуть» — для компактного просмотра. Leaflet-карты монтируются сразу. + const [open, setOpen] = useState(true); return ( <>