Редактор сети
Правка схемы сети прямо на карте: новые трассы и узлы, перенос узлов, изломы участков, слияние узлов, ввод в здание. После каждой операции сеть проверяется на связность, любую правку можно отменить.
Возможности
- «Выбор» (V): выделить узел или участок и открыть его свойства; выделенный узел можно перетащить — трубы потянутся следом.
- «Трасса» (L): участки с изломами — от узла через точки излома до узла, врезки в трубу или пустого места (там появится новый узел).
- «Узел» (N): новый узел выбранного типа щелчком по карте.
- «Изломы» (E): правка изломов участка — тянуть, добавить, убрать правым щелчком.
- «Слияние» (M): слить узел в другой — сначала целевой, затем сливаемый.
- «Ввод в здание» (B): щелчок по зданию — врезка в ближайшую трубу, участок до стены и узел-потребитель.
- Точка трассы по точным координатам (G), привязка к узлам, трубам и контурам зданий, шаг угла.
- Отмена и повтор (Ctrl+Z, Ctrl+Y), история правок с откатом до нужного места, шаблоны свойств новых участков и узлов.
Как это работает
Одна операция — одна транзакция. Трасса, новый узел, перенос узла, изломы, разрез, слияние, разворот, удаление, смена типа узла или линии записываются на сервере целиком или не записываются вовсе. Узлы лежат в nodes, участки — в linesobj с паспортом трубы в heatpipesections; оборудование и карточки узлов — в своих таблицах (dampers, pumps, realconsumers, heatsources и др.). Длина участка считается в местной системе координат (SRID 9998), как в десктопе.
Журнал для отмены. Перед изменением сервер снимает полные образы всех строк, которые операция может задеть, и в той же транзакции пишет запись в таблицу topology_undo_log: образы «до» и контрольные суммы (md5) строк «после». Отмена восстанавливает образы «до» и удаляет созданные строки, но только если с тех пор строки не менялись — иначе отказ с объяснением. Журнал ведётся по пользователю: Ctrl+Z отменяет вашу последнюю операцию, Ctrl+Y повторяет последнюю отменённую. Удаление мягкое: у узла и участка ставится признак removed = 1, строка остаётся в базе.
Проверка связности. После каждой записи веб запрашивает проверку области операции: изменённые узлы и участки и всё, что к ним примыкает. Правила — висячий участок, участок нулевой длины, дубль, непривязанный конец, узел без участков, участок между фрагментами, несовпадение геометрии и узлов, конфликт типов узла, узел без питания. Это предупреждения: правку они не запрещают, потому что десктоп правит ту же базу без этих правил. Подробнее — в «Проверке после правки».
Оптимистичная блокировка. У каждой строки есть версия «дата изменения # номер транзакции» (archivechangedate#xmin). Окна предпросмотра получают версии объектов, запись их сверяет. Если объект за это время изменил кто-то другой (веб или десктоп), сервер отвечает конфликтом версий, ничего не меняя, а веб предлагает перезагрузить объект.
Фрагмент новых объектов. Новые узлы и участки попадают во фрагмент, выбранный на панели редактора. Если на карте один фрагмент — в него; трасса, начатая от узла или трубы, — в их фрагмент. Без фрагмента сервер не создаёт объект и просит выбрать.
Паспорт новых участков. Копируется с участка-образца: сначала примыкающего к тем же узлам, иначе ближайшего в радиусе 300 м; если рядом нет ни одного — значения по умолчанию. Новый узел получает код от ближайшего узла сети.
Ограничения: в трассе до 500 точек; участок короче 0,1 м не создаётся; точка ближе 0,3 м к узлу считается этим узлом. Привязка грузит узлы и участки окна карты не больше 6000 м по стороне и не больше 20 000 объектов — при большем окне её нужно приблизить.
Что нужно для работы
- Права из матрицы «вид объекта × действие»: кнопка редактора видна, если есть хоть одно из прав «создавать», «перемещать», «удалять» хотя бы для одного вида объектов (узлы, участки, потребители, источники, оборудование). Каждый инструмент проверяет своё право: «Трасса» — создавать участки, «Узел» — создавать узлы, «Изломы» — перемещать участки, «Слияние» — удалять узлы. Среди ролей-шаблонов это «Оператор сети» (создаёт любые объекты, правит, переносит и удаляет только свои), «Редактор» (правит и переносит все, удаляет только свои) и «Администратор»; «Просмотр» и «Режимщик» редактора не видят.
- На сервере API включены флаги
MUTATIONS_ENABLEDиTOPOLOGY_MUTATIONS_ENABLED. Без них кнопки нет, а запись отвечает ошибкой 503. Предпросмотры (окна до записи) работают и без флагов. - Для отмены — таблица журнала
topology_undo_log: её создаёт сам API при доводке базы города (миграцияsql/migrations/20260927_topology_undo_log.sql). Без неё правки записываются, но отменить их нельзя.
Шаги
Нажмите «Редактировать топологию сети» в строке режимов над картой.

Над картой появится панель редактора: инструменты, фрагмент, в который попадут новые объекты, параметры трубы и конечного узла, отмена и повтор. Панель можно перетащить за ручку слева и закрепить.

