Перейти к содержанию

PetroNet System

Единая платформа мониторинга и управления топливом Монголии

PetroNet объединяет импорт, хранение, распределение и розничную продажу нефтепродуктов Монголии в один поток данных, наблюдает за ним в реальном времени и даёт регулятору, топливным компаниям и водителю одни и те же цифры. Система создаётся для Управления минеральных ресурсов и нефти (АМГТГ) и заменяет действующую систему mpetro — см. системные требования.

PetroNet System — не одно приложение, а экосистема. Водитель, заправка, топливная компания и регулятор делают четыре разные работы, и у каждого своя платформа под эту работу. Под ними у всех — один набор данных, одна идентификация и один журнал аудита.

Монгол  ·  العربية  ·  中文  ·  English  ·  Français  ·  Русский  ·  Español

License Go Version Next.js


Содержание


Задача

В Монголии работают более 200 топливных компаний, свыше 110 хранилищ и более 1500 АЗС. Их данные лежат в двух системах, которые не связаны между собой, и большая часть вводится вручную, раз или два в неделю.

Нет ни одного места, где можно было бы прямо сейчас узнать, сколько литров какого сорта и где находится. Поэтому государственный резерв управляется по оценке, а когда предложение сжимается, остаются только грубые инструменты — чётные и нечётные номера, единый лимит ₮50 000 на заправку, очереди.

Это не только проблема снабжения. Это проблема информации, а такие задачи программное обеспечение действительно умеет решать.

Что делает платформа

Публичная страница
1 Цепочка ответственности — контракт на импорт → таможня → лаборатория → терминал → перевозка → резервуар АЗС → пистолет → потребитель. Каждый литр прослеживается до своей партии. /supply
2 POS для АЗС — слой драйверов, который говорит с колонками и уровнемерами любого производителя, от современного контроллера до импульсного счётчика, и продолжает работать без сети. /stations
3 Ваучеры — права возникают только из топлива, которое физически поступило, и распределяются по близости, потребности и времени ожидания. /vouchers
4 Государственный контроль — запасы, цена, качество, налоги и расхождения на одной панели, поверх журнала аудита, который нельзя переписать. /oversight

Платформа работает в двух режимах на одной инфраструктуре. В кризис она распределяет: лимиты и квоты меняются за минуты, приоритетные категории сохраняют свой резерв, ваучеры выдаются с временным окном. В остальное время она контролирует: мониторинг налогов, цен, качества и запасов, автоматическая сверка «импорт — хранение — продажа», прогноз спроса и сигналы по стратегическому резерву.

Экосистема

Платформа Для кого Что несёт
Платформа для граждан Водители и граждане Ближайшая АЗС, её сорта, уровень запаса, суточное право и ваучер. Опознание — через eID
Портал предприятия Топливные компании Реестр хранилищ и АЗС, остатки в резервуарах, подача и исправление отчётов за период
Командный центр регулятора АМГТГ и инспекторы Суточная национальная сводка, запас в днях, пробелы охвата, расхождения сверки и сигналы
POS и краевой агент АЗС Заправки Пистолеты, резервуары, смены, оплата и чеки поверх локальной базы: продажа не останавливается вместе с сетью
Хранилище и аналитика Аналитики и руководство Ежедневная загрузка из операционных систем, очистка, бизнес-модель, BI и прогноз
Консоль и наблюдаемость Операторы Организации, права и аудит за собственным входом, рядом метрики, сигналы и резервные копии

Под всеми ними — один бинарник Go, одна база и одна идентификация: экосистема здесь означает много рабочих пространств, а не много серверов. Наружу она соединяется с таможней, госреестром, e-Barimt, eID и уровнемерами на объектах.

Ключевое решение

Ваучер — не обещание. Это зарезервированный литр.

Ваучер появляется только после того, как топливо физически поступило в резервуар АЗС и уровнемер подтвердил рост уровня.

Из этого следует две вещи. Система не может пообещать больше, чем у неё есть, — и очереди не вокруг чего образовываться. А АЗС, которая не сообщает о поставках, не порождает ваучеров, и туда никого не отправляют: соблюдение правил обеспечивается конструкцией, а не инспектором.

