# FR-040 行程鉤稽 — 實作完成，待驗收（2026-06-21 夜間自動跑完）

> 設計見 `../design.md`、決策見 `docs/analysis/2026-06-20-ap-task-control-subject-linkage.md`。
> 全部已 commit（branch `FR-040-AP-improvement`，三 repo），**未 push**。

## 做了什麼

一條「行程」現在能多對多鉤稽 **控制項 / 受評對象（設備·系統·人員）/ 參與人員**，OSCAL task→activity 模型，
1 task = 1 activity；method 放 props（多選多筆，官方範例證實）。

| Repo | Commit | 內容 |
|------|--------|------|
| jedi-oscal-v2（套件） | `8684658` | 2 張 link 表 `ap_task_subjects` / `ap_task_participants` 全套（model/entity/mapper/repo）|
| compliance-manager-be | `7fb60037` | `set_tasks`/`_ap_detail` 擴充 + route schema + migration + 6 unit test |
| compliance-manager-fe | `d955f7d` | Tab3 行程 3 個 MultiSelect + 同步 + payload + i18n |

（文件 commit：BE `5d05a5da` design/plan/analysis）

## 已驗證（夜間）

- ✅ 套件 import + `configure_mappers` + **DEV DB 真實 round-trip**（insert→read→rollback，FK 正確）
- ✅ BE 6 unit test 綠（orchestration：methods→activity.props、controls→related-controls、
  subjects/participants→link 表、associated_activities 引用 activity uuid；_ap_detail 還原）
- ✅ 既有 round 測試無回歸（10 passed）
- ✅ FE `vite build` 通過（RoundApAuthoringView 編進獨立 chunk，無 compile error）
- ✅ migration 已套 **DEV**（`oscal.ap_task_subjects` / `ap_task_participants`，FK+index+GRANT+schema_migrations）

## ⚠️ 環境狀態（驗收前必讀）

1. **BE 需重啟** 才會載入新 service + 套件新表 model。
2. **套件以 symlink 接上**（dev hack，避開 poetry 慢）：
   `.venv/.../site-packages/jedi_oscal_v2` → 套件源碼；原 pin 版備份在 `jedi_oscal_v2.pinbak`。
   → BE 重啟即用新碼。**但若你跑 `poetry install` 會還原成 pin 2.0.0（無新表碼）→ BE 會炸**，
   屆時改用 pyproject path-dep（取消註解第 97 行）或重建 symlink。
3. **DEV 已 migrate；STG/POC/PROD 未**（feature WIP）。
4. **未 push、未發 Nexus**：套件改動已 commit 源碼但**未 bump version / 未發版**（依規範等你明示）。
   正式部署前流程：套件 bump+發 Nexus → BE pin 改新版 → poetry update → 各環境跑 migration。

## 手動驗收 checklist（重啟 BE + 重整 FE）

1. 進稽核計畫填寫頁 Tab1 勾幾個控制項、Tab2 設幾個受評對象（設備/人員）。
2. Tab3「行程與方法」新增一條行程 → 三個新下拉應出現：
   - **鉤稽控制項**：只列 Tab1 勾選的（未勾的不可選）
   - **受評對象**：列 Tab2 設定的（跨設備/系統/人員）
   - **參與人員**：列專案 auditor/manager
3. 各選幾個 + 選方法 + 日期 → 儲存 → **重整頁面**應原樣還原（含控制項/對象/人員）。
4. 切英文 → 三個欄位標籤顯示英文。
5. （可選）DB 看 `oscal.ap_task_subjects` / `ap_task_participants` 有對應 row；
   `oscal.ap_assessment_activities` 該 AP 有 activity（related_controls + props.method）。

## 不在本期範圍（design §9）

- AO/statement 層精準（statement-ids / control-objective-selections）
- activity.steps UI
- 1 task 多 activity
- 行程通知 / 行事曆 / 儀表板（link 表已為這些鋪好查詢路徑）

## 若驗收有問題

- BE 行為異常先看 `log/app.log`。
- 「方法/控制項沒還原」→ 查該 AP 的 `ap_assessment_activities`（associated_activities 的 activity-uuid 對得上嗎）。
- 「受評對象/參與人員沒還原」→ 查 link 表 by task_id。
