Branch:feature/project-flow-engine(BE + FE 同名) 範圍:2026-05-10 整天(M5 跨層完工)+ 2026-05-11 整天(OZ.0–OZ.10) 收尾原因:session 已混亂,交接給下一個 clean session
M5 系列收完三個主軸:
2243f83 ~ ece5aba)40619d0 ~ 58d8ebc)舊 wizard ProjectCreateView(4-step 完整)+ 新 wizard ProjectCreateFromTemplateView(3-step 簡陋)並存,user 反映新 wizard 比舊版倒退。
| Wave | 內容 | 狀態 |
|---|---|---|
| OZ.0 | Analysis 鎖決策:保留 BPMN backend,wizard 統一在 ProjectCreateView | ✅ commit 3758b86 |
| OZ.1 | FE Hybrid Pickers(Dropdown + Dialog + per-row preview) | ✅ commit fe04649 |
| OZ.2 | ProjectCreateView 整合 picker + 切走 POST /project/flow/start endpoint |
✅ 同上 commit |
| OZ.3 | BE StartFlowRequestSchema 加 audit_systems + devices + 配套 helper |
✅ commit f0438d9 |
| OZ.4 | 廢除舊 wizard view / route + cleanup | ✅ commit f60e445 |
| OZ.5 | Tests + 跨 repo summary changelog | ✅ commits 82f9fbe / 4b22bb3 |
| OZ.6 | preview API 顯示實際清單(控制項 / 參與人員 / 單位 / 程序書)取代統計卡片 | ✅ commits 887f678 / 6bc622f / f980683 / 8743847 / aa9e6fe |
| OZ.6.1–4 | 中段一連串 fix:DTO repr / refdoc 欄位名 / dark mode / badge i18n / 字級 / 防呆 / cache | ✅ |
| OZ.7 | FlowProjectOverviewView dark mode + card/table view toggle | ✅ commit 7d2dbe7 |
| OZ.8 | 移除 builtin templates 的 project_kickoff + 名稱對齊(5 個 OSCAL plugin display name) |
✅ commits e1b69ae / 557fac8 |
| OZ.9 Phase 1 | FE infra:FlowPhaseBanner + ActivityRouterPage dispatcher |
✅ commit 42683e9 |
| OZ.9 #1 | palette 隱藏 project_kickoff + review_loop_gateway |
✅ commit 6050ffe |
| OZ.9 #2 | OSCAL plugin display_name 拿掉 prefix | ✅ commit 557fac8 |
| OZ.9 Phase 2 | BE adapter:export_report.on_node_start 接 close_ap_if_open |
✅ commit a7b6075 |
| OZ.9 Phase 3 | 4 個 legacy view (Planning/TaskSetup/AuditReview/Poam) mount FlowPhaseBanner | ✅ commit a89c192 |
| OZ.9 misc | 4 個 legacy view 的 back 按鈕在 flow context 跳 flow-project-overview | ✅ commit 819b8d6 |
| OZ.10 Phase 1 | AO 預設 single-task workflow fallback(builtin-ao-default-single-task) |
✅ commits 8c38848 / 1111bcb |
| OZ.10.x fix loop | canvas 空白 / 儲存失敗的一連串 debugging(重要見「未驗證 / 已知問題」段) | ⚠ 詳見下方 |
┌────────────────────────────────────────────────────────────────┐
│ Flow-engine = 狀態機 orchestrator(不再是新 UI) │
│ Legacy view = 真實業務 UI(ProjectPlanningView / TaskSetupView /│
│ AuditReviewView / PoamView ...) │
└────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────┐
│ ProjectListView「新增專案」按鈕 │
└────────────┬────────────────────┘
▼
ProjectCreateView (canonical wizard)
- FlowTemplatePicker (Hybrid)
- ModuleFramePicker (Hybrid, 依 flow_template.category 過濾)
- 4-step:基本資訊 / 參與者 / 受評範圍 / 確認
- submit → POST /project/flow/start (FLOW_PROJECT_START)
│
▼
FlowProjectOverviewView (/flow-project/:id/overview)
- N 張 AP 卡片(multi-AP)
- card/table view toggle (OZ.7)
- PhaseProgressBar with color-mix dark mode (OZ.7)
- 「啟動新一輪」/「結案專案」按鈕
│
▼ 點 AP 卡 → /flow-project/<projectUid>/ap/<apUid>/activity
ActivityRouterPage
- 讀 current_activity_type
- dispatcher map:OSCAL 5 個 activity_type → legacy AP-scoped route
- 帶 ?flow=1 query → legacy view 掛 FlowPhaseBanner
│
▼
Legacy view (e.g. ProjectPlanningView)
┌─────────────────────────────────────┐
│ FlowPhaseBanner(v-if route.query │
│ .flow === '1') │
│ - 第 N 輪 + 階段 tag │
│ - 「完成此階段」按鈕 │
│ 呼 complete_activity → BPMN │
│ advance + 跳回 overview │
└─────────────────────────────────────┘
- 業務 UI 不動,user 在 banner 下方做事
| activity_type | → legacy route | View |
|---|---|---|
oscal_preparing |
project-planning-ap |
ProjectPlanningView (2,102 行) |
oscal_active |
project-task-setup-ap |
TaskSetupView (1,496 行) |
oscal_internal_review |
project-audit-review?mode=internal |
AuditReviewView (444 行) |
oscal_external_audit |
project-audit-review?mode=external |
AuditReviewView |
oscal_remediation |
project-poam |
PoamView (473 行) |
export_report |
(留 M5.8 panel) | ExportReportPanel |
approval / survey_* / task_* |
(留 M5.8 panel) | 待 Phase 5 |
雙狀態機並存:
| 系統 | 維護什麼 | 觸發 API |
|---|---|---|
Legacy oscal_audit_service |
AP.status (preparing → active → auditing → remediation → closed) + AR_data + review_marks |
launch_audit / confirm_audit / close_round |
BPMN flow_execution_service |
workflow_executions.current_node_id + phase |
complete_activity / revert_activity |
| Plugin | on_node_start | on_node_complete |
|---|---|---|
oscal_preparing |
— | activate_project → AP preparing → active ✅ |
oscal_active |
— | 純 log(AP 留 active;下一節點如為 internal_review/external_audit/export 都接得起來) ✅ |
oscal_internal_review |
— | 查 review_marks → emit oscal.review_has_failures ctx ✅ |
oscal_external_audit |
launch_audit → AP → auditing |
confirm_audit → AP → remediation/closed ✅ |
oscal_remediation |
— | close_round → AP transitions ✅ |
export_report (OZ.9 Phase 2 加) |
close_ap_if_open — 短流程兜底,AP 已 closed 走 no-op |
— |
短流程(builtin-oscal-internal-only)跟完整流程都靠 plugin 自己鉤 legacy API,不用 BE adapter 二次同步。
8 個 builtin 都拿掉 Task_kickoff:
| UID | 顯示名 | 結構 |
|---|---|---|
builtin-oscal-full-audit |
完整稽核流程 | preparing → active → internal_review → external_audit → (gateway has_failures) → remediation→loop / export → end |
builtin-oscal-internal-only |
OSCAL 僅內部稽核 | preparing → active → export → end(短流程 PoC 用) |
builtin-oscal-with-review |
OSCAL 含內部審查 | preparing → active → internal_review → export → end |
builtin-survey-no-review |
任務(含問卷填寫,無審核) | survey_design → assign_respondents → task_survey_fill → export → end |
builtin-survey-with-review |
任務(含問卷填寫,含審核迴圈) | survey_design → assign_respondents → fill → approval → (gateway) → loop / export |
builtin-task-dispatch-simple |
任務直派(簡易) | task_setup → dispatch → execute → export → end |
builtin-task-dispatch-with-review |
任務派發(含主管覆核) | + task_review + loop |
builtin-task-dispatch-with-escalation |
任務派發(含升級催辦) | + task_escalation |
OSCAL templates 的 Task_preparing.name 已改「專案設定」(對齊 user 心智模型)。
| SQL 檔 | 用途 | 跑了 dev DB? |
|---|---|---|
2026-05-10-add-workflow-execution-id-to-papm.sql |
multi-AP pivot — papm 加 workflow_execution_id | ✅ |
2026-05-10-module-frame-polymorphic.sql |
Module Frame Decoupling — type 欄位 + oscal_details / task_details 表 | ✅ |
2026-05-10-rename-survey-builtin-templates.sql |
survey-as-task 改名 | ✅ |
2026-05-11-rename-builtin-templates-remove-kickoff.sql |
8 builtin templates 拿掉 project_kickoff + rename | ✅ |
2026-05-11-add-ao-default-single-task-template.sql |
新增 builtin-ao-default-single-task |
✅ |
2026-05-11-update-ao-default-template-add-di.sql |
補 BPMN DI 給上述 builtin | ✅ |
正式機部署需依序跑 6 個 migration(per CLAUDE.md SQL 規範用 cmmgr 帳號)。
症狀:user 在 TaskSetupView 點 AO 的 BPMN 編輯按鈕,跳到 /workflow/workflow-setup?id=<tmpl_uid>&...,編輯後點儲存出現「儲存失敗」toast。
Console 錯誤:
TypeError: Cannot read properties of undefined (reading 'get')
at syncJobExecutions (WorkflowSetupEditor.vue:383)
at onSaveClick (WorkflowSetupEditor.vue:283)
Root cause(commit 96885a6 已修補):WorkflowSetupEditor.vue 5 處寫 bpmnCanvasRef.value.modeler.value.X — Vue 3 defineExpose({ modeler: ref }) 自動 unwrap,bpmnCanvasRef.value.modeler 已是 Modeler instance,再 .value 是 undefined → .get(...) 拋 TypeError。
對照 TemplateBpmnEditor.vue 既有正確用法是 bpmnCanvasRef.value?.modeler.get(...)。
未驗證:user 還沒回報 commit 96885a6 部署後是否 work。Next session 第一件事:請 user 重試「儲存」並確認 console 沒錯。
中途為了測 PUT endpoint 是否會回 500,用 curl 送了 minimal test BPMN (id=D1, targetNamespace=http://test)到 /api/1.0/module-frame/item/xml/82956503-62aa-42a2-951d-053b12caa47d, 結果那條 PUT 真寫 DB,把 user project 8 的 AO 模板覆蓋成空 BPMN。
已用 SQL UPDATE restore:source xml + 注入該模板對應的 job_execution_uid e4351d00-be4b-410b-be84-c08b7fd14d68。沒留 migration 檔(一次性 fix)。
教訓記在這份摘要 — 之後驗證 endpoint 行為時:
OZ.10.2 (faefba5) 把 WorkflowSetupEditor.getProcessDefinition 改用 BpmnCanvas.loadXml(smart guard:有 DI 不重算)。但 user 後續還在報「畫面 空白」,當時我誤判加了 OZ.10.3 timing fix,後來 revert 掉。
實際 6.1 的 modeler.value bug 修補後,理論上 listener 也終於正確註冊, canvas 重 render 行為要再驗一次。Next session 確認。
WorkflowSetupEditor 既有邏輯(shape.remove listener line 179)會在 user 刪 UserTask 時觸發 DELETE /grc/project/<uid>/job/<jobUid>。這條 listener 之前因 6.1 bug 也沒註冊上(registerEditorListeners 內 modelerInstance 拿到 undefined 後 silently return),所以 user 刪除 task 不會同步刪 BE JobExecution。修補 6.1 後一併恢復。
Phase 4 預期流程(builtin-oscal-internal-only 短流程):
/.../planning?flow=1 + FlowPhaseBanneractivate_project → AP active/.../task-setup?flow=1 + bannerexport_report INSTANT → close_ap_if_open → AP closed沒驗證過。Next session user 測試時請依序驗。
builtin-oscal-full-audit) 整合事後盤點發現 plugin on_node_complete 本來就有接 legacy API(M5+ 寫好):
oscal_preparing.on_node_complete → activate_projectoscal_external_audit.on_node_start → launch_auditoscal_external_audit.on_node_complete → confirm_auditoscal_remediation.on_node_complete → close_round理論上完整稽核流程也能跑通 — 但沒實際 e2e 驗。
dispatcher map 還沒加 task_* / survey_* / approval 對應的 legacy route。 M5.8 panel 還在當 fallback。等短流程 PoC 通了再做。
User 提到「希望可以連同 AO 都可以去挑選流程清單的流程」— 目前 OZ.10 Phase 1 只是 fallback 預設 single-task workflow;user 進 TaskSetupView 後只能編輯 既有 workflow_template 的 BPMN,不能換成其他 template。
完整的「per-AO 換 workflow template」要做:
default_ao_workflow_template_id(A 方案)module_frames.default_ao_workflow_template_id 欄位已存在但 NULL。Admin 應該能在 ModuleFrame 編輯頁配,跟 ModuleFrame 走的所有專案都用該 template 當 AO 預設。
目前 start_oscal_project_for_node step 11 fallback 只用 builtin-ao-default-single-task,沒讀 default_ao_workflow_template_id。 若 admin 配了該欄位希望 override,code 還沒 honour。
| 檔案 | 內容 |
|---|---|
feedback_dark_mode_required.md |
FE 元件必驗 light + dark 雙模;禁用 --blue-50 / --green-50 等 light-only token |
project_flow_project_overview_design_notes.md |
FlowProjectOverviewView 4 個待辦:建好即啟動語意 / table view toggle / dark mode 修補 / 7+ 輪 collapse |
lsof -i :8000 -t 釋放)/.../planning?flow=1 + FlowPhaseBannerPOST /oscal-project/start 路徑仍可用(舊 OSCAL view 內部跳轉還在走它)/project/projects/:id/... 路由族不變,可用 deep link 進 legacy view(不帶 ?flow=1 不顯示 banner)builtin-oscal-internal-only 整條跑通了嗎?3758b86 OZ.0 analysisf0438d9 OZ.3 audit_systems + devices schema4b22bb3 OZ.5 cross-repo summary887f678 6bc622f OZ.6 preview lists2d9f0dd OZ.6.3 start_date/end_date schema 修ca53717 OZ.6.4 participants user_uid 兼容e1b69ae OZ.8 remove kickoff557fac8 OZ.9 #2 OSCAL plugin renamea7b6075 OZ.9 Phase 2 export_report close_ap_if_open8c38848 OZ.10 Phase 1 AO default workflow fallback1111bcb OZ.10.1 DI in seed XMLfe04649 OZ.1+OZ.2 Hybrid Pickers + ProjectCreateViewf60e445 OZ.4 cleanup82f9fbe OZ.5 testsec4f54c f980683 8743847 aa9e6fe OZ.6 preview iterations06e2bae ProjectListView「新增專案」按鈕導ad49ef4 picker module-level cachea4adff7 ProjectListView owner null guard75ff33b row click → flow-project-overview7d2dbe7 OZ.7 dark mode + table togglecac7d63 OZ.8 i18n rename42683e9 OZ.9 Phase 1 banner + dispatcher6050ffe OZ.9 #1 palette hidea89c192 OZ.9 Phase 3 banner → 4 legacy view819b8d6 legacy back 按鈕 flow context 跳對faefba5 OZ.10.2 BpmnCanvas.loadXmlf7f9075 Revert OZ.10.3 timing fix(誤判)96885a6 fix .modeler.value Vue 3 unwrap bug(最新,待 user 驗)scripts/sql/2026-05-11-rename-builtin-templates-remove-kickoff.sqlscripts/sql/2026-05-11-add-ao-default-single-task-template.sqlscripts/sql/2026-05-11-update-ao-default-template-add-di.sql00-summary 第一版寫到 OZ.10 commit 96885a6 為止,但 session 後段有兩個重要 update:
.modeler.value bug 真因確認User 反映 /workflow/workflow-setup 三個功能不見(Task 屬性面板 / 新增 Task 同步 / 改屬性同步回 AO)。Ultrathink 追根:
bpmnCanvasRef.value.modeler.value.XdefineExpose({ modeler: ref }) 對 ref 自動 unwrap → .modeler.value = undefined?.value null guard → if (!modelerInstance) return silent skipsyncJobExecutions line 383)沒 guard → TypeError 拋副作用:5 天內 user 點 BPMN UserTask 沒反應 / 改屬性不存 / 新增 task 不同步 → 沒人發現(直到 user 報「儲存失敗」)
修補:commit 96885a6 拿掉 5 處多餘 .value — 待 user reload 驗證。
Scan 確認:grep .modeler.value src/ 全 0 殘留,TemplateBpmnEditor.vue (L100) 用法一致。
不是單點 bug。User 在 session 後段明確點出 OZ 系列的 hybrid 路線跟原本「BPMN 驅動全 lifecycle」差太多。
對比 main 量化:60 個 .vue 改動,+7,289 / -585 行。
已歸檔:docs/analysis/2026-05-11-bpmn-engine-direction-divergence.md — 完整紀錄 4 個選項(A Hybrid 現狀 / B 退 Legacy / C 純 BPMN / D 分流)+ 取捨 + 反悔條件。
建議路徑:先驗 6.1 fix + 跑 6.5 PoC e2e,根據結果決定 A/B/C/D。
CLAUDE.md(加 FE i18n 紀律 + RBAC seed 規範,未 commit)src/views/module_frame/ModuleFrameTemplateEditView.vuedocs/changelog/flow-engine/20260510_phase5-module-frame-preview-section.md→ 下一個 session 別動 user 這些 in-flight 改動。
| 文件 | 性質 | 是否該寫 |
|---|---|---|
docs/analysis/2026-05-11-bpmn-engine-direction-divergence.md |
方向決策歸檔 | ✅ 本次已寫 |
docs/conversation-history/2026-05-11-oz-series-handover/part-NN-of-NN-*.md |
逐輪 Q&A 拆 part | ⏳ 沒拆(00-summary 夠詳細,user 看那份)— 若 next session 需要可從 jsonl 補 |
Memory:feedback_silent_listener_bug_after_refactor.md |
refactor 跨組件後立即 smoke 紀律 | 🟡 評估中 — user 決定 |
Memory:reference_oz_series_hybrid_direction.md |
OZ Hybrid 架構 quick reference | 🟡 評估中 — 等 PoC 結果定 |
BE / FE changelog of 96885a6 已存在 |
— | ✅ |
| 跨 BE+FE+test+jedi-* 5-repo summary changelog | OZ 系列收尾 | 🟡 等 PoC 通了再寫(現在寫了等於蓋章未驗證的東西) |
CLAUDE.md 不用動(user 自己有 in-flight 編輯)。
建議新增 / 更新:
| Memory 檔 | 類型 | 內容 |
|---|---|---|
feedback_silent_listener_bug_after_refactor.md (新) |
feedback | refactor 跨組件邊界(ref / defineExpose / propsToRef)後必手動 smoke test,不要靠 build pass + 規格不變宣稱;?.value null guard 會吃 silent failure |
reference_oz_series_hybrid_direction.md (新) |
reference | OZ Option C Hybrid 架構 — BPMN 當 phase tracker,ActivityRouterPage dispatch 跳 legacy view + FlowPhaseBanner;4 個 legacy view 已掛 banner;對應 2026-05-11-bpmn-engine-direction-divergence.md |
feedback_dont_curl_test_write_endpoints.md (新) |
feedback | 驗證 PUT/POST endpoint 行為時:先 GET 拿原資料 → 推回去(idempotent)→ 或讀 BE 程式碼直接判讀;不要 curl 送測試 payload(會真寫 DB,曾覆寫 user template xml) |
feedback_oz_phase_review_threshold.md (新) |
feedback | 一個 phase 內超過 10 個小補丁應該停下做 phase recap + 驗證 baseline,不要繼續疊;subagent 並行 wave 之間要對 user 確認 |
不建議現在動的:
whimsical-munching-dolphin.md plan 還沒全做完(OZ 中段把它打斷)