Архитектурын тодорхойлолт

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. Хүсэлтийн урсгал

  1. Дундын middleware — логлолт, panic сэргээлт, load shedding, Prometheus хэмжүүр, аюулгүй байдлын толгойнууд, CORS.
  2. Танилт — session токеныг cookie эсвэл Authorization: Bearer толгойгоос уншиж, sessions хүснэгтээс шалгана. Токен нь өгөгдлийн санд SHA-256 хэш хэлбэрээр хадгалагдана.
  3. Тенантын контекстtenant_id нь Go context-д шингэнэ. Холболт бүрийг platform/dbguard тэр tenant-ийн schema-д уяна (search_path = tenant_<id>, public), тиймээс тусгаарлалт нь шүүлтүүрийн бус физик шинжтэй. Бүх business асуулга WHERE tenant_id-гаа хадгалсаар — энэ нь эхний давхарга.
  4. Апп хаалт — модулийн маршрут бүр app_installations дээрх төлөвөөр шалгагдана; суулгаагүй бол 403 Forbidden.
  5. Модулийн 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 сервис дуудлага (шууд, синхрон) Өөр модулийн лавлагаа шаардлагатай үед billingcontacts.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. Хариуцагчид