gendesign/data/sql/91_engineering_networks_191fz.sql
lekss361 7c43bc5496
feat(infra): auto-apply data/sql/*.sql migrations in deploy pipeline (#150) (#151)
* fix(frontend): apiFetchWithStatus body stream double-read crash

Per user report 2026-05-14: 'Failed to execute text on Response: body stream
already read' при analyze с non-JSON error response.

apiFetchWithStatus делал .json() (consumes stream), потом .text() в catch
(FAILS — stream already consumed). Fetch API: body — ReadableStream,
consumable один раз.

Fix: read text() once → JSON.parse on string. На fail (HTML / non-JSON)
оборачиваем в {detail: rawText}. Никаких double-reads.

Site-finder cad search больше не крашится на error pages.

* feat(infra): auto-apply data/sql/*.sql migrations in deploy pipeline (#150)

Закрывает root cause production 500 на /api/v1/admin/site-finder/weight-profiles
(а также 2 unapplied migrations: #89/#91).

## Why это нужно

После audit обнаружили что:
- backend/alembic/versions/ пустой (Alembic configured но не используется)
- deploy.yml не имеет migration step
- 47+ raw SQL files накопилось без auto-apply
- 3 файла unapplied: 87 (engineering), 89 (drop brin), 90 (weight profiles)

User report: GET weight-profiles → 500 потому что user_weight_profiles
table не существует на prod.

## Changes

### deploy.yml +39 lines
- Path trigger расширен на data/sql/*.sql
- New step 'Apply DB migrations' между compose pull и compose up -d:
  - Idempotent CREATE TABLE _schema_migrations
  - Loop по data/sql/*.sql sorted → skip applied → psql with ON_ERROR_STOP=on
  - Record applied filename в tracking table
  - Exit 1 на failure → containers НЕ обновляются (no partial state)

### NN collision fix
- 87_engineering_networks_191fz.sql → 91_engineering_networks_191fz.sql
  (collision с 87_on_demand_indexes.sql, мой renumber 85→87 был неудачным)

### CLAUDE.md +32 lines
- Subsection 'Auto-apply' под Migration pattern
- Bootstrap procedure docs
- Idempotency requirement
- Failure recovery

### scripts/bootstrap_schema_migrations.sh +100 lines
- One-time seed _schema_migrations с 48 already-applied files
- 3 файла intentionally NOT seeded: 89/90/91 (auto-apply на first deploy)
- Usage docs + verification query

## Vault

domains/infra/Runbook_Auto_Apply_Migrations.md NEW
infra-MOC.md updated

## Required manual steps ДО merge

1. SSH gendesign (tunnel)
2. POSTGRES creds export
3. bash scripts/bootstrap_schema_migrations.sh — seed 48 already-applied files
4. Verify: SELECT COUNT(*) FROM _schema_migrations → 48
5. После merge → first deploy auto-apply #89/#90/#91 → 500 closes

Closes #150

---------

Co-authored-by: lekss361 <claudestars@proton.me>
2026-05-15 08:06:54 +03:00

401 lines
24 KiB
PL/PgSQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 91_engineering_networks_191fz.sql
-- Engineering Networks schema по 191-ФЗ (Сводный план наземных и подземных коммуникаций)
-- Source: QGIS.zip Минстроя Свердл (https://old-minstroy.midural.ru/uploads/2021/05/QGIS.zip)
-- Extracted: 2026-05-12 (via Communication.qgz reverse-engineering)
-- See vault/research/Engineering_Networks_Schema_191FZ_May12.md
--
-- Deploy order: apply after 90_user_weight_profiles.sql
-- Renumbered 87→91 due to NN collision with existing 87_on_demand_indexes.sql
-- Dependencies: PostGIS extension, spatial_ref_sys table
BEGIN;
-- ============ МСК-66 — официальная проекция Свердловской области ============
-- Извлечена из <projectCrs> в Communication.qgs (Минстрой Свердл)
-- Описание: Местная Система Координат Свердловской области (МСК-66)
-- Эллипсоид: Krassovsky 1942
-- Центральный меридиан: 60.05° E
-- Используется для ВСЕХ кадастровых/градостроительных документов Свердл
INSERT INTO spatial_ref_sys (srid, auth_name, auth_srid, proj4text, srtext)
VALUES (
100000,
'USER',
100000,
'+proj=tmerc +lat_0=0 +lon_0=60.05 +k=1 +x_0=1500000 +y_0=-5911057.63 +ellps=krass +towgs84=23.92,-141.27,-80.9,-0,0.35,0.82,-0.12 +units=m +no_defs',
'PROJCS["MSK-66",GEOGCS["Krassovsky 1942",DATUM["D_Krassovsky_1942",SPHEROID["Krassovsky_1942",6378245,298.3],TOWGS84[23.92,-141.27,-80.9,0,0.35,0.82,-0.12]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",60.05],PARAMETER["scale_factor",1],PARAMETER["false_easting",1500000],PARAMETER["false_northing",-5911057.63],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]'
)
ON CONFLICT (srid) DO UPDATE SET
proj4text = EXCLUDED.proj4text,
srtext = EXCLUDED.srtext;
-- Usage: ST_Transform(geom, 100000) для МСК-66, или ST_Transform(geom_msk66, 4326) обратно в WGS84
-- ============ ENUMs ============
DO $$ BEGIN
CREATE TYPE network_category AS ENUM ('thermal','water','sewerage','gas','electricity','transport','auxiliary');
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
DO $$ BEGIN
CREATE TYPE network_object_kind AS ENUM ('pipeline','facility_point','facility_polygon','aux_object','building');
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
DO $$ BEGIN
CREATE TYPE ground_position AS ENUM ('on_ground','above','underground','embanked','underwater');
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
-- ============ REFERENCE TABLES ============
CREATE TABLE IF NOT EXISTS eng_ref_classid (
classid CHAR(9) PRIMARY KEY,
category network_category NOT NULL,
kind network_object_kind NOT NULL,
name TEXT NOT NULL,
description TEXT
);
CREATE TABLE IF NOT EXISTS eng_ref_material (
id SMALLINT PRIMARY KEY,
name TEXT NOT NULL,
is_plastic BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE TABLE IF NOT EXISTS eng_ref_insulation (
id SMALLINT PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS eng_ref_ground_pos (
id SMALLINT PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS eng_ref_pline_type (
id SMALLINT PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS eng_ref_gas_type (
id SMALLINT PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS eng_ref_elline_type (
id SMALLINT PRIMARY KEY,
name TEXT NOT NULL,
voltage_v INTEGER,
is_weak_current BOOLEAN NOT NULL DEFAULT FALSE
);
-- ============ MAIN FEATURES TABLE ============
CREATE TABLE IF NOT EXISTS engineering_networks (
id BIGSERIAL PRIMARY KEY,
global_id UUID NOT NULL DEFAULT gen_random_uuid(),
category network_category NOT NULL,
kind network_object_kind NOT NULL,
classid CHAR(9) REFERENCES eng_ref_classid(classid),
classid_name TEXT,
name TEXT,
address TEXT,
owner TEXT,
balance_holder TEXT,
exploiter TEXT,
length_m REAL,
wear_percent REAL,
diameter_1_mm INTEGER,
diameter_2_mm INTEGER,
material_id SMALLINT REFERENCES eng_ref_material(id),
insulation_id SMALLINT REFERENCES eng_ref_insulation(id),
pline_type_id SMALLINT REFERENCES eng_ref_pline_type(id),
ground_pos_id SMALLINT REFERENCES eng_ref_ground_pos(id),
voltage_v INTEGER,
elline_type_id SMALLINT REFERENCES eng_ref_elline_type(id),
power_mw REAL,
fuel_type INTEGER,
gas_type_id SMALLINT REFERENCES eng_ref_gas_type(id),
facility_subtype_1 INTEGER,
facility_subtype_2 INTEGER,
status INTEGER,
is_planned BOOLEAN NOT NULL DEFAULT FALSE,
source_type INTEGER,
source TEXT,
source_municipality TEXT,
source_dataset_id TEXT,
geom GEOMETRY(Geometry, 4326),
note TEXT,
fetched_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(global_id)
);
CREATE INDEX IF NOT EXISTS gist_eng_networks_geom ON engineering_networks USING GIST(geom);
CREATE INDEX IF NOT EXISTS idx_eng_networks_category ON engineering_networks(category);
CREATE INDEX IF NOT EXISTS idx_eng_networks_classid ON engineering_networks(classid);
CREATE INDEX IF NOT EXISTS idx_eng_networks_municipality ON engineering_networks(source_municipality);
-- ============ SEED DATA ============
-- CLASSID NSI classifiers (extracted from official Минстрой Свердл шаблон)
INSERT INTO eng_ref_classid (classid, category, kind, name) VALUES
('901010100', 'thermal', 'facility_point', 'Источник тепловой энергии'),
('901010200', 'thermal', 'facility_point', 'Центральный тепловой пункт (ЦТП)'),
('901010300', 'thermal', 'facility_point', 'Индивидуальный тепловой пункт (ИТП)'),
('901010400', 'thermal', 'facility_point', 'Тепловая перекачивающая насосная станция (ТПНС)'),
('901010500', 'thermal', 'facility_point', 'Стационарная модульная котельная'),
('901020100', 'thermal', 'pipeline', 'Теплопровод магистральный'),
('901020200', 'thermal', 'pipeline', 'Теплопровод распределительный (квартальный)'),
('901020300', 'thermal', 'pipeline', 'Ответвления теплопровода'),
('901020400', 'thermal', 'pipeline', 'Байпасные трубопроводы'),
('901020500', 'thermal', 'pipeline', 'Паропровод'),
('901020600', 'thermal', 'pipeline', 'Конденсатопровод'),
('901020700', 'thermal', 'pipeline', 'Попутный дренаж'),
('902010100', 'water', 'facility_point', 'Водозаборное сооружение'),
('902010200', 'water', 'facility_point', 'Очистное сооружение'),
('902010300', 'water', 'facility_point', 'Насосная станция'),
('902010400', 'water', 'facility_point', 'Водонапорная башня'),
('902010500', 'water', 'facility_point', 'Резервуар'),
('902010600', 'water', 'facility_point', 'Пневматическая установка'),
('902010700', 'water', 'facility_point', 'Распределительные пункты (на водоводах)'),
('902020100', 'water', 'pipeline', 'Хозяйственно-питьевой'),
('902020200', 'water', 'pipeline', 'Производственный'),
('902020300', 'water', 'pipeline', 'Противопожарный'),
('902020400', 'water', 'pipeline', 'Объединенный'),
('903010100', 'sewerage', 'facility_point', 'Очистные сооружения'),
('903010200', 'sewerage', 'facility_point', 'Канализационная насосная станция'),
('903010300', 'sewerage', 'facility_point', 'Подземный резервуар'),
('903010400', 'sewerage', 'facility_point', 'Разделительная камера'),
('903020100', 'sewerage', 'pipeline', 'Хозяйственно-бытовая'),
('903020200', 'sewerage', 'pipeline', 'Производственная'),
('903020300', 'sewerage', 'pipeline', 'Дождевая открытая'),
('903020400', 'sewerage', 'pipeline', 'Дождевая закрытая'),
('903020500', 'sewerage', 'pipeline', 'Производственно-дождевая'),
('903020600', 'sewerage', 'pipeline', 'Производственно- бытовая'),
('903020700', 'sewerage', 'pipeline', 'Дренажная'),
('904010100', 'gas', 'facility_point', 'Источник газа'),
('904010200', 'gas', 'facility_point', 'Сепаратор'),
('904010300', 'gas', 'facility_point', 'Компрессорная станция'),
('904010400', 'gas', 'facility_point', 'ГРС (газорегуляторная станция)'),
('904010500', 'gas', 'facility_point', 'ГРП (газорегуляторные пункты)'),
('904010600', 'gas', 'facility_point', 'КИП (контрольно-измерительные пункты)'),
('904010700', 'gas', 'facility_point', 'Катодные станции электрохимзащиты'),
('904010800', 'gas', 'facility_point', 'Газгольдерная станция'),
('904010900', 'gas', 'facility_point', 'Подземные хранилища газа'),
('904020100', 'gas', 'pipeline', 'Газопровод высокого давления I категории (от 0,6 до 1,2 МПа)'),
('904020200', 'gas', 'pipeline', 'Газопровод высокого давления II категории (выше 0,3 до 0,6 МПа)'),
('904030300', 'gas', 'pipeline', 'Газопровод среднего давления (выше 0,005 до 0,3 МПа),'),
('904040400', 'gas', 'pipeline', 'Газопровод низкого давления (до 0,005 МПа);'),
('905010100', 'electricity', 'facility_point', 'Трансформаторная подстанция (ТП)'),
('905010200', 'electricity', 'facility_point', 'Распределительный пункт (РП)'),
('905010300', 'electricity', 'facility_point', 'Распределительное устройство (РУ)'),
('905010400', 'electricity', 'facility_point', 'АВР (автоматический ввод резерва)'),
('905010500', 'electricity', 'facility_point', 'Резервный источник питания (КТП –комплектная ТП)'),
('905010600', 'electricity', 'facility_point', 'Базовая станция сети подвижной связи'),
('905010700', 'electricity', 'facility_point', 'Узел телефонной связи'),
('905010800', 'electricity', 'facility_point', 'Телефонная станция'),
('905010900', 'electricity', 'facility_point', 'Радиорелейная вышка'),
('905011000', 'electricity', 'facility_point', 'Узел автоматической коммутации'),
('905011100', 'electricity', 'facility_point', 'Радиостанция'),
('905020100', 'electricity', 'pipeline', 'Сети сильных токов высокого напряжения (>1000В)'),
('905020200', 'electricity', 'pipeline', 'Сети сильных токов низкого напряжения (≤1000В)'),
('905020300', 'electricity', 'pipeline', 'Слаботочные сети (информационные)(телеграф, автоматические телефонные станции,): бытового назначения, коммерческие'),
('906010100', 'transport', 'pipeline', 'Нефтепроводы'),
('906010200', 'transport', 'pipeline', 'Нефтепродуктопроводы'),
('906010300', 'transport', 'pipeline', 'Трубопроводы для транспортировки твердых материалов'),
('906010400', 'transport', 'pipeline', 'Трубопроводы специального назначения'),
('907040100', 'auxiliary', 'building', 'Контуры зданий и сооружений'),
('907010100', 'auxiliary', 'aux_object', 'Аппаратура, от повышения давления (на водоводах)'),
('907010200', 'auxiliary', 'aux_object', 'Водонапорная колонн'),
('907010300', 'auxiliary', 'aux_object', 'Водоразборная колонка'),
('907010400', 'auxiliary', 'aux_object', 'Воздуходувная станция'),
('907010500', 'auxiliary', 'aux_object', 'Воздушный колпак'),
('907010600', 'auxiliary', 'aux_object', 'Выпуск'),
('907010700', 'auxiliary', 'aux_object', 'Гильза'),
('907010800', 'auxiliary', 'aux_object', 'Грозозащитный трос'),
('907010900', 'auxiliary', 'aux_object', 'Дождеприемник'),
('907011000', 'auxiliary', 'aux_object', 'Дюкер'),
('907011100', 'auxiliary', 'aux_object', 'Зажимы изолированные'),
('907011200', 'auxiliary', 'aux_object', 'Заземление'),
('907011300', 'auxiliary', 'aux_object', 'Камера'),
('907011400', 'auxiliary', 'aux_object', 'Ковер'),
('907011500', 'auxiliary', 'aux_object', 'Кожух для наземного размещения арматуры'),
('907011600', 'auxiliary', 'aux_object', 'Колодец'),
('907011700', 'auxiliary', 'aux_object', 'Компенсатор'),
('907011800', 'auxiliary', 'aux_object', 'Конденсатосборник'),
('907011900', 'auxiliary', 'aux_object', 'Лазы ( при d > 800мм)'),
('907012000', 'auxiliary', 'aux_object', 'Лестницы'),
('907012100', 'auxiliary', 'aux_object', 'Ливнеотвод'),
('907012200', 'auxiliary', 'aux_object', 'Ливнеспуск (общесплавная система)'),
('907012300', 'auxiliary', 'aux_object', 'Металлический ковер'),
('907012400', 'auxiliary', 'aux_object', 'Металлический кожух для наружного размещения запорной арматуры'),
('907012500', 'auxiliary', 'aux_object', 'Мостики'),
('907012600', 'auxiliary', 'aux_object', 'Несгораемый шкаф'),
('907012700', 'auxiliary', 'aux_object', 'Ниша компенсатора'),
('907012800', 'auxiliary', 'aux_object', 'Опознавательные и сигнальные знаки местонахождения трубопроводов, указатели и предупредительные знаки.'),
('907012900', 'auxiliary', 'aux_object', 'Опора'),
('907013000', 'auxiliary', 'aux_object', 'Опора в канале'),
('907013100', 'auxiliary', 'aux_object', 'Павильон'),
('907013200', 'auxiliary', 'aux_object', 'Пескоуловитель'),
('907013300', 'auxiliary', 'aux_object', 'Плавучая опора'),
('907013400', 'auxiliary', 'aux_object', 'Подвесные переходы'),
('907013500', 'auxiliary', 'aux_object', 'Подпиточный пункт'),
('907013600', 'auxiliary', 'aux_object', 'Пожарный гидрант'),
('907013700', 'auxiliary', 'aux_object', 'Поливочный кран'),
('907013800', 'auxiliary', 'aux_object', 'Противопожарные средства'),
('907013900', 'auxiliary', 'aux_object', 'Противоэрозионные и защитные сооружения трубопроводов'),
('907014000', 'auxiliary', 'aux_object', 'Разгрузочная камера'),
('907014100', 'auxiliary', 'aux_object', 'Разрядник'),
('907014200', 'auxiliary', 'aux_object', 'Ревизионный люк'),
('907014300', 'auxiliary', 'aux_object', 'Роликовые дорожки с якорями'),
('907014400', 'auxiliary', 'aux_object', 'Сигнальная лента'),
('907014500', 'auxiliary', 'aux_object', 'Сливная станция'),
('907014600', 'auxiliary', 'aux_object', 'Снегоплавильный пункт'),
('907014700', 'auxiliary', 'aux_object', 'Средства телемеханики трубопроводов'),
('907014800', 'auxiliary', 'aux_object', 'Стационарная площадка для обслуживания'),
('907014900', 'auxiliary', 'aux_object', 'Стояка с пожарными кранами'),
('907015000', 'auxiliary', 'aux_object', 'Теплофикационная камера'),
('907015100', 'auxiliary', 'aux_object', 'Упоры'),
('907015200', 'auxiliary', 'aux_object', 'Установка электрохимической защиты газопроводов от коррозии'),
('907015300', 'auxiliary', 'aux_object', 'Футляр'),
('907015400', 'auxiliary', 'aux_object', 'Канал для прокладки коммуникаций'),
('907015500', 'auxiliary', 'aux_object', 'Опоры линий электропередач'),
('907015501', 'auxiliary', 'aux_object', 'Опора деревянная (столб)'),
('907015502', 'auxiliary', 'aux_object', 'Опора деревянная (ферма)'),
('907015503', 'auxiliary', 'aux_object', 'Опора деревянная с подкосинами или оттяжками'),
('907015504', 'auxiliary', 'aux_object', 'Опора металлическая (столб)'),
('907015505', 'auxiliary', 'aux_object', 'Опора металлическая (ферма)'),
('907015506', 'auxiliary', 'aux_object', 'Опора металлическая (фермовый столб))'),
-- TODO(NSI-verify): 'Опора железобетонная (столб)' — отсутствует в исходном QGIS dump.
-- Провизорное назначение 907015507 (review May 14) убрано из seed до подтверждения
-- против официальной NSI-таблицы Минстроя. Не вставляем в eng_ref_classid пока
-- не верифицировано — иначе ON CONFLICT DO UPDATE name перетрёт корректное значение.
-- ('907015507', 'auxiliary', 'aux_object', 'Опора железобетонная (столб)'),
('907015508', 'auxiliary', 'aux_object', 'Опора железобетонная (ферма)'),
('907015600', 'auxiliary', 'aux_object', 'Дополнительные объекты на на опорах линии электропередач'),
('907015601', 'auxiliary', 'aux_object', 'Молниеотводы (на столбах)'),
('907015602', 'auxiliary', 'aux_object', 'Фонари электрические (на столбах)'),
('907015603', 'auxiliary', 'aux_object', 'Часы электрические (на столбах)'),
('907015604', 'auxiliary', 'aux_object', 'Прожекторы (на столбах)'),
('907015605', 'auxiliary', 'aux_object', 'Трансформаторы (на столбах)???'),
('907015606', 'auxiliary', 'aux_object', 'Мачты и башни радио и телевизионные, вышки радиорелейные и ретрансляторы'),
('907020000', 'auxiliary', 'aux_object', 'Особая точка')
ON CONFLICT (classid) DO UPDATE SET name=EXCLUDED.name;
-- Pipe materials (13 types)
INSERT INTO eng_ref_material (id, name, is_plastic) VALUES
(1, 'Сталь', FALSE),
(2, 'Чугун', FALSE),
(3, 'Высокопрочный чугун с шаровидным графитом', FALSE),
(4, 'Металлополимер', TRUE),
(5, 'Стеклопластик', TRUE),
(6, 'Асбоцемент', FALSE),
(7, 'Железобетонные напорные', FALSE),
(8, 'Пластиковые (ПВХ, ПЭ, ПП)', TRUE),
(9, 'Хризотилцемент', FALSE),
(10, 'Металлопластик', TRUE),
(11, 'Керамика', FALSE),
(12, 'Пластмасса', TRUE),
(13, 'Резиноткатевые трубы', FALSE)
ON CONFLICT (id) DO UPDATE SET name=EXCLUDED.name;
-- Insulation types (23 types)
INSERT INTO eng_ref_insulation (id, name) VALUES
(1, 'Стекловата'),
(2, 'Базальтовый утеплитель'),
(3, 'Пенополистирол (пенопласт)'),
(4, 'Пенополиуретан'),
(5, 'Сшитый полиэтилен'),
(6, 'Монолитная оболочка'),
(7, 'Литая оболочка'),
(8, 'Засыпные порошки'),
(9, 'Армопенобетон'),
(10, 'Минеральная вата'),
(11, 'Керамзитобетон'),
(12, 'Перлит'),
(13, 'Нагревательный кабель'),
(14, 'Технологическая труба'),
(15, 'Вспененный полиэтилен'),
(16, 'Пеноплекс'),
(17, 'Изопон'),
(18, 'Керамзит'),
(19, 'Базальт'),
(20, 'Фольгоизол'),
(21, 'Вспененный синтетический каучук'),
(22, 'Битумная мастика'),
(23, 'Ленточные из ПВХ и полиэтилена')
ON CONFLICT (id) DO UPDATE SET name=EXCLUDED.name;
-- Ground positions (3 types)
INSERT INTO eng_ref_ground_pos (id, name) VALUES
(1, 'Наземное'),
(2, 'Надземное'),
(3, 'Подземное')
ON CONFLICT (id) DO UPDATE SET name=EXCLUDED.name;
-- Pipeline placement (5 types)
INSERT INTO eng_ref_pline_type (id, name) VALUES
(1, 'Надземный'),
(2, 'Подземный'),
(3, 'Наземный'),
(4, 'Наземный в обваловании'),
(5, 'Подводный')
ON CONFLICT (id) DO UPDATE SET name=EXCLUDED.name;
-- Gas types (10 types)
INSERT INTO eng_ref_gas_type (id, name) VALUES
(1, 'Природный газ'),
(2, 'Попутный нефтяной газ (ПНГ)'),
(3, 'Смесь природного газа и попутного нефтяного газа (ПНГ)'),
(4, 'Доменный газ'),
(5, 'Коксовый газ'),
(7, 'Сжиженный углеводородный'),
(8, 'искусственный'),
(9, 'Сланцевый'),
(10, 'Генераторный'),
(11, 'Сухой отбензиненный')
ON CONFLICT (id) DO UPDATE SET name=EXCLUDED.name;
-- Electricity line types (18 voltage levels + signal)
INSERT INTO eng_ref_elline_type (id, name, voltage_v, is_weak_current) VALUES
(1, 'Сеть Ультравысокого напряжения 750, 1150,1500кВ', 1500000, FALSE),
(2, 'Сеть Сверхвысокого напряжения 750,500,330кВ', 750000, FALSE),
(3, 'Сеть Высокого напряжения (ВН) 220,150,110 кВ', 220000, FALSE),
(4, 'Сеть Среднего первого напряжения (СН-1) 35кВ', 35000, FALSE),
(5, 'Сеть Среднего второго напряжения (СН-2) 20,10,6,1 кВ', 20000, FALSE),
(6, 'Сеть напряжения 0,38кВ', 380, FALSE),
(7, 'Сеть напряжения 0,2кВ', 200, FALSE),
(8, 'Сеть напряжения 0,11кВ', 110, FALSE),
(9, 'Телефонная линия (бытовая)', NULL, TRUE),
(10, 'Интернет (бытовая)', NULL, TRUE),
(11, 'Теле-радиовещание (бытовая)', NULL, TRUE),
(12, 'Домофония (бытовая)', NULL, TRUE),
(13, 'Сигнализация (бытовая)', NULL, TRUE),
(14, 'Стереосистемы (бытовая)', NULL, TRUE),
(15, 'Пожарная безопасность (коммерческая)', NULL, TRUE),
(16, 'Локально-вычислительная сеть ЛВС(коммерческая)', NULL, TRUE),
(17, 'Автоматизация подсчета энергоресурсов. (коммерческая)', NULL, TRUE),
(18, 'Внутрипроизводственная система оповещения. (коммерческая)', NULL, TRUE)
ON CONFLICT (id) DO UPDATE SET name=EXCLUDED.name;
COMMIT;
-- Migration complete:
-- • МСК-66 (SRID 100000) для PostGIS ST_Transform
-- • 137 NSI CLASSID classifiers
-- • 13 pipe materials
-- • 23 insulation types
-- • 5 pipeline placements (включая подводный)
-- • 10 gas types
-- • 18 ЛЭП voltage levels (8 power + 10 weak-current)
-- • 3 ground positions
-- • main engineering_networks table + GIST + BTREE indexes
--
-- Following NSI hierarchy:
-- 901xxxxxxx — Тепло (5 facility + 7 pipeline types)
-- 902xxxxxxx — Вода (7 facility + 4 pipeline)
-- 903xxxxxxx — Канализация (4 facility + 7 pipeline)
-- 904xxxxxxx — Газ (9 facility + 4 pipeline)
-- 905xxxxxxx — Электро + связь (11 facility + 3 line types)
-- 906xxxxxxx — Транспорт жидкостей (4 pipeline)
-- 907xxxxxxx — Допобъекты (80+ subtypes) + здания