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

Gerege Nexus

Production · Слой 3 — Платформенная основа · Репозиторий: open-gerege-nexus · nexus.gerege.mn

Единая платформа услуг, операций и систем. Модульная платформа, которая сводит услуги, операции, системы и данные государственных и частных организаций на одну основу. Открытый исходный код, лицензия Apache 2.0.

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

Модель экосистемы меняется

Gerege Nexus — преемник Template Platform. Прежняя модель была «один шаблон → форк под каждый продукт»; новая — «один upstream (Nexus) → форк под каждый бренд, обновляемый слиянием из upstream». Переход идёт прямо сейчас — существующие платформы остаются в production. См. Слоистая архитектура.

Главное отличие: приложение — это модуль

В прежней модели новый продукт означал новый репозиторий, новое развёртывание и новую базу данных. В Nexus новый продукт — это, как правило, новый модуль: приложение, скомпилированное в тот же бинарник, которое каждый арендатор может включить или выключить.

Модель Template (прежняя) Модель Nexus (новая)
Новый продукт Форк шаблона Написать модуль и добавить в каталог
Распространение По одному развёртыванию на репозиторий По арендаторам, через магазин приложений
Общий код Пакеты open-gerege-core + @gerege/ui-core Один upstream; форки сливают из него
Вызовы между модулями HTTP (когда репозитории разные) Внутрипроцессные вызовы Go
Включение / выключение Требует развёртывания Решает администратор в app_installations

Модульный монолит

Бизнес-модули реализуют Go-контракт Module и компилируются в один бинарник. Какие приложения активны у конкретного арендатора, динамически определяет таблица app_installations в PostgreSQL.

  • Никаких дополнительных сетевых вызовов — модули вызывают друг друга внутри процесса, поэтому не возникает ни задержек микросервисов, ни сложности оркестрации.
  • Разрешение зависимостей по DAG — зависимости модулей вычисляются рекурсивно по направленному ациклическому графу, с обнаружением циклов и проверкой semver.
  • Синхронизация каталогаcatalog/apps.json является единственным источником истины; таблица apps обновляется из него при каждой загрузке. Добавление приложения не требует SQL вручную.
  • Шлюз приложений — маршрут неустановленного приложения отвечает 403 Forbidden.

Почему не микросервисы?

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

Готовые модули

Модуль ID Путь Назначение
Contacts io.example.contacts /contacts Справочник контрагентов, автозаполнение из ХУР / XYP
Products io.example.products /products Товары, цены, SKU в рамках арендатора
Inventory io.example.inventory /inventory Склады, остатки, журнал движений «только добавление»
Billing & e-Barimt io.example.billing /billing Счета, НДС 10%, чеки e-Barimt
Digital Documents io.example.documents /documents Электронные документы и процессы согласования
Developer Portal io.example.developer_portal /developer/apps Регистрация OAuth2-клиентов
PDF E-Sign io.example.esign /esign Юридически значимая подпись через eID Mongolia (PIN2)
Государственные услуги io.example.gov_services /gov Настраиваемый процесс услуги, иерархия, SLA

Настраиваемый процесс государственной услуги

Модуль gov_services превращает одну кодовую базу в механизм оказания услуг, который каждый арендатор — и каждая услуга внутри арендатора — настраивает под себя. Выбор одного из трёх режимов не требует изменений кода:

Режим Смысл
LOCAL Принявшее подразделение выполняет заявку само
DELEGATE Передаётся нижестоящему подразделению, вышестоящее контролирует и подтверждает
HYBRID Правило маршрутизации решает по каждой заявке

Ведущий принцип — код решает, что возможно, конфигурация решает, что предлагается. Каноническая таблица переходов находится в коде; опубликованная версия может её сузить, но никогда не расширить. Поэтому неверно настроенный арендатор не может достичь невозможного состояния.

Другие гарантии:

  • Статус вычисляется на сервере — клиент отправляет действие, а не статус.
  • Завершение работы нижестоящим подразделением не закрывает заявку — если шаг требует проверки, завершение попадает в AWAITING_VERIFICATION.
  • Просрочка выводится (due_at < now()), а не записывается поверх бизнес-статуса.
  • Изоляция арендатора и подразделения — на уровне схемы: каждый внешний ключ составной, включая tenant_id, поэтому строка не может указывать в чужого арендатора даже при ошибке в коде.
  • Идемпотентный приём — входящая заявка идентифицируется по (tenant_id, source_system, external_request_id); идентичный повтор вернёт "created": false, а повтор с существенно иным содержимым получит 409.
  • Уведомление наружу — через outbox — удалённый endpoint не может откатить или подвесить переход процесса.

Электронная подпись — eID Mongolia (PIN2)

Модуль esign подключается к квалифицированной удалённой подписи eID Mongolia в роли доверяющей стороны:

  1. PDF хешируется → eID отправляет этот дайджест на телефон гражданина,
  2. гражданин подтверждает по PIN2,
  3. собственный doc-signer eID встраивает PKCS#7 вместе с данными OCSP и CRL и собирает PDF с подписью PAdES.