Цепочка ответственности

Этап Что фиксируется Источник
Импорт Контракт, поставщик, сорт, тоннаж, Incoterms, цена, ожидаемая дата Портал импортёра / API
Граница Номер декларации, код ТН ВЭД, пошлины, пункт пропуска Таможня
Качество Октановое число, плотность, сера, вода, сертификат лаборатории Аккредитованная лаборатория
Метрология Наблюдаемые литры, температура, плотность → литры при 15 °C ASTM D1250 / API MPMS 11.1
Терминал Резервуар, ёмкость, уровень, свободная ёмкость, передача в госрезерв Уровнемеры
Перевозка Автоцистерна, водитель, налив, пункт назначения, GPS-трек, электронная пломба Модуль перевозчика
АЗС Принятый объём, рост уровня, расхождение, принимающий сотрудник Уровнемер + подтверждение
Пистолет Суммарный счётчик, литры и сумма по каждой отпуске, сменные показания Контроллер колонок
Потребитель Право, ваучер, погашение, чек, НДС PetroNet + e-Barimt

Каждый узел сверяется с предыдущим, поэтому расхождение сразу называет, когда, где и в чьей ответственности оно возникло.

Что уже сделано

Это не план, а перечень того, что лежит в репозитории, покрыто тестами и запускалось на настоящем PostgreSQL. Полный список и то, что идёт дальше, — в плане разработки.

  • Реестр хранилищ и АЗС, госномера, статус, проверка через ХУР
  • Справочник продуктов с классификацией JODI, семь сортов
  • Права регулятора и политика уровня строк за ними
  • Политика как данные — лимиты, допуски, сроки, изменяемые без релиза
  • Технический учёт АЗС (классы A–D)
  • Отчётные периоды, подачи, строки и заключения
  • Правила проверки — баланс, непрерывность, ёмкость, отклонение, метрология
  • Приведение объёма к 15 °C (ASTM D1250 / API MPMS 11.1)
  • Версионирование отчётов и хеш-цепочка над ними
  • Выгрузка и загрузка шаблонов Excel
  • Процесс проверки — утвердить, вернуть, «четыре глаза»
  • Движения с госномером, состоянием закрытия и расхождением
  • Национальная суточная сводка, охват, запас в днях
  • Обнаружение непоступивших данных и отчёт о пробелах охвата
  • Сверка ΔA–ΔE
  • Семь отчётов в Excel и CSV, по расписанию и по почте
  • Открытые данные: суточная сводка на /api/v1/petro/public/daily
  • Экран отчётности предприятия и экран регулятора

Как это устроено

PetroNet — дистрибутив уровня 2 платформы Gerege Nexus. Кода ядра в этом репозитории нет: одна строка в go.mod — это всё. Здесь живёт топливная бизнес-логика (modules/petro/) и построенные под неё карта, экраны оператора и публичные страницы (frontend/).

Модуль регистрирует свои маршруты, меню, права и миграции через публичный контракт pkg/nexus и компилируется в один бинарник Go. Идентификация, мультиарендность, RBAC, SSO, отчётность и журнал аудита приходят с платформы и здесь не переписываются.

Установка аутентифицирует людей сама: собственный вход, собственный OIDC-issuer, собственная база. Граждан опознаёт eID Mongolia, а не пароль, который системе пришлось бы хранить.

Структура репозитория

main.go                   Регистрирует модуль petro и запускает хост платформы
modules/petro/            Топливный модуль: реестр, отчёты, надзор, ваучеры
  migrations/             SQL этого модуля, одна история
cmd/petro-import/         Импортёр существующих данных mpetro
catalog/                  Каталог приложений, манифесты и хроника версий
frontend/                 Веб-клиент на Next.js — публичный сайт, карта, экраны
deploy/                   Dockerfile, compose-стек, мониторинг, резервные копии
nginx/                    Шесть виртуальных хостов этой установки
docs/                     Эта документация, на семи языках

Быстрый старт

