This page has no English translation yet. Showing the Vietnamese version.

DMN Decision Service — đặc tả

Trạng thái: POC · Ngày: 22/09/2026 · Engine: Drools/Kogito DMN 10.2.0 (Apache 2.0, DMN 1.3 Level 3)

Luật nghiệp vụ nằm trong file .dmn trên đĩa, không nằm trong mã. Người phụ trách nghiệp vụ mở bằng Camunda Modeler, sửa bảng, lưu, gọi /reload. Không rebuild, không deploy, không cần lập trình viên.


1. Ranh giới

Entitlement Service ──▶ DMN Service
   ra quyết định            đánh giá luật
   cấp entitlement          không lưu gì
   gắn TTL và nguồn         không biết session là gì

DMN trả lời "luật nói gì về những dữ kiện này". Entitlement biến câu trả lời đó thành một bản ghi quyền lợi có id, TTL và nguồn gốc.

Đổi engine luật không được làm đổi hợp đồng entitlement. Đây là lý do DMN không tự phát entitlementId.

DMN Service không có trạng thái nghiệp vụ. Restart không mất gì.

2. Vì sao là DMN chứ không phải mã

Trong sơ đồ Luồng 1, Business owner nối thẳng vào Decision / Rule Engine. Nghĩa là người không phải lập trình viên phải sửa được luật.

Luật trong mã Luật trong DMN
Ai sửa được Lập trình viên Người phụ trách nghiệp vụ
Sửa xong cần gì Build, test, deploy Lưu file, gọi /reload
Nghiệp vụ đọc được không Không Có — bảng quyết định
Duyệt trước khi áp Qua code review ⚠️ Chưa có — xem §7

3. Bảng quyết định WifiEntitlement

File: dmn-service/dmn/wifi-entitlement.dmn · Hit policy FIRST — luật có thứ tự, khớp đầu tiên thắng.

Đầu vào

Tên Kiểu Nguồn
userType string claim user_type đã verify chữ ký
employeeVerified boolean claim employee_verified
company string claim company

Cả ba lấy từ token đã kiểm chữ ký, issuer, audience và hạn. Không lấy từ body request — nếu portal tự khai được thì Entitlement chỉ là trang trí.

Đầu ra

Tên Kiểu
eligible boolean
entitlementType string
tier · qosClass string
deviceSlots · ttlSeconds number
sourceType string
reason string — chỉ khi từ chối

Năm luật

# userType verified company Kết quả
1 EMPLOYEE true VIETJET, GALAXY, SOVICO ✅ WIFI_EMPLOYEE_PACKAGE · BOOST · HIGH · 2 thiết bị · 4h
2 EMPLOYEE true (khác) ❌ COMPANY_NOT_ELIGIBLE
3 EMPLOYEE (bất kỳ) (bất kỳ) ❌ EMPLOYEE_NOT_VERIFIED
4 CUSTOMER, rỗng, null — — ✅ WIFI_CUSTOMER_BASIC · BASIC · STANDARD · 1 thiết bị · 1h
5 (còn lại) — — ❌ UNKNOWN_USER_TYPE

Luật 2 là luật đáng demo nhất. HR xác nhận nhân viên thật, đang làm việc, đủ điều kiện — Entitlement vẫn từ chối. Xác thực và cấp quyền là hai câu hỏi khác nhau, và đây là chỗ nhìn thấy điều đó.

Luật 4 nhận cả userType rỗng — người vừa tự đăng ký Galaxy ID chưa có attribute. Họ đã xác thực nên được mức nền, không bị từ chối.

Luật 3 lẽ ra không bao giờ chạy. Nếu nó chạy thì ánh xạ claim trong Keycloak hỏng. Giữ lại để hỏng thì thấy, chứ không im lặng.

Luật 5 fail closed.

4. API

Base: http://localhost:3005

POST /api/v1/decisions/{model}/evaluate

{
  "inputs": {
    "userType": "EMPLOYEE",
    "employeeVerified": true,
    "company": "VIETJET"
  }
}
{
  "model": "WifiEntitlement",
  "results": {
    "WifiEntitlement": {
      "eligible": true,
      "entitlementType": "WIFI_EMPLOYEE_PACKAGE",
      "tier": "BOOST",
      "qosClass": "HIGH",
      "deviceSlots": 2,
      "sourceType": "EMPLOYEE_VERIFICATION",
      "ttlSeconds": 14400,
      "reason": null
    }
  },
  "correlationId": "corr-...",
  "timestamp": "2026-09-22T08:00:00.000Z"
}

Thêm "decision": "TênQuyếtĐịnh" để chỉ chạy một quyết định.

Mã HTTP Khi nào
INVALID_REQUEST 400 Thiếu inputs, hoặc body không phải JSON
MODEL_NOT_FOUND 404 Không có model tên đó
DMN_EVALUATION_ERROR 422 Model lỗi khi chạy
DMN_UNAVAILABLE 503 Không nạp được model nào