Закрытый ключ подписи никогда не попадает на платформу. Уровень сертификата по умолчанию — QUALIFIED: принятие ADVANCED молча понизило бы каждый документ, выпущенный платформой.

Подпись от имени организации

Права представительства читаются напрямую из государственного реестра, а не из сертификата — потому что директор, ушедший вчера, по-прежнему владеет вчерашним сертификатом.

Также включены: журнал подписей (фильтры, постраничный вывод, экспорт в CSV), пакетная подпись, размещение штампа с предпросмотром A4, подключение HSM и политика подписи. Арендатор может требовать квалифицированную подпись eID и полностью отключить канал HSM — в том числе для вызовов напрямую к API.

Аутентификация и государственные интеграции

  • Собственный провайдер OAuth2 / OIDC/.well-known/openid-configuration, /oauth2/token, /oauth2/introspect, /oauth2/revoke; поддерживаются authorization_code, client_credentials и refresh_token.
  • eID и ДАН — четыре официальных канала: цифровая подпись (PKI), Mobile OTP, банковский SSO и биометрическая проверка лица.
  • ХУР / XYP — регистрация граждан (WS100101) и проверка юридических лиц (WS100201).
  • Токены сессии непрозрачны, 256 бит, в базе хранится только SHA-256-хеш. Выход из системы отзывает их по-настоящему.

Mock-режим не работает в production

Mock-режимы E-ID / ДАН / ХУР существуют только для разработки. При ENVIRONMENT=production они выключаются автоматически, поэтому войти с вымышленными данными гражданина невозможно.

ИИ и отказоустойчивость

ИИ — ассистент на Gemini, опирающийся на фактическое состояние базы данных арендатора (/api/v1/ai/chat, /stt, /tts, /translate), управляемые администратором подсказки и база знаний, а также прогноз спроса на складе.

Cloud-native отказоустойчивость (по мотивам go-zero):

Компонент Роль
Adaptive circuit breaker Доля отказов в скользящем окне в стиле Google SRE
Adaptive load shedding 503 + Retry-After при превышении параллелизма
Singleflight coalescing Схлопывает дублирующие запросы, предотвращая обвал кеша
Exponential backoff retry Повторы временных сбоев с экспоненциальной задержкой

Языковая политика

Монгольский плюс шесть официальных языков ООН = семь. Монгольский — источник. Документация существует на всех семи, но программное обеспечение поставляется на монгольском и английском, а остальные пять включаются в Настройки → Оформление. Это тот же принцип, что и политика i18n этого сайта.

Бренды, ответвившиеся от него

Nexus — upstream; каждый бренд ответвляется от него и обновляется слиянием.

Бренд Репозиторий Домен В чём отличие
Gerege Nexus open-gerege-nexus nexus.gerege.mn Upstream, эталонное развёртывание
Gerege SSO sso-gerege-nexus Форк, сосредоточенный на слое входа, прав и доступа
Eduge.mn eduge-mn-nexus eduge.mn Бренд сферы образования; несёт overlay для сборки на хосте, когда GHCR недоступен

Два разных «Gerege SSO»

sso-gerege-nexusновый форк на базе Nexus; sso.gerege.mn в production по-прежнему работает на прежнем коде sso-gerege-mn. Не путайте их: до завершения перехода действует поведение, описанное на странице Gerege SSO.

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

Push в main запускает GitHub Actions: сборка и отправка образов backend и frontend в GHCR → копирование docker-compose.prod.yml на сервер → загрузка образов → переключение API и frontend только после завершения миграций → проверка /health и /ready. Развёртывание начинается лишь после того, как CI действительно прошёл.

Серверу не нужно ничего, кроме Docker — ни исходников, ни Go, ни Node.

PUBLIC_ORIGIN задаёт сразу три вещи

CORS, издатель OIDC и callback eID выводятся из одной переменной. Её изменение перемещает DNS, TLS-сертификат и каждого зависящего от издателя клиента вместе. При смене домена используйте контрольный список на странице Аутентификация и права.

Стек

Слой Выбор
Backend Go 1.25 · роутер chi · pgx (без ORM, SQL вручную)
Frontend Next.js 15 App Router
База данных PostgreSQL 16 — общая схема, изоляция по tenant_id
Миграции goose (backend/db/migrations/); DDL во время работы запрещён
Наблюдаемость Prometheus (/metrics) · OpenTelemetry
Контейнеры Docker Compose · GHCR

Общую картину см. на странице Технологический стек.

Подробная документация

Документация уровня реализации находится в репозитории, на семи языках:

Документ Содержание
README.md Обзор платформы (7 языков)
docs/ARCHITECTURE_SPECIFICATION.md Слои и архитектурные решения (MN/EN)
docs/MODULE_AUTHORING_GUIDE.md Как написать новый модуль приложения
docs/GOV_SERVICES_WORKFLOW.md Полная модель процесса государственной услуги
docs/DOCUMENTS_SIGNING.md Церемония подписания и её контракт
docs/TRANSLATION_GUIDE.md Руководство по переводу на семь языков
CHANGELOG.md Изменения по релизам