Spec 4 接手指南 v1(M7 起手)

建立日期:2026-05-14 撰寫:raymond(透過 Claude Opus 4.7 session 1) 接手對象:新 session 的開發者 / Claude 執行策略:subagent-driven-development(每 milestone 1 implementer + 1 spec reviewer + 1 code reviewer)


§1

一、本案脈絡(5 行掃完)

  • 目標:spec 4 在既有 stage_object / BPMN flow template 機制上新增 review 階段 + 範本方向性驗證 + 全 stage 共用留言
  • 進度:M0–M6 已完成(BE validator 路徑全通);M7–M11 待做
  • branchfeature/project-flow-engine-review(HEAD = 1befd7f 之後)
  • 設計文件docs/features/FR-026-2605-project-flow-engine-integrate/04-review-stage-and-flow-validation/design.md v1.2
  • 實作計畫:同目錄 implementation-plan.md v1.1

§2

二、已完成 milestones(M0–M6)

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 通過

重要決策軌跡(M0–M6 期間累積)

  1. M3 reverse edge 識別:extension property reverse=true 為 primary,嚴格 anchored regex ^\s*\$\{\s*[A-Za-z_]\w*\s*==\s*['\"]reject['\"]\s*\}\s*$ 為 fallback。fullmatch + 大小寫敏感。
  2. M3 reachability:forward-only BFS(reverse edge 不計入路徑),seed 從所有 StartEvent。
  3. M5 find_all 改為 list_active():app service 不直接構造 query entity,走 domain service 既有 list_active() 入口(DDD-clean)。
  4. M5 err.context 是 dead-datajedi_common.handler 目前不序列化 exception attribute。violations 細節透過 /validate endpoint(M6)surfacing;create/update 400 只當守門員。details 在 design.md §16.1 reconciliation 已紀錄。
  5. M6 routing order/validate 靜態路徑明示排在 /<string:uid> 動態之前,避免 URL collision。
  6. M6 schema/route 命名FlowTemplateValidate*Schema / FlowTemplateValidateRoute — 對齊 sibling verb-based naming(M6 review 後 rename 過)。
  7. M4 自訂範本 backfill scan = 0:dev DB 上沒有 user duplicate 自 builtin-full-audit 的範本含未 patch Flow_poam_audit,所以 backfill update 0 列;user 環境若有可能要重跑 dry-run。

環境狀態

  • BE 跑在 port 8002(不是 8000,env config 決定)
  • DB: 192.168.50.188:25432/guidant_ai_devcmmgr 密碼 jedi@123!(migration 一律 cmmgr,cm_app 被 RLS 擋)
  • BE 啟動方式(避開 .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 python
  • Login API(注意 dev schema):POST /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)

§3

三、待做 milestones(M7–M11)

M7 — StageAdvanceRequestSchema + ReviewDecisionHandler

目標:schema 加 decision/comment 欄位 + 寫新 handler 註冊到 stage_registry。

Files:

  • Modify: api/flow_engine/serializers/stage_advance.py — 加 decision (Str, OneOf approve/reject) + comment (Str) + @validates_schema 強制 reject 必填 comment
  • Modify: app/grc/service/oscal_stage_handlers.py — 加 ReviewDecisionHandler class(key=review_decision,純 dispatch decision 不動 AP.status)
  • Modify: di_containers/grc/grc_containers.py — import + Factory + register_stage_hooks_to_registryregistry.register_handler(grc_container.review_decision_handler())

詳細範本程式碼見 implementation-plan.md §M7.1–M7.4。

Commit msg: feat(spec4-M7): StageAdvance schema + ReviewDecisionHandler

M8 — StageAdvanceService 接 decision/comment + JobComment wiring

目標:service 接 decision/comment 參數;推進 BPMN 後寫 GRC JobComment;review stage 走特殊 condition_param。

Files:

  • Modify: app/flow_engine/service/stage_advance_service.py
    • advance_stage signature 加 decision: Optional[str] = None, comment: Optional[str] = None
    • 非 review stage 送 decision → log warning + pop ctx["decision"](design §6.1)
    • _build_condition_param 加 review 分支 {"decision": "approve"|"reject"}
    • 推進 BPMN 後寫 JobComment:先查 JobExecution by template_job_iduid (UUID),再傳給 JobCommentService.add_comment(job_uid=str(job_exec.uid), ...)
    • __init__job_comment_service dependency
  • Modify: api/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 取得方式)
  • Modify: di_containers/grc/grc_containers.pystage_advance_service Factory 加 job_comment_service=job_comment_service

Critical 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 整合

M9 — BE integration test

目標:寫 4–6 條 integration test 覆蓋 decision/comment + validate endpoint。

Files:

  • Create: tests/test_stage_advance_v4.py
  • Create: tests/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

M10 — FE Banner + BPMN editor inline warning(跨 repo

目標:FE 接 review approve/reject 雙按鈕 + ConfirmDialog comment textarea + editor 拖 sequenceFlow 時呼叫 /validate debounce。

Repo~/Projects/Billows/Audit-Manager/compliance-manager-fe

Files:

  • Modify: src/locales/zh-TW.json + src/locales/en.json — 加 keys(見 design §10.4)
  • Modify: src/components/grc/FlowPhaseBanner.vue沒有 banner/ 子層)— 加 review 雙按鈕 + Dialog comment textarea(同一 Dialog 共用所有 stage,靠 rejectMode flag 切換 placeholder 與 disabled 條件)
  • Modify: src/service/FlowPhaseService.js(或對應 stage advance service)— advanceStage 支援 decision/comment
  • Modify: src/views/flow-template/FlowTemplateEditView.vue — 加 debounced validateBpmn call + violation 紅 outline + side-panel warning list
  • Modify: src/views/flow-template/components/BpmnPaletteProvider.js(或 palette config)— 加 review UserTask 預設 stencil
  • New CSS: .violation-marker 紅色 stroke

詳細 plan: implementation-plan.md §M10.1–M10.7。

Commit msg: feat(spec4-fe): Banner approve/reject + BPMN editor inline warningFE repo 自己 commit

🛑 強烈建議 M10 開新 session(FE 跟 BE context 不要混;Vue/PrimeVue/bpmn-js 技術棧不同)

M11 — Manual smoke + BDD + changelog

目標:完整 e2e 跑通 + 寫 BDD scenario + BE/FE 各一份 changelog 收尾。

Repos

  • BE: docs/changelog/2026-05-14-feat-review-stage-flow-validator.md
  • FE: 同名 changelog(FE repo)
  • Test: ~/Projects/Billows/Audit-Manager/compliance-manager-test — 新 BDD scenario

Manual smoke 6 步(design §12.2)— 需要 browser 操作,subagent 做不到,必須 user 手動或 controller 帶著做。


§4

四、執行方式提醒

subagent-driven-development SOP:

  1. 每個 milestone 一個 implementer subagent(餵完整 task text + context;不讓 subagent 自己讀 plan)
  2. Spec compliance reviewer subagent(驗實作對齊 spec)
  3. Code quality reviewer subagent(驗實作品質)
  4. 若 reviewer flag issue → 同 implementer 修 → re-review → 完成才標 milestone done

每個 implementer prompt 必含:

  • Task description full text
  • Context(working dir / branch / dependencies)
  • Files (Create / Modify) 明確路徑
  • Before You Begin: 提醒可發問
  • Your Job 步驟條列
  • Report Format(Status / files / commit SHA / self-review)

CLAUDE.md 規範必貼:

  • commit 用 HEREDOC + Co-Authored-By: Claude Opus 4.7 (1M context)
  • NEW commit 不用 amend(即使是 review fix)
  • DO NOT push(user 還沒指示)
  • SQL migration 用 cmmgr 不用 cm_app
  • BE restart 必 kill -9(不是 pkill)

§5

五、已知限制 / Caveat

項目 影響 後續處理
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

§6

六、檔案 cheatsheet

核心改動位置

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 條)

Spec 1/2/3 既有檔(不要動,了解即可)

  • 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 驗證點

§7

七、若 session 卡關 / 中斷

回報 user 並建議:

  1. 卡 BE 啟動 → 看 log/app.log + /tmp/be*.log
  2. 卡 subagent 一直跑不過 → 退到 inline 自己做(更快)
  3. 卡 DB migration → 確認用 cmmgr,密碼 jedi@123!
  4. design.md / plan.md 跟實作對不上 → 看 design.md §16 reconciliation 段,加新條目記偏差

§8

八、文件版本

版本 日期 變更
v1 2026-05-14 初版 — M0–M6 完成、M7 起手交接