# SUMMARY — 標記審閱（控制項 / AO sign-off）在 FR-040 失效修復

> 日期：2026-06-21 ／ branch `FR-040-AP-improvement`（BE + FE 皆未 push）
> 狀態：BE py_compile 過；user 手測 AO 標記 OK；控制項 FE 改動待手測。BE 需重啟、FE 重整頁面。

## Commits
| Repo | Commit | 內容 |
|------|--------|------|
| compliance-manager-be | `a16a1953` | review resolve 改走 living SSP（含 changelog） |
| compliance-manager-fe | `6537e3c` | `ctrlStatusFromAos` 狀態/進度同源 |

> 兩 repo 各自只 commit 本 arc 檔案；working tree 仍夾其他 session WIP（BE `api/project/*`、`poam_app_service.py`、`grc_error_code.py`；FE i18n + `RoundApAuthoringView.vue`、`RoundPoamView.vue`），未動。

## 問題與根因（三層）
1. **stg 500** — `_resolve_control_ids` 以 `LEFT JOIN compliance.project_assessment_plan_mapping` 反查 `project_id`；該表 v1 遺留、v2 無寫入點，stg 0 筆 → `project_id` NULL → insert `ReviewMark`（NOT NULL）撞 IntegrityError。dev 留有 191 筆 v1 遺產才偶然能用。
2. **localhost 404** — 改 AP 鏈仍失敗：FR-040 規劃階段 round 無 AP（`assessment_plan_id`/`ssp_id` 皆 NULL，AP 待 `launch_audit` 才生），FE round 模式把 round uid 放進 `/ap/<ap_uid>` 段。
3. **控制項按不下（FE）** — `ctrlStatusFromAos` summary 分支讀 `total_tasks/completed_tasks` 忽略 `jobs`，僅有 jobs 時算 total=0 → not_started；進度條讀 jobs → 100%。徽章/進度矛盾，gate 看徽章 → 鎖死。

## 修法
- **BE**：resolve 改與 `get_ap_dashboard` / control-tree 同源 —— `projects.uid → project_extensions.living_ssp_id → ssp.import_profile_id → profile_imports.source_catalog_id → catalog_controls`。`project_uid` 一路串到 repo；不再依賴 AP / v1 mapping。
- **FE**：`ctrlStatusFromAos` 拿掉忽略 jobs 的 fallback，一律走 jobs（原 detail 分支邏輯），狀態與進度同源。

## 驗證
失敗請求（project `6d686f15`、control `IA.L1-3.5.1`、AO `IA.L1-3.5.1_obj.1`）在 dev 跑新 query：project_id=282 / control_db_id=2844 / group_db_id=1009 / ao_id=14473，全非 NULL。

## 已更新橫向文件
- ✓ changelog `docs/changelog/2026-06-21-fix-grc-review-mark-v2-living-ssp.md`
- ✓ Notion 任務（新建，狀態 Done）https://app.notion.com/p/386346da4cd08164a406d08116f1864f
- ✓ memory feedback `feedback_grc_v2_readers_resolve_via_living_ssp.md` + `feedback_fe_status_progress_same_source.md`
- ✓ 本 SUMMARY

## Follow-up
- v1 遺留表 `compliance.project_assessment_plan_mapping`：review 已不依賴它，是否仍有其他 reader、可否退役 → 另案盤點（DROP 前走安全四查）。
- 部署：BE 需重啟；兩 repo 未 push（等 user 指示）。
- 對話紀錄歸檔：本次未做（user 未要求匯出對話）；需要時 `scripts/extract_claude_sessions.py --ts-prefix`。
