---
title: "FR-112 規劃頁新增任務與平行流程 — 收尾 SUMMARY"
brand: "Guidant AI · **FR-112** 規劃頁新增任務與平行流程"
eyebrow: "FR-112 · 收尾 SUMMARY · 2026-09-19"
h1: "任務在規劃頁上開、流程圖只管順序 — 實作完成"
lede: "24 張 Notion 卡全部 Done，跨四個 repo。本文彙整做了什麼、使用者看得到的前後差異，以及 arc-review 後的修正與發版收尾（§10）。"
chips: [
  {text: "24 卡全 Done", kind: ok},
  {text: "四 repo · 已 push", kind: accent},
  {text: "arc-review 4C/6I 已修", kind: ok},
  {text: "無 DB migration", kind: ok}
]
footer: "FR-112 收尾 SUMMARY · 2026-09-19（2026-09-20 補 arc-review 收尾）· 設計決策見 design.html · 每一棒的細節見各 Notion 子卡"
---

> 狀態：**實作完成，arc-review 已修正、已 push**｜日期：2026-09-19（arc-review 收尾 2026-09-20）
> 母卡 CM-1952｜子需求 CM-1953（套件）／CM-1957（BE）／CM-1966（FE）｜子任務 CM-1954～1976、CM-1977～1980

---

## 1. 一句話

PM 要替一個查核項目多開一件事，動線回到**專案規劃頁**——按「新增任務」、填名稱、存檔就好；新任務預設**平行**（誰先做都行，全部做完該查核項目才算過）。**流程圖編輯器降為純粹的走向設計工具**，屬性面板只剩名稱。連帶修掉一個既有引擎缺口：**合流閘道不等兄弟分支就放行**。

---

## 2. Commits（四 repo 分列）

### compliance-manager-be（15 筆，branch `feature/planning-task-parallel-flow`）

| hash | 做了什麼 |
|---|---|
| `e931f5a1` | 討論稿與 design 定案（D1–D7 拍板，拆 4 子需求 16 子任務） |
| `d88c1b4a` | D6 改為「至少保留一個任務」——刪到零在兩個入口都擋下 |
| `5937f03b` | D-4.1 開工前查證落地：輪次圖與查核項目圖**不共用**（DEV 全庫 44 vs 1525 零交集），可開工；覆核輪 re-clone 陷阱列為延伸項 |
| `efe31bf6` | 🔴 合流閘道等待修正**兩落點**（`complete_job` / `complete_main_workflow_job`），共用私有判定方法、不複製第三份 |
| `4fbc68c3` | 新增任務不帶節點編號時後端自己在圖上掛平行分支＋主表／翻譯表雙寫 |
| `0b558ed9` | 圖寫入收斂成只寫 `name`；描述／指南／類型的讀取路徑改讀 DB 欄位 |
| `78f15021` | 刪除任務升為主路徑：至少保留一筆、移節點改走雙寫 |
| `36cf6161` | 初始狀態與可否退回改依**拓樸**判定（不再看數量、不再只看下一批第 0 筆） |
| `7a4dd71e` | 流程圖存檔改由後端**三向 diff** 決定新增／刪除；新增 `workflow_xml_sync_service.py` |
| `868c7ec9` | §5.8 加第五列：一節點對多筆任務擋下、不靜默刪 |
| `6b39e730` | 新增／刪除任務接**規劃期守門**（`GRC_412054`）；存檔端點只在真的要增減任務時才問 |
| `da9e8a32` | 子需求 B 收尾：實作一節點多任務擋下（`GRC_400127`）、修假倉儲缺方法、reviewer 掃描 |
| `081b39be` | 任務清單改依建立時間排序（`ORDER BY je.created_at ASC, je.id ASC`） |
| `9e7e4957` | 任務區塊 Master-Detail 重排 mockup（決策者手測後裁示，C-3.5 依據） |
| `8e17b7bd` | 建案寫範本 XML 改走倉儲雙寫——新專案開編輯器不再一存就被擋 |

### compliance-manager-fe（20 筆，同 branch）

