Skip to content

Module Overview — Projects Task Lifecycle And Tour Income

1. projects thực tế là task-runtime module có project shell ở ngoài

LớpThành phầnVai trò
Project shellProject, ProjectCreate, ProjectDetail, project, project_memberTạo board, cấu hình members, xem detail
Task runtimeproject_task, TaskCreate, TaskDetail, QuickViewTaskDetailCreate/update task, chuyển trạng thái, chạy subtask và service flow
Collaboration runtimeproject_task_comment, project_task_file, task_log, project_task_status_logComment, file, audit và timeline
Tour-income runtimeproject_task_assignee, ecommerce_task_log, request_working_schedule, GetListTourLimitTour fee, doctor commission, KPI/salary/report coupling

Điểm quan trọng là UI gọi module này là "project management", nhưng config route và backend runtime cho thấy trọng tâm thực nằm ở task_managementproject_task (diva-admin/src/modules/projects/module.ts:145).

2. Surface map

FE routes

Route familyVai trò
/p/projectList project, create/edit/clone project
/p/project/:idProject detail, task board
/p/project/:id/task/create*Tạo task/subtask từ board hoặc cột
/p/project/:id/task/:taskIdTask detail đầy đủ
/p/project/:id/task/view/:taskIdQuick view dialog cho thao tác nhanh

Runtime backend

RuntimeVai trò
Hasura CRUD trên project_task*Surface chính cho create/update/delete
Event project_task_insert, project_task_update_1Đồng bộ task log, doctor commission, customer visit, order code
Event project_task_assignee_*Notification assignee, KPI log, salary sync, customer note sync, auto-fill tour_money
Event project_task_comment_*, project_task_file_insert_deleteComment history, notifications, mirror file sang reference_file
Scheduler reset_task, task_expiredReset task automate quá hạn, gửi overdue notification, ghi KPI overdue
Action GetListTourLimitTính read model tour limit/report dựa trên task done + assignee tour fee

3. Hai dialect status đang cùng tồn tại

Automate board dialect

StatusÝ nghĩa
new_branchTrạng thái mặc định khi create task automate (TaskCreate.tsx:243)
waiting_branchChờ branch hoặc chờ điều kiện bổ sung, có thể do doctor commission request
accepted_branchĐã nhận việc
inprogress_branchĐang thực hiện
done_branchHoàn tất
canceled_branchHủy

My-task / personal dialect

StatusCách map ở FE
newstatus_id ilike new_% (MyTaskItem.tsx:116)
reopenstatus_id ilike reopen_%
inprogressis_inprogress = true
reviewingstatus_id ilike pending_%
completedstatus_id ilike done_%
cancelled / missedDùng enum riêng trong MY_TASK_STATUES (types.ts:102)

Đây không phải chỉ là vấn đề naming. Nó tạo ra hai mental models khác nhau giữa board runtime và báo cáo/task cá nhân.

4. Lifecycle tổng quát của task

text
Create task in FE
  -> Hasura insert project_task + assignees/files/labels
  -> event project_task_insert
     -> HandleTaskLogUpdate
     -> doctor commission sync nếu doctor_task
     -> updateTaskCapture(parent) nếu là subtask
     -> UpdateOrderCode

Update task / assignee / status
  -> Hasura update/delete child rows
  -> assignee events
     -> notification
     -> KPI workload
     -> salary/customer note/tour fee sync
  -> project_task_update_1
     -> updateAllCustomerVisits
     -> updateEcommerceTaskLog
     -> ProjectTaskCustomerVisitInsertUpdate

Daily schedulers
  -> reset_task
  -> task_expired

5. Assignee runtime không phải field phụ

project_task_assignee có quyền insert/update/delete mở cho role user và treo trực tiếp 3 event trigger insert/update/delete (diva-backend/services/controller/metadata/databases/project/tables/public_project_task_assignee.yaml:68). Vì vậy mọi thao tác đổi assignee đều có side effect runtime thực:

  • main assignee insert có thể ghi KPI workload và auto-advance parent task (project_task_assignee_insert.go:87),
  • main assignee delete ghi KPI workload âm và đụng salary flow (project_task_assignee_delete.go:62),
  • update tour_money chạm ecommerce_task_log, salary và customer note metadata (project_task_assignee_update.go:146).

6. Scheduler boundary

SchedulerLịchHành vi
reset_task0 18 * * * (cron_triggers.yaml:241)Lấy automate tasks due hôm qua, reset status_id = new_branch, rồi xóa toàn bộ assignees (reset_task.go:82)
task_expired0 18 * * * (cron_triggers.yaml:253)Lấy task overdue chưa done, gửi notification và ghi KPI MetricOverdueTask (notification_task_expired.go:21)

Việc hai cron chạy cùng giờ là một boundary đáng chú ý. Tối thiểu, cần coi chúng là một batch vận hành chứ không phải 2 timer độc lập.

7. Findings nổi bật

IDFinding
MO-F01Route tree dưới ROUTE_PROJECT_TASK_DETAIL đang duplicate cả ROUTE_PROJECT_TASK_DETAIL_QUICK_VIEWROUTE_PROJECT_UPDATE_IN_DETAIL, làm route config khó suy luận và dễ drift (module.ts:96).
MO-F02Navigation của projects ôm cả entry Hoàn Tiền với moduleId = refund_request_management, cho thấy module boundary ở FE đang bẩn (module.ts:223).
MO-F03filterTaskAssignerIds() đang trả supporter ids thay vì assigner ids, đây là bug logic chứ không chỉ naming issue (useTaskHelper.ts:115).
MO-F04Doctor commission cancel path có khả năng update sai record vì query tìm request theo reference_id nhưng mutation lại where id = projectTask.ID (project_task_insert.go:124, project_task_insert.go:229).
MO-F05Khi task chuyển done_branch, nhánh insert all_customer_visits đang dùng time.Now() thay vì taskNew.DoneAt, làm sai ngày visit trong trường hợp backdate hoặc sửa done time (project_task_update_1.go:236).
MO-F06reset_task không chỉ reset status mà còn delete assignees. Nếu BA/QA hiểu tên cron theo nghĩa hẹp, rất dễ bỏ sót regression ở workload và reassignment (reset_task.go:84).