Тохируулж болох төрийн үйлчилгээний ажлын урсгал

io.example.gov_services нэг кодын суурийг хэрхэн үйлчилгээ хүргэх чадвар болгодог тухай: тенант бүр, түүнчлэн тенант доторх үйлчилгээ бүр өөрийгөө өөрөө тохируулна — өөрийн байгууллагад дотооддоо гүйцэтгэх, баталгаажуулалттайгаар шилжүүлэн даалгах, эсвэл хүсэлт бүрээр чиглүүлэх.


1. Загвар

Ойлголт Хүснэгт Зорилго
Байгууллагын нэгж gov_org_units Тенант тус бүрийн зэргэлдээ жагсаалтын шатлал
Нэгжийн гишүүнчлэл gov_unit_members Хэрэглэгч аль нэгжийн өмнөөс ажилладаг, түүнийг хянадаг эсэх
Ажлын урсгал gov_workflows Нэр бүхий процесс
Ажлын урсгалын хувилбар gov_workflow_versions Нийтэлсэн, өөрчлөгдөшгүй тодорхойлолт
Алхам gov_workflow_steps Дараалал, гүйцэтгэгчийн дүрэм, SLA, баталгаажуулалтын шаардлага
Шилжилт gov_workflow_transitions Төлөвийн машиныг сонголтоор нарийсгах
Чиглүүлэлтийн дүрэм gov_routing_rules Тенант эсвэл үйлчилгээний хүрээнд стратеги сонгох
Үйлчилгээ gov_services Нийтэлсэн хувилбар ба гүйцэтгэлийн горим руу заана
Хүсэлт gov_applications Дээд түвшний үйлчилгээний хүсэлт
Даалгавар gov_tasks Түвшин тус бүрийн гүйцэтгэх ажил
Хугацааны хэлхээ gov_application_events Шилжилт бүрийн зөвхөн нэмэгддэг аудит
Гаралтын хайрцаг gov_delivery_outbox Дээд систем рүү хүргэхийг хүлээж буй төлөвийн шинэчлэлүүд

Гүйцэтгэлийн горимууд

  • LOCAL — хүсэлтийг хүлээн авсан нэгж өөрөө гүйцэтгэнэ.
  • DELEGATE — хүсэлтийг доод нэгж рүү дамжуулж, дээд нэгж нь үр дүнг хянаж баталгаажуулна.
  • HYBRID — чиглүүлэлтийн дүрэм хүсэлт бүрээр эдгээрийн алийг хэрэглэхийг шийднэ.

Үйлчилгээ өөрийн горим ба нийтэлсэн ажлын урсгалын хувилбараа сонгоно; кодод өөрчлөлт оруулах шаардлагагүй.


2. Төлөвийн машин

Даалгаврын төлөвүүд:

RECEIVED → ASSIGNED → IN_PROGRESS ─┬─→ COMPLETED → CLOSED
                                   ├─→ AWAITING_VERIFICATION → COMPLETED
                                   │                        └→ RETURNED → …
                                   ├─→ FORWARDED (delegation; child task opens)
                                   ├─→ INFO_REQUESTED → IN_PROGRESS
                                   ├─→ REJECTED
                                   └─→ CANCELLED

Юу боломжтойг код шийднэ; юуг санал болгохыг тохиргоо шийднэ. Каноник шилжилтийн хүснэгт workflow.go дотор байрлаж, тогтмол зарчмуудыг кодчилдог — баталгаажуулалт хүлээгээгүй ажлыг баталгаажуулж болохгүй, төгсгөлийн төлөвт байгаа даалгаварт үйлдэл хийж болохгүй. Нийтэлсэн хувилбар нь тэр багцыг gov_workflow_transitions-ээр нарийсгаж болно; хэзээ ч өргөтгөж чадахгүй. Энэ нь тогтмол зарчмуудыг өгөгдлийн сангүйгээр unit-тест хийх боломжтой байлгаж, буруу тохируулсан тенант боломжгүй төлөвт хүрч чадахгүй гэсэн үг.