| hash | 做了什麼 |
|---|---|
| `bdeacba` | 規劃頁任務區塊補新增／刪除任務按鈕（C-3.1） |
| `737b846` | 流程圖編輯器屬性面板瘦身到只剩名稱（C-3.2） |
| `7ab8d14` | 編輯器存檔瘦身到只存一次 XML，增刪交給後端三向 diff（C-3.3） |
| `6b07993` | 存檔被擋下時顯示是哪個節點有問題（三支碼併陳 BE 明細） |
| `ba4346d` | 補 `GRC_412054` 兩語系翻譯 |
| `03df3b4` | 補 `GRC_400127` 翻譯＋併陳 BE 明細 |
| `84cece0` | AO「已配置」改為**全部**任務都有指派人才算（`some` → `every`） |
| `aba80cb` | 「任務設定」統計改以**任務**為單位（與「證據蒐集」分母一致） |
| `0f6b36e` | AO 卡「未配置」標籤帶筆數（`1/2 未配置`） |
| `01a78a1` | 任務區塊改 Master-Detail 並抽成子元件（C-3.5，主檔淨減 880 行） |
| `ff8d9ef` | 統計卡可點開未設定清單，與範本頁共用同一組元件（C-3.4） |
| `177ae97` | 任務區塊改上下排版——清單改橫向籤列、表單吃滿寬 |
| `2cfd545` | 任務籤列改用 PrimeVue `TabView`，移除自刻的 `AoTaskList` |
| `1c2e58a` | 任務區塊外層改 `dark-card` 與現況說明卡一致 |
| `8cbca4c` | 規劃頁四處風格統一（麵包屑改 Breadcrumb、SSP 分頁包卡片、主籤列接合內容） |
| `fb50c0f` | 規劃頁與範本編輯頁版型統一，版型樣式抽共用檔 `_planning-layout.scss` |
| `f25b452` | 專案總覽頁與任務抽屜對齊規劃頁版型；AO 任務區抽成清單元件 |
| `c787e7b` | 待辦任務抽屜改覆蓋滑入＋表格內建捲動；抽屜頁首重排、底色統一 |
| `eaf2bbe` | 抽屜頁首與租戶分組抽子元件——超標檔行數回到改前 |
| `a57351a` | 補 `FLOW_ENGINE_412003` 翻譯＋刪除鈕停用原因改成畫面常駐 |

### jedi-flow-engine（3 筆，同 branch）

| hash | 做了什麼 |
|---|---|
| `b5d36c0` | 新增 `bpmn_topology.py` 三支純查詢函式：分叉／合流分辨、上游型別、兄弟分支末端任務（A-1.3） |
| `27984b1` | `append_parallel_user_task_to_xml()`：三種圖形收斂成同一支函式，既有節點 id 與 uid 全程不動（A-1.1） |
| `e34372a` | `remove_user_task_from_xml()` 擴充：收退化閘道、擋下刪到零任務（新碼 `FLOW_ENGINE_412003`）（A-1.2） |

### compliance-manager-test（2 筆）

| hash | 做了什麼 |
|---|---|
| `9653718` | FR-112 平行任務 e2e 回歸與新情境：既有回歸對齊 DOM 改版（紅 23 → 0）＋新增 12 條情境（D-4.3） |
| `d068536` | 拿掉 `@known-bug` 標記——四條全轉綠 |

---

## 3. 改動範圍

