手冊首頁 / 專案與任務 / 稽核輪次清單

稽核輪次清單(Audit Round List)

功能群:專案管理|狀態機與共用概念先讀 功能群總覽

事實基準:2026-07-05 從 FE / BE code 掃出(FR-038 v2 round-based 架構);endpoint 對照 routes.json,round DTO 對照 audit_round_app_service._to_dto,表結構取自 db_schema.json

1. 功能描述

稽核輪次清單是單一專案下所有稽核輪次的列表:從專案列表點專案名稱進來,看到該專案的每一輪(首次 / 持續監督 / 覆核),每列顯示輪次序號、名稱、類型、七態狀態、建立者與時間;點整列進入該輪的總覽頁。頁面也承載「發起覆核」這個輪次生命週期動作。

「一專案一稽核」模型下,手動新增輪次入口目前以功能旗標隱藏ALLOW_MANUAL_ROUND_CREATE=false)——全新一輪稽核採「開新專案」而非在此加輪次;BE 建輪次端點仍在(見 §12)。

主要使用者:專案 manager(發起覆核)、所有參與者(檢視 / 進入輪次)。

角色速覽(完整定義與 manager 全域代行慣例見 _overview §3):

角色 一句話
manager 專案經理 — 可發起覆核;(新增輪次入口目前隱藏)
auditor 稽核員 — 覆核的 BE 授權角色(manager 可代行)
參與者 檢視清單、點入輪次

1.1 功能總覽(本頁全部功能)

# 功能 說明 位置 詳述
1 輪次清單 該專案全部輪次,無分頁(一專案輪次數少) 資料表 UC-PAL-01
2 輪次血緣 close-out 子輪名稱下標「↩︎ 覆核自第 M 輪」 名稱欄 §6.2
3 七態狀態徽章 planning→…→closed,色階對應 狀態欄 _overview §2
4 建立者 / 時間 created_user_name(nickname)/ created_at 建立者欄 §6.2
5 點列進總覽 整列可點 → 該輪總覽頁(round-scoped) 全列 UC-PAL-01
6 發起覆核 pending_reverify 輪且為 PM、未發起過 → 開 close-out 子輪 操作欄 UC-PAL-02
7 已發起覆核標示 已有子輪指向本輪 → 唯讀「已發起覆核」,防重複 操作欄 UC-PAL-02
8 新增輪次 dialog 名稱 / 類型 / 開始日期——預設隱藏(功能旗標關) Header 按鈕(隱藏) §12
9 空狀態 無輪次時資料夾 icon + 提示 資料表 §5

UC(§2)展開 1 / 5(瀏覽並進總覽)與 6(發起覆核)兩條核心路徑;狀態機轉換的完整語意在 _overview §2

2. Use Case

角色速覽(完整定義與 manager 全域代行慣例見 _overview §3):

角色 一句話
manager 專案經理 — 可發起覆核;(新增輪次入口目前隱藏)
auditor 稽核員 — 覆核的 BE 授權角色(manager 可代行)
參與者 檢視清單、點入輪次

流程圖視覺慣例:菱形 = 判斷、橘底 = 例外 / 擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。

UC-PAL-01 瀏覽輪次並進入總覽

項目 內容
角色 任一參與者
前置條件 已登入;為專案參與者
產出 / 後置條件 載入該專案全部輪次;點列導向該輪總覽頁
uc_pal_01_load mount onMounted proj GET /grc/project/{uid} (專案名稱+participants) mount->proj 並行 rounds POST /projects/{uid}/audit-rounds/list (無 body,回本專案全部輪次) mount->rounds 並行 role FE 由 participants 推導 isProjectManager proj->role render 渲染輪次表格 (依 status/角色決定操作欄按鈕) rounds->render role->render
UC-PAL-01 載入:並行取專案詳情與輪次清單,依 status/角色決定操作欄,點列進總覽

UC-PAL-02 發起覆核(launch-reverify)