Выберите инструмент — например, «Трасса». Строка состояния внизу подсказывает следующий щелчок. Начните трассу щелчком по узлу, трубе или пустому месту, ставьте изломы; закончите щелчком по узлу или трубе, а в пустом месте — двойным щелчком или Enter (Backspace убирает последнюю точку). После операции появится панель проверки связности для изменённого места.

Все клавиши редактора — в справке: нажмите «?» или кнопку с клавиатурой на панели. Выйти из редактора — той же кнопкой в строке режимов.

Примеры
На копии базы Алматы, фрагмент 74, в пустом месте у восточного края сети:
- Трасса из трёх точек (две новые, одна — излом): один участок 244,44 м с признаком «общий», два новых узла, одна операция в журнале.
- Сразу после неё панель проверки: «Проверка правки: 1 предупреждение — Узлы без питания: узел #…; часть сети без питания: 2 узла». Новая трасса не соединена с источником, это ожидаемо.
- Разрез этого участка на четверти длины: половины 62,34 и 182,10 м — в сумме те же 244,44 м.
- «Убрать узел, соединив трубы» после разреза вернуло один участок 244,44 м.
Если не получается
- Кнопки редактора нет в строке режимов — нет права на создание, перенос или удаление объектов сети, либо правка сети выключена на сервере.
- «Сначала завершите рисование или измерение» — закройте панель «Измерения».
- Привязка к зданиям не работает — приблизьте карту (подсказка «Здания — с масштаба 15» на панели).
- Объекты попали не в тот фрагмент — фрагмент новых объектов выбирается на панели редактора; если на карте несколько фрагментов, редактор спросит.
- Правка оказалась ошибочной — Ctrl+Z или «Отменить» на панели; более ранние правки — через историю правок (H).
Для администратора
- Флаги
MUTATIONS_ENABLEDиTOPOLOGY_MUTATIONS_ENABLED— в.envAPI. После выключения сервер сразу отклоняет любую запись сети; веб узнаёт о флагах при входе и загрузке страницы — тогда же пропадает кнопка редактора. - Права выдаются в окне «Пользователи» матрицей «вид × действие» с охватом «нет / свои / все». «Свои» — объекты, которые пользователь создал сам (таблица авторства объектов в базе города).
- Журнал отмены растёт с каждой правкой. Окно истории показывает последние 50 операций пользователя, API отдаёт до 200.
Для разработчика
- Эндпоинты (
routers/topology.py):POST /api/v1/topology/chains(трасса,dry_run),POST /api/v1/topology/node,PUT /api/v1/topology/node/{id}/move,PUT /api/v1/topology/line/{id}/geometry(изломы),POST /api/v1/topology/split-line,POST /api/v1/topology/merge-nodes,POST /api/v1/topology/reverse-line,GET|POST /api/v1/topology/node/{id}/type,GET|POST /api/v1/topology/line/{id}/type,GET /api/v1/topology/node|line/{id}/delete-preview,POST /api/v1/topology/node/{id}/dissolve,DELETE /api/v1/topology/node/{id},DELETE /api/v1/topology/line/{id},GET /api/v1/topology/snap-data,GET /api/v1/topology/versions,POST /api/v1/topology/convert-point; отмена и история —GET|POST /api/v1/topology/undo,GET|POST /api/v1/topology/redo,GET /api/v1/topology/history,POST /api/v1/topology/undo-to,GET /api/v1/topology/operations/{id}/check. - Ошибки: 409
version_conflict,blocked,object_mismatch,fragment_required; 422validation(трасса с ошибками); 503 — правка выключена флагами. - Сервер:
database/topology.py(операции,_run— транзакция с журналом),topology_cad.py(трасса, привязка),topology_journal.py(образы строк),topology_history.py,topology_rules.py,topology_dissolve.py,node_types.py,line_types.py. - Веб:
composables/useTopologyEditor.ts(состояние, клавиши, отмена),composables/useTraceDraw.ts,composables/useSnapIndex.ts,composables/useContextSnap.ts;components/EditorToolbar.vue,EditorStatusBar.vue,EditorContextMenu.vue, окнаChainPreviewDialog,SplitPreviewDialog,MergePreviewDialog,ReversePreviewDialog,DeletePreviewDialog,NodeTypeDialog,LineTypeDialog,CoordPointDialog,EditHistoryPanel,TopologyCheckPanel; права инструментов —utils/editorTools.ts, видимость кнопки —canEditTopologyвutils/permissions.ts; запросы —services/api/topology.ts. - Тесты: e2e
e2e/functions/network-editor.spec.ts(трасса, тип узла и линии, разворот, разрез, слияние, удаление, координаты, Ctrl+Z/Ctrl+Y, откат по истории — с проверкой через API и уборкой); модульныеtests/composables/useTopologyEditor.spec.ts,tests/utils/editorTools.spec.ts,topologyEditor.spec.ts,cadSnap.spec.ts; APItests/test_cad_topology.py,test_topology_undo.py,test_history.py,test_topology_rules.py.
