Архитектурын тодорхойлолт
Gerege Nexus-ийн систем архитектур, давхаргууд ба
техникийн шийдвэрүүд. Төсөл нь Gerege Template Platform
(open-gerege-mn-erp) загварын суурин дээр баригдсан.
1. Системийн ерөнхий архитектур
Gerege Nexus нь өндөр бүтээмжтэй, Монгол Улсын цахим дэд бүтэцтэй нягт холбогдох боломжтой Modular Monolith ERP & бизнес аппликейшн платформ юм.
1.1 Өндөр бүтээмжтэй модуль монолит
- Zero-latency execution — бизнес модулиуд
(
contacts,products,inventory,billing,documents,developer_portal,gov_services,esign,ledger,office) нь Go хэлнийModuleконтрактыг хэрэгжүүлж, нэг бинарид компиллогдоно. - Тенант бүрийн апп стор — модуль тус бүр тенантад
идэвхтэй эсэхийг PostgreSQL (
app_installations) динамикаар шийднэ. - DAG хамаарал шийдвэрлэлт — Directed Acyclic Graph ба semver ашиглан модулийн хамаарлыг мөчлөг үүсгэхгүйгээр тооцоолно.
- Каталогийн синк —
catalog/apps.jsonцорын ганц эх сурвалж бөгөөдappsхүснэгт ачаалал бүрт түүнээс шинэчлэгдэнэ.
1.2 Cloud-native тэсвэрлэлт (go-zero-оос санаа авсан)
- Adaptive circuit breaker
(
resilience/breaker.go) — Google SRE-ийн гулсах цонхон дээрх алдааны харьцаагаар хүсэлтийг татгалзана. Үндэсний үйлчилгээний live дуудлага бүрobservability.Guard-аар үйлчилгээ тус бүрийн breaker-ээр хамгаалагдана (dan/eid/ebarimt/xyp/esign). - Adaptive load shedding
(
resilience/loadshedder.go) — зэрэг ажиллах хүсэлтийн тоо хэтэрвэл503 Service Unavailableбуцаана. - Exponential backoff retry
(
resilience/retry.go) — түр зуурын алдаанд давтан оролдоно.
1.3 Төрийн мэдээлэл солилцоо ба танилт нэвтрэлт
- ХУР систем — иргэний бүртгэл
(
WS100101), хуулийн этгээдийн мэдээлэл (WS100201). - ДАН ба E-ID (
eidmongolia.mn,developer.gerege.mn) — тоон гарын үсэг, Mobile OTP, банкны SSO, царай танилт. - OAuth2 / OIDC provider
(
/.well-known/openid-configuration) — платформын өөрийн бие даасан танилтын сервер: authorization code + PKCE (зөвхөн S256), RS256 id_token ба JWKS, эргэлддэг refresh token, зөвшөөрлийн дэлгэц. Гадаад апп нь энэ гарцаар л хүнийг таньдаг — платформ бусдын кодыг ажиллуулдаггүй.
Mock горим нь зөвхөн хөгжүүлэлтийн орчинд ажиллана.
ENVIRONMENT=productionүед автоматаар унтарна.
2. Системийн бүтцийн диаграм
+-----------------------------------------------------------------------------------+
| Gerege Nexus |
+-----------------------------------------------------------------------------------+
|
+-------------------------+-------------------------+
| |
+-------------------+ +-------------------+
| Next.js 16 Client | | Go 1.26 Backend |
| (App Router) | | (Chi Router) |
+-------------------+ +-------------------+
| |
+-------+-------+ +-------+-------+
| | | |
+---------------+ +---------------+ +---------------+ +---------------+
| AI Copilot UI | | E-ID / DAN | | Cloud-Native | | State Exchange|
| Drawer Panel | | SSO Provider | | Resilience | | (xyp.gerege) |
+---------------+ +---------------+ +---------------+ +---------------+
|
+---------------+
| Schema-per- |
| tenant Postgres|
+---------------+
3. Хүсэлтийн урсгал
- Дундын middleware — логлолт, panic сэргээлт, load shedding, Prometheus хэмжүүр, аюулгүй байдлын толгойнууд, CORS.
- Танилт — session токеныг cookie эсвэл
Authorization: Bearerтолгойгоос уншиж,sessionsхүснэгтээс шалгана. Токен нь өгөгдлийн санд SHA-256 хэш хэлбэрээр хадгалагдана. - Тенантын контекст —
tenant_idнь Go context-д шингэнэ. Холболт бүрийгplatform/dbguardтэр tenant-ийн schema-д уяна (search_path = tenant_<id>, public), тиймээс тусгаарлалт нь шүүлтүүрийн бус физик шинжтэй. Бүх business асуулгаWHERE tenant_id-гаа хадгалсаар — энэ нь эхний давхарга. - Апп хаалт — модулийн маршрут бүр
app_installationsдээрх төлөвөөр шалгагдана; суулгаагүй бол403 Forbidden. - Модулийн handler — бизнес логик, өгөгдлийн сангийн гүйлгээ.
4. Өгөгдлийн загварын үндсэн хүснэгтүүд
| Хүснэгт | Зориулалт |
|---|---|
tenants, users,
memberships |
Олон тенант, хэрэглэгчийн харьяалал |
roles, permissions,
role_permissions, membership_roles |
RBAC эрхийн загвар |
sessions |
Сервер талын session токен (SHA-256 хэш) |
apps, app_installations,
installation_events |
Апп стор ба суулгалтын түүх |
contacts, products,
warehouses, stock_levels,
stock_movements |
Үндсэн бизнес өгөгдөл |
billing_invoices, billing_payments,
billing_allocations, document_records |
Нэхэмжлэх, төлбөр, хуваарилалт ба цахим баримт |
oauth2_clients |
OAuth2 client аппликейшнүүд |
ai_prompts, ai_knowledge |
Тенантын AI тохиргоо ба мэдлэгийн сан (миграц
00005) |
gov_services, gov_applications,
gov_application_events, gov_appointments |
Төрийн үйлчилгээний бүртгэл, хүсэлт, цаг захиалга (миграц
00006) |
gov_org_units, gov_unit_members,
gov_workflows, gov_workflow_versions,
gov_workflow_steps, gov_workflow_transitions,
gov_routing_rules, gov_tasks,
gov_upstream_connectors,
gov_delivery_outbox |
Тохируулгат workflow хөдөлгүүр — tenant-ийг багтаасан composite
FK-ууд хөндлөн тенант холбоосыг хаана (миграц 00007) |
access_change_events |
Эрхийн өөрчлөлтийн аудит бүртгэл (миграц 00008) |
esign_documents, esign_signature_logs,
esign_cert_checks |
PDF цахим гарын үсэг, сертификатын шалгалт (миграц
00009, 00011) |
audit_events, national_identity_links |
Аудитын мөр, үндэсний танилтын холбоос (миграц
00010) |
oauth2_tokens |
OAuth2 access токен (зөвхөн digest, миграц 00015;
tenant_id нь 00047-д) |
oauth2_authorization_codes,
oauth2_refresh_tokens, oauth2_consents,
oauth2_signing_keys |
Authorization code урсгал: нэг удаагийн код, эргэлддэг refresh
хэлхээ, хүн тус бүрийн зөвшөөрөл, шифрлэгдсэн гарын үсгийн түлхүүр
(миграц 00047) |
platform_events |
Модуль хоорондын event outbox — producer-ийн transaction дотор
бичигдэж, in-process poller at-least-once дамжуулна (миграц
00035) |
ledger_accounts, journal_entries,
journal_lines |
Давхар бичилтийн, зөвхөн нэмэгддэг ерөнхий журнал; цуцлалт = сөрөг
бичилт (миграц 00039) |
webhook_endpoints, webhook_deliveries |
Тенантын webhook төгсгөл ба найдвартай хүргэлтийн бүртгэл + дахин
оролдлого (миграц 00040) |
platform_admins |
Платформын операторууд — tenant-аас дээш эрх; олголт бүр аудитлагдах
мөр (миграц 00041) |
tenants.status |
active / suspended — платформын
түдгэлзүүлэлт (миграц 00041) |
sessions.impersonated_tenant_id,
sessions.impersonation_reason |
Платформын операторын түр (30 мин) session; tenant_id
нь NULL хэвээр тул гишүүнчлэлийн FK-д өртөхгүй (миграц
00042) |
office_documents |
Office модулийн docx/xlsx файлууд, хадгалалт бүрд
version ахина (миграц 00044, tenant план
0003) |
Хаана байрлана: platform_events,
webhook_endpoints/deliveries нь дарааллын дэд бүтэц тул
public-д үлддэг (2 секундын poller-ууд бүх tenant-ийн ажлыг
нэг query-гээр олох ёстой). Бусад бизнес хүснэгтүүд tenant бүрийн
tenant_<uuid> schema-д; identity/RBAC/апп стор/аудит
нь public-д.
Дэлгэрэнгүйг DATABASE_SCHEMA.md-аас үзнэ
үү.
Бүх схемийн өөрчлөлт goose миграцаар хийгдэх бөгөөд хоёр
план-тай: backend/db/migrations/control/ (public —
identity, RBAC, апп стор, аудит, дараалал) ба
backend/db/migrations/tenant/ (tenant schema бүрд
хэрэглэгдэх business хүснэгтүүд). Бизнес хүснэгтийн өөрчлөлт хоёуланд нь
орно. Ажиллах үед DDL гүйцэтгэхийг хориглоно.
4.1 Гадаад үйлчилгээний хил (External service boundary)
Дараах системүүд нь биднээс хамаарахгүй гадаад service worker-ууд бөгөөд платформ зөвхөн клиентээр нь холбогдоно — бид тэдгээрийн дотоод логикийг хэзээ ч өөрсдөө хэрэгжүүлэхгүй:
| Үйлчилгээ | Клиент | Үүрэг |
|---|---|---|
| ХУР (XYP) | platform/gerege/xyp.go |
Төрийн мэдээлэл солилцоо |
| E-ID / ДАН | platform/eid, platform/dan |
Үндэсний танилт нэвтрэлт |
| Gerege eSign HSM | platform/gerege/esign.go |
Тоон гарын үсэг (PKCS#7) |
| e-Barimt | platform/ebarimt (PosAPI 3.0) + billing-ийн асинхрон
submitter |
Татварын баримт (ДДТД, сугалаа) |
Клиент бүрийн гэрээ: (1) mock горим config.MockEnabled
дүрмээр — production-д анхдагчаар унтраастай; (2) дахин оролдлого нь
алдааны ангилалтай (зөвхөн transport/5xx; 4xx болон бизнес няцаалт
давтагдахгүй); (3) context cancellation-ийг мөрдөнө; (4)
national_service_calls_total ба
national_service_mock_mode метрик гаргана. Эдгээрээс
бусад бүх зүйлийг бид өөрсдөө бүтээнэ — платформын
зорилго нь шинэ бизнес апп-уудыг чөлөөтэй, хурдан үүсгэх суурь байх
(make new-app scaffolding, MODULE_AUTHORING_GUIDE.md).
4.2 Модуль хоорондын харилцаа
Апп-ууд нэг бинарид байдаг ч бие биеийнхээ хүснэгт рүү шууд ханддаггүй. Тогтсон гурван суваг:
| Суваг | Хэзээ | Жишээ |
|---|---|---|
| Master data сервис дуудлага (шууд, синхрон) | Өөр модулийн лавлагаа шаардлагатай үед | billing → contacts.Service.Get (нэхэмжлэх
дээрх харилцагч) |
| Snapshot | Хуулийн ач холбогдолтой утга баримт дээр хөлдөх ёстой үед | Нэхэмжлэх дээрх харилцагчийн нэр — сүүлд солигдсон ч өөрчлөгдөхгүй |
Event bus (platform/events) |
Модуль өөрийн үйлдлээ зарлаж, бусад нь урвал үзүүлэх үед | Publish (producer-ийн transaction ДОТОР outbox мөр
бичнэ) ба PublishOutside (гүйлгээний гадна), хоёулаа
platform_events outbox + poller, at-least-once. Нийтлэгч:
billing (invoice.created,
invoice.cancelled, credit_note.created,
payment.posted, payment.cancelled — тус бүр
өөрийн гүйлгээнд, тул зөвхөн нэг нь бичигдэх цонх байхгүй),
esign (document.signed),
documents (signed/approved).
Хэрэглэгч: ledger нь тавуулангийнх нь subscribe хийж
балансласан журнал бичнэ (нэхэмжлэх: DR авлага; төлбөр: DR касс/харилцах
— CR авлага, мөнгө хөдөлсөн өдрөөр; цуцлалт: буцаах
бичилт; залруулга: буцаалт биш өөрийн бичилт — DR
борлуулалт + DR НӨАТ / CR авлага), SubscribeAll нь бүх
event-ийг тенантын webhook рүү дамжуулна.
PublishSync устгагдсан (2026-08-21): тэр
нь зөвхөн төрлөөр индексжсэн handler-уудыг дуудаж
SubscribeAll-ыг алгасдаг байсан тул «найдвартай» гэж
сонгосон event бүрийн webhook чимээгүй унтардаг байв |
Тенантын webhook
(platform/webhook) |
Гадаад тенантын систем рүү мэдэгдэх үед | Bus-ийн SubscribeAll-оор бүх event-ийг тенантын
бүртгэсэн төгсгөл рүү найдвартай хүргэнэ (өмнөх in-memory
integration.Manager-ийг орлосон) |
Capability discovery
(appregistry) |
Модуль өөр модулийн боломжийг import хийлгүй interface-ээр олох үед | FindCapability[T]() /
FindCapabilities[T]() — inventory нь
internal.StockAvailability хэрэгжүүлдэг; провайдер байхгүй
бол "алга" буцаана |
| Transactional outbox (асинхрон) | Гадаад систем рүү тусгайлан дамжуулах үед | gov_delivery_outbox → дээд систем;
billing_invoices → e-Barimt |
Хамаарал нэг чиглэлтэй: master data модулиуд (contacts,
products) графын хамгийн доор, тэд дээшээ хамаардаггүй.
Хэрэглэгч модуль өөрт хэрэгтэй нарийн интерфэйсээ өөрөө зарлана
(consumer-defined interface).
Дэлгэрэнгүй үндэслэл: RESEARCH_ERP_MODULARITY.md.
5. Архитектурын шийдвэрүүд
| Шийдвэр | Шалтгаан |
|---|---|
| Микросервис биш модуль монолит | Процесс доторх дуудлага нь сүлжээний хоцролтгүй; модулийн хил нь Go интерфейсээр хангагдана |
ORM ашиглахгүй (pgx + гар бичмэл SQL) |
Асуулгыг тодорхой, оновчтой байлгах; далд N+1-ээс сэргийлэх |
| Schema-per-tenant олон тенант | Бизнес хүснэгт tenant бүрийн tenant_<uuid>
schema-д, control хүснэгт public-д. dbguard
холболт бүрийг хүсэлтийн tenant-аар search_path-д уяна —
тусгаарлалт нь шүүлтүүрийн бус физик. Аппликейшны
WHERE tenant_id эхний давхарга хэвээр. Миграц
00037-ийн RLS бодлогууд DB-д хэвээр (буцах зам), гэхдээ
binary тэдгээрээс хамаарахаа больсон |
| Каталог файл нь эх сурвалж | Апп нэмэхэд SQL гараар бичихгүй; apps хүснэгт
автоматаар синк болно |
| Opaque session токен | JWT-ийн цуцлах боломжгүй байдлаас зайлсхийж, шууд хүчингүй болгоно |
6. Хариуцагчид
- Gerege Systems Development Team (@gerege-systems)
- Gemini AI, Claude AI