手冊首頁 / 專案與任務 / AO 任務配置與啟動

AO 任務配置與啟動(Task Config)

功能群:專案管理|上層見 專案規劃頁(本頁=其 Tab0「控制項實作」的 AO 任務配置,規劃頁功能總覽第 4/5/6 項)

事實基準:2026-07-06 從 FE / BE code 掃出;表結構對 db_schema.json、endpoint 對 routes.json、欄位對 marshmallow serializer + service 組裝碼逐條核

變更紀錄

  • 2026-08-01(FR-059):profile 下拉動態化——CINC Auditor / GCB 的 profile 欄位改由「掃描設定檔庫」動態餵選項:param_schema 升 v2 加 "options_source": "profile_library" 宣告並拿掉靜態 options,FE 偵測宣告改呼 profile menu API(帶工具 uid 過濾,GCB 池與 CINC 池分開);型別維持 select_or_text、手填能力保留。取值來源三層並存:庫內檔案型(profile:<uid> 參照)/ 庫內連結型 / 現場手填(既有任務存的舊靜態選項值照常可用)。設定檔的上傳與維護見新頁 掃描設定檔管理
  • 2026-08-01(FR-058.5/.6/.7):檢測工具下拉新增 SonarQube(原始碼安全檢測 SAST),三種取源模式以 scan_mode 參數分流——pull 讀取既有結果/scan 掃描公開 Git repo/upload 上傳源碼壓縮包(各自參數與適用情境見 §5「SonarQube 的掃描參數與三種執行模式」);scanupload寫入行為(會在客戶 SonarQube 建立/更新 Guidant-AI- 前綴專案),任務卡加橘色警語區塊事前告知(D24 配套);upload 模式的壓縮包不在本頁上傳(於任務抽屜發起執行時提供,D26);upload 任務不進「開始執行任務」自動派發(D33,批次發佈 confirm 文案加註提示);condition.value 語法擴充支援陣列形式(一欄可同時綁多個模式值)。另 GCB 的 profile 下拉由 1 筆示範擴為 8 支 TWGCB 作業系統類基準(fr058-18;後續已由 FR-059 改為設定檔庫動態餵)
  • 2026-07-31(FR-058):檢測工具下拉新增四款(ZAP / CINC Auditor / Nmap / 政府組態基準 GCB),各自的掃描參數見 §5「四款新工具的掃描參數」;任務層敏感參數加密param_schemasecret:true 欄位如 ZAP 登入密碼,DB 存密文、API response 整個 key 剝除、FE 靠 secret_keys_set 顯示「已設定」);掃描參數必填驗證(原本完全不驗、缺參數的任務照樣存檔到 agent 執行期才失敗,改為存檔前擋下且 condition-aware);CINC Auditor 的 profile 參數由 textselect_or_text
  • 2026-07-29(FR-057):檢測工具任務新增 select_or_text 掃描參數型態(下拉常用選項 + 自由輸入,OpenSCAP profile 欄位用);選定工具後有 default 值的參數欄位自動帶入預設值(onSelectDetectionTool 新行為,見 §5 / §10)
  • 2026-07-27(FR-056):任務類型新增 detection_tool(檢測工具執行)——選定工具後動態渲染掃描參數 + 完成模式(manual/auto);「開始執行任務」批次動作新增自動派 detection 任務首次掃描(見 §6.3)
  • 2026-07-06 FR-047 從 project-planning.md 拆出並納入快速配置 / 開始執行

1. 功能描述

AO 任務(prep-job)是「為每個控制項評估目標(AO)蒐集證據」的工作項。本頁涵蓋任務域的三件事:①單一任務逐欄配置(inline 編輯)、②快速配置(一鍵把多位人員批次併入所有可編輯任務)、③開始執行(PM 把已指派任務批次轉 PROCESSING 並通知)。

規劃頁 Tab0 的左樹選到某個 AO 後,右面板下方列出該 AO 的任務卡;每張卡片直接 inline 編輯(非獨立 Dialog):任務名稱 / 描述 / 指南、任務類型(一般 general / 問卷 survey)、指派人員(可標審核人)、部門、設備、問卷(可標審批要求)。儲存以 PUT job 一次寫回,關聯欄位採 full-replace 語意(送 [] 清空、省略 = 不動)。快速配置開始執行是 Header 的批次動作:前者 FE 端逐一 PUT 合併、後者呼叫專屬 start-task-execution endpoint。

任務真相來自範本 BPMN 的 userTask(見規劃頁背景);儲存時 BE 會在同一 transaction 同步回寫 BPMN userTask,讓 BPMN 編輯器與規劃頁兩端一致。與 SSP 編輯不同,任務指派不受 SSP 凍結影響,只要輪次在 planning 階段、使用者對該節點有三層遞進的 manager 權即可編。

主要使用者:對該控制節點有 manager 權者(專案 / 群組 / 控制項任一層 manager)。

角色速覽(完整定義見 _overview §3):

角色 一句話
manager(三層任一) 專案 / 群組 / 控制項 manager — 可編此節點下的任務(canEdit 遞進,見規劃頁 §3)
參與者 auditor / reviewer / viewer — 可讀不可寫

1.1 功能總覽(本頁全部功能)