項目 內容
角色 專案 manager(BE 授權 auditor / manager 代行)
前置條件 母輪 status = pending_reverify;尚未有 close-out 子輪指向它
產出 / 後置條件 複製母輪 AP 成獨立副本、開新 close-out 子輪(status=planning)、綁主工作流;_sync_project_status
uc_pal_02_reverify start gate FE 判定:status=pending_reverify 且 isProjectManager 且尚未有子輪指向本輪? start->gate hide 不顯示「發起覆核」按鈕 (已發起則顯示唯讀「已發起覆核」) gate->hide confirm 按「發起覆核」→ 確認對話框 (將重新凍結系統快照) gate->confirm cancel 取消 → 不動作 confirm->cancel 取消 call POST /audit-round/{round_uid}/launch-reverify confirm->call 確定 role BE 檢查:使用者是本專案 auditor 或 manager 代行? call->role deny1 403 GRC_403001 (GRC_NOT_AUDITOR) role->deny1 pending BE 檢查:母輪 status = pending_reverify? role->pending deny2 412 GRC_412037 (母輪不在待複驗狀態) pending->deny2 dup BE 檢查:已有 close-out 子輪指向本輪? pending->dup deny3 412 GRC_412041 (本輪已發起覆核) dup->deny3 create 複製母輪 AP 成獨立副本 開新 close-out 子輪(status=planning) 綁主工作流(沿用前輪 flow template) dup->create sync _sync_project_status (新增未 closed 輪次 → IN_PROGRESS) create->sync done 重新查詢輪次清單 toast「已發起覆核」 sync->done
UC-PAL-02 流程:FE gate(pending_reverify+PM+未發起)→確認→POST launch-reverify→BE 三重前置(角色/母輪狀態/未重複)→建子輪

3. 權限矩陣

專案層角色基調見 _overview §3。本頁的實際檢查點:

操作 FE 判定 BE 強制 BE 檢查位置
讀清單 參與者即可 專案可見性(GET /grc/project 帶 participants) app/grc/service/project_service.py::get_project
發起覆核 status==='pending_reverify' && isProjectManager && !reverifyLaunched _check_role(auditor,manager 代行)+母輪 pending_reverify +未重複 app/grc/service/audit_round_app_service.py::launch_reverify
新增輪次 isProjectManager && ALLOW_MANUAL_ROUND_CREATE(旗標關 → 隱藏) _check_role(manager)+ round_type ∈ {initial, surveillance} 同檔 create_round(端點仍在)

⚠️ FE 覆核鈕以 isProjectManager 顯示,BE 授權為 auditor-or-manager——manager 代行慣例下一致;改權限時對照 _overview §3

4. 狀態機與前置條件

輪次 7 態狀態機見 _overview §2。本頁相關:

