# Spec 4 接手指南 v2（M10 起手，FE + 收尾）

> **建立日期**：2026-05-14
> **撰寫**：raymond（透過 Claude Opus 4.7 session 2）
> **接手對象**：M10 FE 新 session 的開發者 / Claude
> **執行策略**：subagent-driven-development（M10 一個 implementer + 1 spec reviewer + 1 code reviewer）

---

## 一、本案脈絡（5 行掃完）

- **目標**：spec 4 在既有 stage_object / BPMN flow template 機制上新增 `review` 階段 + 範本方向性驗證 + 全 stage 共用留言
- **進度**：M0–M9 已完成（BE 全範圍 ship）；剩 M10 FE + M11 smoke/BDD/changelog 收尾
- **branch**（BE / FE / test 三 repo 都用同名）：`feature/project-flow-engine-review`
- **設計文件**：`docs/features/FR-026-2605-project-flow-engine-integrate/04-review-stage-and-flow-validation/design.md` v1.3
- **實作計畫**：同目錄 `implementation-plan.md` v1.1

---

## 二、已完成 milestones（M0–M9 全 BE）

### Session 1（M0–M6）— 詳見 handoff-v1.md

DB schema + ORM mapping + BpmnTopologyValidator + builtin BPMN patch + `POST /flow-engine/flow-templates/validate` endpoint。

### Session 2（M7–M9）— 本 session 產出

| M | 內容 | Commit |
|---|---|---|
| M7 | StageAdvanceRequestSchema 加 decision/comment + ReviewDecisionHandler + DI register | `faa21d5` |
| M8 | StageAdvanceService 接 decision/comment + 業務驗證 + JobComment(UUID fix) + Route 傳參 + design.md §16.2 reconciliation + log enrichment | `dfc526d` + `83a7eb6` + `47b99d5` |
| M9 | 5 條 service-level mock test + 1 條 validate HTTP smoke + 1 條 skip(deferred) + BPMN fail-case fixture + autouse→opt-in hygiene | `bf69977` + `fcbaa53` |

### Session 2 重要決策軌跡（給 FE 接手時參考）

1. **`@validates_schema` 訊息被 jedi-common 吞掉 → 業務驗證放 service 層**：FE 從 `/stage/advance` 拿到 400 時 `msg` 是 generic「請求參數錯誤」，**真實 error code 在 `error_code` 欄位**（GRC_400061 / GRC_400062）。FE 顯示錯誤訊息時必須走 i18n by error_code，不要直接顯示 msg。詳見 design.md §16.2。

2. **`ReviewDecisionHandler` silent default approve 已被 service 層先擋住**：M9 test 已驗證 decision=null → GRC_400062；FE 送 advance 時若 stage 是 review 必須帶 decision，否則一定 400。

3. **JobComment 寫入失敗不擋推進**（M8 log enrichment fix）：BE 在 BPMN 推進成功後寫 JobComment 是 best-effort；如果寫失敗只 log warning + 帶 `ap_uid / project_uid / user_id / template_job_id` context，**FE 在 success response 後不要假設 comment 一定寫進 DB**。M11 manual smoke 需驗證 comment 列表確實顯示退回原因。

4. **HTTP `/validate` endpoint 路徑**：`POST /api/1.0/flow-engine/flow-templates/validate`（注意 `/api/1.0` prefix；M9 test 已驗）。

---

## 三、待做 milestones（M10–M11）

### M10 — FE：Banner approve/reject 雙按鈕 + ConfirmDialog comment + BPMN editor inline warning

**Repo**：`~/Projects/Billows/Audit-Manager/compliance-manager-fe`

切換指令：
```bash
cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
git fetch
git checkout feature/project-flow-engine-review 2>/dev/null || git checkout -b feature/project-flow-engine-review
```

**⚠️ FE 檔名跟 plan 描述不完全一致，實際路徑（已驗）**：

| Plan 寫的路徑 | 實際存在路徑 |
|---|---|
| `src/components/grc/FlowPhaseBanner.vue` | ✅ 同名 `src/components/grc/FlowPhaseBanner.vue` |
| `src/views/flow-template/FlowTemplateEditView.vue` | ⚠️ 實際是 `src/views/flow-template/FlowTemplateEditorView.vue`（多 `or`） |
| `src/service/FlowPhaseService.js` | ❌ 不存在；實際是 `src/service/FlowTemplateService.js`（M10.3 需找 stage advance 的 service，可能在別處 — implementer 必先 grep `advanceStage\|stage/advance`） |
| `src/views/flow-template/components/BpmnPaletteProvider.js` | ⚠️ palette 實際在 `src/views/flow-template/bpmn/` 或 `src/views/flow-template/components/` — implementer 必先 ls 確認 |