| 層 | 主要落點 |
|---|---|
| **套件** | `jedi_flow_engine/common/utils/bpmn_topology.py`（新）、`bpmn_uilts.py`（插節點／移節點）、`common/enum/error_code.py`（＋1 碼） |
| **BE app** | `app/flow_control/service/workflow_xml_sync_service.py`（新，223 行）、`job_service.py`（守門＋`delete_job_from_diagram`）、`app/flow_engine/service/workflow_execution_service.py`（合流等待兩落點） |
| **BE infra** | `infra/flow_control/repository/flow_control_job_repo_impl.py`（插節點／雙寫／初始狀態／可否退回／`create_job_for_node` 等）、`infra/readmodel/oscal/ssp_control_implementation_query.py`（排序＋三欄） |
| **BE 其他** | `app/flow_control/service/prep_job_generation_service.py`（建案寫範本改雙寫）、`common/code/flow_control_error_code.py`（＋5 碼）、`api/module_frame`（存檔端點接 sync service） |
| **FE** | `ProjectPlanningView.vue`（3,682 → 2,776 行）、新元件 `AoTaskSection` / `AoTaskForm` / `PlanningStatsBar` / `StatCard` / `UnfilledListOverlay`、composable `usePlanningStats` / `usePlanningJump`、`WorkflowSetupEditor.vue`（瘦身到 588 行）、三語系 error-code.json |
| **test** | `site-regression/` 新增 `planning-task-parallel.feature`（12 條）＋兩支 page object ＋ factory；既有回歸對齊 DOM |
| **DB** | **無 migration**（本案不動 schema） |

---

## 4. 行為差異（使用者看得到的）

| 場景 | 之前 | 現在 |
|---|---|---|
| 替一個查核項目多開一件事 | 只能開流程圖編輯器、拖方塊、手動接線、填一堆屬性 | 規劃頁按「新增任務」、填名稱、存檔；後端自己畫圖 |
| 一個查核項目的任務數 | 實質只有一筆 | 可多筆，**預設平行**（誰先做都行） |
| 該查核項目何時算通過 | 那一筆完成即通過 | **全部任務完成**才通過 |
| 多筆任務的畫面 | 每筆一個可展開面板往下堆，四筆全展開要捲好幾屏 | 上方籤列選一筆、下方顯示那一筆的表單；只有一筆時籤列不顯示 |
| 刪除任務 | 只能在流程圖編輯器刪方塊，任務可能還在 | 規劃頁與編輯器**兩個入口效果完全一樣**，都會真的刪掉任務與關聯資料 |
| 刪到最後一筆 | 可以刪光（該項目變成「開始→結束」、無人經手即通過） | **擋下**，按鈕旁常駐顯示「查核項目至少要有一個任務」 |
| 稽核開跑後改任務清單 | 沒有限制 | 新增／刪除鈕停用並顯示原因、後端同步擋下；**純調整走向仍然存得下去** |
| 流程圖編輯器屬性面板 | 名稱／工作描述／指南／任務類型／設備／部門 | **只剩名稱**；其餘回規劃頁填 |
| 編輯器存檔 | 逐節點打 API 更新任務，會蓋掉規劃頁設好的問卷與審查旗標 | 只存一次 XML，增刪由後端比對決定；**不再覆蓋任何任務資料** |
| 存檔被擋下時的訊息 | 一句籠統的話，圖上十幾個方塊不知道要改哪個 | **指出是哪個方塊**（四支碼都併陳後端明細） |
| 平行分支上的任務狀態 | 第二筆以後全部排隊 `TODO`（畫面像「有三個任務但只能做一個」） | 平行分支上的任務**全部是進行中** |
| 「兩條平行 → 合流 → 主管覆核」 | 完成第一條，覆核任務就提早跳成進行中 | 兩條都結束才啟動覆核任務 |
| 退回任務 | 下一批第 1 筆已完成也照樣放行（使用者做過的事無聲消失） | 下一批**沒有任何一筆已完成**才可退 |
| 「任務設定」進度卡 | 以 AO 為單位，新增空任務分母不動 | 以**任務**為單位；三張卡皆可點開未設定清單並跳到該項 |
| AO「已配置」綠勾 | 任一筆有指派人就算（空任務被掩蓋） | **每一筆**都有指派人才算；未配置標籤帶筆數 |
| 規劃頁任務排序 | 看 DB 回傳，平行新增多筆後順序會跳 | 依建立時間固定 |

---

## 5. 規範文件（本次收尾一併更新）