Хаана ч үйлчлэх дүрмүүд:

  • Үр дүнгийн төлөвийг сервер тал тооцоолно. Клиент үйлдэл илгээнэ, төлөв хэзээ ч биш.
  • reject, return, request_info-г тайлбаргүйгээр татгалзана.
  • Алхам requires_verification-г тохируулсан бол гүйцэтгэл AWAITING_VERIFICATION төлөвт орно, ингэснээр доод нэгж ажлаа дуусгасан ч нийт хүсэлтийг хаадаггүй. Эцэг нь хүүхэд баталгаажих хүртэл FORWARDED хэвээр байна.
  • Хугацаа хэтэрсэн эсэхийг гаргаж авдаг (төгсгөлийн бус төлөвт due_at < now()), бизнесийн төлөв дээр хэзээ ч дарж бичдэггүй.
  • Шилжилт бүр нэг гүйлгээ: даалгаврын шинэчлэл, хугацааны хэлхээний үйл явдал, эцэг рүү дамжих каскад, гаргаж авсан хүсэлтийн төлөв, гаралтын хайрцгийн мөр бүгд хамт commit хийгдэнэ.

Зэрэгцээ ажиллагаа

gov_tasks.row_version нь үйлдэл бүрт шаардагдаж, шинэчлэлтийг хамгаална. Нэг даалгавар дээр ижил уншилтаас гарч ажилласан хоёр ажилтан нэг ялагч, нэг CONFLICT_VERSION гаргана — алдагдсан шинэчлэл хэзээ ч биш.


3. Тенант ба байгууллагын тусгаарлалт

Тусгаарлалтыг зөвхөн query-д биш, схемд албаддаг. Нэгж, ажлын урсгалын хувилбар эсвэл хүсэлтийг лавладаг хүснэгт бүр tenant_id-г агуулсан нийлмэл гадаад түлхүүр-тэй тул програмын кодод алдаа гарсан ч мөр тенант дамжин зааж чадахгүй:

CONSTRAINT gov_tasks_unit_fk FOREIGN KEY (unit_id, tenant_id)
    REFERENCES gov_org_units (id, tenant_id)

Тенант дотор:

  • Хэрэглэгчийн хамрах хүрээ нь gov_unit_members дэх нэгжүүд; SUPERVISOR нь өөрийн нэгжийн бүх удам залгамжлагчийг мөн хамарна.
  • Дараалал ба хяналтын самбарын query-үүд тэр хамрах хүрээг SQL-д хэрэглэдэг тул хуудаслалт хилээ давж алхаж чадахгүй.
  • Нэгжид хуваарилагдаагүй хэрэглэгч тенантыг биш, хоосон дараалал харна.
  • Тенантын администраторуудыг бүхэл тенантаар хязгаарлана.
  • verify болон return-г дээд түвшин хэрэгжүүлдэг тул эцэг даалгаврын нэгжийн эсрэг шалгадаг.

4. Чиглүүлэлт

Стратеги Сонгодог зүйл
SELF Одоогийн нэгж
PARENT Дээд нэгж (үндэс дээр амжилтгүй болно)
CHILD Хүүхэд нэгж; хэд хэд байвал ойлгомжгүй тул дуудагч аль нэгийг нэрлэнэ
SPECIFIC_UNIT Тохируулсан нэгж
REGION_MATCH region_code нь хүсэлтийн талбартай таарах нэгж

Стратеги бүр нь тодорхой салаа. Илэрхийллийн үнэлэгч байхгүй тул тенантын тохиргоо платформыг дурын оролт үнэлүүлж хэзээ ч чадахгүй. Дүрмүүдийг эрэмбээр эрэмбэлдэг ба тэнцүү эрэмбэд үйлчилгээний хүрээний дүрэм тенант хэмжээний дүрмээс давуутай.


5. Дээд системээс хүлээн авах

POST /api/v1/gov/requests/ingest
{
  "source_system": "E-MONGOLIA",
  "external_request_id": "EM-2026-000123",
  "service_code": "PASSPORT",
  "applicant_name": "Бат Болд",
  "fields": { "region": "UB-NORTH" }
}