# 功能 說明 位置 詳述
1 編輯任務基本文案 名稱 / 描述 / 指南 + 類型(general / survey) 任務卡 inline UC-TE-01
2 指派人員(含審核人) MultiSelect 指派;survey 型可標審核人(is_approver 任務卡 UC-TE-01
3 部門 / 設備關聯 MultiSelect 綁部門(org_unit)/ 設備(device) 任務卡 UC-TE-01
4 問卷關聯(含審批) 僅 survey 型;MultiSelect 選問卷,每張可標「審批要求」 任務卡 UC-TE-01 / §12
5 儲存任務 一次 PUT,關聯 full-replace,同步 BPMN 每卡「儲存」 §6.2
6 快速配置 多選人員一鍵 additive 併入所有可編輯 AO 的任務(FE 逐一 PUT) Header 按鈕 → dialog UC-PP-02 / §12
7 開始執行任務 PM 把「已指派且 TODO」的任務批次轉 PROCESSING 並通知(idempotent);FR-056detection_tool 型任務一併自動派第一次掃描(scan_mode=upload 者除外——自動路徑不帶檔案,D33,見 §6.3) Header 按鈕(限 PM) UC-PP-02 / §6.3
8 檢測工具綁定與參數(FR-056) 任務類型選「檢測工具執行」後:選定工具(config.detection_tools)+ 依工具 param_schema 動態渲染掃描參數 + 完成模式(manual/auto);FR-058:secret 參數加密存放 + 存檔前必填驗證 任務卡(jobType==='detection_tool' 條件層) §5 / §6.2

UC(§2)展開兩條核心路徑:UC-TE-01(單一任務逐欄 inline 編輯,含 M2M / 審核人坑)與 UC-PP-02(快速配置 → 開始執行的批次流)。快速配置 ⚠️ 有清空關聯的坑(見 §12)。

2. Use Case

角色速覽(同 §1)。流程圖視覺慣例:菱形 = 判斷、橘底 = 例外/擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。

UC-TE-01 編輯 AO 任務

項目 內容
角色 對該節點有 manager 權者
前置條件 輪次 AP=planning;已載入 control-tree(任務內嵌於樹);canEdit 為真
產出 / 後置條件 job_executions(本體)+ reconcile 四關聯表(指派 / 部門 / 設備 / 問卷);同步 BPMN userTask;名稱變更 best-effort 觸發 Drive 改名
taskedit_uc_01 start open 展開 AO 任務卡(inline 編輯,無獨立 Dialog) canEdit=三層遞進 manager(否則欄位 disabled) start->open fields 填 名稱 / 描述 / 指南 / 類型(general·survey)/ 指派人員(含審核人 switch)/ 部門 / 設備 open->fields survey 類型 = survey? fields->survey surveyui 顯示問卷 MultiSelect + 每張問卷「審批」switch + 有審批要求時人員列出現「審核人」switch survey->surveyui save 按儲存 → FE 檢查:有審批問卷但無審核人? survey->save 否(general) surveyui->save feerr FE toast warn(需指定審核人,不送出) save->feerr 是(缺審核人) put PUT /grc/project/{uid}/job/{jobId} payload:assignees[{uid,is_approver}] / department_uids / device_uids / surveys[{uid,approval_required}] save->put guard BE:job_uid 存在?(⚠️ route 僅 JWT、無角色守門) put->guard nf GRC_404005(GRC 任務不存在) guard->nf 找不到 replace full-replace 關聯:陣列送 []=清空、null/省略=不動 寫 job_executions(本體)+ reconcile task_assignees / job_execution_org_units / job_execution_devices / survey.task_surveys guard->replace 找得到 bpmn 同 transaction 同步 BPMN userTask (name/description/guide/job_type/問卷 actionInfo) replace->bpmn done 回 Job 節點 DTO(形狀同 control-tree)→ 前端更新 名稱變更 → best-effort 觸發 Drive 資料夾改名 bpmn->done
UC-TE-01 流程:展開任務卡 inline 編輯(canEdit 三層 manager,否則 disabled)→填基本欄+指派/部門/設備→survey 型顯示問卷+審批+審核人 switch→儲存時 FE 檢查審批問卷需審核人(缺 toast 不送)→PUT job(route 僅 JWT 無角色守門)→job 不存在 GRC_404005→full-replace 寫 job_executions + 四關聯表→同 transaction 同步 BPMN→回 DTO、名稱變更觸發 Drive 改名

UC-PP-02 快速配置與開始執行

項目 內容
角色 快速配置:有編輯權者;開始執行:專案 manager
前置條件 輪次 = planning;AO 下已有任務(BPMN 範本衍生的 prep-job)
產出 / 後置條件 快速配置:對每個可編輯任務 additive 併入指派人員後逐一 PUT job;開始執行:compliance.task_assignees 等已備妥後 job_executions.status TODO→PROCESSING、站內通知送出
uc_pp_02 start pick 點選 AO → 展開任務卡 start->pick assign 指派人員/部門/設備 (survey 型:選問卷) pick->assign quick (可選)快速配置 dialog 多選人員一鍵指派到 所有可編輯 AO 任務 assign->quick chk 問卷需審核 且未設審核人? assign->chk save 點「儲存」 PUT /grc/project/{uid}/job/{jobId} (關聯欄位 full-replace) quick->save warn FE 擋:toast「審核人員必填」 (僅前端檢查,見 §12 坑 7) chk->warn chk->save warn->assign 補審核人 saved 關聯表更新 (task_assignees 等四張+task_surveys 展開) save->saved pm PM 點「開始執行任務」? (isProjectManager 才看得到) saved->pm mgr BE 檢查: 使用者是專案 manager? pm->mgr stay 留在規劃頁 (之後可再啟動) pm->stay deny 403 GRC_403002 mgr->deny exec POST /start-task-execution 已指派 TODO 任務批次 → PROCESSING +站內通知(idempotent 可重按) mgr->exec
UC-PP-02 流程:指派→儲存(full-replace)→PM 批次啟動(idempotent 可重按);審核人檢查只在 FE

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
讀任務 參與者即可(隨 control-tree 一起載) require_participant(讀樹) 規劃頁 control-tree 路徑
編輯 / 儲存任務 三層遞進 canEdit(專案 → 群組 → 控制項 manager,ProjectPlanningView.vue:663-679 ⚠️ 無角色守門(route 僅 @jwt_required() api/grc/routes/job_route.py:98(route);service app/grc/service/job_service.py
快速配置 同編輯(逐一 PUT job) 同上(每筆 PUT 無角色守門) FE executeQuickConfigProjectPlanningView.vue:1192
開始執行任務 isProjectManager 才顯示按鈕 _check_manager(須專案 manager,否則 GRC_403002 app/grc/service/task_execution_service.py_check_manager:8-17

⚠️ FE / BE 權限不對齊:FE 用三層遞進的 canEdit 擋按鈕,但 PUT job route 層只有 JWT 登入、無任何角色檢查——任一登入者繞過 FE 直接打 API 都能改任務指派。與規劃頁 §3 / §12 記載的同一 finding。唯有「開始執行」有 BE manager 守門GRC_403002)。

4. 狀態機與前置條件

承接輪次階段 gate(見 規劃頁 §4):

條件 效果 出處
apStatus === 'planning' 任務可編(不受 SSP 編輯凍結影響) 規劃頁 FE 行為
!canEdit(非三層 manager) 任務卡全部欄位 disabled ProjectPlanningView.vuecanEdit:disabled,約 :1953-2029)
類型 = survey 才顯示問卷 MultiSelect + 審批 / 審核人 switch 同檔(jobType==='survey' gate,約 :1985/:2015)

5. UI 設計

版面骨架(Header 批次動作 + AO 任務卡 inline 編輯,含 survey 型條件層 + 代表性 API):

專案規劃頁 Tab[0] — AO 任務配置與啟動(Header 批次動作 + AO 任務卡) Header 動作: 快速配置 開始執行任務(限 PM) 快速配置=FE 逐一 PUT job(無專屬 endpoint) POST /grc/project/{uid}/start-task-execution → {activated_count} AO 任務卡(Panel,inline 編輯;canEdit=三層遞進 manager,否則 disabled) 名稱 InputText ・ 描述 Textarea ・ 指南 Textarea 類型 SelectButton:general | survey 指派人員 MultiSelect(chip;每位可標「審核人」is_approver) 部門 MultiSelect ・ 設備 MultiSelect (僅 survey 型顯示)問卷 MultiSelect 每張問卷「審批」switch approval_required ・ 有審批時人員列出現「審核人」switch 審核人檢查只在 FE(saveTask 前擋,BE 無驗證) 儲存(每卡「儲存」鈕)→ 一次 PUT,關聯 full-replace([]=清空、省略=不動) PUT /grc/project/{uid}/job/{job_uid} payload:assignees(uid,is_approver) ・ department_uids ・ device_uids ・ surveys(uid,approval_required) 寫 job_executions 本體 + reconcile 四關聯表(指派/部門/設備/問卷)+ 同 transaction 同步 BPMN userTask → 本頁 §6.2;問卷關聯跨 survey.task_surveys(非 compliance) 橘=任務配置區塊(標代表性 API)|紫虛線框=survey 型才出現的條件層|full-replace:陣列送 [] 會清空關聯
AO 任務配置版面骨架:Header 快速配置/開始執行+任務卡 inline 編輯(基本欄/指派/部門/設備/survey 型問卷審批審核人)+PUT job 代表性 API

📸 截圖待補(亮色模式):AO 面板 + 任務卡展開(general 型)taskedit-general.png、survey 型(含問卷 + 審批 + 審核人 switch)taskedit-survey.png。(規劃頁 §5 已有 planning-ao-tasks.png 概覽可參考)

任務卡 inline 表單(ProjectPlanningView.vue Panel 卡片,無獨立 Dialog)。欄位

# i18n label 型別 必填 列舉 / 來源 payload 欄位 disabled 備註
1 task_name_label 任務名稱 InputText name !canEdit
2 task_desc_label 描述 Textarea(autoResize) description !canEdit
3 task_guide_label 指南 Textarea(autoResize) guide !canEdit
4 任務類型 SelectButton general / survey job_type !canEdit 切 survey 才顯示問卷區
5 assignees_label 指派人員 MultiSelect(chip) /users/menu{id,name} assignees[{uid,is_approver}] !canEdit dataKey=id
5a is_approver_label 審核人 InputSwitch(每位人員) assignees[].is_approver !canEdit survey 型且有問卷開審批時顯示
6 departments_label 部門 MultiSelect /org-units/menu{id,name} department_uids[] !canEdit
7 devices_label 設備 MultiSelect POST /devices{id,name} device_uids[] !canEdit
8 surveys_label 問卷 MultiSelect /surveys/menu{id,name} surveys[{uid,approval_required}] !canEdit survey 型顯示
8a approval_required_label 審批 InputSwitch(每張問卷) surveys[].approval_required !canEdit 與問卷名並列
9 檢測工具(FR-056) Dropdown 是(detection_tool 型必選) 工具目錄選單(menuStore.detectionToolMenu,來源 GET /detection-tools tool.uid !canEdit job_type==='detection_tool' 顯示;未選不可儲存(toast warn_tool_required
9a 掃描參數 param_schema 動態渲染(DetectionConfigField,型態含 text/number/select/select_or_text/password 依欄位定義,FR-058 起存檔前實際驗證 GET /detection-tools/{uid}/param-schema tool.params(Raw,不硬編欄位) !canEdit 選定工具後才出現;選定工具當下若欄位有 default 值會自動帶入onSelectDetectionTool,FR-057,見 §10),非空表單;各工具參數見下方「四款新工具的掃描參數」與 檢測工具管理 §6.2
9b 完成模式 SelectButton 否(預設 manual manual / auto tool.completion_mode !canEdit manual=掃完留 PROCESSING 等人工;auto=掃完自動完成

select_or_text 型態(FR-057 新增):PrimeVue editable Dropdown——下拉列常用選項,也可直接輸入清單外的自由字串。用於各工具的 profile 欄位(OpenSCAP 的 xccdf profile id 會因目標主機自帶的 SSG 版本不同而有自訂值;CINC Auditor / GCB 的 profile 可以是 Git 網址、Agent 主機上的本機路徑或 Supermarket 名稱)。FR-058 把 CINC Auditor 的 profiletext 改為 select_or_text(FE 元件早已支援,FE 與 agent 零改動)。渲染元件與檢測工具管理 §5 設定表單共用同一 DetectionConfigField.vue

profile 下拉動態化(FR-059):欄位定義帶 "options_source": "profile_library" 宣告時(CINC Auditor / GCB 的 profile 欄位,param_schema v2 起),DetectionConfigField 不再讀欄位內的靜態 options 陣列,改呼 GET /detection-tool-profiles/menu?detection_tool_uid=(帶當前工具 uid——GCB 抽屜只見 gcb 池、CINC 只見 inspec 池)動態組選項;選項的 value 是 BE 組好的 profile:<uid> 庫內參照,派工時展開。選項載入走 src/composables/useDetectionProfileOptions.js模組層級快取(規劃頁 N 個任務列共用、同工具只打一次 API);menu 拉不到時顯示警示但欄位照常可手填(不擋畫面)。取值來源三層並存:庫內檔案型 / 庫內連結型 / 現場手填(URL、Agent 本機路徑、Supermarket 名稱——不進庫、單次執行用;既有任務存的舊靜態選項值屬手填路徑,升級後照常可用)。回顯相容:值不在選項內時 editable Dropdown 原樣顯示該字串;已停用的 profile:<uid> 參照補一個唯讀 fallback 選項標示「庫裡已沒有的項目」,不露裸 UUID(DetectionConfigField.vue::profileOptions:82-92)。沒有宣告的欄位維持靜態 options 行為零影響;機制 tool-agnostic,新工具 seed 宣告即接庫、FE 零改。設定檔的維護見 掃描設定檔管理

四款新工具的掃描參數(FR-058,DEV 實查 config.detection_tool_param_schemas 當前生效版)

工具(code) 參數欄位
ZAPzap target_url(text,必填)/scan_mode(select,必填,預設 passive:被動掃描 / 主動掃描 / 登入後主動掃描)/login_urllogin_username(text,必填,condition: scan_mode=authenticated)/login_password(password,secret: true,必填,同 condition)logged_in_indicator(text,必填,同 condition)/timeout_sec(number,預設 3600)
CINC Auditorinspec hosts(text,必填,多台逗號分隔、逐台各產一份報告、單台失敗不影響其餘)/transport(select,必填,預設 ssh:SSH(Linux 目標)/WinRM(Windows 目標))/profile(select_or_text,必填,FR-059 起帶 options_source: "profile_library" 宣告、選項改由掃描設定檔庫動態餵——原靜態預置的 dev-sec Linux/Windows 基準已搬入庫成公用版連結型,下拉內容零回歸)/timeout_sec(number,預設 3600,逐台各自計時非總時間)
Nmapnmap hosts(text,必填,「執行主機」=Agent 登入並執行 nmap 的機器)targets(text,必填,「掃描目標」=IP/網段/主機名稱)scan_type(select,必填,預設 connect:TCP 連線掃描(不需提權)/SYN 掃描(較快,需 sudo)/服務版本偵測(探測流量較多,需確認已獲授權))/port_range(text,預設 1-1024)/timeout_sec(number,預設 3600)
GCBgcb 與 CINC Auditor 同構(hoststransportprofiletimeout_sec)。profile 同樣帶 options_source 宣告(FR-059)——下拉列掃描設定檔庫 gcb 池內容:8 支 TWGCB 公用版(Windows Server 2016/2019/2022、Windows 11、RHEL 8/9、Ubuntu 22.04 等,原 FR-058 靜態容器路徑選項搬遷而來)+租戶自行上傳的自有版

Nmap 的 hoststargets:其餘工具「登進去掃自己」,hosts 同時是登入對象與掃描對象;Nmap 是 Agent 以 SSH 登入 hosts 這台執行主機,再由該主機對 targets(可能是整個網段)送出探測封包。兩個欄位語意不同,任務執行抽屜 的摘要卡與執行詳情視窗因此分開顯示兩者。

ZAP scan_mode='authenticated' 對單頁式應用(SPA)不可使用:不只是掃不到——會引發登入無限重試,累積到 ZAP 保護門檻後 daemon 主動停止,連帶中斷其他租戶正在執行的掃描。詳見 檢測工具管理 §12 坑 14;ZAP 卡片的部署前提說明已明白標示。

profile 下拉一律用 tarball 形式.../archive/refs/heads/master.tar.gz)而非裸 GitHub 網址:裸網址走 CINC 的 git fetcher,需 shell out 呼叫 git 查 default branch;實測把 agent 容器內的 git 移走後裸網址直接失敗、tarball 照常可用。下拉是平台預置的建議值,選少一個故障點的形式。

GCB 的 profile 選項演進:fr058-13 上架時僅 1 筆 Windows 最小示範(2 項);fr058-14 加入 TWGCB-01-011 Server 2022 完整基準後,fr058-16 把示範筆移出下拉(select_or_text 手填仍可用);fr058-18 擴為 8 支 TWGCB 作業系統類基準——Windows 組 4 支(007 Server 2016/009 Server 2019/010 Windows 11/011 Server 2022,各 540/539/108/558 項自動檢查)+ Linux 組 4 支(008 RHEL 8/012 RHEL 9/013 RHEL 9/014 Ubuntu 22.04 LTS,各 53/74/60/35 項)。排序先 Windows 後 Linux、組內照編號;012 與 013 是 NICS 官方兩份不同的 RHEL 9 基準(非重複),label 一律帶 TWGCB 編號區分。來源集合共 23 支,其餘 14 支(macOS 15、browser/application/network/cloud 類)可自動檢查項數皆 0 或標的形態接不上 SSH/WinRM transport,不上架。2026-08-01 起選項來源再改為掃描設定檔庫動態餵(FR-059 options_source,見變更紀錄),上述 8 支已搬遷為庫內 SYSTEM 公版。

SonarQube 的掃描參數與三種執行模式(FR-058.5/.6/.7,DEV 實查 param_schema v4 當前生效版)

SonarQube 是平台第一個拉取快照(pull-snapshot)平台發動掃描並存的工具,以 scan_mode 參數在同一張工具卡內分流三種取源模式(D17 ZAP 式單卡多模式;憑證兩模式共用同一組 base_url+User Token):

模式(scan_mode 誰發動掃描 源碼來源 對客戶 SonarQube 適用情境
scan 原始碼掃描(預設,D24) 平台(Agent 執行 sonar-scanner) 公開 Git repo(D19) 寫入——推分析結果,專案不存在自動建立 沒有 CI 整合、要掃「稽核當下」的源碼狀態
upload 上傳原始碼壓縮包 平台(同上) 使用者上傳的壓縮包(FR-058.7) 寫入(同上) 源碼在私有 repo 或不在 git(委外交付源碼包、特定版本快照)——客戶打包上傳即可,不必把 git 憑證交給平台
pull 讀取既有結果 客戶自己的 CI / 開發者機器 平台不碰源碼 唯讀——只取回最近一次分析結果 已有成熟 CI、SonarQube 天天在跑,只要把結果收進證據池

各模式的參數欄位(conditionscan_mode,不可見欄位不必填也不送出):

key 型別 顯示條件 說明
scan_mode select・必填・預設 scan 永遠顯示 三選項如上表;hint 註明「上傳模式的檔案於發起執行時提供,設定頁不需填寫」
repo_url text・必填 scan 公開 Git repo 的 HTTPS 網址;不支援私有 repo 認證(要掃私有源碼改走 upload
project_key_suffix text・必填 scanuploadcondition.value 陣列形式 ["scan","upload"],FR-058.7 語法擴充) 只填後半段識別字;實際推上客戶 server 的專案代碼是 Guidant-AI-<此欄>,前綴由平台組上(D21——防撞號、可辨識來源)
project_key text・必填 pull 客戶 SonarQube 上的既有專案代碼
branch text・選填 pull 多分支為付費版(Developer Edition 起)功能;Community Build 留空即可,填了而 server 不支援回明確錯誤(D14)

三個必知限制與配套:

  • scanupload 是寫入行為且沒有 dry-run——每次掃描都把結果推上客戶 SonarQube,專案不存在會自動建立。FE 於 scan_mode 為寫入模式時(含舊 v1 任務 scan_mode 未存值、實際生效預設 scan 的情況)在參數區塊顯示橘色警語(D24 配套①,ProjectPlanningView.vue::isWritingScanMode);setup_guide 另載收緊做法(預先建好專案+移除 token 帳號的 Create Projects 全域權限)。
  • 支援語言僅七種 A 類純源碼語言(Python/JS/TS/Go/PHP/Ruby/Kotlin,D18)——不需編譯即可分析。C#/VB.NET 永遠只能走 pull:這不是取捨而是架構限制——.NET 的分析發生在編譯器內部(Roslyn analyzer 隨 MSBuild 編譯執行),SonarScanner CLI 明文不支援,且送進去不會報錯、只會靜默淺掃(產出一份看似正常實際幾乎沒分析到的報告),故 setup_guide 以醒目警語要求改用 pull。Java/C/C++ 目前亦不支援。
  • upload 的壓縮包不在本頁提供(D26)——任務設定只選模式;檔案於任務抽屜發起執行時上傳(壓縮包是「這一次要掃的源碼快照」,不是「任務怎麼掃」的設定),已上傳的檔案 sticky 保留供重掃沿用(D29)。格式與限額見任務抽屜頁 §11.1。

出處:param_schema v4 seed scripts/sql/2026-08-01-fr058-21-sonarqube-upload-scan-mode.sql(v1→v4 演進:2026-07-31-fr058-17(pull 兩欄)→ fr058-19(scan 模式+setup_guide 改寫)→ 2026-08-01-fr058-20(標籤精簡)→ fr058-21(upload 選項));FE 警語 ProjectPlanningView.vue:1008-1023condition.value 陣列支援 src/utils/detectionFieldValidation.jsDetectionConfigField.vue(純擴充,字串形式行為不變)。

任務層敏感參數加密(FR-058.0)

param_schemasecret: true 欄位(現況只有 ZAP 的 login_password)屬某一次掃描任務的機密,不是工具連線設定,只能落在 config.job_execution_detection_tools.tool_params(JSONB,與非機敏欄位混雜)。租戶層那套「整欄加密」無法直接套用,故另做「同一個 JSONB 內挑欄位加密」的機制(common/util/detection_secret_params.py):

環節 行為
寫入 job_service._encrypt_tool_secret_params() 把 secret 欄位包成自我描述 envelope {"__enc__": "fernet", "value": "<密文>"};欄位留空時從既有綁定沿用舊密文(否則使用者改任何其他參數都會清空密碼,且症狀要到掃描時才出現)
讀取(API response) JobToolResponseSchema.params 整個 key 不出現(非遮罩成 ****);另回 secret_keys_set(已設定值的 secret 欄位 key 名清單,只回 key 不回值)
FE 顯示 DetectionConfigFieldhasExistingValuesecret_keys_set.includes(field.key))顯示「已設定,留空=沿用原值」,而非空白必填紅框——逼使用者重打密碼才是真正的洩漏誘因
派工 decrypt_secret_params() 還原明文下發給 agent;agent 用完即丟。解密失敗(金鑰輪替、資料損毀)剝除該 key 而非落密文——送密文過去 agent 會拿它當密碼登入,症狀是「掃描跑完但沒進到登入後頁面」,比缺欄位更難查
稽核 log 同樣走 strip_secret_params() 剝除

為何用 envelope 而非裸密文:密文存進 JSONB 後與明文同為 string,無法從值本身判斷是否已加密。若靠「查 schema 哪些 key 是 secret」決定要不要解密,正確性就綁在 schema 上——而 param_schema 是版本化的(is_current 切換),改版後舊任務會解錯。改存 envelope 後值本身就說明自己加密與否,schema 只用來決定「新寫入的值要不要加密」,不參與解密判定。換工具時 FE 會一併清空 toolSecretKeysSet(否則新工具的同名 secret 欄位會誤顯示「已設定」,使用者不填就存 → 存進空密碼)。

掃描參數必填驗證(FR-058.2)

原本 FE 對掃描參數完全不驗,缺參數的任務照樣存檔 → 派工 → 到 agent 執行期才失敗(ZAP 缺 logged_in_indicator 實測踩過兩次)。改為 saveTask 前檢查,缺漏時 toast 列出欄位名稱並不送出。判斷是 condition-aware 的:因 condition 不成立而隱藏的欄位不算必填(被動掃描時 ZAP 的登入四欄不該被誤擋);secret 欄位已設定過(在 toolSecretKeysSet 內)留空=沿用原值、不算缺。與 DetectionConfigFieldvisible / showError 同源——三處都呼叫 src/utils/detectionFieldValidation.jsisDetectionFieldVisible() / findMissingRequiredDetectionFields(),不各判一套。出處:ProjectPlanningView.vue::saveTask:1037-1057

FE 別名坑:指派人員的審核旗標,FE 早期送 is_admin,serializer AssigneeInputSchema@post_load coalesce 進 is_approverapi/grc/serializers/job.py:105-114)。新資料一律 is_approver

狀態呈現:無 socket;儲存中 per-任務 spinner(taskSavingSet Set);儲存後前端 state 更新(不整頁重載)。

6. API 規格

Envelope:成功 {"status": true, "data": …}、失敗 {"error_code": "…", "msg": "…"}

6.1 總清單

分類 Method + Path 說明 完整規格
任務 PUT /grc/project/{project_uid}/job/{job_uid} 任務更新(關聯 full-replace) §6.2
picker GET /users/menu/org-units/menu/surveys/menu、POST /devices 指派 / 部門 / 設備 / 問卷下拉 GAI-SD-02

批次啟動 POST /grc/project/{uid}/start-task-execution 屬規劃頁功能 6,見 規劃頁 §6.4

6.2 核心 endpoint

[PUT] /grc/project/{project_uid}/job/{job_uid}

任務更新。全部欄位選填load_default=None);關聯陣列 full-replace(送 [] 清空、null/省略 = 不動)。Request(JobUpdateRequestSchemaMeta.unknown=EXCLUDE):

{
  "name": "訪談紀錄蒐集",
  "description": "…",
  "guide": "…",
  "job_type": "survey",
  "control_uid": null,
  "assignees": [{ "uid": "<user uid>", "is_approver": true }],
  "department_uids": ["<org_unit uid>"],
  "device_uids": ["<device uid>"],
  "surveys": [{ "uid": "<survey uid>", "approval_required": true }],
  "tool": { "uid": "<detection_tool uid>", "params": {"hosts": "<target host>"}, "completion_mode": "manual" }
}
欄位 型別 必填 說明
name / description / guide string|null 任務文案 → job_executions
job_type string|null OneOf GrcJobType(general / survey / detection_tool
control_uid string|null 控制層 workflow_execution.uid;可省略,BE 由 job 的 workflow 階層自動解析
assignees array|null [{uid(必填), is_approver(預設 false;相容 is_admin 別名)}]task_assignees
department_uids array[string]|null 部門 org_unit uid → job_execution_org_units
device_uids array[string]|null 設備 uid → job_execution_devices
surveys array|null [{uid(必填), approval_required(預設 null)}]survey.task_surveys送 null 保留既有審批旗標(BPMN 編輯器同步不誤蓋,SurveyInputSchema:117-125
tool object|null 否(detection_tool 型必填才可正常掃描) {uid(必填,detection_tools uid), params(Raw,依 param_schema), completion_mode("auto"|"manual",未帶=partial-update 不動既有值,新建綁定時 app service 補預設 "manual")}config.job_execution_detection_toolsDetectionToolBindingSchema:138-153

出處:request api/grc/serializers/job.py:128-153(含 DetectionToolBindingSchema:138-153)、route api/grc/routes/job_route.py:100-136、service app/grc/service/job_service.pyupdate_job + _reconcile_task_surveys:228 + _replace_detection_tool_binding

Response dataJobResponseSchema,形狀同 control-tree 的 Job 節點):

欄位 型別 說明
id / name / description / guide string 任務基本資料(id=job uid)
job_type / status string 類型 / 狀態
template_job_id string|null 範本任務來源
can_revert_job bool 可否退回
assignees / departments / devices / surveys array 關聯子物件(形狀同 control-tree Job 節點)
tool object|null detection_tool 型才有值:{uid, code, name, params, completion_mode, secret_keys_set}JobToolResponseSchema,供 FE 讀取端 prefill)。params 已剝除所有加密 envelope 欄位(整個 key 不出現);secret_keys_set 是已設定值的 secret 欄位 key 名清單(只回 key 不回值),供 FE 顯示「已設定,留空=沿用原值」——剝除後 FE 無從分辨「沒設過」與「設過但看不到」,會把已設定的必填欄位標成缺漏(FR-058.0 T-0.3)

出處:api/grc/serializers/job.py:71-98JobToolResponseSchema,含 secret_keys_set)/:86-JobResponseSchema);加解密與剝除 util common/util/detection_secret_params.py;寫入端 app/grc/service/job_service.py::_encrypt_tool_secret_params:338-370