| 文件 | 更新內容 |
|---|---|
| `docs/spec-site/current/project-management/project-planning.md` | hub 頁：功能總覽補新增／刪除任務、§4 加兩道 gate、§5 補 Master-Detail 版面與麵包屑、§6.2 補 endpoint 與「名稱取圖上其餘取 DB」、§7 檔案地圖、§10 進度卡改任務單位＋未設定清單、§12 加三條坑 |
| `docs/spec-site/current/project-management/project-task-edit.md` | 子頁（本案主要落點）：§1 真相分工、§3 兩道新守門、§4 兩道 gate、**§5 新增三節**（Master-Detail 版面／新增與刪除任務／三向 diff／編輯器能力範圍）、§6.2 補三支 endpoint、§7/§8 檔案地圖、§11 合流等待與雙寫、§12 加六條坑 |
| `docs/spec-site/current/compliance-framework/flow-template-manage.md` | §12 坑 1：補記 workflow-setup 編輯器已降為純走向工具（該頁無獨立 spec，順帶記在這裡） |
| `docs/user-manual/lifecycle-and-use-cases.md`（＋ spec-site 同名副本） | §3.5 補「一個 AO 可多任務、全部做完才算過」；Phase 1 新增兩節操作段：**新增與刪除工作任務**、**流程圖編輯器只用來調整先後順序** |
| `docs/features/README.md` | FR-112 那列狀態更新 |
| `docs/features/FR-112-.../README.md` | 新建（結論／總進度表／需求討論紀錄三段） |
| `docs/claude/memory/` | 同步兩支新 memory（Bifrost 磁碟滿、FE 先查 PrimeVue） |

**驗證**：`mkdocs build --strict` 通過、`fix_anchor_ids.py` 無新增錨點、禁用句型 grep（`原本｜改判｜第 N 棒｜整理後｜這次整理｜當初｜收斂前`）在本次新增內容中 0 命中。

---

## 6. 🔴 已知 follow-up

### 6.1 必做四件事（有順序）—— ✅ 皆已完成（2026-09-20，詳見 §10）

| # | 事 | 狀態 |
|---|---|---|
| 1 | jedi-flow-engine 發版 1.1.2 → 1.2.0（後續 arc-review 又再發到 1.3.0） | ✅ 已發版 |
| 2 | BE 還原 pin 並一起 commit | ✅ 已完成 |
| 3 | 主 checkout 的 `.venv` 還原 | ✅ 已完成 |
| 4 | arc-review ＋ merge 回 `feature/review` | ✅ 已完成，見 §10 |

### 6.2 延伸 FR（design §8 四條，皆未開案）

| 項目 | 為什麼會長出來 |
|---|---|
| **編輯器 UI 優化／屬性面板擴充** | 決策者原話「目前的 UI 設計不是很好用，之後再來優化」——本案先收到只剩名稱以止住第二份真相 |
| **稽核中補任務** | D1 把新增限制在規劃期，但「稽核到一半發現漏了一項」確實會發生；牽涉補件流程與報表口徑 |
| **多任務流程範本** | `_first_user_task_id()` 只抓第一個 `userTask`，範本做成多任務會靜默漏建 |
| **覆核輪對多任務查核項目的任務生成** | 覆核輪 re-clone 第一輪範本後重跑生成，只認第一個方塊——AO 可多任務後會出現「圖上三個方塊、資料庫一筆任務」且無錯誤訊息（arc-review I5「合流等待在分支任務沒被建出來時永久卡住」與此同源，優先度建議拉高，仍留延伸、未開案） |

另 design §8 列有「圖上舊 camunda 屬性清理」，狀態為**不排程**（風險大於收益）。

### 6.3 既有紅測試 —— ✅ 已由 CM-1979 修復（2026-09-20）

| 測試 | 狀況 |
|---|---|
| BE `test/test_error_code_mirror_parity.py` | ✅ 已修：`jedi-compliance-audit` 補齊碼表 12 個成員並發版 1.1.3，兩邊 242 對 242 零漂移 |
| 套件 `test_verify_workflow_executions_exist_by_uid_not_exists` | ✅ 已修：斷言改成正確的 `ConflictError` |

### 6.4 已知不修

