FR-038 — 前端遷移到 audit-round 新引擎 實作計畫

範圍:把專案/稽核生命週期的 FE 從舊 /grc/project/<uid>/ap/<uid>/* 引擎,遷到新的 audit-round(稽核輪次)引擎/oscal-project/start/projects/<id>/audit-rounds/*/audit-round/<id>/*/ap/<id>/*/ar/*/poam*)。 原則:大部分 FE 沿用,只動 4 塊;漸進式、每 Step 可獨立 ship + 手測。 撰寫日:2026-06-16 BE 端新引擎 API 已上線(見 fr038-api-inventory.md §3)。

0. 已拍板決策

# 決策 影響
D1 路由參數從 apUid 改為 roundUid(新引擎輪次為核心;AP 沿 engagement 多輪共用) 所有 ap-scoped route + 麵包屑 meta.breadcrumb.parent + 側欄高亮要跟著改
D2 /grc/project/ap 引擎漸進退場:新 view 全接新 API;舊 route 先留但拔掉入口(避免使用者誤入依賴退役表的舊 AR/task-setup);全綠後再刪舊 route + service 過渡期新舊並存,但使用者只走得到新的

1. 範圍總表

區塊 現行檔 動作 難度
① Audit Round 列表 ProjectApListView.vue 重構(AP 清單 → 輪次清單)
② AP 維護 (無) 新建
③ AR 維護 AuditReviewView.vue + AuditVerdictPanel.vue 重構(控制項層 → AO 層 + risk)
④ POA&M PoamView.vue + PoamDetailDrawer.vue 重構(扁平 → 三層) 中大
保留 MyTasksView / TaskSetupView / RoundSwitcherBar / AuditTreeNav / AuditControlRef / FlowPhaseBanner / StatusBadge / JobExecutionDrawer 驗證即可

Step 0 — 地基(先做)

目標:常數 + 路由 + 輪次切換器就位,讓後續 Step 有地基。

  • src/config/api/api.js:新增端點常數
    • OSCAL_PROJECT_START = /oscal-project/start
    • AUDIT_ROUNDS = /projects(+ /<id>/audit-rounds[/list]
    • AUDIT_ROUND = /audit-round(+ /<id> + 動詞 /launch-audit|launch-reverify|start-auditing|close-round
    • AP = /ap(+ /<id>/reviewed-controls|assessment-subjects|tasks)、AUDIT_ROUND_AP = /audit-round/<id>/ap[/generate-draft]
    • AR_FINDINGS /audit-round/<id>/ar/findingsAR_FINDING /ar/finding/<id>AR_RISKS /audit-round/<id>/ar/risksAR_RISK_FINDINGS /ar/risk/<id>/findingsAR_OBSERVATIONSAR_FINALIZE
    • POAM_ITEMS /audit-round/<id>/poam-itemsPOAM_ITEM /poam-item/<id>REMEDIATION_MILESTONES /remediation/<id>/milestonesPOAM_MILESTONE /poam-milestone/<id>
  • src/config/router/index.js:新增 round-scoped route(D1)
    • /project/projects/:id/round/:roundUid/{plan,audit,poam} 等;舊 :apUid route 先留(D2)
    • menu.json 補新 route name;meta.breadcrumb[0].parent 指對 owning 列表頁
  • RoundSwitcherBar.vue:改接 POST /projects/<id>/audit-rounds/list(payload 對齊 round_no / status / parent)
  • 驗收:常數可 import、新 route 可進(空殼)、RoundSwitcher 能列輪次。

Step 1 — ① Audit Round 列表(重構,中)

目標ProjectApListView 改成列輪次 + 生命週期動詞按鈕。

  • ProjectApListView.vue
    • 列表來源 → POST /projects/<id>/audit-rounds/list;欄位 round_type / status(七態)/ parent 血緣 / start_at
    • 「建輪次」→ POST /projects/<id>/audit-rounds(initial / surveillance)
    • 按鈕可用性改用 round.status 七態(取代舊 flow stage 判斷):
      • planning → 啟動稽核 POST /audit-round/<id>/launch-audit
      • audit_planning → 進 AP 維護(Step 2)
      • auditing → 進 AR 維護(Step 3);start-auditing 動詞
      • remediation → POA&M(Step 4)
      • pending_reverify → 發起覆核 launch-reverify
      • closed → 唯讀
  • 驗收:建輪次 / launch-audit / 狀態正確顯示 / 各狀態按鈕正確。

Step 2 — ② AP 維護(新建,大)

目標:launch-audit 後,稽核員編 AP 的全新畫面。

  • 新 view AuditPlanView.vue(route /round/:roundUid/plan):
    • 載入 GET /audit-round/<id>/ap;可 POST .../ap/generate-draft 重生
    • 三區塊:
      • 查核控制項PUT /ap/<id>/reviewed-controls(可重用 AuditTreeNav 當控制項勾選器)
      • 抽查名單PUT /ap/<id>/assessment-subjects(subject_type ∈ component/inventory-item/location/party/user,全量覆寫)
      • 行程 + 方法PUT /ap/<id>/tasks(timing + methods EXAMINE/INTERVIEW/TEST)
  • 驗收:草稿載入 / 三區塊存檔 / 重生草稿。

Step 3 — ③ AR 維護(重構,大)

目標AuditReviewView 判定下沉到 AO 層 + 新增 risk。

  • AuditReviewView.vue + AuditVerdictPanel.vue
    • 矩陣來源 → GET /audit-round/<id>/ar/findings(控制項導覽 + 展開 AO;每 AO 一筆 finding)
    • AuditVerdictPanel 重構:從單一 control verdict → AO 逐項判定PUT /ar/finding/<id>,met/not_met/pending)
    • observation:POST /audit-round/<id>/ar/observations
  • 新增 RiskPanel.vue
    • 列表/建立 GET|POST /audit-round/<id>/ar/risks(severity low/medium/high/critical)
    • 組風險:PUT /ar/risk/<id>/findings(多對多勾 finding,全量覆寫)
  • finalize:POST /audit-round/<id>/ar/finalize → 無 not_met 結案 / 有 not_met 轉 remediation + 自動生 POA&M
  • 可留:RoundSwitcherBar / AuditTreeNav / AuditControlRef / FlowPhaseBanner / PreviousFindingsPanel
  • 驗收:AO 逐項判定 / 建風險 + 關聯 finding / finalize 兩條路徑(closed vs remediation)。

Step 4 — ④ POA&M(重構,中大)

目標PoamView 從扁平改成三層。

  • PoamView.vue + PoamDetailDrawer.vue
    • item 列表 POST /audit-round/<id>/poam-items/list(讀 deadline_warning / days_remaining,BE 已回)
    • item 詳情 GET /poam-item/<id>(封面 + risk/remediation/milestone)
    • 整改計畫 POST /ar/risk/<id>/remediations
    • 里程碑 POST /remediation/<id>/milestonesPUT /poam-milestone/<id>per-milestone assignee + target_date
    • 結案 POST /audit-round/<id>/close-round(POA&M 全 closed 才可)
  • 驗收:三層 CRUD / per-里程碑指派 / 180 天告警 / close-round 連動。

2. 漣漪 / 共用改動 checklist

3. 保留不動(驗證即可)

My Jobs(MyTasksView,任務引擎獨立)、Task Setup(TaskSetupView,控制項→AO→job 階層,驗 context 傳遞)、JobExecutionDrawer、共用元件庫(StatusBadge / AuditTreeNav / AuditControlRef / FlowPhaseBanner)。

4. 開工順序

Step 0 → 1 → 2 → 3 → 4(依賴遞增、風險遞增)。每 Step 獨立 commit + 手測 + 不破壞既有;Step 1 一通整條生命週期入口就活。BE 新引擎 API 已上線,FE 可直接接。

對應後端設計:engagement 模型 / 七態狀態機 / 四 clone-snapshot 邊界見 design.md §3、api-contract.md §3~§8。