6.3 批次動作

快速配置(無專屬 endpoint,FE 逐一 PUT)

FE-only 編排:多選人員(來源 = 專案參與人員)→ 迴圈所有可編輯canEditCtrl)控制項底下的任務 → 每個 job 把選取人員 additive 併入既有指派(已存在者跳過)→ 逐一 PUT job⚠️ 每筆 PUT 送 department_uids: [] / device_uids: [] / surveys: []——因 full-replace 語意,會清空該任務既有的部門 / 設備 / 問卷關聯(見 §12 坑)。出處:ProjectPlanningView.vue:executeQuickConfig:1192-1230

[POST] /grc/project/{project_uid}/start-task-execution

無 body。把該專案「已指派且 TODO」的 prep-job 批次轉 PROCESSING 並發站內通知。限專案 manager_check_manager,否則 GRC_403002);idempotent 可重按。Response data{"activated_count": int, "detection_dispatched_count": int}(分別為實際轉 PROCESSING 的任務數、自動派出首次掃描的 detection_tool 任務數)。

FR-056:自動派 detection_tool 首次掃描——批次轉 PROCESSING 的同時,對其中 job_type='detection_tool'查無任何 detection_executions 紀錄NOT EXISTS,冪等防重)的任務逐筆呼叫 DetectionOrchestrationService.start_execution() 派出第一次掃描;單筆派工失敗(如未設定憑證)用 SAVEPOINT 隔離、不擋整批發佈與其餘任務,失敗的任務留給執行者從 任務執行抽屜 手動補派。出處:service app/grc/service/task_execution_service.py_check_manager:49-56start_task_execution:58-96_auto_dispatch_detection_scans:98-134)、query infra/grc/repository/task_execution_query.py::get_detection_jobs_without_execution:134-、serializer api/grc/serializers/task_execution.py