Требуется Go 1.26+, Node.js 20+, PostgreSQL 16+ (или Docker).

# Всё сразу
docker compose -f deploy/docker-compose.yml up -d

# Или только API
go run .

# И веб-клиент
cd frontend && npm ci && npm run dev

Веб-клиент отвечает на http://localhost:3000.

Установка без организации отправляет любого посетителя на /setup. Токен, который спрашивает мастер, один раз пишется в лог API при запуске:

docker logs petronet2_backend 2>&1 | grep -i "setup token"

Конфигурация

Полный список — в .env.example. Значения, определяющие поведение установки:

Переменная Описание
PUBLIC_ORIGIN Где отвечает этот экземпляр. Задаёт CORS, OIDC-issuer и адрес возврата eID в одном месте
PETRONET_POSTGRES_PASSWORD Собственная база этого стека
SSO_DEFAULT_CLIENT_SECRET Без него платформа не стартует в production
BRAND_* Название, описание, цвета и значки установки
SERVICE_URL_* Адреса консоли, хранилища данных, резервных копий, мониторинга и документации. На главной рисуются только заданные
EID_RP_UUID / EID_RP_SECRET Пара relying-party для eID. Без неё вход по eID недоступен
CONTROL_PLANE_HOST Имя хоста, на котором отвечает консоль оператора, и только оно
PROMETHEUS_URL Откуда консоль читает состояние платформы

Развёртывание

На production-хосте лежит /opt/petronet-v2/ — src/ (git-checkout этого репозитория), .env (chmod 600) и brand/. git pull там никто не запускает: единственный путь в production — git → CI → self-hosted runner на хосте:

commit → PR → main → CI (ci.yml) ✓ → Deploy (deploy.yml)
  → self-hosted runner: deploy/ci-deploy.sh <sha>   # git reset --hard <sha>
  → ./deploy.sh                                     # build, migrate, verify, rollback

deploy.sh собирает из этого репозитория оба образа — backend и web, — поэтому API, карта и экраны оператора всегда выходят одной ревизией.

Рядом стоят шесть имён: платформа (petronet.mn), консоль оператора (admin.), мониторинг (monitor.), карта хранилища данных (dwh.), эта документация (docs.) и описание резервных копий (backups.). Что каждое из них означает и какие ловушки есть в конфигурации nginx — в документе этой установки.

Тестирование

go vet ./... && go test -race ./...     # Go: модульные и интеграционные с PostgreSQL
cd frontend && npm test && npm run build

CI выполняет и то и другое на каждый push и pull request и собирает оба Docker-образа.

Безопасность

  • Токены сессии — случайные 256-битные значения; хранится только их SHA-256.
  • Пароли хешируются bcrypt, попытки входа ограничены по частоте.
  • Данные арендатора изолированы ролью БД, контекстом арендатора и row-level security на объявленных таблицах. Доступ регулятора — политика в SQL, а не проверка в обработчике.
  • Версии отчётов связаны хешем, поэтому утверждённую подачу нельзя отредактировать так, чтобы цепочка этого не показала.
  • У консоли оператора собственная идентификация, cookie, журнал аудита и роль БД, и отвечает она только на CONTROL_PLANE_HOST.

О найденных уязвимостях сообщайте так, как описано в SECURITY.md.

Указатель документации

Документ Описание
Центр документации Все документы и переводы
Системные требования Что потребовал заказчик
План разработки Что сделано, что дальше и критерии приёмки
Мировые практики Как это решали другие страны и что не сработало
Эта установка Имена хостов, порты, резервные копии — только этот хост
Архитектура Плоскости, схемы, изоляция данных
Написание модуля Контракт pkg/nexus
Эксплуатация Развёртывание, мониторинг, резервирование и восстановление
Инструкции Когда что-то сломалось
Перевод Языковая политика и генератор
Участие · Безопасность · Кодекс поведения Правила проекта

Лицензия

Copyright (c) 2026 Gerege Systems Development Team, Gerege Nomadica Foundation. Распространяется по лицензии Apache 2.0 — см. LICENSE.

Иконки флагов — Flaticon (атрибуция).