Skip to content

Type Deep Dive — Project Task Lifecycle And Assignment

1. Route tree đang drift khỏi mental model sạch

Những gì route config đang nói

Vùng routeÝ nghĩa
ROUTE_PROJECT*CRUD project shell
ROUTE_PROJECT_TASK*Create/update/detail task
ROUTE_MY_TASK_DETAILDeep link task cá nhân
ROUTE_PROJECT_TASK_DETAIL_QUICK_VIEWDialog quick view

Drift nổi bật

  1. Dưới ROUTE_PROJECT_TASK_DETAIL, config đang lặp lại cùng một quick-view child và cùng một update-in-detail child nhiều lần (module.ts:96).
  2. Navigation của module còn chứa entry Hoàn Tiền sang route ecommerce withdraw (module.ts:245).

Hai điểm này khiến boundary FE của module không còn rõ: vừa duplicate route tree, vừa ôm navigation ngoài domain.

2. Create/update form không phải một flow đơn

TaskCreate.tsx đang xử lý cùng lúc nhiều mode:

ModeDấu hiệu
Create task thườngkhông có taskId, insert task mới
Update tasktaskId, gọi update path
Create subtaskparentTask / parentId
Gift / service giftis_gift, gifted_from, service_gift_id
Doctor taskdoctor_task = true
Popup / in-detail / create-from-columncancel/redirect phụ thuộc route name (TaskCreate.tsx:137)

Rule quan trọng

RuleSource
Automate board luôn ép status_id = new_branch khi tạo taskTaskCreate.tsx:243
POS có thể ghi session_created_by/session_updated_by ở child assigneesTaskForm/index.tsx:138
Update path có xoá delta files/labels/assignees chứ không chỉ update headerTaskCreate.tsx:156

3. Assignee role extraction ở FE đang có bug thật

Bug 1: supporter detection typo

Trong TaskForm, helper lấy danh sách supporter dùng điều kiện:

!e?.supervisor && !e?.main_assignee && !e?.assinger

nhưng field chuẩn là assigner (TaskForm/index.tsx:577). Điều này có thể làm một số assigner bị nhận nhầm là supporter khi edit task cũ.

Bug 2: assigner ids trả sai

filterTaskAssignerIds() đang trả:

filterTaskManagers(assignees).map(...)

thay vì filterTaskAssigner(assignees) (useTaskHelper.ts:115). Nếu bất kỳ dialog/filter nào dùng helper này để build list assigner, kết quả sẽ sai hệ thống.

4. Scope và permission của task detail/list

Query scope builder

useProjectTaskWhereBuilder đang áp các rule sau:

RuleSource
POS chỉ xem automate boarduseProjectTaskWhereBuilder.ts:36
List mặc định chỉ lấy root tasks parent_id is nulluseProjectTaskWhereBuilder.ts:100
Board manual dùng overlap logic giữa created_atdue_date cho filter dateuseProjectTaskWhereBuilder.ts:123
Non-admin, non-board-leader, non-department-leader chỉ xem task assign cho mình hoặc mình tạouseProjectTaskWhereBuilder.ts:166

Detail scope builder

useProjectTaskPermission.withScopeAssignees() cho phép bypass hoàn toàn nếu:

  • ITLeader, hoặc
  • project member có manager = true

ngược lại chỉ thấy task mình tạo, task assign cho mình, hoặc subtasks có liên quan (useProjectTaskPermission.ts:10).

5. Quick view là write surface thật

QuickViewTaskDetail không chỉ đọc:

  • nó gọi changeTaskByPk trực tiếp để đổi status (QuickViewTaskDetail.tsx:44),
  • nhưng nó chặn cứng nếu task chưa có main_assignee (QuickViewTaskDetail.tsx:45).

Điểm này quan trọng cho QA vì quick view phải được test như một mutation surface riêng, không phải mirror của detail page.

6. Findings kỹ thuật

IDMức độMô tả
PT-F01CaoRoute children bị duplicate trong ROUTE_PROJECT_TASK_DETAIL, tăng nguy cơ route resolution drift và làm người đọc hiểu sai cấu trúc module (module.ts:96).
PT-F02Trung bìnhNavigation projects chứa entry Hoàn Tiền, cho thấy FE module boundary đã lẫn với refund runtime (module.ts:245).
PT-F03CaofilterTaskAssignerIds() trả sai ids do gọi nhầm filterTaskManagers() (useTaskHelper.ts:115).
PT-F04Caoassinger typo trong role extraction khiến supporter/assigner partition có thể sai ở form edit (TaskForm/index.tsx:577).
PT-F05Trung bìnhPOSITION_SUPORTOR, MY_TASK_STATUES và column supportor cho thấy debt naming đã lan qua constants, i18n và table columns (types.ts:67, types.ts:102, MyTaskItem.tsx:247).