scan_mode=upload 的任務不進自動派發(FR-058.7,D33):自動路徑不帶檔案,upload 任務必然打中「首次無檔」400(DETECTION_TOOLS_400005),且該錯誤被批次派發的 try/except 吞掉只留 warning log——PM 看到成功 toast、執行者無感,又因失敗不產生執行紀錄、冪等條件永遠成立,每按一次「開始執行任務」就再失敗一次。故在挑選階段排除:get_detection_jobs_without_execution 的查詢排除 tool_params->>'scan_mode'='upload' 的綁定(task_execution_query.py:142/:169),upload 任務一律由執行者在任務抽屜上傳檔案後手動執行(抽屜有無檔不給按執行的前置擋門);pull/scan 自動派發行為不變。FE 配套:批次發佈 confirm 文案加註「上傳型掃描任務需由執行者上傳檔案後手動執行」(i18n start_task_execution_confirm_message)。已執行過的 upload 任務本來就不在冪等清單內,不受影響。

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/project/ProjectPlanningView.vue 任務卡 inline 編輯(Panel 卡片、四關聯 MultiSelect、審核人 / 審批 switch、saveTask PUT);檢測工具區(onSelectDetectionTool 帶 default + 清舊 secret 狀態、detectionParamSchemaCache 依工具快取 schema、FR-058 掃描參數必填驗證)
src/components/detection-tools/DetectionConfigField.vue 掃描參數的動態欄位渲染,與檢測工具管理設定表單共用同一元件hasExistingValue 在本頁綁 toolSecretKeysSet,在該頁綁 config.has_credentials
src/utils/detectionFieldValidation.js (FR-058)isDetectionFieldVisible() / findMissingRequiredDetectionFields()——condition 可見性與必填檢查的共用實作,本頁 saveTaskDetectionConfigField、檢測工具管理頁三處同源
src/service/BaseService.js put(...)/grc/project/{uid}/job/{jobId}

