Skip to content

Type Deep Dive — Task Log, Comment, File And Status Events

1. Task log và status runtime bắt đầu ngay từ insert

project_task_insert gọi HandleTaskLogUpdate(...) ngay sau khi nhận payload insert (project_task_insert.go:48). Nghĩa là lifecycle audit của task không đợi đến lúc người dùng comment hay đổi status lần đầu.

Ngoài ra cùng event insert còn có thể:

  • tạo hoặc update doctor commission request,
  • update capture của parent task,
  • update order code liên quan service flow.

2. Comment runtime có 4 loại notification khác nhau

project_task_comment_insert đang phân nhánh tương đối dày:

Loại commentTrigger notification
Comment mới có mentionNotificationTriggerProjectTaskCommentMentioned
Reply có mentionNotificationTriggerProjectTaskCommentReplyMentioned
Reply comment ownerNotificationTriggerProjectTaskCommentReply
Comment mới cho assignees cũNotificationTriggerProjectTaskCommentNew

Source chính nằm ở project_task_comment_insert.go:100, :140, :181, :228.

Comment action history

Action historyKhi nào ghi
insertluôn ghi khi comment mới (project_task_comment_insert.go:29)
pinghi thêm nếu comment mới ở trạng thái pinned (project_task_comment_insert.go:37)
editghi khi đổi content (project_task_comment_update.go:52)
deleteghi ở event delete (project_task_comment_update.go:15)

Drift nhỏ nhưng thật

Khi update Pinned, code luôn ghi action pin dù là pin hay unpin (project_task_comment_update.go:67). Timeline sẽ khó phân biệt 2 semantics nếu đọc action history thuần.

3. File runtime đang mirror sang customer note/reference file

project_task_file_insert_delete có 2 nhánh:

NhánhHành vi
Insertnếu task có customer_note, insert reference_file loại result và đánh dấu is_from_trigger = true (project_task_file_insert_delete.go:77)
Deleteupdate reference_file.is_from_trigger = true, không xoá record mirrored ở mutation thực tế (project_task_file_insert_delete.go:125)

Điểm quan trọng là delete path hiện nhìn giống soft-mark hơn là đồng bộ xóa 1-1.

4. Scheduler side effects phải đọc cùng nhau

reset_task

Runtime này:

  1. tìm automate tasks due hôm qua với status inprogress_branch hoặc new_branch,
  2. chunk theo 100 records,
  3. delete_project_task_assignee,
  4. update_project_task.status_id = new_branch với updated_by = "Hệ thống" (reset_task.go:82).

Tên cron là "reset task", nhưng hành vi thật là "reset task và wipe assignment".

task_expired

Runtime này:

  1. tìm tasks overdue chưa done, chưa disabled,
  2. gửi notification cho mọi assignee không phải supervisor,
  3. tìm main assignee,
  4. ghi KPI MetricOverdueTask theo branch ids + user id (notification_task_expired.go:87).

Hai scheduler cùng chạy lúc 0 18 * * * (cron_triggers.yaml:241, cron_triggers.yaml:253), nên QA cần coi đây là một combined runtime boundary.

5. Assignee events và status events có liên thông gián tiếp

EventSide effect
project_task_assignee_insertnotification, KPI workload, auto-advance parent task, auto-fill tour_money, update parent capture
project_task_assignee_deleteKPI workload âm, salary sync
project_task_assignee_updatetour limit guard, update ecommerce_task_log, log change, salary sync, customer note sync
project_task_update_1customer visits + ecommerce task log khi task done/date change

Vì vậy khi test "đổi assignee" hoặc "đổi trạng thái", không thể chỉ nhìn bảng project_task hay UI badges.

6. Findings kỹ thuật

IDMức độMô tả
TE-F01Caoreset_task xoá toàn bộ assignees trước hoặc cùng lúc reset status, gây side effect lớn hơn tên cron thể hiện (reset_task.go:84).
TE-F02Trung bìnhtask_expiredreset_task chạy cùng giờ 18:00, có nguy cơ tạo interaction khó đoán khi một cron reset assignment còn cron kia ghi overdue KPI (cron_triggers.yaml:241, cron_triggers.yaml:253).
TE-F03Trung bìnhComment pin/unpin đều được log bằng action pin, nên audit trail không tách được pin với unpin (project_task_comment_update.go:67).
TE-F04Trung bìnhFile delete path chỉ update reference_file.is_from_trigger = true, không thể hiện rõ semantics xoá mirror record (project_task_file_insert_delete.go:125).