狀態:v1 大方向版,待 review 整體脈絡:
../README.md
讓使用者管理「專案流程範本」 — 用 BPMN 編輯器組合「階段物件」與分支,存成可重用範本;公司可有自己的流程,也可參考 / 複製系統內建範本。
來源:requirement.md §「想法(粗略)」§1「新增專案流程管理功能」
本輪 spec seed 4 個基礎階段物件,覆蓋 requirement.md §現況的 phase 2~5。
| requirement.md 原 phase | 對應 |
|---|---|
| Phase 1「新增稽核計畫」 | BPMN StartEvent + 系統建立 AP(不是 UserTask,不需 seed) |
| Phase 2~5 | 4 個 seed 階段物件(下表) |
| Phase 6「結案」 | BPMN EndEvent + 系統自動關閉 AP(不是 UserTask,不需 seed) |
| Phase 7「再開新一輪」 | launch_new_round 動作,不在本案範圍 |
| code | 顯示名稱 | 類型 | AP.status | 對應頁面 | 預設主要角色 |
|---|---|---|---|---|---|
planning |
規劃 | routed | preparing |
/project/projects/:projectUID/settings |
manager |
task_execution |
執行任務 | stateful | active |
(無專屬頁面,靠 overview + 待辦任務頁的資料過濾) | manager |
audit |
稽核 | routed | auditing |
/project/projects/:projectUID/ap/:apUID/audit |
auditor |
poam |
缺失改善 | routed | remediation |
/project/projects/:projectUID/ap/:apUID/poam |
manager |
「預設主要角色」= 預設「能 complete 此 stage」者;使用者在 BPMN 編輯器拖 UserTask 後可逐個覆蓋。 角色 code 沿用系統現有
project_participants.role:manager/reviewer/auditor/viewer。 導航按鈕(routed view 入口)不在此控制 — 沿用既有 FEv-if邏輯(狀態 + 角色),新 spec 不動。
每個 stage 的「完成此階段」推進,本質上是呼叫既有 OSCAL 流程的 4 個 API。Spec 2 的「副作用搬家」= 把這些 API 包進對應 stage 的 on_complete handler;不重做這些 API。
| code | 推進按鈕文字 | 推進對應既有 API | 推進後 AP.status |
|---|---|---|---|
planning |
啟動專案 | POST /grc/project/<uid>/ap/<apUid>/activate |
preparing → active |
task_execution |
啟動稽核 | POST /grc/project/<uid>/ap/<apUid>/launch-audit |
active → auditing |
audit |
提交稽核 | POST /grc/project/<uid>/ap/<apUid>/confirm-audit |
auditing → remediation(有缺失)/ closed(無缺失) |
poam |
完成改善 | POST /grc/project/<uid>/ap/<apUid>/close-round |
remediation → closed |
對應
docs/api/grc/design.md §2.1既有狀態機。
| 欄位 | 說明 |
|---|---|
code |
唯一識別字串,BPMN UserTask 用這個 reference |
name_i18n |
顯示名稱(多語言) |
kind |
routed(綁定特定頁面) / stateful(無專屬頁面,行為由資料層過濾) |
route_pattern |
僅 routed 有,含 placeholder(如 :projectUID / :apUID) |
complete_button_label_i18n |
Banner 上「完成此階段」的按鈕文字 |
complete_handler_key |
BE 註冊的 on_complete handler 識別(對應 §3.2 的既有 API) |
precondition_key |
BE 註冊的 precondition function 識別(檢查前置條件,例如「全部 task 已 closed」) |
default_main_roles |
預設「能 complete 此 stage」角色清單 |
is_builtin |
內建 / 自訂(v1 全部 builtin) |
complete_handler_key/precondition_key對應的具體 handler / function 實作屬於 Spec 2 範圍,本 spec 只負責 schema 與 key 命名規範。 v1 不含default_view_roles— 導航按鈕沿用既有 FE 邏輯,stage object 不控制可見角色。
對應 README 提的 A / B / C 三種專案情境:
| 範本 code | 顯示名稱 | 用途 | 階段組合 |
|---|---|---|---|
builtin-full-audit |
完整稽核流程 | A 專案(正式稽核導入) | Start → planning → task_execution → audit → Gateway →(有缺失)poam → audit /(無缺失)End |
builtin-internal-check |
內部自查流程 | B 專案(內部自我檢查) | Start → planning → task_execution → End |
builtin-self-assessment |
自我評估稽核 | C 專案(內部稽核無改善) | Start → planning → task_execution → audit → End |
每個 UserTask 預設套用該階段物件的 default 角色設定;使用者複製成自訂範本後可逐個 UserTask 修改主要 / 參與角色。
v1 BPMN UserTask 屬性面板不含「參與角色」 — 導航按鈕沿用既有 v-if 邏輯(狀態 + 角色),stage 不控制可見角色。
GET /flow-engine/stage-objects — 列出所有可用階段物件(Spec 2 / 3 都要用)GET /flow-engine/flow-templates — 範本列表(Spec 3 wizard 用)GET /flow-engine/flow-templates/<uid> — 範本詳情含 BPMN XML(Spec 3 snapshot 用)紀錄 FE 實作期間發現的偏差跟取捨理由。不是補救,是給未來讀者保留決策軌跡 — 看 spec 跟看 code 行為對不上時,有這份就不會繞遠路。
| 項目 | 內容 |
|---|---|
| 原 spec | 列表頁「新增範本」dialog 提交 → POST blank XML → 取回 uid → push 編輯頁 |
| 實際落地 | dialog 提交 不 POST,純 router push 到 /flow/template-manage/new?name=...&description=...;使用者編完 BPMN(加 UserTask + EndEvent + 設階段物件)後在編輯頁點儲存才真的 POST |
| 為什麼偏差 | BE _validate_bpmn 嚴格要求 >=1 UserTask + EndEvent(line 142),blank XML 只含 StartEvent 直接 reject 回 GRC_400040。FE side commit 40f6f52 修這個 |
| 考慮過但排除的方案 | A. BE 放寬 create validation:讓 blank 入庫,update 時才嚴格驗。排除原因:DB 會留 ghost 範本,Spec 2/3 套用範本到 AP 時要再加防呆 |
| 未來可能反悔的條件 | 若 Spec 2 引入「範本草稿 / 發佈」狀態(§八 開放問題之一),blank 草稿可入庫就合理,屆時 BE 放寬 + FE 改回 |
| 項目 | 內容 |
|---|---|
| 原 spec | 「全部 / 內建 / 自訂」filter(沒指定元件) |
| 實際落地 | v-for <Button text> + 外層 wrapper 加 border + 內 padding;active 狀態 inline style rgba(99,102,241,0.2) 紫底 + 主色字 |
| 為什麼偏差 | PrimeVue 3.53 SelectButton 預設 unselectable=true quirk 會「點當前 active 變 null」;對齊 project-dashboard 我的代辦任務 segmented pill 既有 pattern |
| 沉澱規範 | FE CLAUDE.md 新增「Segmented Filter Bar Pattern」段,未來互斥分類 filter 一律用此 pattern |
| 項目 | 內容 |
|---|---|
| 原 spec / 初版 | builtin 顯示 pi-search「檢視」、自訂顯示 pi-pencil「編輯」 |
| 實際落地 | 統一 pi-pencil「編輯」;builtin 進去仍是 readonly Viewer,但 label 一致 UX 更直觀(可走「另存為新範本」修改) |
| 為什麼偏差 | User feedback:兩種 icon 反而困惑,本質都是進編輯頁 |
.name-link 可點| 項目 | 內容 |
|---|---|
| 原 spec | 沒明說 |
| 實際落地 | name cell 加 cursor pointer + hover 變色加底線 + tooltip「編輯」+ click 進編輯頁(與操作欄編輯按鈕等效) |
| 為什麼偏差 | User feedback:DataTable 名稱應該直觀可點 |
| 項目 | 內容 |
|---|---|
| 原 spec | 沒規範文案,使用「User Task」術語 |
| 實際落地 | zh-tw 5 處字串全改成「任務」;en 維持「User Task」(BPMN 正式術語不翻譯) |
| 為什麼偏差 | User feedback:「User Task 屬性」中英夾雜怪 |
| 項目 | 內容 |
|---|---|
| 原 seed | name = builtin-full-audit / builtin-internal-check / builtin-self-assessment(英文 slug) |
| 實際落地 | name = 「完整稽核流程」 / 「內部自查流程」 / 「自我評估稽核」(中文) |
| 為什麼偏差 | User feedback:列表顯示應對齊其他中文 UI |
| 部署備註 | dev DB 已跑 2026-05-12-rename-builtin-flow-templates-to-zh.sql 修補;prod 部署前必須先跑 fix-up(直接重跑 seed 會造成 6 列「中英並存」) |
markRaw 不能進 Vue reactivity| 項目 | 內容 |
|---|---|
| 原 spec | 沒明說 |
| 實際落地 | selectedElement 用 shallowRef + markRaw(el) 包裝 bpmn-js shape;不可用 ref(el) |
| 為什麼偏差 | bpmn-js shape 內部用 Object.defineProperty(labels, writable:false, configurable:false) 定義 read-only 屬性;Vue 3 reactive Proxy 攔截 get 會違反 invariant 直接 TypeError 炸(commit d16c504 修) |
| 沉澱規範 | 若未來 FE 還有其他第三方 lib instance(Cytoscape / Three.js 等)需要 ref,一律走 shallowRef + markRaw 雙保險 |
bpmn-auto-layout 補 DI| 項目 | 內容 |
|---|---|
| 原 spec | builtin BPMN XML 在 scripts/sql/seeds/bpmn/builtin-*.bpmn 只含 process 定義(StartEvent / UserTask / SequenceFlow / EndEvent),沒帶 <bpmndi:BPMNDiagram> DI 資訊 |
| 實際落地 | FE Editor / Preview 在 initModeler / renderBpmn 偵測 !xml.includes('BPMNDiagram'),先過 bpmn-auto-layout 的 layoutProcess(xml) 補 DI 再 import |
| 為什麼偏差 | 直接餵 bpmn-js Viewer 會炸 Error: no diagram to display。原 spec 沒考慮 DI 缺失 case |
| 未來改進 | 若 FE 拖拉編輯後存檔的 XML 已含 DI,新建自訂範本後續就不需要再 auto-layout(只有 builtin / 純後端 seed 缺 DI) |