422 không phải là "từ chối". Bảng lỗi khác hoàn toàn với bảng nói "không". Trộn hai thứ này là che mất lỗi mô hình.

GET /api/v1/decisions

Liệt kê model đang nạp, kèm tên file nguồn — để biết luật đang chạy đến từ đâu.

POST /api/v1/decisions/reload

Đọc lại toàn bộ .dmn từ đĩa. Runtime đổi nguyên khối: request đang chạy giữ model cũ, không bao giờ thấy bảng nạp dở.

Không nạp được model nào thì báo lỗi to, không phục vụ bảng rỗng — bảng rỗng sẽ từ chối tất cả mọi người mà trông như đang hoạt động bình thường.

GET /health

5. Quy trình sửa luật

# 1. Mở trong Camunda Modeler (app Mac, miễn phí)
open -a "Camunda Modeler" poc/identity/dmn-service/dmn/wifi-entitlement.dmn

# 2. Sửa bảng, lưu

# 3. Nạp lại — không rebuild
curl -X POST localhost:3005/api/v1/decisions/reload

# 4. Kiểm tra
curl -s -X POST localhost:3005/api/v1/decisions/WifiEntitlement/evaluate \
  -H 'Content-Type: application/json' \
  -d '{"inputs":{"userType":"EMPLOYEE","employeeVerified":true,"company":"HDBANK"}}'

Thư mục dmn/ mount read-only vào container. Sửa trên máy host.

Sau khi sửa phải chạy lại test. tests/e2e.mjs có bài đối chiếu DMN với bảng dự phòng trong policy.js — sửa một bên mà quên bên kia thì test fail. Đó là thứ duy nhất ngăn hai bản luật trôi khỏi nhau.

6. Khi DMN sập

Mặc định fail closed. Entitlement trả 503 DMN_UNAVAILABLE, không ai được vào mạng.

POLICY_FALLBACK=local cho phép bảng dự phòng trong policy.js tiếp quản.

Fail closed (mặc định) Fallback
DMN sập Không ai vào được Cả khoang vẫn online
Luật đang áp — Bản trong mã, không phải bản nghiệp vụ vừa sửa
Audit Rõ ràng Lúc đó không ai biết luật nào đang chạy

Đây là quyết định nghiệp vụ, không phải kỹ thuật — ghi là T-DMN-FALLBACK. Mặc định fail closed vì nhất quán với mọi guardrail khác trong nền tảng này.

7. Còn thiếu

# Thiếu gì Mức
1 Không có quy trình duyệt. Ai cũng sửa .dmn rồi /reload được. Một luật sai là cả khoang mất Wi-Fi giữa trời 🔴 Cao
2 /reload không có xác thực 🔴 Cao
3 Không có lịch sử phiên bản luật — không biết ai sửa gì lúc nào 🟠
4 Không lưu lại từng lần đánh giá để đối soát sau 🟠
5 Không có môi trường staging để thử luật trước 🟠
6 Chỉ một bảng quyết định 🟡 Đủ cho POC

Mục 1 và 2 phải xong trước production. Cách làm tối thiểu: .dmn nằm trong git, sửa qua pull request, CI đẩy vào và gọi /reload — người nghiệp vụ vẫn sửa bằng Modeler, nhưng có vết và có người duyệt.

8. Vì sao Kogito/Drools chứ không phải Camunda

Đánh giá
Camunda 7 CE ❌ Hết vòng đời 10/2025, không còn vá bảo mật
Camunda 8 Run ⚠️ Khuyến nghị 4 core + 8 GB RAM. Là nền BPMN đầy đủ trong khi ta chỉ cần DMN
Kogito/Drools DMN ✅ Apache 2.0, ~250 MB, DMN 1.3 Level 3, đang được bảo trì

Camunda Modeler vẫn dùng để soạn bảng — file DMN 1.3 là chuẩn, engine nào đọc cũng được. Nên lựa chọn engine không khoá công cụ của người nghiệp vụ.

Nếu sau này tập đoàn chuẩn hoá trên Camunda, file .dmn chuyển thẳng sang được; chỉ thay service này.

9. Câu hỏi còn mở

Ref Câu hỏi
T-DMN-FALLBACK DMN sập thì fail closed hay chạy bảng dự phòng?
T-DMN-GOVERN Ai được sửa luật? Ai duyệt? Lưu vết ở đâu?
T-TIER member_tier đã có trong token nhưng chưa luật nào đọc. Loyalty có vào bảng quyết định không?
T1 / ADR-011 BASIC/BOOST có phải tier thật? Đòn bẩy là thời lượng hay tốc độ?

API-OVERVIEW.md · KEYCLOAK-INTEGRATION-SPEC.md · API-MATRIX.md

GIW POC Identity Platform · local demo · not production · generated from the repository