# FR-041 稽核結果（AR）填寫優化 — 設計（SD）

> Date: 2026-06-21 · Branch: `FR-040-AP-improvement`（沿用當前 branch；不另切）
> 前置：FR-040（AP 行程 + Phase 7 每方法查核指引）已完成。
> OSCAL 依據：v1.2.2 Assessment Results model（Observation → Finding → Risk → POA&M 四段）。
> 決策脈絡見本檔 §3（A/B/C 評估與排除選項）。

## 1. 範圍 / WHY

稽核員在「稽核結果判定頁」(`RoundAuditReviewView.vue`)對每個控制項下判定、記觀察、開風險。現況痛點：

1. **規劃與執行脫勾**：AP 規劃階段寫的「查核指引（每方法看什麼怎麼看，FR-040 Phase 7）」在 AR 判定當下**看不到** → 稽核員對著空白 textarea 從零寫。
2. **填寫模式偏簡**：判定只有 `met/not_met/pending` + 一段自由文字；觀察是「自由新增」與規劃無連動；風險在另一分頁手動開、與判定流程斷開；缺失 → 風險 → 矯正（POA&M）三段未串。

> **關鍵認知**：現有畫面**已具備** OSCAL 四段對應區塊（判定=Finding、觀察=Observation、風險分頁=Risk、POA&M 獨立模組）。本 feature **不是重做**，是針對既有面板的**漸進增強**。

## 2. OSCAL 原生 AR 流程（本設計的脊椎）

```
觀察(Observation) → 發現(Finding) → 風險(Risk) → 矯正(POA&M)
 看到什麼+證據(事實)   滿足/不滿足(結論)   嚴重度+影響     矯正計畫+里程碑+負責人
```

OSCAL 兩條鐵則（本設計必守）：
- **觀察 ≠ 發現**：觀察是中立事實（含 methods/subjects/evidence/collected），發現是對控制目標的判定（satisfied/not-satisfied）。
- **嚴重度 / 矯正計畫不屬於 Finding**，屬於 **Risk / POA&M**。Finding 只給判定 + 連 observation + 連 risk。
- AR 透過 `import-ap` 承接 AP 規劃（reviewed-controls 含 objectives + methods）→ AR「照 AP 規劃填實際結果」本就是 OSCAL 預期。

## 3. 三塊增強（A / B / C）對應現有畫面

| | OSCAL 段 | 落在現有畫面 | 現況 | 增強 | 量 |
|---|---|---|---|---|---|
| **A** 繼承 AP 指引 | import-ap（跨段） | 中欄「控制參考」面板 `AuditControlRef` | 只顯示 SSP 實作狀態/描述 | **加顯示** AP 規劃的查核指引 + 方法（FR-040 Phase 7 steps）；BE 在 AR init 把 steps 一併 snapshot | 小（唯讀面板加料 + BE echo） |
| **B** 缺失→風險→矯正 | Finding→Risk→POA&M | 「風險」分頁 + POA&M 模組 | 風險另分頁手動開、無矯正建議欄、與判定斷開 | 判定 `not_met` 時**就地**帶出風險（嚴重度+影響）+ **矯正建議**欄 → 接既有 POA&M 生成 | 中（串接 + 加欄） |
| **C** 觀察引導化 | Observation | 右欄「觀察記錄」區 | 自由「＋新增觀察」，與規劃無連動 | 改成**照 A 帶進的規劃方法逐項引導**填「看到什麼 + 證據」，roll up 成 Finding | 大（面板內互動重整） |

**排除的做法**：把嚴重度/矯正塞進 Finding（違反 OSCAL，B 改走 Risk/POA&M）；整頁重寫（現有四段結構可沿用，不需要）；per-AO 展開（FR-040 已定案維持 per-method，AR 同步走控制層 + 既有 AO fallback）。

**相依**：C 依賴 A（C 的「逐項引導」要 A 把規劃方法/指引帶進 AR 才有母體）。B 獨立。→ 實作序 **A → B → C**。

## 4. A — 繼承 AP 查核指引進 AR

### 4.1 BE
- AR 建立（`assessment_result_app_service.init_ar_matrix_for_round`）時，除既有 echo（reviewed-controls / subjects / `_assessment_log_from_tasks` 的 methods/timing）外，**把 AP `ap_assessment_activities`（含 `steps` 查核指引 + props methods + related_controls）依控制項 snapshot 進 AR**（落點：assessment_log entry 擴充，或 AR result 一個 `planning_context` JSONB；**pre-flight 決定**，傾向不動 schema、塞 assessment_log）。
- AR 讀取（`get_findings` / control detail API）**依控制項回傳規劃脈絡**：`{control_id: {methods:[], guidance:[{method, description}], subjects:[]}}`，供 FE 中欄面板顯示。
- 來源是 AP 的 activity.steps（per-method 指引），control 對應靠 activity.related_controls 的 control-id。

### 4.2 FE
- 中欄 `AuditControlRef` 加一區「規劃查核指引」：列出該控制項規劃的方法 + 各方法指引（唯讀，唯讀面板加料、不改判定/觀察邏輯）。
- 資料來自 AR control detail/findings API（A.4.1）。i18n 補標題。

## 5. B — 缺失 → 風險 → 矯正打通

### 5.1 BE
- Risk 既有（`risks` 表 + severity + link findings + CRUD 端點）。**加「矯正建議 / remediation」欄**（pre-flight 驗 risk entity 有無對應欄；無則於 jedi_oscal_v2 risk model 補 `remediation` 或用 props 承載 → 對齊 OSCAL `risk.remediation`/POA&M）。
- POA&M 生成（close round 從 not_met findings → poam）：**讓 risk 的嚴重度/矯正建議流進 POA&M seed**（pre-flight 對 `poam_app_service` 生成路徑，確認讀 risk 還是 finding）。

