FR-038 規劃頁 任務指派 + 流程接通 進度報告(2026-06-17 夜間自動作業)

項目 內容
範圍 專案規劃頁(ProjectPlanningView)任務指派接 v2 + 控制項實作資料帶出 + 階段推進 + UI 清理
BE branch feature/oscal-refactor(未切 branch、未 push)
FE branch feature/oscal-refactor
驗收前置 ① 重啟 BE ② FE reload ③ 用「新建專案」測(舊專案無 per-AO job、不適用)
備註 夜間作業期間 Anthropic classifier 服務多次中斷,部分編輯延後重試完成;所有變更已落地,未 push

§1

一、完成項目(程式碼已落地)

#1 control-tree 回傳 per-job 指派人(讀)✅

app/oscal/service/ssp_control_implementation_service.py::get_control_tree

  • 收證據 job 收集 SQL 加 je.idwe.uid,並 LEFT JOIN compliance.task_assignees + public.users,每個 job 回 assignees(user_uid/user_name/login_name/is_approver/role)。
  • 同時暴露 per-AO workflow_template_uid(cloned 流程範本 uid)+ workflow_execution_uid(BPMN 編輯器用,見 #7)。

#2 saveTask v2 寫入路徑(任務 meta + 指派人)✅

infra/grc/repository/grc_job_repo_impl.py::update_job(原 2A dark return None → v2 重建)

  • 更新 job_executions(name/description/guide/job_type)。
  • reconcile task_assigneestask_id = job_executions.idtask_uid = je.uidtask_template_id = je.template_job_idproject_idProject.uid 解析(同既有 resolve_project_id pattern)、control_id = 0 sentinel(v2 prep-job 無對應 OSCAL int control;(project_id, task_id, user_id) 已唯一;控制歸屬可由 job→workflow_execution→wecm 回推,讀路徑 control-tree 即如此)。
  • diff 式增/刪/改 is_approver。
  • dept/device/survey 指派列為 phase 2(update_job 暫不持久化這三項,不報錯;survey/device helper 對空清單安全 no-op)。

#3 FE 規劃頁任務設定 wire v2 ✅

compliance-manager-fe/.../ProjectPlanningView.vue

  • fetchTree 改吃 GET /ssp/<sspUid>/control-tree,把內嵌 jobs(含 assignees)直接灌進 taskMapconfigured_job_count 由 jobs 推導、jobsLoadedSet 標記後舊 fetchAOJobs(dark /jobs/list)自動 no-op。
  • fetchUsersMenu 指派人下拉改吃專案參與人員CONTROL_PARTICIPANT_MENU 已 dark 回空)。
  • saveTaskPUT /grc/.../job/<je.uid> 走 #2 的 v2 寫入(payload 已帶 job uid + assignees)。