**M10 sub-tasks**：

1. **M10.1** i18n keys — `src/locales/zh-TW.json` + `en.json` 加 `flowEngine.validator.*` + `flowEngine.banner.review.*`（design §10.4 / plan §M10.1）

2. **M10.2** `FlowPhaseBanner.vue` review 階段加雙按鈕 + Dialog comment textarea
   - Submit / Reject 兩個 button
   - 共用同一個 Dialog，靠 `rejectMode` flag 切 placeholder + confirm-button disabled 條件
   - reject 必填 comment（trim 後不空）；approve comment 可選
   - 對 BE 送的 payload：`{ decision: 'approve'|'reject', comment: '...' }`
   - 詳細 template / setup code 見 plan §M10.2

3. **M10.3** Service / API client — `advanceStage(projectUid, apUid, payload)` 支援 decision/comment
   - **必先 grep 找 stage advance 對應 service 檔**（plan 寫的 FlowPhaseService.js 不存在）
   - endpoint：`POST /project/<uid>/ap/<ap_uid>/stage/advance`

4. **M10.4** BPMN editor inline warning — `FlowTemplateEditorView.vue` 拖 sequenceFlow 時 debounce 500ms 呼叫 `/flow-engine/flow-templates/validate`
   - 用 lodash `debounce`
   - violations 從 envelope `data.violations` 取
   - **`/validate` endpoint 一律回 200**（valid + violations），不會 throw 400；FE 不需 catch error 走 fallback
   - violations[].sequence_flow_id 用來 highlight（紅色 outline）
   - 側邊欄渲染 warning list，violation reason 走 i18n key（M10.1 加的 `flowEngine.validator.*`）+ context interpolate
   - CSS：`.djs-element.violation-marker .djs-visual > * { stroke: var(--danger-color, #dc3545) !important; }`

5. **M10.5** Palette 加 review UserTask 預設 stencil
   - 對齊既有 4 個 stage palette 模式
   - properties: `{ stage_object_code: 'review', main_role: 'reviewer' }`

6. **M10.6** FE smoke 3 項（要實際開瀏覽器 + BE 起來 + DB 有 spec 4 seed）
   - 建專案選「完整稽核流程（含審核）」→ review banner 顯示雙按鈕
   - BPMN editor 拖違規 sequenceFlow → 側邊欄出現 warning
   - reject 不填 comment → confirm 按鈕 disabled

7. **M10.7** Commit FE
   - HEREDOC + Co-Authored-By: Claude Opus 4.7 (1M context)
   - explicit git add（不 `-A` / `-am`）

**Commit msg 範本**：見 plan §M10.7（line 2292）

---

### M11 — Manual smoke + 跨 repo BDD + changelog（收尾）

**三 repo 都要動**：
- BE: `docs/changelog/2026-05-14-feat-review-stage-flow-validator.md`
- FE: 同名 changelog
- Test: `~/Projects/Billows/Audit-Manager/compliance-manager-test` 新 BDD scenario `features/flow-engine-review/review-stage.feature`

**M11.1** Manual smoke 6 步（design §12.2）— 需 user 操作瀏覽器，subagent 做不到：
1. 建專案選「完整稽核流程（含審核）」→ AP1 走 planning → task_execution → review
2. reviewer 在 review banner 按「退回」+ 寫退回原因 → 確認 BPMN 回 task_execution、JobComment 可見
3. PM 重新走 task_execution → review，reviewer 「送出審核」approve → 確認走到 audit
4. 走完 audit → 缺失 → poam → audit → 無缺失 → End
5. 同專案 launch_new_round 切回「完整稽核流程」（無 review）→ 確認 AP2 走原本 4-stage 流程，行為與 Spec 2 ship 一致
6. 範本管理頁拖 sequenceFlow 從 Gateway 指向 poam → 確認側邊欄即時警告 + 畫布紅框；強制存檔 → BE 回 400

**M11.2** BDD scenario（compliance-manager-test repo）
- Feature file: `features/flow-engine-review/review-stage.feature`
- 對應 step definition + page object（mirror 既有 banner BDD pattern）
- 跑：`npm run test:bdd -- --tags @flow-engine-review`

**M11.3** Changelog（BE + FE 各一份；test repo 不需 changelog）
- `type: feat`, `breaking: false`, `modules: [flow-engine, grc]`
- 結構見 plan §M11.3（line 2364）

