本卡屬 FR-148(母卡見上方連結),第 ④ 棒:規劃頁。依賴 ①③。
PM 在專案規劃頁替任務選要套哪個任務關卡樣板、每一關派誰。原本表單上的「部門+指派人員」兩格,換成一行摘要(例:「標準三關(3 關)· 2 關已指派、1 關未指派 ⚠」)+「設定」按鈕;按下去開彈窗,在裡面選樣板、每一關各選部門→人員(可多人),也可以「套用到其他任務」。零關(預設的免審直通)一樣開彈窗,裡面只有一組部門+人員。
compliance-manager-fe/src/components/grc/planning/AoTaskForm.vue 749 行(接近 800 上限)
:436 部門 MultiSelect / :443 人員 MultiSelect(依部門篩:usersInDepts、keepAssigneesInDepts :116-119)
:448 問卷任務的審核者開關(is_approver)
compliance-manager-fe/src/components/grc/planning/AoTaskSection.vue 278 行
compliance-manager-fe/src/views/project/ProjectPlanningView.vue 2,604 行(超標,只准一行掛載)
app/flow_control/service/job_service.py:323 update_job / :355 記舊名單 / :503 _notify_newly_added_assignees
app/flow_control/service/flow_apply_to_tasks_service.py 流程圖「套用到其他任務」的候選列法(同專案同輪)
PUT /grc/jobs/<job_uid>/review-steps body {template_uid, steps_assignees:[{seq, dept_uids, user_uids}]}:未開始的任務——把樣板關卡複製進 job_review_steps(換樣板時同 seq 已派的人保留、多的關空著、少掉的關刪掉)、寫 review_template_id;第 1 關的人寫 task_assignees+任務部門關聯(沿用 job_service.update_job 既有寫法,不另寫一套,問卷的 is_approver 保留邏輯照舊)、第 2 關以後寫 job_review_step_assignees。選零關樣板=清掉關卡、review_step_no 設 NULL。PreconditionFailedError;只換人可以。換人的是哪一關 寄給誰
任務還沒啟動 不寄;啟動時寄給第 1 關當下的名單(既有行為)
進行中、換當下那關 只寄「新加」的人(比照 _notify_newly_added_assignees 比新舊名單)
進行中、換還沒走到的關 不寄;走到那關時由推進服務寄給那時的名單
進行中、換已走過的關 不寄
被移除的人 一律不通知(現況也沒有)
POST /grc/jobs/review-steps/apply body {template_uid, job_uids}:批次套樣板(只套樣板、人保留同 seq);候選限同專案同輪、未開始、非問卷。assert_project_role)。問卷任務呼叫這兩支 → 拒絕(D9)。AoTaskForm.vue 只剩約 51 行額度:非問卷任務把部門+人員兩格整段換成新子元件 TaskReviewStepSummary(一行摘要+「設定」;已開始時按鈕字改「檢視/換人」);問卷任務維持原兩格與審核者開關不動。TaskReviewStepDialog(新檔):樣板下拉(含零關、標公司預設)→ 關卡預覽 → 每關一列「部門 MultiSelect → 人員 MultiSelect(依部門篩,重用既有 usersInDepts/keepAssigneesInDepts,不要另寫)」,第 1 關小字標「=原本的指派人員」;有關卡沒派人時下方橘色提示「第 N 關還沒指派人,啟動時會跳提醒」;左下「套用到其他任務」、右下取消/儲存。已開始:樣板下拉唯讀、人可改。docs/features/FR-148-2610-task-review-steps/prototype/planning.html(只取結構)。不准左側粗色邊框。