Appearance
Shared Rules — KPI Lifecycle And Notification
1. Thuật ngữ chuẩn
| Thuật ngữ | Nghĩa trong code hiện tại | Ghi chú |
|---|---|---|
| KPI core | kpi | Header KPI definition |
| Participant | kpi_participant | Đối tượng KPI: user hoặc branch |
| Metric relation | kpi_metric_relation | Target threshold gắn participant |
| KPI log | kpi_metric_relation_log | Log runtime cho metric relation |
| KPI stats | kpi_stats, kpi_metric_stats | Read models tổng hợp |
| Branch KPI | kpi_branch | Target doanh thu theo branch |
| Staff KPI | kpi_staff | Target doanh thu theo staff |
| KPI permission | kpi_permission | Mapping role cho audience/scope notification |
| Manual metric | metric thuộc group kpi_metric_group_manual | FE nhập tay |
| Auto metric | các metric còn lại | Runtime backend tự ghi log |
2. Status Matrix
| Status | Nguồn suy ra | Ý nghĩa |
|---|---|---|
new | from > now | KPI chưa bắt đầu |
inprogress | from <= now <= to và chưa cancel | KPI đang hiệu lực |
closed | to < now và chưa cancel | KPI hết hạn thời gian |
canceled | canceled_at IS NOT NULL | KPI bị hủy thủ công |
done | progress >= 100% ở một số component | Display state phụ, không phải canonical DB state |
3. Result Matrix cho participant
| Result bucket | Cách suy ra |
|---|---|
not_achieved | điểm tích lũy < ngưỡng need_to_improve |
need_to_improve | điểm tích lũy >= need_to_improve và < qualified |
qualified | điểm tích lũy >= qualified và < exceed_requirements |
exceed_requirements | điểm tích lũy >= exceed_requirements |
Kết quả participant vì vậy là computed result từ stats/threshold, không phải cột status vật lý.
4. Actor Matrix
| Actor | Vai trò |
|---|---|
| Creator KPI | Tạo và chỉnh sửa KPI core |
| Manager roles | Thấy tab metric và target ở detail |
| Assignee / participant | Thấy my-kpi hoặc participant detail theo permission |
| Branch manager | Thấy branch-kpi cho branch họ quản lý |
| Full-view roles | BOD, ITStaff, ITLeader xem participant detail rộng hơn |
| Scheduler/system | Ghi KPI logs và gửi notification định kỳ |
5. Invariants quan trọng
SR-001: KPI core không có status engine riêng
- Create/update/cancel/delete đều đi qua Hasura mutations trực tiếp.
statuskhông phải single-source DB field.- Mọi bề mặt status hiện dựa vào
from,to,canceled_at.
SR-002: Progress runtime không đồng nhất với lifecycle header
- KPI có thể đang
inprogressnhưng progress vẫn là 0. - KPI có thể
closednhưng display component vẫn map sangdonenếu đạt 100%. - QA phải test riêng lifecycle date logic và progress/result logic.
SR-003: Manual metric và auto metric cùng đổ vào kpi_metric_relation_log
- FE nhập tay qua
upsertManualMetrics. - Backend events/schedulers ghi qua
AddKpiLog. - Cùng một read model nhưng hai đường ghi dữ liệu khác nhau.
SR-004: disabled và canceled_at là hai semantics khác nhau
disabled = truegần với soft delete/hide khỏi list.canceled_atlà hủy KPI đang chạy.- Hai field này không nên bị trộn khi đọc yêu cầu nghiệp vụ.
SR-005: kpi_permission chỉ chi phối một phần KPI runtime
- Route access còn dùng
KPI_PERMISSIONSvàPERMISSIONS_KPI. - Participant detail còn dùng
checkPermissionParticipant. - Scheduler notifications mới dùng
kpi_permissionđể chọn audience nhóm rộng.
6. Boundary Checklist
Khi phân tích bug hoặc change request trong vùng KPI, luôn hỏi:
- Đây là KPI core, KPI revenue, hay KPI log runtime?
- Vấn đề là lifecycle date/status, hay progress/result computation?
- Dữ liệu đang được ghi từ FE manual input hay từ
AddKpiLogbackend? - Đây là quyền vào route, quyền xem participant, hay quyền nhận notification?
- Bug nằm ở event trigger tức thời hay ở scheduler chạy theo giờ/ngày?
7. Rủi ro / Findings
| ID | Finding |
|---|---|
| SR-F01 | KPI_STATUS_DONE là pseudo-state, không nằm trong bộ filter chuẩn KPI_STATUSES. |
| SR-F02 | useKPIBuilder.setStartEndDate() dùng from cho cả nhánh to, có dấu hiệu bug filter ngày cuối. |
| SR-F03 | Module có nhiều lớp permission song song: route config, runtime dashboard gating, participant permission và kpi_permission. |
| SR-F04 | KPI logs phụ thuộc nặng vào upstream domain events; nếu event không bắn, progress sẽ sai dù KPI header vẫn hợp lệ. |