**M11.4** 最終 summary（CLAUDE.md「做 summary」流程）
- 盤點 BE + FE + jedi-* + test 全 case commits
- 文件齊全度 audit：changelog / issue / analysis 缺什麼補什麼
- 對話紀錄歸檔到 `docs/conversation-history/2026-05-13-review-stage-and-flow-validation/part-NN-of-NN-*.md`（按 phase 拆 part）
- 產出 SUMMARY.md（含 commits 清單 / 改動範圍 / 行為差異 / 規範文件清單 / 已知 follow-up / 部署 handover）
- design.md §16 reconciliation 段：M10 + M11 期間若有偏離，追加新條目（目前 §16.1 + §16.2 已記）

---

## 四、執行方式提醒

`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: 提醒可發問（特別是 FE 檔名 fallback）
- Your Job 步驟條列
- Report Format（Status / files / commit SHA / self-review）

CLAUDE.md 規範必貼（兩 repo 都要遵守）：
- **commit 用 HEREDOC + Co-Authored-By: Claude Opus 4.7 (1M context)**
- **NEW commit 不用 amend**（即使是 review fix）
- **DO NOT push**（user 還沒指示）
- **explicit git add 檔名**，不用 `-A` / `-am`（CLAUDE.md 反覆強調；BE working tree 有 2 個未追蹤 SQL 不該掃進）

---

## 五、BE → FE API contract（M10 implementer 必看）

### POST /api/1.0/project/<uid>/ap/<ap_uid>/stage/advance

Request body（M7 + M8 加的欄位）：
```json
{
  "force": false,
  "decision": "approve" | "reject" | null,
  "comment": "...string..." | null,
  "ctx": {}
}
```

Response（success / failure 都用既有 envelope）：
- 200 success：`{ "status": true, "data": { "advanced": true, "handler_result": {...}, "current_stage_info": {...} } }`
- 400 業務驗證失敗：`{ "status": false, "error_code": "GRC_400061" | "GRC_400062", "msg": "..." }`（msg 是 generic「請求參數錯誤」，**FE 必須用 error_code 走 i18n**）

**Error code 對照（FE 必加 i18n）**：

| error_code | 中文 | 觸發條件 |
|---|---|---|
| `GRC_400060` | 範本流程結構不合法 | template create/update 時 topology violation |
| `GRC_400061` | 退回審核必須附留言 | stage=review + decision=reject + comment 空/whitespace |
| `GRC_400062` | decision 值必須為 approve 或 reject | stage=review + decision 缺值 |

非 review stage 送 decision → BE 不擋，靜默 ignore + log warning（不影響 FE）。

### POST /api/1.0/flow-engine/flow-templates/validate

純驗證 endpoint，**一律回 200**：

Request:
```json
{ "bpmn_xml": "<bpmn:definitions>...</bpmn:definitions>" }
```

Response:
```json
{
  "status": true,
  "data": {
    "valid": true | false,
    "violations": [
      {
        "rule": "successor_not_allowed" | "start_stage_not_allowed" | "end_stage_not_allowed" | "unknown_stage_code" | "gateway_missing_condition" | "unreachable_node" | "no_end_path",
        "reason_i18n_key": "flowEngine.validator.successor_not_allowed",
        "context": {
          "sequence_flow_id": "Flow_xxx",       // 部分 rule 帶
          "source_stage": "audit",              // successor_not_allowed
          "target_stage": "poam",
          "stage": "poam",                      // start_/end_stage_not_allowed
          "code": "xxx",                        // unknown_stage_code
          "gateway_id": "Gateway_xxx",          // gateway_missing_condition
          "node_id": "Flow_xxx"                 // unreachable_node
        }
      }
    ]
  }
}
```

**`/validate` 不會 throw 400/500**（除非 BPMN 完全無法 parse）；FE 不需 catch error 走 fallback path，只要看 `data.valid` 與 `data.violations` 即可。

### POST /api/1.0/flow-engine/flow-templates（create / update）

加上 topology 守門員。違規回 400 with `error_code = GRC_400060`，**但 violations 細節不在 response**（design §16.1 reconciliation：`err.context` 被 jedi-common 吞掉）。

**FE 設計建議**：存檔前先呼叫 `/validate` 拿 violations，UI 顯示；user 確認 OK 才送 create/update。若 BE 仍回 400（race condition / direct API call），FE 把 GRC_400060 對應到 generic「流程結構不合法，請開啟編輯器查看詳情」訊息。

---

## 六、已知限制 / Caveat（給 FE / M11 接手時看）

| 項目 | 影響 | 後續處理 |
|---|---|---|
| jedi-common ValidationError + ClientError 訊息被吞 | FE 只能拿到 error_code，msg 是 generic | FE i18n by error_code，不靠 msg。design.md §16.1 + §16.2 已紀錄 |
| FE 檔名跟 plan 不完全一致 | plan §M10 寫 `FlowPhaseService.js` / `FlowTemplateEditView.vue` 不存在 | implementer 必先 grep / ls 找實際路徑（handoff §三表格列了校正） |
| dev DB Spec 4 stage_objects 已 seed | M9 HTTP validate 測試 pass-case skipped（因 dev DB 還沒跑某 seed？實際 M1 已跑） | M11 manual smoke 必須先確認 `psql ... -c "SELECT code FROM compliance.stage_objects ORDER BY sort_order"` 5 列含 `review`；若缺，跑 `scripts/sql/2026-05-14-spec4-stage-objects-rules-and-review.sql` |
| 自訂範本 backfill scan 結果為 0（dev DB） | M4 backfill update 0 列；user 環境若有 duplicated builtin-full-audit 範本含未 patch reverse 仍需重跑 | M11 smoke step 4（launch_new_round 切回無 review 範本）若行為異常，先 SELECT 對 duplicated 範本檢查 |
| BE log 位置 `log/app.log` | 跨 BE / FE smoke 時若出現 500，先 grep BE log | 不要靠 lsof 找 stdout，CLAUDE.md 已寫 |
| BE port 8002 不是 8000 | env config 決定；FE 預設 axios baseURL 必須對齊 | FE config 看 `src/config/api/` 是否有 dev 對 8002 設定 |

---

## 七、檔案 cheatsheet

### BE 已 ship 範圍（M0–M9，不要再動）

```
compliance-manager-be/
├── 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 kwargs
├── app/flow_engine/
│   ├── service/flow_template_app_service.py   ← M5 validator integration
│   ├── service/stage_advance_service.py        ← M7+M8 加 decision/comment + JobComment
│   └── util/bpmn_topology_validator.py         ← M3 純 function
├── 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
│       └── builtin-full-audit-with-review.bpmn                ← M4 new
├── tests/test_bpmn_topology_validator.py       ← M3 22 條
├── tests/test_stage_advance_service_v4.py      ← M9 5 條 service-level mock
├── tests/test_flow_template_validate_endpoint.py ← M9 HTTP smoke
└── tests/fixtures/bpmn/invalid_start_to_poam.bpmn ← M9 fail-case fixture
```

### FE 待做範圍（M10）

```
compliance-manager-fe/
├── src/locales/
│   ├── zh-TW.json                              ← M10.1 加 flowEngine.validator.* + banner.review.*
│   └── en.json                                 ← M10.1 對應
├── src/components/grc/FlowPhaseBanner.vue      ← M10.2 雙按鈕 + Dialog comment
├── src/views/flow-template/
│   ├── FlowTemplateEditorView.vue              ← M10.4 debounced /validate + violation outline
│   └── （palette 位置 implementer ls 確認）    ← M10.5 review UserTask stencil
└── src/service/?                                ← M10.3 advanceStage(decision/comment)
                                                    （路徑 implementer grep `advanceStage|stage/advance` 確認）
```

### 測試 repo 待做範圍（M11）

```
compliance-manager-test/
└── features/flow-engine-review/
    ├── review-stage.feature                    ← M11.2 BDD scenario
    └── （對應 step definition + page object）
```

---

## 八、若 session 卡關 / 中斷

回報 user 並建議：
1. 卡 FE component 結構 → 看既有 `FlowPhaseBanner.vue` 其他 stage 怎麼處理，mirror 模式
2. 卡 axios error envelope → 對齊 BE response 結構（envelope `{ status, error_code, msg, data }`）
3. 卡 bpmn-js 事件 / canvas marker API → 看 `FlowTemplateEditorView.vue` 既有 commandStack 監聽，沿用既有 modeler 物件
4. design.md / plan.md 跟實作對不上 → 看 design.md §16 reconciliation 段，加新條目記偏差（v1.4 開頭）

---

## 九、文件版本

| 版本 | 日期 | 變更 |
|---|---|---|
| v1 | 2026-05-14 | M0–M6 完成、M7 起手交接 |
| v2 | 2026-05-14 | M7–M9 完成、M10 起手交接（FE + 收尾） |