條件 效果 出處
任一輪 status != 'closed' hasActiveRound=true:新增輪次鈕(若啟用)禁用 ProjectApListView.vue:41
status === 'pending_reverify' + 未發起 顯示「發起覆核」鈕 同檔 :285
已有子輪 parent_round_uid === 本輪 uid 顯示唯讀「已發起覆核」 reverifyLaunched(:112)
launch-reverify 前置 母輪 pending_reverify(否則 GRC_412037)、未重複(否則 GRC_412041 audit_round_app_service.py

5. UI 設計

版面骨架與區塊職責(該專案全部輪次的單表清單,pending_reverify 才顯發起覆核操作;彩色區塊可點跳本頁小節錨點,API 僅標代表性):

Header:返回 + 專案名稱 + 新增輪次(旗標關) ALLOW_MANUAL_ROUND_CREATE=false 跳至 §2 Use Case(UC-PAL-01 瀏覽輪次並進入總覽) 輪次資料表(該專案全部輪次,無分頁) 六欄:輪次/輪次名稱(子輪下標「↩ 覆核自第 M 輪」血緣)/類型/七態狀態徽章/建立者/建立時間 整列可點 → 該輪總覽頁(round-scoped) POST /projects/{project_uid}/audit-rounds/list(輪次清單) GET /grc/project/{uid}(名稱 + participants → isProjectManager) → 點我跳 §2 UC-PAL-01 空狀態:無輪次時資料夾 icon + 提示 跳至 §6 API 規格(POST /audit-round/{round_uid}/launch-reverify 發起覆核) 操作欄:發起覆核(UC-PAL-02) 僅 pending_reverify + PM + 未發起 → 開 close-out 子輪 已有子輪指向本輪 → 唯讀「已發起覆核」(防重複) POST /audit-round/{round_uid}/launch-reverify 彩色=可點跳本頁小節錨點(框內標錨點+代表性 API)|灰=本頁描述|虛線框=依旗標/輪次狀態才出現的層 API 僅列代表性 2~3 條,完整規格見 §6;FE 覆核鈕以 isProjectManager 顯示,BE 授權 auditor-or-manager 代行
稽核輪次清單版面 wireframe:Header 返回+(隱藏)新增輪次、六欄輪次表(含子輪血緣/七態徽章)、pending_reverify 發起覆核操作欄、空狀態

實機截圖(STG,亮色模式,2026-07-05,帳號 blsadmin):

輪次清單:單輪次列(輪次/輪次名稱/輪次類型/狀態/建立者/建立時間)

pending_reverify 列「發起覆核」按鈕截圖從缺:2026-07-05 盤點 STG 全庫,目前無任何存活專案的輪次處於 pending_reverify 狀態(也沒有 close-out 血緣的多輪次專案),暫無真實資料可拍;待有此狀態資料再補。

狀態呈現:狀態欄 PrimeVue TagProjectApListView.vue:87ROUND_STATUS_SEVERITY 對應 6 態planning=secondary / audit_planning=info / auditing=warning / remediation=danger / pending_reverify=help / closed=success)。DB project_audit_rounds.status 另有第 7 態 not_started(新建未啟動)——本頁 severity map 未涵蓋(輪次一律從 planning 起,not_started 不出現在此清單;若真出現會以 Tag 預設樣式呈現)。整列 cursor-pointer row-click;無分頁、無 socket。

6. API 規格

Envelope:成功 {"status": true, "data": …}(輪次清單 data.data 為陣列)、失敗 {"error_code": "…", "msg": "…"}

6.1 總清單(本頁呼叫的全部 endpoint)

分類 Method + Path 說明 完整規格
載入 GET /grc/project/{uid} 專案詳情(名稱 + participants → isProjectManager) GAI-SD-02
載入 POST /projects/{project_uid}/audit-rounds/list 該專案全部輪次 §6.2
生命週期 POST /audit-round/{round_uid}/launch-reverify 發起覆核(開 close-out 子輪) §6.2
(隱藏) POST /projects/{project_uid}/audit-rounds 新增輪次(UI 旗標關;端點仍在) §6.2

6.2 核心 endpoint

[POST] /projects/{project_uid}/audit-rounds/list

無 body。Response data(陣列,每項 = _to_dto):

欄位 型別 說明
uid string 輪次 UID
name string 輪次名稱
round_no int 輪次序號
round_type string initialsurveillanceclose-out
status string 7 態
parent_round_uid string close-out 母輪,血緣用
assessment_plan_id int
ap_uid string
ssp_id int
ssp_uid string
ar_result_id int
poam_id int
flow_template_snapshot_uid string
workflow_execution_uid string
start_at date
end_at date
created_at date
created_user string login_name
created_user_name string nickname

出處:app/grc/service/audit_round_app_service.py:164-191

[POST] /audit-round/{round_uid}/launch-reverify

無 body。開 close-out 子輪。前置:角色 auditor / manager(否則 GRC_403001)、母輪 pending_reverify(否則 GRC_412037)、未重複發起(否則 GRC_412041)。副作用:複製母輪 AP 成獨立副本、建子輪(status=planning、parent_round_id=母輪、round_type=close-out)、綁主工作流、_sync_project_status。出處:app/grc/service/audit_round_app_service.py::launch_reverify