- **DEV 上 migration 前建立的專案，範本翻譯表沒有任務編號**——`8e17b7bd` 只修寫入路徑，決策者裁示不補舊資料。這些專案開編輯器仍會被三向 diff 擋下。
- **DEV 上兩組「一節點對多筆任務」的殘留**（`we 12443` 的 job 12705/12754、`we 12445` 的 12707/12752）——舊版編輯器留下的，存檔會被 `GRC_400127` 擋下，要由人決定留哪一筆。**刻意不自動選**。

---

## 7. 部署 handover

| 項目 | 狀況 |
|---|---|
| **DB migration** | **無**。本案不動 schema，也沒有 seed |
| **套件** | 🔴 **要發版**：jedi-flow-engine 1.1.2 → 1.2.0（見 §6.1）。BE 沒有這支新版就跑不起來——三支拓樸函式與 `FLOW_ENGINE_412003` 都在套件裡 |
| **環境** | 全程只動 DEV；**STG / POC 一律未動**（開發期鐵律）。上版順序照常：DEV 驗收 → 決策者放行 → STG → POC |
| **出貨基線** | 不受影響（無 migration） |
| **FE** | 純前端改動，隨常規 build 走；新增 i18n key 在 zh-tw / en 兩語系（zh-cn 該檔只維護 6 個檔，照既有慣例不另建） |
| **設定 / 環境變數** | 無新增 |

---

## 8. 驗收怎麼確認（決策者親手可驗，摘自 design §7.2）

1. 起一個新專案 → 規劃頁點任一查核項目 → 按「新增任務」→ 填名稱存檔 → **重新整理仍在**
2. 打開流程圖編輯器 → 新方塊與原任務**並排**（平行），不是串在後面
3. 同一查核項目連續新增到三筆 → 三筆**全部是進行中**，沒有任何一筆在排隊
4. 只完成其中一個 → 該查核項目**不可以**變已完成；全部完成 → 才變
5. 編輯器把流程改成「兩條平行 → 合流 → 主管覆核」→ 完成第一條 → **覆核任務不得變進行中**
6. 編輯器點方塊 → 右邊**只剩名稱欄**
7. 編輯器刪掉一個方塊存檔 → 回規劃頁該任務**消失**
8. 規劃頁刪到剩一筆 → 刪除鈕停用，**不必把滑鼠移過去就看得到**「查核項目至少要有一個任務」
9. 輪次凍結後 → 新增／刪除按鈕停用、**畫面看得到原因**；直接打後端端點也被擋；但純調整走向照樣存得下去

e2e 已覆蓋上述多數情境（`planning-task-parallel.feature`，12 條）。

---

## 9. 讀哪一份

| 你想知道 | 看哪份 |
|---|---|
| 為什麼這樣決定、被排除了什麼 | [`design.md`](../design.md)（D1–D7 全文） |
| 完整的選項推演與業界對照 | [`discussion.md`](../discussion.md) |
| 做完之後頁面長什麼樣、欄位與 API | SPEC `docs/spec-site/current/project-management/project-task-edit.md` |
| 使用者怎麼操作 | `docs/user-manual/lifecycle-and-use-cases.md` Phase 1 |
| 每一棒做了什麼、踩了什麼坑 | 各 Notion 子卡（CM-1954～1976、CM-1977～1980）與四 repo 的 commit message |

---

## 10. arc-review 與修正（2026-09-20）

母卡 CM-1952 收尾隔天，依 §6.1 排程跑了 arc-review（CM-1977），找出問題後開三張修正卡（CM-1978／1979／1980）全部修完、Done，再發套件版、merge push 三 repo。

### 10.1 review 結論（CM-1977）

**4 個 Critical、6 個 Important，共同病因是「同一件事有兩個入口，只改了一邊」**：

| # | 問題 | 根因 |
|---|---|---|
| C1 | 編輯器拖新方塊建的任務會排隊，規劃頁做就不會 | 規劃頁那條已改用拓樸判定，編輯器那條還在用舊判準——兩支平行改動互不知情，一支比另一支早 6 分鐘 commit，「屆時一起改」的註解永遠等不到 |
| C2 | 編輯器刪方塊不會歸檔 Google Drive 資料夾 | design §5.4 要求接上，編輯器那條路徑整支沒接 Drive 呼叫 |
| C3 | 「二選一→兩邊各接一件事→合流」流程會永久卡死，後台查不到 | 套件 `bpmn_topology.py` 合流判定漏掉二選一分支下再接任務的情境 |
| C4 | 一次刪兩個方塊加一個新的，被系統自己擋下 | 上層總帳算對（2-2+1=1），但執行順序是先刪後建，刪到一半總筆數歸零，底層防呆誤判整批擋下 |

