跳轉到

專案管理 功能群總覽

本檔放「本功能群多個頁面共用的知識」:頁面地圖、稽核輪次狀態機、角色權限基調、核心資料模型。

各頁面 spec 引用本檔,只寫自己頁面的差異——改共用邏輯時改這裡一份

變更紀錄

日期 內容
2026-08-02 新增 §4「覆核輪受評範圍=母輪未通過控制(narrowed scope)」共用概念——覆核輪範圍收斂真相在本輪 AP、規劃階段即生效(167f578f / 1182034d / 9b2eae04);§5 補坑 5「覆核輪範圍有兩個寫入者」。同步修正 §2「啟動複驗」與 §4 的輪次狀態同步描述(b283f1abfinalize_audit 補掛 _sync_project_status

1. 頁面地圖

頁面 FE route 用途一句話 spec
專案列表頁 /project/projects 專案清單、建立入口 專案列表頁
專案建立 /project/projects/new 三步精靈成立專案(clone 資源庫三件組) 專案建立
專案總覽頁 /project/projects/:id/round/:roundUid 單一專案儀表板、輪次切換與階段導覽中樞 專案總覽頁
專案規劃頁 /project/projects/:id/round/:roundUid/planning planning 階段主工作區:SSP 現況 + 任務指派 + 程序書 專案規劃頁
稽核計畫填寫頁 /project/projects/:id/round/:roundUid/ap-authoring(屬稽核執行群) audit_planning 階段:AP 行程 / 查核方法 →稽核執行群

頁面 × 階段對應:每個稽核輪次階段有一個「主場頁面」——

planning        → 專案規劃頁(本群)
audit_planning  → 稽核計畫填寫頁(稽核執行群)
auditing        → 稽核執行頁(稽核執行群)
remediation     → POA&M 頁(稽核執行群)
closed          → 各頁唯讀

2. 稽核輪次狀態機(本群與稽核執行群共用的核心)

模型:一個專案 = 一輪主稽核 + N 輪覆核(close-out);輪次實體是 compliance.project_audit_rounds,狀態由綁定的 BPMN workflow(jedi-flow-engine)驅動。

稽核輪次狀態機:7 態與轉換動作(動作後的英文 = API endpoint,括號 = 允許角色)

轉換權限與前置條件(BE 強制,enforcement 在 app/grc/service/audit_round_app_service.py):

轉換 誰能按 前置條件 失敗 error code
建立輪次 → planning manager 專案有 living SSP GRC_ROUND_LIVING_SSP_MISSING
啟動稽核 launch-audit → audit_planning manager status=planning、living_ssp_id 非空 GRC_ROUND_PHASE_READONLY
開始稽核 start-auditing → auditing auditor(manager 可代行) status=audit_planning、AP 已存在
結束本輪 close-round manager POA&M 全部 closed
啟動複驗 launch-reverify auditor(manager 可代行) status=pending_reverify

通用 phase guard:寫入 API 用 common/util/round_guard.pyassert_round_phase(round, {允許階段}),階段不符回 GRC_ROUND_PHASE_READONLY(412)。新增本群寫入 API 時必加

3. 角色權限基調

角色是誰

  • manager(專案負責人)——開專案、定範圍、指派任務,時機到了啟動稽核輪次。「身為 manager,我要規劃這輪稽核要涵蓋哪些控制項、指派誰負責,準備好就啟動稽核。」
  • auditor(稽核員)——規劃期可協助編修稽核計畫,主戰場在稽核執行群。「身為 auditor,我要在規劃期先看到專案範圍與 SSP 現況,為稍後的判定做準備。」
  • viewer(一般參與者,如受評方成員)——只能檢視進度。「身為 viewer,我要能查看目前規劃到哪,不需要編輯權限。」

專案層角色compliance.project_participants.role):manager / auditor / viewer(一般參與者)。

動作類型 manager auditor viewer
輪次生命週期(建立 / launch / close)
稽核規劃寫入(AP / 任務指派) ✓(全域代行)
檢視

manager 全域 override 慣例:BE 檢查 auditor 的地方一律允許 manager 代行(role not in ("auditor", "manager") 才拒絕)。

頁內三層遞進(專案規劃頁特有,FE 判定):專案 manager → 控制群組 manager → 控制項 manager,任一層即可編輯該層以下內容;詳見 專案規劃頁 §3。