8. 後端檔案地圖(本頁核心鏈路)

鏈路 Route App Service 底層
任務更新 api/grc/routes/job_route.py(PUT,僅 JWT) JobService.update_job(full-replace reconcile + BPMN 同步,同一 transaction) compliance.job_executions + reconcile task_assignees / job_execution_org_units / job_execution_devices + survey.task_surveys_reconcile_task_surveys)+ config.job_execution_detection_tools_replace_detection_tool_binding,FR-056)
開始執行任務(含自動派掃描) api/grc/routes/start-task-execution app/grc/service/task_execution_service.py::start_task_execution_check_manageractivate_jobs → 通知 → _auto_dispatch_detection_scans job_executions(狀態轉換)+ DetectionOrchestrationService.start_execution()(見 檢測工具管理

⚠️ DDD 提醒:PUT job route 層無角色守門(別比照為權限典範);問卷關聯跨到 survey schema 的 task_surveys(非 compliance.job_execution_surveys),維護留意 schema 邊界;detection_tool 綁定表 config.job_execution_detection_toolsconfig schema(非 compliance),跨 schema 命名慣例注意。

9. DB

9.1 資料表總清單(本頁讀寫的全部表)

讀寫 說明 詳述
compliance.job_executions 讀 / 任務本體(name / description / guide / job_type) §9.3
compliance.task_assignees 讀 / (reconcile) 指派人員(含 is_approver §9.3
compliance.job_execution_org_units 讀 / (全刪重建) 任務↔︎部門 §9.3
compliance.job_execution_devices 讀 / (全刪重建) 任務↔︎設備 §9.3
survey.task_surveys 讀 / (reconcile) 任務↔︎問卷(含 approval_required §9.3
config.job_execution_detection_tools 讀 / (FR-056) 任務↔︎檢測工具綁定(工具 uid / 掃描參數 / 完成模式,is_delete 軟刪) §9.3

9.2 ER 圖

planning_er_jobs cluster_flow BPMN(唯讀容器) cluster_jobs 任務(本頁寫入) cpart oscal.catalog_control_parts AO(props.workflow-template-uid) wftpl compliance.workflow_templates per-AO 範本快照 cpart->wftpl props.workflow-template-uid wfexe compliance.workflow_executions wftpl->wfexe template_id job compliance.job_executions prep-job(TODO → PROCESSING) wfexe->job 1:N asg compliance.task_assignees 指派人員(+is_approver) job->asg task_id jorg compliance.job_execution_org_units 部門 job->jorg jdev compliance.job_execution_devices 設備 job->jdev jsvy compliance.job_execution_surveys 問卷(snapshot) job->jsvy tsvy survey.task_surveys survey × device 展開(執行期追蹤) jsvy->tsvy 展開
任務鏈:AO 經 BPMN 範本快照長出 prep-job,本頁寫四張關聯表;虛線 = props 參照 / 展開

9.3 核心表欄位(取自 DEV DB dump,含 DB comment)

compliance.job_executions — 任務本體

欄位 型別 說明
uid varchar(50) 任務 UUID(對外 job id)
name varchar(500) 任務名稱 ← name
description / guide text 描述 / 指南
job_type varchar(50) general / surveyjob_type(另有 type jobtype enum 欄)
status jobstatus 任務狀態(TODO / PROCESSING…)
org_unit_id / tenant_id integer 租戶 / 組織(RLS)

compliance.task_assignees — 指派人員

欄位 型別 說明
project_id / control_id / task_id integer 複合定位
task_uid / task_template_id varchar 任務 uid / 範本任務 id
user_id integer 指派人
role varchar(50) 角色
is_approver integer 是否審核者(0/1)← assignees[].is_approver

compliance.job_execution_org_units / job_execution_devices — 部門 / 設備關聯

欄位 型別 說明
job_execution_id integer → job_executions
org_unit_id / device_id integer 部門 / 設備(全刪重建 reconcile)

survey.task_surveys — 問卷關聯(跨 schema)

欄位 型別 說明
task_id / survey_id integer 任務 / 問卷
approval_required boolean 是否需審核 ← surveys[].approval_required
device_id / department_id integer 問卷施測的設備 / 部門
job_evidence_id integer soft ref → job_evidences.id(標記 GRC 建立)
is_delete boolean 軟刪旗標

⚠️ schema 註:問卷關聯在 survey schema 的 task_surveysjob_service._reconcile_task_surveys 管理),不是 compliance.job_execution_surveys(那是另一張簡單映射表,本更新路徑不寫)。欄位一律取自 db_schema.json

config.job_execution_detection_tools — 任務↔︎檢測工具綁定(FR-056)

欄位 型別 說明
job_execution_id integer compliance.job_executionsuq_jedt_job_active 唯一約束:is_delete=false 下每任務僅一筆有效綁定)
detection_tool_id bigint config.detection_tools(工具目錄)
tenant_config_id bigint|null tenant_detection_tool_configs.id建表時預留,寫入端從未寫過此欄(一律 NULL,見 檢測工具管理 §12 已知坑),憑證解析改走 (tenant_id, detection_tool_id) fallback 反查
tool_params jsonb 掃描參數(動態欄位,依 detection_tool_param_schemas 定義)。secret: true 欄位以加密 envelope {"__enc__":"fernet","value":"<密文>"} 存放(FR-058.0),與明文欄位混在同一個 JSONB;金鑰同租戶層憑證的 DETECTION_TOOL_ENCRYPTION_KEY
completion_mode varchar(20) manual(預設)/ auto
is_delete boolean 軟刪(重新綁定其他工具=標舊列刪除 + 建新列,非 update)

10. 頁面邏輯與資料對應

任務隨 control-tree 一次載入(內嵌於 AO 節點)。欄位對應

畫面元素 FE state payload 欄位 → DB
名稱 / 描述 / 指南 task.name / .description / .guide 同名 → job_executions
類型 task.jobType job_typejob_executions.job_type
指派人員(含審核人) task.assignees[{id,name,is_approver}] assignees[{uid,is_approver}]task_assignees
部門 / 設備 task.departments / .devices department_uids / device_uids → org_units / devices 關聯
問卷(含審批) task.surveys[{id,name,approval_required}] surveys[{uid,approval_required}]survey.task_surveys
檢測工具 / 參數 / 完成模式(FR-056) task.tool.{uid,params,completionMode} tool{uid,params,completion_mode}config.job_execution_detection_tools
secret 參數的「已設定」狀態(FR-058.0) task.toolSecretKeysSet(string[]) response tool.secret_keys_set唯讀,不回送

選定檢測工具的預設值帶入(FR-057,FR-058 補清 secret 狀態):切換 task.toolUid 時先把 toolParams 清成 {}toolSecretKeysSet 清空(換工具=換一套 schema,舊工具的 secret 已設定狀態不再適用),取回該工具的 param_schema 後,遍歷欄位定義找出有 default 值(非 undefined/null)的欄位組成預設物件,一次性寫回 toolParams——避免使用者看到全空表單以為沒有預設值可用(如 timeout_sec 預設 3600、Nmap port_range 預設 1-1024、CINC Auditor transport 預設 ssh)。出處:ProjectPlanningView.vue::onSelectDetectionTool:1011-1023

儲存流程saveTask 依序做 client 檢查——① detection_tool 型必須選定工具(warn_tool_required)→ ② 掃描參數必填檢查(FR-058,condition-aware,缺漏列出欄位名,見 §5)→ ③「survey 有審批要求但無審核人」→ 任一不過皆 toast warn 不送 → PUT → 前端 state 更新。錯誤對應GRC_404005(任務不存在)/ GRC_409033(問卷已有填答無法移除)→ toast。

11. 背景行為與外部依賴

類型 內容
socket (儲存後前端 state 更新)
BPMN 同步 update_job 在同一 transaction 回寫 BPMN userTask(name / description / guide / job_type / 問卷 actionInfo),維持 BPMN 編輯器一致
Drive 任務名稱變更 → best-effort 觸發 Drive 資料夾改名(無 Drive 整合則靜默跳過)
依賴 /users/menu(指派)/ /org-units/menu(部門)/ /surveys/menu(問卷)/ POST /devices(設備)

12. 邊界情況與已知坑

  1. PUT job 無 BE 角色守門:route 僅 @jwt_required(),FE 靠三層 canEdit 擋;繞過 FE 直打 API 任一登入者都能改任務指派(與規劃頁 §12 同一 finding)。
  2. 審核人檢查只在 FE:「survey 有審批要求則至少一審核人」只在 saveTask 前 client 檢查(toast 不送),BE 無此驗證——直打 API 可存出「有審批要求卻無審核人」的任務。
  3. 問卷關聯跨 schema、非直覺:任務問卷走 survey.task_surveys_reconcile_task_surveys),不是 compliance.job_execution_surveys;後者是另一映射表,本路徑不動。
  4. surveys[].approval_required 送 null 保留既有值SurveyInputSchemaapproval_required load_default=None——BPMN 編輯器同步問卷時不帶此欄(無此 UI),送 null → _reconcile_task_surveys 保留既有審批旗標,不誤蓋規劃頁設定;規劃頁顯式送 True/False 行為不變。
  5. is_adminis_approver 別名:FE 早期送 is_admin,serializer @post_load coalesce 進 is_approver;下游只讀 is_approver
  6. 關聯 full-replace 語意assignees/department_uids/device_uids/surveys[] 清空、null/省略不動;部門 / 設備關聯是全刪重建(reconcile)。
  7. 問卷已有填答不可移除:移除已有答案的問卷 evidence → GRC_409033GRC_SURVEY_HAS_ANSWERS)。
  8. ⚠️ 快速配置會清空部門 / 設備 / 問卷關聯executeQuickConfig 對每個 job 只 additive 合併指派人員,但送 department_uids: [] / device_uids: [] / surveys: []——因 full-replace 語意([]=清空),會把該任務既有的部門 / 設備 / 問卷關聯一併清掉。若已配置這些關聯,用快速配置補人員前要留意會被清空(ProjectPlanningView.vue:1218)。
  9. survey × device 笛卡爾積:任務掛多問卷多設備時 survey.task_surveys 列數會乘開(每問卷 × 每設備一列),指派前想清楚資料量。
  10. date-only 顯示 08:00 陷阱:任務時間相關欄位 BE 慣例吐 YYYY-MM-DDTHH:MM:00 無 tz,前端 date-only 顯示要留意時區偏移(見 _overview 時區慣例)。
  11. job_execution_detection_tools.tenant_config_id 恆為 NULL(FR-056 已知坑):欄位建表時預留、讀取端(start_execution)會讀,但寫入端 _replace_detection_tool_binding 從未寫過此值——實務上憑證解析一律 fallback 走 (tenant_id, detection_tool_id) 反查(該組合有 UNIQUE 約束可唯一定位)。若使用者「先建任務、後設工具憑證」,查詢時解析比綁定時寫死更穩,故此設計非遺漏;該欄位是否退役留待未來討論。
  12. secret 掃描參數留空=沿用、不是清空(FR-058.0)encrypt_secret_params() 對空值會從既有綁定沿用舊密文——因為 FE 對已設定的 secret 欄位承諾「留空=沿用原值」,不沿用則使用者每次改別的參數(如 timeout_sec)都會把密碼清空,且症狀要到掃描時才浮現。代價是「清空單一 secret 參數」沒有 UI 入口;真要清空得換工具(onSelectDetectionTool 會清 toolParamstoolSecretKeysSet)或直接改 DB。
  13. 換檢測工具會清空全部掃描參數onSelectDetectionTool 切換 toolUid 時先把 toolParams 清成 {}toolSecretKeysSet 清空,再依新工具 param_schema 帶入 default。這是刻意的——不清會讓新工具的同名 secret 欄位誤顯示「已設定」,使用者不填就存 → 存進空密碼。誤按下拉再切回原工具,參數要重填。
  14. tool_params 的加密判定看值不看 schemais_encrypted() 只認 envelope 的 __enc__ 標記,不查 param_schema 哪些 key 是 secret——因為 param_schema 版本化(is_current 可切換),若靠 schema 判定,改版後舊任務會把明文當密文解(拋例外)或把密文當明文送給 agent(帳密以密文形式送出,掃描失敗且難查)。改動加解密路徑時勿引入 schema 依賴。
  15. 檢測工具任務不走 flow-engine complete 觸發掃描detection_tool 型任務的「開始執行」走獨立的 DetectionOrchestrationService(見 任務執行抽屜 §11.1),與本頁「儲存任務」/「開始執行任務」的批次轉 PROCESSING 是兩件事——後者只是把任務從 TODO 轉 PROCESSING 讓任務「可以」被執行,掃描本身另外觸發(規劃頁批次轉 PROCESSING 時會自動觸發首次掃描,見 §6.3)。

13. 開發與驗證

  • 跑起來:起 BE + FE;登入見 .env / 部署文件測試帳號(需該節點 manager;開始執行需專案 manager)
  • 導航:規劃頁 Tab0 → 左樹選 AO → 右面板任務卡展開編輯;快速配置 / 開始執行在 Header
  • 前置資料:需 AP=planning 的專案 + 至少一個控制項有 AO 任務;備 user / org_unit / device / survey master 測四關聯;切 survey 型測問卷 + 審批 + 審核人 switch 連動;測快速配置後檢查部門/設備是否被清空(坑 8)
  • 相關:現況編輯 / 程序書見 現況編輯;批次匯入見 批次維護;任務真相=範本 BPMN userTask;問卷設計見 survey 功能群