Тохируулж болох төрийн үйлчилгээний ажлын урсгал
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 нь ажлын урсгалын шилжилтийг буцааж эргүүлэх, эсвэл зогсоох ёсгүй тул хүргэлтийг салгасан:
- Төлөвийн өөрчлөлт нь
gov_delivery_outbox-д нэг гүйлгээний дотор мөр бичнэ. gov_upstream_connectorsнь эх систем тус бүрийн зорилтот URL баsecret_ref— гарын үсгийн нууцыг эзэмшиж буй коннекторын нэр-ийг хадгална. Нууц өөрөө гаралтын хайрцагт хэзээ ч хадгалагдахгүй, API-аар хэзээ ч буцаагдахгүй, лог-д хэзээ ч бичигдэхгүй.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 → төв
COMPLETED → close.
Баталгаажуулахын оронд буцаах нь хүүхдийг дахин боловсруулахаар
RETURNED төлөвт оруулна.
8. Миграц ба нийцтэй байдал
00007_gov_workflow.sql миграц нь нэмэлт шинжтэй. Одоо
байгаа үйлчилгээ, хүсэлт, хугацааны хэлхээ, цаг захиалгууд мөрөө
хадгална.
Модулийг аль хэдийн ашиглаж буй тенант бүрийн нөхөн дүүргэлт:
HQүндэс нэгж үүснэ.LEGACY_LOCALажлын урсгал үүсч, ганцFULFILLалхам өгөгдөж нийтлэгдэнэ.Тохиргоогүй үйлчилгээнүүдийг
LOCALгоримоор түүн рүү зааж чиглүүлнэ.Одоо байгаа хүсэлт бүр төлөвөө агуулсан яг нэг даалгавар авна:
gov_applications.statusgov_tasks.statusSUBMITTEDRECEIVEDIN_REVIEWIN_PROGRESSINFO_REQUESTEDINFO_REQUESTEDAPPROVEDCOMPLETEDREJECTEDREJECTEDCOMPLETEDCLOSEDCANCELLEDCANCELLED
Үнэний нэг эх сурвалж. 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 дээр — ногоон хэвээр байна.