### 5.2 FE
- 判定區：選 `not_met` 時**就地展開**「風險」小表單（嚴重度 + 影響/風險描述 + 矯正建議），存判定時一併建/更新 risk 並 link 該 finding（沿用既有 risk 端點）。
- 「風險」分頁保留（總覽/跨控制管理），但不再是唯一入口。

## 6. C — 觀察引導化（依賴 A）

### 6.1 FE（主要）
- 右欄「觀察記錄」：由「自由新增」改成**照 A 帶進的規劃方法逐項**列出（文件檢查 / 訪談 / …），每項一個「看到什麼 + 證據引用 + （可選）對象」輸入；存成 observation（沿用既有 `POST /observations`，methods 預填該項方法）。
- 證據引用沿用既有 evidence 來源（job 檔/問卷/Drive，`loadEvidence`）。
- 仍允許「額外自由觀察」補充非規劃項。

### 6.2 BE
- 沿用既有 observation 端點（methods/subjects/relevant_evidence/description）；**原則零新欄**（pre-flight 確認 observation 能承載「對應哪個規劃方法」→ 用 methods 即可，必要時 props 標記）。

## 7. OSCAL 相容
- A：AR `import-ap` 承接規劃，OSCAL-native（只是把規劃脈絡顯示出來）。
- B：嚴重度/矯正走 Risk + POA&M，符合 OSCAL「Finding 只判定、Risk/POA&M 承載風險與矯正」。
- C：observation 為 OSCAL 蒐證主單位（methods/subjects/evidence），引導化不改其語意。

## 8. 不在本期 / DEFERRED
- per-AO 展開（FR-040 已定案 per-method；AR 同步控制層 + 既有 AO fallback）。
- 觀察自動 roll-up 成 finding 的自動判定（C 仍人工下判定，只是引導蒐證）。
- 那份外部 Excel 報表（user 已說忘掉，不做）。
- finding 多層分類（category enum）—— OSCAL 用 target.status，不另加。

## 9. 落地順序與驗收
1. **A**（小、零破壞）→ user 手測「判定頁中欄看得到規劃指引」→ 通過再進 B。
2. **B**（風險/矯正串接）→ 手測「判定 not_met 就地開風險+矯正、POA&M 帶到」→ 通過再進 C。
3. **C**（觀察引導化）→ 手測「照規劃方法逐項記觀察+證據」。
每階段 BE 改 service 提醒重啟、FE 重整；收尾（changelog/Notion/push）等 user 各階段下令。

## 10. 狀態
**A / B / C 已實作上線（2026-06-21，commit 見 §2 交接表）。缺失改善（POA&M）頁 A 版重設計 + 延伸已完成（§11）。**

## 11. 缺失改善（POA&M）頁 A 版實作紀錄（2026-06-21 收尾）

> 規格：`handoff/2026-06-21-poam-page-redesign-spec.md`（A 模式：DataTable + Sidebar 抽屜）。
> commit：BE `98371f40`；FE `e5dd953`（+ `e4e8dc3` AP 唯讀、`cb22aa5` OSCAL 文案）。

### 11.1 已落地
- **清單 + 抽屜**：accordion → `DataTable`（控制項/嚴重度/狀態/期限/進度，排序 + 狀態篩選）+ 點列滑出 `Sidebar`，抽屜三分頁（矯正措施 / 缺失脈絡 / 證據）。
- **矯正措施區**：問題脈絡條 + 改善計畫（來源徽章 稽核建議/自訂計畫）+ 里程碑卡片。
- **里程碑卡片**：顯示/編輯兩模式；狀態 chip 點擊循環切換（即存）；就地編輯/新增（取代彈窗）。
- **刪除**：里程碑、自訂改善計畫可刪（confirm）。**稽核建議不可刪**（FE 隱藏鈕 + BE 擋 `GRC_POAM_RECOMMENDATION_PROTECTED` 409）。
- **缺失脈絡標籤化**：觀察拆「看到什麼 / 蒐證方法 / 查核對象」。
- **結案/覆核提示**：總覽列下方說明流程。
- **日期修補**：Flask RFC 日期字串 → `YYYY-MM-DD`。

### 11.2 結案 / 覆核流程（核 BE 邏輯確認）
- 缺失層級結案是**衍生**：`_item_status` = 里程碑全 `done` 才 `closed`（無里程碑 → open，無法空著結案）。
- 進階前置：`close_round` 要本輪所有 item closed（`GRC_POAM_NOT_ALL_CLOSED`）、manager 守門。
- 母輪結案 → `pending_reverify`（不自宣告通過）→ `launch_reverify` 開 close-out 覆核輪 → 覆核確認連動關母輪。

### 11.3 延伸（同 session 一併處理）
- **稽核建議定位決策**：不可刪、但可加里程碑（屬稽核紀錄，由稽核階段擁有；改善方以它為起點追蹤）。
- **AP 唯讀「行程與方法」**：disabled 表單 → 乾淨標籤化唯讀呈現（commit `e4e8dc3`）。
- **移除 AP/AR user-facing OSCAL 字眼**：subjects_hint「OSCAL assessment-subjects」、AR 副標/發現面板「AO」（commit `e5dd953` + `cb22aa5`）。

### 11.4 零新表
全程沿用既有表/端點，無 migration。BE 新增端點走 `BaseRepositoryImpl.delete_by_id`，**未動 jedi_oscal_v2 套件 model**。
