建立日期:2026-05-14 撰寫:raymond(透過 Claude Opus 4.7 session 1) 接手對象:新 session 的開發者 / Claude 執行策略:subagent-driven-development(每 milestone 1 implementer + 1 spec reviewer + 1 code reviewer)
review 階段 + 範本方向性驗證 + 全 stage 共用留言feature/project-flow-engine-review(HEAD = 1befd7f 之後)docs/features/FR-026-2605-project-flow-engine-integrate/04-review-stage-and-flow-validation/design.md v1.2implementation-plan.md v1.1| M | 內容 | Commit | 交付 |
|---|---|---|---|
| M0 | Pre-flight grep / psql verify | (inline) | DB schema / wiring 假設驗證 |
| M1 | compliance.stage_objects 加 4 欄 + seed review |
5613b9b |
DB 5 列含 review (sort=25) |
| M2 | ORM model / entity / mapper 對 4 欄 | e5a8901 |
Python 層讀寫 4 欄 OK |
| M3 | BpmnTopologyValidator 純函式 + 20 條 unit test |
2769ba7 + efd41ae |
pytest 20 pass / 1 expected-defer |
| M4 | builtin BPMN patch + 新 builtin-full-audit-with-review | fe0bd19 |
DB 7 列 flow_templates;M3 test 22 pass |
| M5 | FlowTemplateAppService 整合 validator + 3 error code | 7d79e83 + c78321a |
create/update 加 topology 守門員;§16 reconciliation 紀錄 err.context limitation |
| M6 | POST /flow-engine/flow-templates/validate endpoint |
d6d45ef + 1befd7f |
純驗證 endpoint live;happy + fail path smoke 通過 |
reverse=true 為 primary,嚴格 anchored regex ^\s*\$\{\s*[A-Za-z_]\w*\s*==\s*['\"]reject['\"]\s*\}\s*$ 為 fallback。fullmatch + 大小寫敏感。find_all 改為 list_active():app service 不直接構造 query entity,走 domain service 既有 list_active() 入口(DDD-clean)。err.context 是 dead-data:jedi_common.handler 目前不序列化 exception attribute。violations 細節透過 /validate endpoint(M6)surfacing;create/update 400 只當守門員。details 在 design.md §16.1 reconciliation 已紀錄。/validate 靜態路徑明示排在 /<string:uid> 動態之前,避免 URL collision。FlowTemplateValidate*Schema / FlowTemplateValidateRoute — 對齊 sibling verb-based naming(M6 review 後 rename 過)。builtin-full-audit 的範本含未 patch Flow_poam_audit,所以 backfill update 0 列;user 環境若有可能要重跑 dry-run。192.168.50.188:25432/guidant_ai_dev,cmmgr 密碼 jedi@123!(migration 一律 cmmgr,cm_app 被 RLS 擋).env 直接 source 卡 escape):
lsof -ti :8000 2>/dev/null | xargs kill -9 2>/dev/null
lsof -ti :8002 2>/dev/null | xargs kill -9 2>/dev/null
sleep 1
nohup python3 -c "from dotenv import load_dotenv; load_dotenv('.env'); import runpy; runpy.run_path('main_socketio.py', run_name='__main__')" > /tmp/be.log 2>&1 &
sleep 10
lsof -nP -iTCP -sTCP:LISTEN 2>/dev/null | grep pythonPOST /api/1.0/login body = {"username": "blsadmin", "password": "Billows@123!", "cf_turnstile_token": "XXXX.DUMMY.TOKEN.XXXX"},回 data.access_token(不是 token)blsadmin / Billows@123!(manual);blsit / Billows@123!(pytest)StageAdvanceRequestSchema + ReviewDecisionHandler目標:schema 加 decision/comment 欄位 + 寫新 handler 註冊到 stage_registry。
Files:
api/flow_engine/serializers/stage_advance.py — 加 decision (Str, OneOf approve/reject) + comment (Str) + @validates_schema 強制 reject 必填 commentapp/grc/service/oscal_stage_handlers.py — 加 ReviewDecisionHandler class(key=review_decision,純 dispatch decision 不動 AP.status)di_containers/grc/grc_containers.py — import + Factory + register_stage_hooks_to_registry 加 registry.register_handler(grc_container.review_decision_handler())詳細範本程式碼見 implementation-plan.md §M7.1–M7.4。
Commit msg: feat(spec4-M7): StageAdvance schema + ReviewDecisionHandler
StageAdvanceService 接 decision/comment + JobComment wiring目標:service 接 decision/comment 參數;推進 BPMN 後寫 GRC JobComment;review stage 走特殊 condition_param。
Files:
app/flow_engine/service/stage_advance_service.py:
advance_stage signature 加 decision: Optional[str] = None, comment: Optional[str] = None_build_condition_param 加 review 分支 {"decision": "approve"|"reject"}JobExecution by template_job_id 拿 uid (UUID),再傳給 JobCommentService.add_comment(job_uid=str(job_exec.uid), ...)__init__ 加 job_comment_service dependencyapi/flow_engine/routes/stage_advance_route.py — 在 service.advance_stage(...) call 加 decision=body.get("decision"), comment=body.get("comment") kwargs;不動既有 ctx build 邏輯(保留 user_ctx.nickname 取得方式)di_containers/grc/grc_containers.py — stage_advance_service Factory 加 job_comment_service=job_comment_serviceCritical fix 細節:原 design v1 寫 job_uid=curr_job_template.id(BPMN element id)會 silent fail;M5 spec reviewer 抓到並修進 design v1.1 §8.2。正解:
job_exec = self._job_execution_domain_service.get_job_execution(
JobExecutionQueryEntity(
workflow_execution_id=wf_ctx["workflow_execution_id"],
template_job_id=curr_job_template.id,
)
)
if job_exec is None:
logger.warning("JobExecution not found ... skip JobComment")
else:
self._job_comment_service.add_comment(
job_uid=str(job_exec.uid), # ← UUID
content=comment.strip(),
user_id=user_id,
author_nickname=ctx.get("user_nickname") or curr_user,
)詳細 plan: implementation-plan.md §M8.1–M8.6。
Commit msg: feat(spec4-M8): StageAdvanceService 接 decision/comment + JobComment 整合
目標:寫 4–6 條 integration test 覆蓋 decision/comment + validate endpoint。
Files:
tests/test_stage_advance_v4.pytests/fixtures/bpmn/invalid_start_to_poam.bpmn(inline XML,內容見 plan)注意:implementation-plan.md §M9 提示 seed_review_ap / seed_planning_ap fixture 不易在 dev DB 上重現;若卡關可退而用 service-level unit test with mock — 對齊 Spec 3 §16.1 條 3 的 deferral pattern。重點不是 100% integration coverage,是核心路徑被測過。
Commit msg: test(spec4-M9): StageAdvance decision/comment integration tests
目標:FE 接 review approve/reject 雙按鈕 + ConfirmDialog comment textarea + editor 拖 sequenceFlow 時呼叫 /validate debounce。
Repo:~/Projects/Billows/Audit-Manager/compliance-manager-fe
Files:
src/locales/zh-TW.json + src/locales/en.json — 加 keys(見 design §10.4)src/components/grc/FlowPhaseBanner.vue(沒有 banner/ 子層)— 加 review 雙按鈕 + Dialog comment textarea(同一 Dialog 共用所有 stage,靠 rejectMode flag 切換 placeholder 與 disabled 條件)src/service/FlowPhaseService.js(或對應 stage advance service)— advanceStage 支援 decision/commentsrc/views/flow-template/FlowTemplateEditView.vue — 加 debounced validateBpmn call + violation 紅 outline + side-panel warning listsrc/views/flow-template/components/BpmnPaletteProvider.js(或 palette config)— 加 review UserTask 預設 stencil.violation-marker 紅色 stroke詳細 plan: implementation-plan.md §M10.1–M10.7。
Commit msg: feat(spec4-fe): Banner approve/reject + BPMN editor inline warning(FE repo 自己 commit)
🛑 強烈建議 M10 開新 session(FE 跟 BE context 不要混;Vue/PrimeVue/bpmn-js 技術棧不同)
目標:完整 e2e 跑通 + 寫 BDD scenario + BE/FE 各一份 changelog 收尾。
Repos:
docs/changelog/2026-05-14-feat-review-stage-flow-validator.md~/Projects/Billows/Audit-Manager/compliance-manager-test — 新 BDD scenarioManual smoke 6 步(design §12.2)— 需要 browser 操作,subagent 做不到,必須 user 手動或 controller 帶著做。
subagent-driven-development SOP:
每個 implementer prompt 必含:
CLAUDE.md 規範必貼:
| 項目 | 影響 | 後續處理 |
|---|---|---|
err.context 在 jedi_common handler 被吞 |
create/update 400 path 只回 error_code+msg,無 violations details | 走 /validate endpoint 拿 violations(FE 已對齊)。design.md §16.1 已紀錄;未來 jedi_common patch 才修 |
| M9 integration test fixture seed_review_ap 不易重現 | 可能要 mock 路徑替代 | 對齊 Spec 3 §16.1 條 3 的 deferral pattern |
| BE restart .env source 易卡 JSON escape | 用 python-dotenv load_dotenv() preload 包 runpy |
已在 §環境狀態 列指令 |
| Two untracked SQL files 在 working tree | 2026-05-14-feature-project-flow-engine-integrate-deploy.sql / spec3_phase6_pr1_audit_completed_projects.sql |
上一個 task arc 留下來;本 spec 4 commits 一律用 explicit git add <files>,不用 -A |
compliance-manager-be/
├── app/flow_engine/
│ ├── service/flow_template_app_service.py ← M5 加 validator integration
│ ├── service/stage_advance_service.py ← M8 目標:加 decision/comment
│ └── util/bpmn_topology_validator.py ← M3 純 function
├── api/flow_engine/
│ ├── serializers/flow_template.py ← M6 加 validate schemas
│ ├── serializers/stage_advance.py ← M7 目標:加 decision/comment
│ ├── routes/flow_template_route.py ← M6 加 validate endpoint
│ └── routes/stage_advance_route.py ← M8 目標:傳 decision/comment
├── app/grc/service/oscal_stage_handlers.py ← M7 目標:加 ReviewDecisionHandler
├── di_containers/
│ ├── flow_engine/flow_template_containers.py ← M5 wired stage_object_domain_service
│ └── grc/grc_containers.py ← M7/M8 目標:wire review_decision_handler + job_comment_service
├── domain/flow_engine/entity/stage_object_entity.py ← M2 加 4 欄
├── infra/flow_engine/
│ ├── models/stage_object.py ← M2 加 4 欄
│ └── mapper/stage_object_mapper.py ← M2 加 4 欄 mapping
├── common/code/grc_error_code.py ← M5 加 GRC_400060/061/062
├── scripts/sql/
│ ├── 2026-05-14-spec4-stage-objects-rules-and-review.sql ← M1 migration
│ ├── 2026-05-14-spec4-builtin-flow-templates.sql ← M4 migration
│ └── seeds/bpmn/
│ ├── builtin-full-audit.bpmn ← M4 patched reverse
│ └── builtin-full-audit-with-review.bpmn ← M4 new
└── tests/test_bpmn_topology_validator.py ← M3 unit tests (22 條)
app/flow_engine/service/workflow_execution_service.py:complete_main_workflow_job — M8 advance_stage 內部呼叫的 BPMN 推進方法app/grc/service/job_comment_service.py:add_comment(job_uid, content, user_id, author_nickname) — M8 寫 JobComment 入口(job_uid 是 UUID 不是 BPMN element id)infra/grc/repository/grc_job_comment_repo_impl.py:30 — filter JobExecution.uid == job_uid 驗證點回報 user 並建議:
log/app.log + /tmp/be*.logjedi@123!| 版本 | 日期 | 變更 |
|---|---|---|
| v1 | 2026-05-14 | 初版 — M0–M6 完成、M7 起手交接 |