[POST] /projects/{project_uid}/audit-rounds(目前 UI 隱藏)

Request CreateAuditRoundRequest

欄位 型別 必填 說明
name string
round_type string initialsurveillance
start_at date %Y-%m-%d

前置:角色 manager(否則 GRC_403002)、round_type 合法(否則 GRC_412033,覆核請走 launch-reverify)。出處:api/project/serializers/audit_round.py:5-15audit_round_app_service.py::create_round

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/project/ProjectApListView.vue 主檢視(輪次表、狀態色階、發起覆核、建輪次 dialog、旗標 ALLOW_MANUAL_ROUND_CREATE
src/config/router/index.js:766-770 route project-ap-list/project/projects/:id
src/service/BaseService.js HTTP 包裝
src/config/api/api.js endpoint 常數(GRC_PROJECT / AUDIT_ROUNDS / AUDIT_ROUND
src/config/locales/i18n/zh-tw/project-ap-list.json 頁面 i18n

8. 後端檔案地圖(本頁核心鏈路)

鏈路 Route App Service 底層
輪次清單 api/project/routes/audit_round_route.py::AuditRoundsListRoute app/grc/service/audit_round_app_service.py::list_rounds_to_dto compliance.project_audit_rounds
專案詳情 api/grc/routes/project_route.py::ProjectDetailResource.get project_service.get_project jedi_project + participant service
發起覆核 api/project/routes/audit_round_route.py::AuditRoundLaunchReverifyRoute audit_round_app_service.launch_reverify_check_role + 前置) AP clone + 新輪 + workflow bind + _sync_project_status
建輪次 api/project/routes/audit_round_route.py::AuditRoundsRoute audit_round_app_service.create_round 同上(第一輪由專案成立時建,見 專案建立

DDD 提醒:輪次寫入照 _check_role + 狀態前置;狀態轉換一律走 API(BPMN 驅動,不直接 UPDATE,見 _overview §5)。

9. DB

9.1 資料表總清單(本頁讀寫的全部表)

讀/寫 說明 欄位詳述
compliance.project_audit_rounds 讀 / (發起覆核建子輪) 輪次主檔(清單主體、血緣、狀態) §9.3
compliance.projects / project_participants 專案主檔 / 角色(isProjectManager) GAI-SD-03
public.users created_user(login_name)→ nickname enrich GAI-SD-03
oscal.assessment_plans 讀 / (覆核複製 AP) 覆核時複製母輪 AP 成獨立副本 GAI-SD-03
oscal.system_security_plans 輪次凍結 SSP 指標(DTO 帶出,不在本頁展開) GAI-SD-03

9.2 ER 圖(本頁讀寫範圍)

pal_er proj compliance.projects uid / name (Header 標題來源) part compliance.project_participants project_id / user_id role(manager 判定+權限矩陣) proj->part 1:N round compliance.project_audit_rounds uid / round_no / name / round_type status(7 態)/ parent_round_id(覆核血緣) assessment_plan_id / ssp_id(凍結快照) ar_result_id / poam_id flow_template_snapshot_uid / workflow_execution_uid created_user / created_at proj->round 1:N round->round parent_round_id (close-out 自我參照) usr public.users login_name → nickname (created_user_name enrich) round->usr created_user (login_name 查 nickname) ap oscal.assessment_plans uid(→ ap_uid,本頁 DTO 帶出 不在本頁展開) round->ap assessment_plan_id ssp oscal.system_security_plans uid(→ ssp_uid,凍結快照 不在本頁展開) round->ssp ssp_id
稽核輪次清單讀寫範圍:黃 = 輪次主檔(self-FK 血緣)、藍 = 專案 / 角色、虛線 = DTO 帶出的凍結指標

9.3 核心表欄位(取自 DEV DB dump,含 DB comment)

compliance.project_audit_rounds — 稽核輪次主檔

清單主體。欄位(uid / round_no / name / round_type / status / parent_round_id(close-out self-FK 血緣)/ assessment_plan_id / ssp_id(凍結快照)/ ar_result_id / poam_id / flow_template_snapshot_uid / workflow_execution_uid / created_user / created_at)與完整說明見 規劃頁 §9.3。本頁除發起覆核建新子輪外只讀。

10. 頁面邏輯與資料對應

載入時序:見 §2 UC-PAL-01(並行取專案詳情與輪次清單)。

關鍵欄位對應

畫面元素 FE state API 欄位
輪次序號 round_no(顯示「第 N 輪」)
名稱 + 血緣 parentLabel(row) name + parent_round_uid(查母輪 round_no)
狀態徽章 ROUND_STATUS_SEVERITY[status] status
建立者 created_user_name(fallback created_user
發起覆核鈕顯示 reverifyLaunched(row) 是否有 parent_round_uid === 本輪 uid 的子輪

儲存流程:發起覆核 / 建輪次成功後 fetchRounds() 重查;無本地快取。

錯誤對應:BE error envelope → toast;覆核 GRC_403001 / GRC_412037 / GRC_412041;建輪次 GRC_403002 / GRC_412033

11. 背景行為與外部依賴

類型 內容
狀態同步 發起覆核建未 closed 子輪 → _sync_project_status 連動專案 status
BPMN 子輪綁主工作流(沿用前輪 flow template snapshot)
Socket 本頁 socket / 輪詢;清單靠操作後重查
jedi-* 套件 jedi-oscal-v2(AP clone)、jedi-flow-engine(workflow bind)、jedi-auth(JWT)
系統參數 ALLOW_MANUAL_ROUND_CREATE(FE 常數,非 BE feature flag)目前 false

12. 邊界情況與已知坑

  1. 手動新增輪次 UI 隱藏但 BE 端點仍活ALLOW_MANUAL_ROUND_CREATE=false 只隱藏 FE 按鈕,POST /projects/{uid}/audit-rounds 仍可被直接呼叫。要硬性禁止需在 BE create_round 加守門(目前只有 manager + round_type 檢查);這是「一專案一稽核」政策的可逆設計,翻旗標即恢復入口
  2. 發起覆核防重複靠 FE + BE 雙層:FE 用 reverifyLaunched(清單內有子輪指向本輪)隱藏按鈕;BE 另有 GRC_412041 擋——繞過 FE 直接打 API 仍會被 BE 擋
  3. 「啟動稽核」不在本頁:launch-audit 已搬到輪次內的 FlowPhaseBanner(規劃 / 總覽頁),列表不放捷徑
  4. 無分頁:一專案輪次數少,DataTable 不分頁;若某專案輪次爆量(異常)會全量渲染
  5. 血緣顯示依賴同批資料parentLabel 靠清單內找得到母輪 round_no;母輪若因故不在回傳集內(理論上不會)則不顯示血緣
  6. 狀態機 7 態但色階圖只列 6 態not_started 未在 ROUND_STATUS_SEVERITY,落預設 secondary;實務上列表輪次多已離開 not_started
  7. date-only 顯示start_at / created_at 走本地 toLocaleDateString,留意時區(見專案共用坑)

13. 開發與驗證

  • 跑起來:BE python main_socketio.py(port 8000,log 在 log/app.log);FE 在 compliance-manager-fe/ 起 Vite dev server。BE 改 service code 後必須重啟
  • 測試帳號:dev 環境 blsadmin(密碼見 .env / 部署文件)
  • 導航路徑:專案列表 → 點專案名稱(/project/projects/:id
  • 前置資料:專案需已成立(有 ≥1 輪次);驗發起覆核需一輪推進到 pending_reverify
  • E2Ecompliance-manager-test/ repo;以 稽核輪次 / audit-round / reverify 搜尋
  • 相關文件:單輪入口見 專案總覽頁、覆核狀態機 _overview §2、建立首輪見 專案建立;FR-038 docs/features/FR-038-2606-oscal-redesign/