Appearance
Type — Timeline, Notification And Role Boundary
1. Timeline model
Complaint timeline được dựng từ complaint_schedule_history, không phải từ diff của complaint_schedule.
Shape dữ liệu chính
| Field | Vai trò |
|---|---|
complaint_schedule_id | Complaint cha |
user_id | Người thực hiện activity |
status | Loại activity |
contents | JSONB nội dung business của activity |
files | File đính kèm của activity |
created_at | Thời điểm activity |
ComplaintTimeline render history theo thứ tự thời gian và hiển thị label/status dựa trên mapping FE ở types.ts.
2. Complaint detail không chỉ đọc bảng chính
complaintScheduleDetail trả về ít nhất 3 lớp dữ liệu:
- complaint core fields,
- history/timeline,
complaint_action_role.
Do đó detail action này vừa là read model vừa là permission projection. Nếu thay đổi permission logic mà không cập nhật detail action, FE sẽ drift ngay.
3. Branch permission model
Bảng cấu hình
| Table | Vai trò |
|---|---|
complaint_permission_branch | Bật/tắt branch permission |
complaint_permission_resolver | Gắn resolver vào branch |
complaint_permission_approver | Gắn approver vào branch |
Runtime use cases
| Surface | Cách dùng |
|---|---|
| List | Gom branch mà user là resolver/approver để mở rộng scope nhìn thấy |
| Detail | Quyết định complaint có mở được không và action role là gì |
| Mutate actions | Check resolver/approver của branch trước khi transition |
Điểm chốt là branch permission không chỉ là setting screen; nó là runtime gate của toàn bộ complaint workflow.
4. Full-view boundary
Full-view roles ở list/detail
it_leaderit_staffaudit_leaderaudit_staffaccountant_leaderaccountant_staffcustomer_service_leadercustomer_service_staffbod
Ý nghĩa
- Những role này có thể xem complaint ngay cả khi không nằm trong branch permission tables.
- Nhưng việc "xem được" không đồng nghĩa "mutate được", vì mutate actions có guard riêng và đang không đồng nhất.
5. Customer workspace boundary
Complaint xuất hiện ở customer workspace qua raw query ComplaintDetail.
| Surface | Semantics |
|---|---|
| Complaint module | runtime operation surface, có action role và mutate path |
| Customer workspace | reference/read-only surface, FE ép complaint_action_role = view |
Đây là boundary quan trọng cho BA/QA:
- cùng một complaint nhưng ở user module không mang semantics thao tác giống complaint module,
- bug "không thấy nút" trong customer workspace chưa chắc là bug, có thể là chủ đích read-only.
6. Notification boundary
Trong phạm vi code đã đọc cho complaint workflow:
- không thấy action notification riêng cho complaint,
- không thấy event trigger hoặc scheduler dành riêng cho complaint lifecycle,
- không thấy FE complaint dialog tự gọi notification action sau transition.
Suy ra hợp lý nhất là:
- complaint timeline/audit là first-class,
- notification nếu có thì đang nằm ở layer khác hoặc chưa được implement ngay trong complaint surface này.
Điều này quan trọng vì nhiều business flow thường giả định "approve/reject sẽ tự gửi thông báo". Với complaint hiện tại, assumption đó chưa được chứng minh từ code đã đọc.
7. Rủi ro / Findings
| ID | Finding |
|---|---|
| TRN-F01 | Timeline correctness phụ thuộc vào việc mọi mutate action đều insert history đúng schema; thiếu history là mất audit trail ngay. |
| TRN-F02 | Branch permission tables là runtime dependency thật, không chỉ là admin config tĩnh. |
| TRN-F03 | List/detail visibility và mutate permission hiện không hoàn toàn dùng cùng semantics, nên role boundary có risk drift. |
| TRN-F04 | Không thấy notification-specific runtime trong complaint path đã đọc; nếu business kỳ vọng có thông báo tự động thì hiện docs/module khác mới cần xác minh tiếp. |