Important 六項含權限判準不一致（I1）、輪次凍結反查查不到時 fail-open（I2）、任務名稱讀取方向與 §5.1 相反（I4）等，詳見 CM-1977 全文。決策者當場裁示四項待決：①編輯器刪任務不必是專案 manager身分（接受）②輪次凍結反查不到維持放行（接受）③任務名稱真相方向另開卡（不在本輪）④這輪要再發一次 jedi-flow-engine 版本（是，用來拆超標的套件檔）。

### 10.2 三張修正卡

| 卡 | 修了什麼 | commit |
|---|---|---|
| **CM-1978** | C1／C2／C4／M1（重複雙寫邏輯收成一份）。C1 改吃拓樸判定並確認餵的是新圖非舊圖；C2 補上 Drive 歸檔呼叫；C4 改成「先建、再寫圖、最後刪」並修掉過程中發現的 ORM 快取讀舊圖問題；同時把用假物件繞過真正檢查的既有測試改成打真實路徑。194 條測試全綠，四項修法各自做過突變驗證（拿掉修法確認測試真的變紅）。design.md §5.4／§5.8 補上決策者裁示 | `6769cfdf` |
| **CM-1979** | C3（套件 `bpmn_topology.py` 合流判定）＋ arc-review 建議的拆檔：把套件 `bpmn_uilts.py` 從 1,213 行拆成 `bpmn_uilts.py`（534，讀圖）／`bpmn_mutation.py`（496，改圖，新增）／`bpmn_di.py`（148，畫座標，新增）／`bpmn_nodes.py`（89，最底層節點操作，新增），比原訂多切一支是為了避免改圖與畫座標互相 import 造成循環相依。順手補齊碼表鏡像 12 個成員（`test_error_code_mirror_parity` 轉綠）、修掉一支既有紅測試斷言。發版 `jedi-flow-engine` 1.2.0→1.3.0、`jedi-compliance-audit` 1.1.2→1.1.3，BE pin 已更新（`poetry update` 指名兩支套件）| pkg `c86952b`／`dfe260a`，BE `67951f70` |
| **CM-1980** | 卡住任務的人工出口——新增 `GET .../job/<job_uid>/blocked-status` 與 `POST .../force-start` 兩支端點（manager-only），判定共用套件拓樸函式與畫面診斷同一支邏輯，守門用 `project_uid` 直接走 `assert_project_manager`（反查鏈只覆蓋約 11% 流程，不可用）。新增稽核事件碼 `JOB_FORCE_STARTED=6150`。FE 兩處（規劃頁任務表單、抽屜）都加警示與按鈕，兩檔皆淨減行數。23 條新測試 + 既有 109 條全過，三道突變驗證全變紅 | BE `525989b7`，FE `d2d2599` |

### 10.3 發版與 merge

八支套件（含本輪與此前 arc 累積的 pin bump）已發版、BE/FE pin 已對齊，三 repo（BE／FE／jedi-python-package）已 merge 回 `feature/review` 並 push。`bpmn_uilts.py` 已從 `docs/claude/oversized-files.md` 超標清單劃掉（1,213→534）。

### 10.4 仍未收的

- **待裁③任務名稱真相方向**（`ssp_control_implementation_service.py:512` 圖優先、DB fallback，與 §5.1「DB 是真相」方向相反）——決策者裁另開卡，本輪未動。
- **I5 合流等待在分支任務沒被建出來時永久卡住**——與 §6.2 延伸項「覆核輪對多任務查核項目的任務生成」同源，優先度建議拉高，仍未開案。
- design §8 四條延伸 FR（見 §6.2）維持未開案。