4. 核心資料模型

專案管理核心資料模型(藍 = compliance 業務層、黃 = oscal 合規資料層)

living vs 凍結 SSP(本群最重要的概念): - living SSPproject_extensions.living_ssp_id)=專案「現在」的控制項實作狀態,專案規劃頁編輯的就是它 - 凍結快照project_audit_rounds.ssp_id)= launch-audit 當下拍的快照,稽核後續階段(AP / AR)都基於快照,living 繼續演進不影響本輪稽核 - 讀控制項結構一律從 projects.uid → living_ssp_id → profile_imports → catalog_controls 解析(不要繞舊 v1 表)

覆核輪受評範圍=母輪未通過控制(narrowed scope,2026-08-02 起)

覆核輪(close-out)不是重跑整輪,是 OSCAL 語意的 partial reassessment —— 本輪受評範圍收斂成「母輪判定 not_met 的那幾條控制」,不是母輪全集

面向 規則
範圍真相 本輪自己的 APoscal.ap_reviewed_controls.control_selectionslaunch_reverify clone 母輪 AP 時就地收斂成 narrowed),非 living profile、非母輪 AP
narrowed 怎麼算 母輪 ar_result_idassessment_findingstarget_status_state='not-satisfied' → 對回控制項(AssessmentResultAppService.narrowed_control_ids_from_parent
生效時機 規劃(planning)階段即生效,不必等「啟動稽核」——覆核輪 planning 期 ssp_id 仍是 NULL(SSP 快照延到 launch_audit),控制樹改以「close-out + ssp_id IS NULL + 有 AP」判定(_is_planning_stage_reverify)一樣讀本輪 AP
影響的畫面 控制項導覽(專案總覽頁 / 專案規劃頁 左樹)、稽核計畫填寫頁 受評控制項 / 行程、AR 判定矩陣、OSCAL AP 匯出——全部讀同一顆 AP,故一致
稽核行程 覆核輪 clone 母輪 AP 時,ap_assessment_activities.related_controls 同步收斂;過濾後無控制項的行程整條不 clone(含其 task)——覆核輪不該帶著母輪已通過控制的行程

OSCAL 依據reviewed-controls.control-selections 在 AP 是「本次計畫查哪些」、 在 AR result 是「本次實際查哪些」。AP=全集 / AR=narrowed 的落差會被讀成 「計畫查 N 條卻只查了 M 條」(像評估未完成),匯出 OSCAL AP 也會把矛盾一併輸出。

輪次狀態 → 專案狀態同步projects.status 由輪次驅動(全輪 closed→completed、 否則 in_progress),同步點 _sync_project_status 掛在所有輪次 writer 上, 含 finalize_audit(稽核順利通過、無 not_met 直接關閉的路徑;2026-08-02 補齊, 此前該路徑漏掛導致專案永遠停在 in_progress、列表「已完成」篩選撈不到)。

5. 本群共用的已知坑

  1. AO 識別碼是 _obj.N 格式(非 UUID),由 SSP 實作記錄衍生(app/grc/service/ao_derivation.py);三套識別碼(tree / SSP / AR)都以 _obj.N 為 canonical
  2. 任務名稱/描述的真相來源是 BPMN 範本的 userTask,不是 DB 任意欄位;改任務文案要動範本
  3. v1 殘留profile_controlscatalog_control_assessments 等 v1 表已 drop,看到舊 code 引用是死路,不要照抄
  4. 輪次狀態是 BPMN 驅動:直接 UPDATE project_audit_rounds.status 會跟 workflow 脫鉤,一律走 API
  5. 覆核輪範圍有兩個寫入者,改一個不夠(2026-08-02):AP 的 reviewed-controls 除了 launch_reverify 建輪時寫,稽核計畫頁每次存行程(set_tasks)也會用「行程控制項聯集」回寫它(FR-040 Phase9 行程驅動,_backfill_scope_from_tasks)。因此收斂覆核輪範圍必須行程與 reviewed-controls 一起收斂——只改 reviewed-controls 而行程仍帶母輪全集,下一次存行程就會被打回全集(STG 實證:建輪後 11 秒被打回)。修既有髒資料時同理,兩張表都要改