Идемпотентийн гэрээ

  • Таних тэмдэг нь (tenant_id, source_system, external_request_id), unique индексээр албадагдана.
  • Ижилхэн дахин оролдлого нь одоо байгаа хүсэлтийг "created": false-той буцаах бөгөөд хоёр дахь даалгавар, хоёр дахь хугацааны хэлхээний бичлэг үүсгэхгүй.
  • Ижил таних тэмдэгтэй боловч агуулгаараа мэдэгдэхүйц өөр payload авчирсан давталтыг 409 IDEMPOTENCY_CONFLICT-оор татгалзана. "Өөр" гэдэг нь каноник талбарын багц дээрх өөр SHA-256 гэсэн үг бөгөөд payload_fingerprint болгож хадгалагдана.

Нэвтрэлт танилт. Энэ endpoint нь платформын session/bearer middleware, аппын хаалга ба gov.apply эрхийн ард ажиллана. Үүнийг OAuth2 client credentials-тэй холбох (машин клиентүүдийг ажилтнаас ялгах боломжтой болгох) нь санаатайгаар хойшлуулсан цорын ганц алхам — §8-г үз.


6. Төлөв хүргэх зааг

Алсын endpoint нь ажлын урсгалын шилжилтийг буцааж эргүүлэх, эсвэл зогсоох ёсгүй тул хүргэлтийг салгасан:

  1. Төлөвийн өөрчлөлт нь gov_delivery_outboxнэг гүйлгээний дотор мөр бичнэ.
  2. gov_upstream_connectors нь эх систем тус бүрийн зорилтот URL ба secret_ref — гарын үсгийн нууцыг эзэмшиж буй коннекторын нэр-ийг хадгална. Нууц өөрөө гаралтын хайрцагт хэзээ ч хадгалагдахгүй, API-аар хэзээ ч буцаагдахгүй, лог-д хэзээ ч бичигдэхгүй.
  3. GET /api/v1/gov/outbox нь хүргэлтийн төлөвийг (payload-гүйгээр) операторуудад харуулна.

Илгээх ажлыг worker framework нэмэхийн оронд дуудагчид — cron бичлэг эсвэл платформын хуваарьлагчид — санаатайгаар үлдээсэн.


7. Тохиргооны жишээнүүд

Дотооддоо гүйцэтгэх

// 1. Create and publish the template
POST /api/v1/gov/workflows        { "template": "LOCAL_FULFILMENT" }
POST /api/v1/gov/workflow-versions/{id}/publish

// 2. Point the service at it
PUT  /api/v1/gov/services/{serviceId}/configuration
{ "fulfillment_mode": "LOCAL", "workflow_version_id": "…", "owner_unit_id": "…" }

Дараа нь хүсэлт эзэмшигч нэгж дээр нэг даалгавар нээнэ: RECEIVED → IN_PROGRESS → COMPLETED → CLOSED.

Баталгаажуулалттай шилжүүлэн даалгах

POST /api/v1/gov/workflows        { "template": "DELEGATE_ONE_LEVEL" }
POST /api/v1/gov/workflow-versions/{id}/publish
PUT  /api/v1/gov/services/{serviceId}/configuration
{ "fulfillment_mode": "DELEGATE", "workflow_version_id": "…", "owner_unit_id": "<HQ>" }

Урсгал: төв хүлээн авна → delegate (дүүрэгт хүүхэд даалгавар нээгдэж, төв нь FORWARDED болно) → дүүрэг гүйцэтгэнэ → хүүхэд AWAITING_VERIFICATION болно → төв verify хийнэ → хүүхэд COMPLETED → төв COMPLETEDclose.

Баталгаажуулахын оронд буцаах нь хүүхдийг дахин боловсруулахаар RETURNED төлөвт оруулна.


8. Миграц ба нийцтэй байдал

00007_gov_workflow.sql миграц нь нэмэлт шинжтэй. Одоо байгаа үйлчилгээ, хүсэлт, хугацааны хэлхээ, цаг захиалгууд мөрөө хадгална.

Модулийг аль хэдийн ашиглаж буй тенант бүрийн нөхөн дүүргэлт:

  1. HQ үндэс нэгж үүснэ.

  2. LEGACY_LOCAL ажлын урсгал үүсч, ганц FULFILL алхам өгөгдөж нийтлэгдэнэ.

  3. Тохиргоогүй үйлчилгээнүүдийг LOCAL горимоор түүн рүү зааж чиглүүлнэ.

  4. Одоо байгаа хүсэлт бүр төлөвөө агуулсан яг нэг даалгавар авна:

    gov_applications.status gov_tasks.status
    SUBMITTED RECEIVED
    IN_REVIEW IN_PROGRESS
    INFO_REQUESTED INFO_REQUESTED
    APPROVED COMPLETED
    REJECTED REJECTED
    COMPLETED CLOSED
    CANCELLED CANCELLED

