稽核執行頁 / AR 判定(Audit Review)
功能群:稽核執行|階段轉換、AP→AR→POA&M 資料模型、AO 判定粒度先讀 功能群總覽
事實基準:2026-07-05 從 FE / BE code 掃出(FR-038 v2 round-based B5 AR + FR-041 稽核指引 + FR-044 稽核紀錄匯入);API schema 逐條對照
api/project/serializers/audit_round.py與app/grc/service/assessment_result_app_service.py
變更紀錄
| 日期 | FR | 變更 |
|---|---|---|
| 2026-07-06 | FR-047 | 改造成 hub 導航頁:Tab0 判定工作區拆至 稽核判定工作區、Tab1 風險管理拆至 稽核風險管理;本頁保留頁級 chrome(統計徽章 / finalize 推進 / 稽核紀錄 XLSX 匯入 / 唯讀模式)與跨子頁導航 |
| 2026-07-09 | FR-047 | 已知坑修復:判定存檔後風險來源清單自動刷新(六項#4,saveVerdict
收尾重載 findings) |
1. 功能描述
稽核執行頁是稽核輪次 auditing 階段的主工作區:稽核員逐一檢視在範圍控制項的證據,做出判定(met / not_met / pending)、記錄觀察(observation)、把不符合項組成系統風險(risk),最後 finalize 產出 AR(Assessment Results,評估結果)。判定的控制項母體來自凍結 SSP 快照;finalize 時 not_met 缺失自動生成 POA&M(見 _overview §2 / §4)。
本頁為 TabView 兩 tab 的導航 hub:Tab0「控制項稽核判定」(三欄判定工作區)與 Tab1「風險」(系統風險管理)各自的 field-level 逐欄規格拆成子頁;頁級 chrome(頂部統計徽章、FlowPhaseBanner finalize 推進、稽核紀錄 XLSX 匯入鈕、非 auditing 階段的整頁唯讀)與跨子頁共用的狀態機/權限基調留在本頁。
主要使用者:稽核員(auditor)、專案經理(manager,可代行)。
角色速覽(完整定義見 _overview §3;本群主角是 auditor):
| 角色 | 一句話 |
|---|---|
| auditor | 稽核員 — 判定 / 觀察 / 風險 / finalize 的執行者 |
| manager | 專案經理 — 可代行 auditor |
| viewer | 一般參與者 — 只能檢視 |
1.1 功能總覽(本頁全部功能)
本頁是 hub(頁級 chrome + 兩 tab 導航):Tab0 判定工作區(樹 / 參考面板 / 判定 + 觀察)與 Tab1 風險管理各自的 field-level 逐欄規格拆成子頁,見「詳述」欄連結。
| # | 功能 | 說明 | 位置 | 詳述 |
|---|---|---|---|---|
| 1 | 控制項樹導覽 / 搜尋 / 篩選 | 群組→控制項樹;判定色點、繼承圖示、findings 數徽章;搜尋 + 展開/收合 | Tab0 左欄 AuditTreeNav |
稽核判定工作區 |
| 2 | 控制項參考面板 | 選中控制項的指引 / SSP 現況 / AO 與各 AO 的證據頁籤 | Tab0 中欄 AuditControlRef |
稽核判定工作區 |
| 3 | 判定(verdict) | 對控制項選 met / not_met / not_applicable / pending,填判定說明 | Tab0 右欄 SelectButton + 說明 | 稽核判定工作區 |
| 4 | 判定內嵌風險(not_met 時) | 判定為 not_met 時就地填風險等級 / 影響 / 矯正建議,存判定同時建/更新風險 | Tab0 右欄(editState==='not_met' 顯示) |
稽核判定工作區 |
| 5 | 觀察(observation)新增 / 編輯 / 刪除 | 記錄「看到什麼」:方法(EXAMINE…)+ 描述 + 受評對象 + 引用證據 | Tab0 右欄觀察區 | 稽核判定工作區 |
| 6 | 證據瀏覽 | 觀察卡的證據以按鈕收合,點開 dialog 列出檔案 / 問卷 / 連結,可預覽 | Tab0 觀察卡 → 證據 dialog + EvidencePreviewDialog |
稽核判定工作區 |
| 7 | 判定統計徽章 | 頂部 met / not_met / not_applicable / pending 四色計數 + 進度文字 | Header | §5 |
| 8 | 系統風險管理 | 建立風險(標題 / 描述 / 等級 / 來源 not_met 控制項)、編輯、刪除 | Tab1「風險」 | 稽核風險管理 |
| 9 | 風險關聯判定(finding) | 一個風險勾選由哪幾條 not_met finding 組成(多對多,全量覆寫) | Tab1 風險卡 sources + 內嵌風險 | 稽核風險管理 |
| 10 | 稽核紀錄 XLSX 匯入 | 上傳既有稽核紀錄 xlsx 批次帶入判定 / 觀察(FR-044) | Header「匯入稽核紀錄」→ ArImportDialog |
§2 UC-AR-04 |
| 11 | Finalize(結案判定) | 完整性檢查通過後推進:not_met=0→closed、not_met>0→remediation(自動生 POA&M) | FlowPhaseBanner 推進 | §2 UC-AR-03 |
| 12 | 唯讀模式 | 非 auditing 階段整頁唯讀,判定 / 觀察 / 風險編輯全禁用 | 全頁 | §4 |
展開成 UC:判定 + 觀察(3/4/5)與內嵌風險見 稽核判定工作區 UC-AR-01;系統風險與關聯(8/9)見 稽核風險管理 UC-AR-02;本 hub 保留 finalize(11,UC-AR-03)與稽核紀錄 XLSX 匯入(10,UC-AR-04),因兩者是頁級(跨 tab)動作。純顯示 / 導覽類(1 樹導覽、2 參考面板、6 證據瀏覽、7 統計徽章、12 唯讀模式)不另開 UC。
2. Use Case(本頁保留 finalize / 匯入)
角色速覽(完整定義見 _overview §3;本群主角是 auditor):
| 角色 | 一句話 |
|---|---|
| auditor | 稽核員 — 判定 / 觀察 / 風險 / finalize 的執行者 |
| manager | 專案經理 — 可代行 auditor |
| viewer | 一般參與者 — 只能檢視 |
流程圖視覺慣例:菱形 = 判斷、橘底 = 例外/擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。
判定 + 觀察的 UC-AR-01 見 稽核判定工作區 §2;系統風險與關聯的 UC-AR-02 見 稽核風險管理 §2。本 hub 保留兩條跨 tab 的頁級動作 UC:
UC-AR-03 Finalize 結案判定
| 項目 | 內容 |
|---|---|
| 角色 | auditor |
| 前置條件 | 輪次 = auditing;無 pending 判定;每條風險至少關聯 1 finding |
| 產出 / 後置條件 | not_met=0 → 輪次 closed;not_met>0 → 自動生 POA&M、輪次
remediation、回填 poam_id;覆核輪連動關母輪 |
UC-AR-04 匯入稽核紀錄 XLSX 批次帶入判定 / 觀察
| 項目 | 內容 |
|---|---|
| 角色 | auditor / manager(canImportAr:輪次 = auditing +
判定已初始化 stats.total>0) |
| 前置條件 | 輪次 = auditing;判定矩陣已初始化(stats.total>0,否則匯入鈕禁用) |
| 產出 / 後置條件 | 沿判定寫入路徑批次帶入判定 / 觀察(assessment_findings
/ assessment_observations);統計徽章刷新 |
3. 權限矩陣
專案層角色基調見 _overview §3。本頁檢查點(FE / BE 對齊,phase guard BE 硬擋):
| 操作 | FE 判定 | BE 強制 | BE 檢查位置 |
|---|---|---|---|
| 讀 findings / risks / 樹 / 證據 | 參與者即可(JWT) | 讀走 writable=False(finalize 後仍可讀) |
assessment_result_app_service.py::get_findings |
| 判定 / 觀察 / 風險 寫入 | canEdit = roundStatus==='auditing'(RoundAuditReviewView.vue:49) |
_check_auditor +
assert_round_phase({auditing}) |
assessment_result_app_service.py:111-118、round_guard.py:31 |
| Finalize | banner user_can_advance |
_check_role(..., "auditor") + 完整性檢查 |
audit_round_app_service.py:422-462 |
| XLSX 匯入稽核紀錄 | canImportAr(roundStatus auditing + auditor/manager +
stats.total>0,:66-67) |
同判定寫入的 phase guard | AR import service |
判定 / 觀察 寫入的權限詳述見 稽核判定工作區 §3;風險寫入見 稽核風險管理 §3。
本頁 FE / BE 權限對齊良好:兩端都以 auditing 階段 + auditor/manager 判定;BE
assert_round_phase硬擋——過階段直接打 API 仍回 412(見 _overview §5 坑 2)。
4. 狀態機與前置條件
輪次狀態機見 專案管理群 _overview §2;本群階段轉換與 finalize 分歧見 _overview §2。本頁(頁級)相關 gate:
| 條件 | 效果 | 出處 |
|---|---|---|
roundStatus === 'auditing' |
canEdit=true:判定 / 觀察 / 風險可寫、匯入可用 |
RoundAuditReviewView.vue:49 |
| 其餘狀態 | canEdit=false:唯讀 banner + 全表單禁用 |
同上 + Message(:686-688) |
| BE 寫入 phase guard | AR 寫入一律 assert_round_phase({auditing}),過階段回
412 |
round_guard.py:31 |
| Finalize 前置:無 pending | 有 pending 判定 → GRC_VERDICT_INCOMPLETE(412) |
assessment_result_app_service.py:807-808 |
| Finalize 前置:風險皆關聯 | 有風險未關聯 finding →
GRC_RISK_NO_FINDING_LINKED(412) |
同檔 :809-811 |
| 範圍過濾 | inScopeTreeGroups 只顯示有 finding 的控制項(AP
可能縮小 scope) |
RoundAuditReviewView.vue:327-332 |
判定工作區 tab 內的樹 / 判定 gate 見 稽核判定工作區 §4;風險 tab 的 finalize 前置關聯規則見 稽核風險管理 §4。
5. UI 設計
實機截圖(STG,亮色模式,2026-07-05,帳號 blsadmin,專案「亞○ CMMC L1 合規」/ auditing 輪次):