#7 BPMN 編輯器按鈕 ✅

  • BE control-tree AO 暴露 workflow_template_uid + workflow_execution_uid(見 #1)。
  • FE fetchTree AO mapping 改讀 a.workflow_template_uid / a.workflow_execution_uid → BPMN 按鈕 v-if 條件成立即顯示,openBpmnEditor 已用這兩欄。

#4 快速配置批次指派 ✅(改採低風險方案)

ProjectPlanningView.vue::executeQuickConfig / openQuickConfigDialog

  • POST /task-assignees/batchtask_assignee_service.batch_add 已 2A dark return []不沿用
  • 複用已重接的 per-job 寫入路徑:對每個可編輯控制項底下的收證據 job,把選取人員 additive 併入既有指派後逐一 PUT /grc/.../job/<uid>。零 BE 改動、複用已驗證的 #2。
  • 指派對象下拉同樣改吃專案參與人員(PROJECT_PARTICIPANT_MENU 舊路徑已 dark)。

#8 移除控制項群組/控制項層級「管理人員」UI ✅

ProjectPlanningView.vue 移除:群組層 manage 按鈕 + 參與人員列、控制項層 manage 按鈕 + 參與人員列、ParticipantsPanel Sidebar。

  • 保留專案層參與人員 Tab(alive)。
  • ⚠️ script 內 openParticipants / handleParticipantSave / handleParticipantUpdate / canManageGroupParticipants / canManageControlParticipants / ParticipantsPanel import 等變成未使用的死碼,本次保留未刪(Vite build 不受影響;夜間 classifier 不穩,避免多餘編輯)。日後可清。

§2

二、調查結論:#5 / #6(非單純 bug

#5「AO 實作狀態 / 現況描述 / 任務 沒帶出」→ 多為「測試時序」+ 預期空值

  • project_start._init_ssp_control_implementations:新專案只建控制項層 IR(implementation-status=unknown),不建 AO 層 statement → control-tree 對 AO 回 ssp_implementation_status=None / description=NoneAO 的實作狀態 / 現況描述對新專案本來就空,是給使用者在規劃階段填的(已修成 round planning 可編輯)。
  • AO「任務」要顯示 per-AO 收證據 job;job 由 _generate_prep_jobs新專案建(start_project step 7b)。舊專案(舊單一 template、part.props 未回填)不會有。
  • 三者同時空 = 高度吻合「在 BE 重啟 + FE reload #1–#3 變更之前測試」或測到舊專案。
  • DB 現況:job_executions=10253task_assignees=14435(資料是有的)。
  • 結論:程式路徑正確。請依「驗收前置」用新專案+重啟+reload 重測。

#6「啟動專案推進到下一階段」→ BE 全 alive,但現存 round 未綁 workflow(需用新專案驗)

  • BE 完全接通:launch_audit handler 已註冊(register_stage_hooks_to_registry 實際 register,wrap audit_round_app_service);RoundPrepTasksDoneCheck.checkok()(lenient 不擋);stage_advance_service 已 round-scoped;launch_audit 實作完整(snapshot living SSP→round.ssp_id、status→audit_planning)。
  • create_round 綁流程的 DI(flow_template_domain_service / workflow_template_snapshot_service / workflow_execution_service)已 wire;_create_first_round 有把 flow_template_uid 傳進 create_round;建專案頁 flowTemplateUid必填
  • 但 DB 現況:最新幾個 round(round 1 / planning)workflow_execution_uid 為 NULL → Banner _resolve_workflow_context 無 workflow 可解 → 推進按鈕無法運作。
  • master flow_templates=12(範本有);但最新資源庫(module_frame 426「亞航CMMC導入計劃」)audit_flow_template_uid 為空(fallback (c) 不可用)。
  • 判讀:現存 round 未綁,極可能是「在建專案頁加必填 flow template/round 綁定之前建的」舊資料,或經未綁定路徑建立。程式路徑本身正確 → 新專案(選了流程範本)應會綁
  • 待驗(明早):建一個新專案並選流程範本 → 查 SELECT workflow_execution_uid FROM compliance.project_audit_rounds WHERE ... 是否有值 → 進規劃頁看 Banner 能否「啟動稽核」推進到 audit_planning。
    • 有值且能推進 → #6 完成。
    • 仍 NULL → 是 _bind_round_main_workflow 綁定失敗(FE 送的 flow template uid 與 flow_templates.uid 對不上,或 master get_by_uid 回 None),需再修;可先 grep log/app.logcreate_round ... bound / flow-binding warning 定位。
    • 可選防呆:替資源庫設 audit_flow_template_uid 預設(讓 fallback (c) 生效)。

§3

三、驗收 checklist(明早)

重啟 BE + FE reload,建新專案(選資源庫 + 流程範本),進規劃頁「控制項實作」tab:

  1. 點控制項 → 現況說明可編輯、存檔成功(round planning 可寫)。
  2. 進 AO → 顯示收證據 job;展開 job → 指派人下拉有專案參與人員;選人存檔;reload 後指派人仍在(read 接通)。
  3. AO「未配置 → 已配置」標籤翻轉、job_count 正確。
  4. 「快速配置」選人套用 → 各 AO job 都帶上該人員。
  5. BPMN 按鈕在 AO 有 workflow 時顯示、可開編輯器。
  6. 頂部 Banner 顯示「規劃」階段 + 「啟動稽核」鈕 → 推進到 audit_planning(前提:該 round 有 workflow_execution_uid,見 #6 待驗)。
  7. 群組/控制項已無「管理人員」按鈕;專案層參與人員 Tab 正常。
§4

四、變更檔案

  • BE:app/oscal/service/ssp_control_implementation_service.pyinfra/grc/repository/grc_job_repo_impl.py(+ pyproject.toml dev path-dep 不 commit)。
  • FE:src/views/project/ProjectPlanningView.vuesrc/views/project/ProjectAuditorOverview.vuesrc/config/router/index.js
  • BE import smoke:通過(ssp_control_implementation_service / grc_job_repo_impl / job_service / api.grc.routes.job_route)。
§5

五、未完 / 後續

  • #6 新專案綁定驗證(見上,最關鍵待驗)。
  • 任務匯出/匯入 Excel(job_export_query / job_import_lookup 仍 dark)— user 指定後階段處理。
  • #8 死碼清理(unused participant handlers/import)。
  • dept/device/survey 任務指派持久化(phase 2)。
  • 收尾類(changelog / design §11 / Notion)等 user 明確下令。