Үнэний нэг эх сурвалж. gov_tasks нь төлөвийг эзэмшинэ. gov_applications.status нь анхны клиентүүдийн уншдаг нийцтэй байдлын талбар хэвээр үлдэх бөгөөд syncApplication-аар үндэс даалгавраас нэг гүйлгээний дотор гаргаж авдаг — хоёул хэзээ ч зөрж чадахгүй.

Анхны endpoint-ууд (/services, /applications, /applications/{id}/…, /appointments, /officer/queue) ажилласаар байх бөгөөд одоо доор нь ижил төлөвийн машиныг ажиллуулна: хуучин хэлбэрийн илгээлт даалгавар нээж, хуучин хэлбэрийн шийдвэрийг ажлын урсгалын үйлдэл болгон хөрвүүлнэ.

Хойшлуулсан: /requests/ingest-г OAuth2 client credentials-тэй холбох. Платформ opaque токен олгож /oauth2/introspect-г нээж өгдөг тул үлдсэн ажил нь bearer токеныг introspect хийж, клиентийг тенант руу шийдвэрлэж, машин актор оруулдаг middleware юм. Түүнийг хийх хүртэл endpoint нь gov.apply-тай баталгаажсан принципал шаардана.


9. Эрхүүд

Эрх Олгодог зүйл
gov.read Бүртгэл, хүсэлтүүд, дараалал, нэгжийн мод
gov.apply Хүсэлт илгээх, хүлээн авах, цуцлах
gov.process Хуваарилах, эхлүүлэх, гүйцэтгэх, татгалзах, хаах
gov.delegate Доод нэгж рүү дамжуулах
gov.verify Доод нэгжийн ажлыг баталгаажуулах эсвэл буцаах
gov.configure Нэгж, ажлын урсгал, чиглүүлэлт, үйлчилгээний тохиргоо
gov.report Эрх бүхий хамрах хүрээн дэх хяналтын самбарууд

Эдгээрийг rbac.SQLPermissionStore-оор сервер тал албаддаг бөгөөд тэр нь memberships → membership_roles → role_permissions → permissions-ийг туулна. Go модуль ба catalog/manifests/gov-services.json нь ижил багцыг зарладаг. UI-д товч нуух нь тав тух, хэзээ ч хяналт биш.


10. API-ийн хураангуй

Method Path Эрх
GET /api/v1/gov/units, /units/tree gov.read
POST /api/v1/gov/units, /units/members gov.configure
GET /api/v1/gov/workflow-templates, /workflows, /workflow-versions/{id} gov.read
POST /api/v1/gov/workflows, /workflow-versions/{id}/publish gov.configure
GET/POST /api/v1/gov/routing-rules gov.read / gov.configure
PUT /api/v1/gov/services/{id}/configuration gov.configure
POST /api/v1/gov/requests/ingest gov.apply
GET /api/v1/gov/requests/{id} gov.read
GET /api/v1/gov/tasks gov.read
POST /api/v1/gov/tasks/{id}/actions үйлдэл тус бүрээр
GET /api/v1/gov/dashboard gov.report
GET /api/v1/gov/outbox gov.configure

/tasks нь status, unit_id, service_id, overdue, from, to, page, page_size-г дэмждэг ба {items, total, page, page_size}-г буцаана. Алдаанууд хүн уншдаг error-ийн хажууд тогтвортой code-той байна.


11. Тестлэх

# State machine and routing (no database required)
cd backend && go test ./internal/apps/gov_services/...

# Full workflow against a migrated throwaway database
GOV_TEST_DATABASE_URL=postgres://… go test ./internal/apps/gov_services/...

Интеграцийн тестүүд GOV_TEST_DATABASE_URL тохируулаагүй үед алгасдаг тул go test ./... нь өгөгдлийн сангүй машин дээр — эсвэл CI runner дээр — ногоон хэвээр байна.