狀態呈現(頁級):頂部統計徽章 met / not_met /
not_applicable / pending 四色計數 + 進度文字(來源
stats);非 auditing 階段整頁蓋唯讀
banner(Message)並禁用所有寫入表單。無
socket,各動作後手動重取(判定後 refreshStats)。Tab0 /
Tab1 各自的狀態呈現(樹色點、per-按鈕 spinner、證據 lazy 快取)見各子頁
§5。
6. API 規格
Envelope:成功 {"code": 1, "data": …}、失敗
{"code": 0, "msg": "…"}。
6.1 總清單(本頁呼叫的全部 endpoint)
| 分類 | Method + Path | 說明 | 完整規格 |
|---|---|---|---|
| 載入 | GET /grc/project/{project_uid} |
專案 + 參與人員(角色判定) | GAI-SD-02 |
| 載入 | GET /audit-round/{round_uid} |
輪次 metadata(status / ssp_uid) | GAI-SD-02 |
| 載入 | GET /ssp/{ssp_uid}/control-tree |
凍結 SSP 控制樹(中欄參考) | 見 project-planning §6.2 |
| 載入 | GET /audit-round/{round_uid}/ar/findings |
AO 全量判定矩陣(控制項分組 + 觀察 + 統計 + 稽核指引) | 稽核判定工作區 §6.2 |
| 載入 | GET /audit-round/{round_uid}/ar/risks |
系統風險清單(含關聯 finding) | 稽核風險管理 §6.2 |
| 證據 | GET /job-evidences?job_execution_uid={jobId}、GET
/grc/project/{uid}/job/{jobId} |
選中控制項的 AO 證據 / 問卷(lazy) | GAI-SD-02 |
| 判定 | PUT
/audit-round/{round_uid}/ar/finding/{finding_uid} |
存單一 AO 判定(met/not_met/pending + 說明 + 關聯觀察) | 稽核判定工作區 §6.3 |
| 觀察 | POST /ar/observations、PUT/DELETE
/ar/observation/{obs_uid} |
觀察增 / 改 / 刪 | 稽核判定工作區 §6.3 |
| 風險 | GET/POST /ar/risks、PUT/DELETE
/ar/risk/{risk_uid} |
風險列 / 增 / 改 / 刪 | 稽核風險管理 §6.2 |
| 風險關聯 | PUT /ar/risk/{risk_uid}/findings |
關聯 finding(全量覆寫) | 稽核風險管理 §6.2 |
| 結案 | POST /audit-round/{round_uid}/ar/finalize |
完整性檢查 → 推進 remediation/closed + 生 POA&M | §6.2 |
| 匯入 | POST /audit-round/{round_uid}/ar-imports/parse |
稽核紀錄 xlsx 解析(FR-044) | GAI-SD-02 |
判定 / 觀察 的完整 request/response 見 稽核判定工作區 §6;風險 / 風險關聯見 稽核風險管理 §6。以下 §6.2 為本 hub 專屬(跨 tab)的 finalize endpoint 完整規格。
6.2 結案類(本 hub 專屬)
[POST] /audit-round/{round_uid}/ar/finalize
無
body。完整性檢查:stats.pending==0(否則
GRC_VERDICT_INCOMPLETE)、每 risk 至少 1 finding(否則
GRC_RISK_NO_FINDING_LINKED)。通過後依 not_met
數分歧。Response data:
| 欄位 | 型別 | 說明 |
|---|---|---|
| round_status | string | closed(not_met=0)/
remediation(not_met>0) |
| not_met_count | int | 不符合 finding 數 |
| poam_generated / poam_item_count | bool / int | 是否生 POA&M / 項目數 |
| parent_round_closed / parent_round_uid | bool / string | 覆核輪連動關母輪 |
出處:app/grc/service/audit_round_app_service.py::finalize_audit:422-462
→
assessment_result_app_service.py::finalize_assessment:795-822;POA&M
生成 PoamService.generate_from_findings。
7. 前端檔案地圖(compliance-manager-fe/)
| 檔案 | 角色 |
|---|---|
src/views/project/RoundAuditReviewView.vue |
主檢視(約 1,000 行;TabView 容器 + 頁級 chrome;判定 / 觀察 / 風險 CRUD 亦在此檔) |
src/config/router/index.js:824-829 |
route project-audit-review-round(path
/round/:roundUid/audit) |
src/components/grc/FlowPhaseBanner.vue |
階段推進橫幅(finalize 前進) |
src/components/grc/ar-import/ArImportDialog.vue |
稽核紀錄 xlsx 匯入(FR-044) |
src/service/BaseService.js |
axios 封裝(AR findings / verdict / obs / risk 直接呼叫) |
src/config/api/api.js |
端點常數(AUDIT_ROUND / SSP_CONTROL_TREE
…) |
src/config/locales/i18n/{zh-tw,en}/audit-review.json・round-audit-poam.json |
頁面 i18n(namespace 見 §12 坑 6) |
Tab0 判定工作區元件(AuditTreeNav /
AuditControlRef / EvidencePreviewDialog)見 稽核判定工作區
§7;Tab1 風險元件見 稽核風險管理
§7。
8. 後端檔案地圖(本頁核心鏈路)
| 鏈路 | Route | App Service | 底層 |
|---|---|---|---|
| Finalize | AuditRoundFinalizeRoute |
audit_round_app_service.py::finalize_audit →
finalize_assessment(完整性檢查 + 生 POA&M +
輪次狀態) |
PoamService.generate_from_findings |
| 階段推進 | api/flow_engine/routes/stage_advance_route.py |
oscal_stage_handlers.py::ConfirmAuditOnCompleteHandler(呼
finalize_audit;status 派生 gateway has_findings) |
BPMN gateway 路由 audit→poam / audit→End |
| 稽核紀錄匯入 | ArImportUploadRoute(上傳解析)+
ArImportRoute(預覽)+
ArImportConfirmRoute(confirm
才真正寫入判定),api/project/routes/ar_import_route.py:30/56/91 |
AR import service(沿判定寫入路徑) | assessment_findings /
assessment_observations |
判定矩陣 / 判定寫入 / 觀察鏈路見 稽核判定工作區 §8;風險鏈路見 稽核風險管理 §8。
DDD 提醒:AR 寫入 API 都照層級走(route 不碰 DB、app
service @transaction、_check_auditor +
assert_round_phase 雙檢查)——與 AP 頁一致的 phase-guard
樣板。
9. DB
9.1 資料表總清單(本頁讀寫的全部表)
| 表 | 讀/寫 | 說明 | 欄位詳述 |
|---|---|---|---|
| compliance.project_audit_rounds | 讀/寫(finalize 改 status / poam_id) | 稽核輪次主檔 | 見 project-planning §9.3 |
| oscal.system_security_plans | 讀 | 凍結 SSP 快照(判定母體) | GAI-SD-03 |
| oscal.assessment_plans | 讀 | AP(import_ap_id 溯源;FR-041 稽核指引來源) |
見 ap-authoring §9.3 |
| oscal.assessment_results / ar_results | 讀/寫 | AR root / 每輪 result | 稽核判定工作區 §9.3 |
| oscal.assessment_findings | 寫 | 逐 AO 判定(target_status_state) | 稽核判定工作區 §9.3 |
| oscal.assessment_observations | 寫 | 觀察 | 稽核判定工作區 §9.3 |
| oscal.assessment_risks | 寫 | 系統風險(severity 在 characterizations) | 稽核風險管理 §9.3 |
| oscal.assessment_finding_risks | 寫 | finding ↔︎ risk 多對多 | 稽核風險管理 §9.3 |
| oscal.assessment_remediations | 寫 | 矯正建議(response,remediation 欄落此) | 見 poam.md |
| oscal.poams / poam_items | 寫(finalize 生成) | not_met → POA&M | 見 poam.md |
| compliance.job_executions / evidence 相關 | 讀 | AO 證據(lazy 載入) | GAI-SD-03 |
9.2 ER 圖(本頁讀寫範圍)
核心表(assessment_results / ar_results /
assessment_findings /
assessment_observations)欄位卡見 稽核判定工作區
§9.3;assessment_risks /
assessment_finding_risks 欄位卡見 稽核風險管理
§9.3。
10. 頁面邏輯與資料對應
載入時序:
頁級關鍵欄位對應(畫面 ↔︎ API):
| 畫面元素 | FE state | API 欄位 |
|---|---|---|
| 統計徽章 | stats |
findings 回傳 {met, not_met, pending, na, total} |
Tab0 判定 / 觀察的欄位對應見 稽核判定工作區 §10;Tab1 風險欄位對應見 稽核風險管理 §10。
頁級儲存流程:判定後
refreshStats(重取統計)驅動頂部徽章與樹範圍;finalize 走
POST ar/finalize,成功後輪次階段變更由 FlowPhaseBanner
反映。
錯誤對應:BE error envelope → toast;頁級常見碼
GRC_VERDICT_INCOMPLETE(412,finalize 有
pending)、GRC_RISK_NO_FINDING_LINKED(412,風險未關聯)。412
由 axios interceptor → event bus → App.vue toast 統一處理。判定 / 風險
tab 內的錯誤碼見各子頁 §10。
11. 背景行為與外部依賴
| 類型 | 內容 |
|---|---|
| 通知 | 本頁判定 / 觀察 / 風險無站內通知 |
| BPMN | finalize = ConfirmAuditOnCompleteHandler 呼
finalize_audit;回傳 status 派生 gateway
has_findings(remediation=true)→ 路由 audit→poam /
audit→End;handler 副作用先於 BPMN 前進、同 transaction 失敗全
rollback |
| POA&M 生成 | finalize 且 not_met>0 →
PoamService.generate_from_findings 從 not_met findings
一控制項一 item 生成 |
| Socket | 本頁無 socket / 輪詢;各動作後手動重取 |
| jedi-* 套件 | jedi-oscal-v2(AR finding/observation/risk repo +
AssessmentResultService)、jedi-flow-engine(stage
advance)、jedi-auth(JWT) |
| 系統參數 | 蒐證方法來自 AP planning(FR-041)或 fallback OSCAL 三法;無 feature flag |
12. 邊界情況與已知坑
- phase guard BE 硬擋:AR 寫入只在 auditing,過階段直接打 API 也回 412(見 _overview §5 坑 2)
- verdict 值 API↔︎DB 映射:API
met/not_met/pending、DBtarget_status_state存satisfied/not-satisfied、pending 落target_statusJSONB;比對兩邊都要看(_overview §5 坑 4)。詳見 稽核判定工作區 §12 - 判定 AO 層 / 顯示與 POA&M
控制項層:
stats有met/not_met/pending(AO 計數)與controls_with_not_met(控制項計數)兩套;控制項 verdict 由 AO roll-up(任一 AO not_met → 控制項 not_met) - risk severity 存
JSONB:
assessment_risks無 severity 欄,等級在characterizations(_overview §5 坑 5)。詳見 稽核風險管理 §12 - finalize 前置雙檢查:無 pending + 每風險至少 1
finding,缺一即 412。判定存檔後風險來源清單已自動刷新(2026-07-09 FR-047
六項#4)——
saveVerdict收尾await fetchFindings()重建findingByControl→notMetControls依伺服器真相重算,不再停留在改判定前的過時清單 - i18n namespace 與檔名不齊:本頁讀
lang.round_audit.*namespace,但檔案為audit-review.json(key 為audit_review);round_auditkey 定義在round-audit-poam.json——動本頁 i18n 前先確認 namespace↔︎檔案對應,勿只看檔名 - 證據自包含 + lazy 快取:觀察
relevant_evidence內含 file 中繼資料(供 POA&M 免 N+1);證據 per-控制項 lazy 載入並快取,切控制項可能短暫顯示前一個的快取。詳見 稽核判定工作區 §12 - engagement 共用 AR:覆核輪不另開 AR root,append
一筆
ar_results;比對 workflow_execution_uid 找輪次是死路(_overview §5 坑 7) - 範圍過濾:
inScopeTreeGroups只顯示有 finding 的控制項(AP reviewed-controls 可能縮小 scope),樹上看不到的控制項不代表不存在、是不在本輪範圍
13. 開發與驗證
- 跑起來:BE
python main_socketio.py(port 8000,log 在log/app.log);FE 在compliance-manager-fe/起 Vite dev server。BE 改 service code 後必須重啟(無 hot reload) - 測試帳號:dev 環境稽核員角色帳號(密碼見
.env/ 部署文件) - 導航路徑:登入 → 專案 → 進入 auditing 狀態的輪次 → 稽核執行
- 前置資料:輪次需已
start-auditing(AP reviewed-controls 非空 → 進 auditing,AR 矩陣已初始化);控制項要有證據才判得動 - E2E:
compliance-manager-test/repo(Cucumber + Playwright);以稽核執行/audit-review/AR搜尋 - 相關文件:稽核判定工作區(Tab0 判定 / 觀察 / 內嵌風險)、稽核風險管理(Tab1 系統風險與關聯);FR-038(v2 遷移 B5 AR)、FR-041(稽核指引)、FR-044(稽核紀錄匯入);稽核計畫填寫見 稽核計畫填寫頁、後續整改見 poam.md(待撰);DB / API 全量見 GAI-SD-02/03