標記審閱在 FR-038 2B 重建後又壞(接續已 Done 的 AO/控制項審閱在 v2 全壞):任一專案在控制項/AO 按「標記為已審閱」都失敗,且控制項即使進度 100% 也按不下去。
使用者回報:188 上控制項/AO 標記審閱都出錯;localhost 控制項一直跳「控制項完成後才可標記」按不了。
三層根因(逐層揭開):
GrcReviewRepoImpl._resolve_control_ids 以 LEFT JOIN compliance.project_assessment_plan_mapping 反查 project_id。該表是 v1 遺留、v2 已無寫入點(全 grep ..._mapping_service.add( 零呼叫)。stg 該表 0 筆 → project_id 解出 NULL → insert ReviewMark(project_id NOT NULL)→ IntegrityError 500。dev 因留 191 筆 v1 遺產才偶然能用。assessment_plan_id/ssp_id 皆 NULL,AP 要 launch_audit 才生),且 FE round 模式把 round uid 放進 URL /ap/<ap_uid> 段。以 AP 解析必查無。ctrlStatusFromAos summary 分支讀 total_tasks/completed_tasks 忽略 jobs,只有 jobs 無 task counts 時算出 total=0 → not_started;但進度條 ctrlProgress 讀 jobs → 100%。同一控制項「100%/未開始」,審閱 gate 看徽章 → 鎖死。AO 沒踩到(aoStatusFromAo 優先讀 jobs)。BE:review resolve 改與 dashboard/control-tree 同源,從專案 living SSP 解控制集,不再依賴 AP 也不依賴 v1 mapping —— review 在任何階段皆可用:
projects(uid=project_uid) → project_extensions.living_ssp_id
→ ssp.import_profile_id → profile_imports.source_catalog_id → catalog_controls
project_uid 一路從 route 串到 repo(route 本就有此 path param)。ap_uid(=round uid)保留在 signature 但暫不參與解析。
FE:ctrlStatusFromAos 拿掉忽略 jobs 的 summary fallback,統一走 jobs(原 detail 分支邏輯一律套用),狀態與進度同源(100% ⇔ completed)。未引進新語意。
(被排除:只回填 stg mapping 資料 = 治標,新專案仍會壞,不採。)
compliance-manager-be + compliance-manager-fe,branch FR-040-AP-improvement(未 push)a16a1953 / FE 6537e3c| 檔案 | 改動 |
|---|---|
BE api/grc/routes/review_route.py |
4 endpoint 傳 project_uid |
BE app/grc/service/review_service.py |
mark_/unmark_control/ao 加 project_uid |
BE domain/grc/service/grc_review_domain_service.py |
add_review/remove_review 加 project_uid |
BE domain/grc/repository/i_grc_review_repo.py |
interface 對齊 project_uid, ap_uid |
BE infra/grc/repository/grc_review_repo_impl.py |
_resolve_control_ids 改 living SSP;移除 2 個未用 import |
FE src/views/project/ProjectAuditorOverview.vue |
ctrlStatusFromAos 一致化(統一走 jobs) |