feat(site-finder): газ — свободная мощность ГРС + пометка ЕЭСК в §3 (#2119 Фаза B1) #2123

Merged
bot-backend merged 1 commit from feat/gas-grs-capacity into main 2026-07-02 12:54:06 +00:00
Collaborator

Что (issue #2119, Фаза B1)

Газовая вертикаль точек подключения: свободная мощность ГРС (главный газовый gate для девелопера) в карточку «Ресурсные резервы» §3 + честная пометка ЕЭСК у городских ПС.

Backend

  • Миграция data/sql/181_gas_grs_capacity.sql: gas_grs_capacity (ГРС с выходами, UNIQUE NULLS NOT DISTINCT (grs_name_norm, output_name) — грабли #140; geom NULL — геокод в Фазе C).
  • gazprom_grs_loader — bs4-парсер инлайн HTML-таблицы «техническая возможность» ГТЕ (~316 ГРС; гео-блок → RUN-ON-PROD): header-driven маппинг колонок (переживёт перестановку), rowspan forward-fill имени (допущение col-0 задокументировано), числа через общий parse_reserve_number, SAVEPOINT per-row, неизвестные колонки → raw jsonb.
  • Celery sync_gas_grs_capacity + beat вт 05:00 MSK.
  • Endpoint /connection-capacity: блок gascity_grs (городские ГРС «Свердловск/Екатеринбург», агрегация по выходам: SUM design/free, AVG %, MAX расшивка) + total_free_th_m3_h; graceful при отсутствии таблицы (schema-first окно). Плюс reserve_note у ПС ЕЭСК без опубликованного резерва: «Резерв — по запросу в АО «ЕЭСК» (город)».
  • Схемы аддитивны (GasGrsRow/GasCapacityBlock/reserve_note), api-types +31/−0.

Frontend (§3 карточка + попап)

  • Блок «ГАЗ» между электро и водой: на каждую городскую ГРС «свободно X из Y тыс. м³/ч» + бейдж «резерв»/«исчерпана», « · расшивка: {срок}», «(N выхода)», суммарная строка; источник «Газпром трансгаз Екатеринбург». Fallback «загружаются».
  • Попап ЦП: серая строка reserve_note для городских ПС.

Проверки

  • 57 backend-тестов (парсер header-drift/rowspan/н-д, агрегация, graceful-degradation, reserve_note) + ruff + psycopg3-guard чисты; фронт tsc/eslint/prettier чисты.
  • Deep-review: APPROVE (2 minor: col-0 допущение — задокументировал в docstring; MAX(upgrade_due) лексикографический — as-in-source, отмечено).

После merge

  1. Deploy применит миграцию 181 (schema-first).
  2. Прогон лоадера на проде (docker exec) — первая встреча парсера с живой таблицей ГТЕ; header-driven + counters покажут расхождения.
  3. Скриншот-верификация блока «ГАЗ» и пометки ЕЭСК. Spot-check: городские ГРС реально матчатся ILIKE-фильтром (ревьюер предупредил — источник может именовать иначе).
## Что (issue #2119, Фаза B1) Газовая вертикаль точек подключения: **свободная мощность ГРС** (главный газовый gate для девелопера) в карточку «Ресурсные резервы» §3 + честная пометка ЕЭСК у городских ПС. ## Backend - **Миграция `data/sql/181_gas_grs_capacity.sql`**: `gas_grs_capacity` (ГРС с выходами, `UNIQUE NULLS NOT DISTINCT (grs_name_norm, output_name)` — грабли #140; geom NULL — геокод в Фазе C). - **`gazprom_grs_loader`** — bs4-парсер инлайн HTML-таблицы «техническая возможность» ГТЕ (~316 ГРС; гео-блок → RUN-ON-PROD): header-driven маппинг колонок (переживёт перестановку), rowspan forward-fill имени (допущение col-0 задокументировано), числа через общий `parse_reserve_number`, SAVEPOINT per-row, неизвестные колонки → raw jsonb. - **Celery** `sync_gas_grs_capacity` + beat вт 05:00 MSK. - **Endpoint** `/connection-capacity`: блок `gas` — `city_grs` (городские ГРС «Свердловск/Екатеринбург», агрегация по выходам: SUM design/free, AVG %, MAX расшивка) + `total_free_th_m3_h`; **graceful** при отсутствии таблицы (schema-first окно). Плюс `reserve_note` у ПС ЕЭСК без опубликованного резерва: «Резерв — по запросу в АО «ЕЭСК» (город)». - Схемы аддитивны (`GasGrsRow`/`GasCapacityBlock`/`reserve_note`), api-types **+31/−0**. ## Frontend (§3 карточка + попап) - Блок **«ГАЗ»** между электро и водой: на каждую городскую ГРС «свободно X из Y тыс. м³/ч» + бейдж «резерв»/«исчерпана», « · расшивка: {срок}», «(N выхода)», суммарная строка; источник «Газпром трансгаз Екатеринбург». Fallback «загружаются». - Попап ЦП: серая строка `reserve_note` для городских ПС. ## Проверки - **57 backend-тестов** (парсер header-drift/rowspan/н-д, агрегация, graceful-degradation, reserve_note) + ruff + psycopg3-guard чисты; фронт tsc/eslint/prettier чисты. - **Deep-review: ✅ APPROVE** (2 minor: col-0 допущение — задокументировал в docstring; MAX(upgrade_due) лексикографический — as-in-source, отмечено). ## После merge 1. Deploy применит миграцию 181 (schema-first). 2. Прогон лоадера на проде (docker exec) — первая встреча парсера с живой таблицей ГТЕ; header-driven + counters покажут расхождения. 3. Скриншот-верификация блока «ГАЗ» и пометки ЕЭСК. Spot-check: городские ГРС реально матчатся ILIKE-фильтром (ревьюер предупредил — источник может именовать иначе).
bot-backend added 1 commit 2026-07-02 12:38:23 +00:00
feat(site-finder): газ — свободная мощность ГРС + пометка ЕЭСК в §3 (#2119 Фаза B1)
All checks were successful
CI / changes (pull_request) Successful in 8s
CI / frontend-tests (pull_request) Successful in 1m9s
CI / openapi-codegen-check (pull_request) Successful in 2m1s
CI / backend-tests (pull_request) Successful in 14m39s
641f0d56ed
Газовая вертикаль точек подключения:
- Миграция 181: gas_grs_capacity (ГРС с выходами; UNIQUE NULLS NOT DISTINCT
  на (grs_name_norm, output_name) — грабли #140).
- gazprom_grs_loader: bs4-парсер инлайн HTML-таблицы «техническая возможность»
  ГТЕ (~316 ГРС; гео-блок → RUN-ON-PROD): header-driven маппинг колонок,
  rowspan forward-fill имени (допущение col-0 задокументировано), числа через
  общий parse_reserve_number, SAVEPOINT per-row, unknown-колонки → raw jsonb.
- Celery sync_gas_grs_capacity + beat вт 05:00 MSK.
- Endpoint connection-capacity: gas.city_grs (городские ГРС Свердловск/
  Екатеринбург, агрегация по выходам) + gas.total_free_th_m3_h; graceful при
  отсутствии таблицы (schema-first окно). reserve_note у ПС ЕЭСК без
  опубликованного резерва: «Резерв — по запросу в АО «ЕЭСК» (город)».
- Схемы GasGrsRow/GasCapacityBlock/reserve_note аддитивны; api-types +31/-0.
- Фронт: блок «ГАЗ» в карточке резервов (по-ГРС «свободно X из Y тыс. м³/ч»,
  бейджи резерв/исчерпана, расшивка, N выходов, суммарная строка) + серая
  reserve_note-строка в попапе ЦП. Числа через toFiniteNumber.

57 backend-тестов зелёные; deep-review  APPROVE (2 minor-нота учтены).
bot-backend merged commit 5839680998 into main 2026-07-02 12:54:06 +00:00
bot-backend deleted branch feat/gas-grs-capacity 2026-07-02 12:54:06 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2123
No description provided.