# 稽核輪次流程引擎再整合 — FE Implementation Plan

> **For agentic workers:** 對應 BE plan [round-flow-engine-implementation-plan.md](./round-flow-engine-implementation-plan.md)。FE 在 `~/Projects/Billows/Audit-Manager/compliance-manager-fe/`。
> **開工前必讀（cross-repo 鐵則）**：先讀 FE `CLAUDE.md`（646 行）+ `docs/claude/frontend-overview.md`，不憑印象。

**Goal:** FE 接上 round-scoped flow 引擎：Banner/stage 從 `apUid` retarget 到 `roundUid`、新增 `ap_authoring`（稽核計畫填寫）畫面、建專案照新規格（資源庫 + 第一輪範本）、建輪次選流程範本。

**Architecture:** FlowPhaseBanner（既有，generic）改吃 `roundUid` 驅動 round 生命週期；輪次轉換**一律走 Banner 的 stage/advance**（O2：直接轉換 route 已退役），不再用 round.status 七態各自打動詞 API。

**Tech Stack:** Vue 3 Composition API + PrimeVue 3.53 + Pinia + vue-i18n；`BaseService`（envelope 已拆）；i18n `lang.*`。

**設計依據:** [round-flow-engine-reintegration-design.md](./round-flow-engine-reintegration-design.md)。

---

## 0. 與既有 `audit-round-fe-migration-plan.md` 的關係（必讀）

既有遷移計畫 Step 1 用 **round.status 七態直接打動詞 API**（`launch-audit`/`start-auditing`/`close-round`）。本增量的 **O2 已把那些直接轉換 route 退役** → **該作法被取代**：

| 既有遷移計畫 | 本增量調整 |
|---|---|
| Step 1「按鈕可用性改 round.status 七態 + 動詞 API」 | **改由 FlowPhaseBanner 的 stage/advance 推進**（單一入口；動詞 route 已退役）|
| Step 2「AP 維護 view 新建」 | **= 本增量的 `ap_authoring` routed stage 畫面**（同一個，route `/round/:roundUid/ap`）|
| Step 0 api 常數 + round route | 沿用；本增量補 stage round-scoped 端點 + 建專案/建輪次範本欄 |

> 其餘（AR 維護、POA&M、風險）仍走既有遷移計畫，不在本 flow-engine 增量。

---

## 前置驗證
- [ ] 讀 FE `CLAUDE.md` + `docs/claude/frontend-overview.md`
- [ ] 確認在正確 branch（FE 不對停下問 user，**不自己切**）
- [ ] grep 確認 FlowPhaseBanner / useStageInfo / StageService 簽章未 drift（`src/components/grc/FlowPhaseBanner.vue`、`src/composables/useStageInfo.js`、`src/service/StageService.js`）

---

## 任務總覽

| # | 任務 | 依賴 BE | 風險 |
|---|------|---------|------|
| 1 | 建專案畫面（新規格：資源庫 + 第一輪流程範本雙下拉）| BE Task 8b | 低 |
| 2 | stage 機制 retarget `apUid`→`roundUid`（StageService/useStageInfo/Banner/api.js）| BE Task 9 | 中 |
| 3 | 建輪次選流程範本（預設帶資源庫）| BE Task 8 | 中 |
| 4 | `ap_authoring` 稽核計畫填寫畫面（routed stage）| BE Task 3/7 + AP API | 大 |
| 5 | 掛 Banner 的 views 改傳 roundUid + i18n | BE Task 3 | 中 |

---

### Task 1: 建專案畫面（新規格：資源庫 + 稽核流程範本雙下拉）

**File:** `src/views/project/ProjectCreateView.vue`

**模型（決策 D6）:** 建專案畫面**維持雙下拉**——選 **合規資源庫 + 稽核流程範本**。流程範本 = **第一個 audit_round（initial）的流程**（建專案順帶建 round 1）。後續輪在建輪次各自選（Task 3）。

**新規格 payload:** 資源庫下拉送 `module_frame.uid`（非 `oscal_profile_uid`）+ 流程範本下拉送 `flow_template_uid`。舊專案已清空、不做向後相容。

- [ ] **Step 1: payload 照新規格**（`handleCreate`，約 line 233）
```js
const payload = {
    resource_library_uid: selectedModuleFrame.value?.uid,   // ← module_frame.uid（非 oscal_profile_uid）
    flow_template_uid: step0.flowTemplateUid,               // ← 保留：第一輪的稽核流程範本
    name: step0.name,
    start_date: formatDate(step0.startDate),
    end_date: formatDate(step0.endDate),
    participants: selectedParticipants.value.map(p => ({ user_uid: p.uid, role: p.role })),
}
if (step0.description) payload.description = step0.description
// owner_uid 選填，預設建立者；本期不加 UI
```
- [ ] **Step 2: 資源庫下拉改綁 module_frame.uid**（Dropdown `optionValue` `oscal_profile_uid`→`uid`；`selectedModuleFrame` computed 改 `m.uid === step0.moduleFrameId`；`route.query.profile_uid` 帶入邏輯一併改 uid）。**流程範本下拉 + 必填 + 預覽全保留不動。**
- [ ] **Step 3: 手測**（雙下拉都選 → 建專案成功、建好後第一輪 initial 已綁該範本、導到 overview Banner 顯示 planning）
- [ ] **Step 4: Commit**（FE repo，顯式 git add，**不 -am**）
```bash
git add src/views/project/ProjectCreateView.vue
git commit -m "feat(FR-038): 建專案照新規格送 resource_library_uid + flow_template_uid（第一輪範本）"
```

---

### Task 2: stage 機制 retarget apUid → roundUid

**Files:** `src/config/api/api.js`、`src/service/StageService.js`、`src/composables/useStageInfo.js`、`src/components/grc/FlowPhaseBanner.vue`

- [ ] **Step 1: api 常數**（`STAGE_API` 註解改 round-scoped；對應 BE `/project/<projectUid>/audit-round/<roundUid>/stage/{info,advance}`）
- [ ] **Step 2: StageService**（`getStageInfo(projectUid, roundUid)` / `advanceStage(projectUid, roundUid, payload)` URL 改 `/${projectUid}/audit-round/${roundUid}/stage/...`）
- [ ] **Step 3: useStageInfo**（param `apUid`→`roundUid`，全檔引用改）
- [ ] **Step 4: FlowPhaseBanner**（prop `apUid`→`roundUid`，`apUidRef`/watch/onMounted 改；其餘 generic 邏輯不動）
- [ ] **Step 5: 手測**（Banner 能 fetch round stage info、顯示 planning、推進按鈕 + precondition tooltip 正常）
- [ ] **Step 6: Commit**
```bash
git add src/config/api/api.js src/service/StageService.js src/composables/useStageInfo.js src/components/grc/FlowPhaseBanner.vue
git commit -m "refactor(FR-038): Banner/stage 機制 retarget apUid→roundUid"
```

---

### Task 3: 建輪次選流程範本（預設帶資源庫）

**Files:** 建輪次的 dialog/view（`ProjectApListView.vue` 重構成輪次列表後的「建輪次」入口，見既有遷移計畫 Step 1）、`src/service/FlowTemplateService.js`（既有）

- [ ] **Step 1: 建輪次 dialog 加流程範本 Dropdown**（`listFlowTemplates({page:1,size:100})` 取 published；預設值帶 BE 回的資源庫 `audit_flow_template_uid`（建專案後 project detail 帶出，或建輪次時 BE 自動帶、FE 僅顯示可改）；可預覽 BPMN（沿用 `FlowTemplatePreviewDialog`）
- [ ] **Step 2: 建輪次 payload 帶 `flow_template_uid`**（`POST /projects/<id>/audit-rounds`，選填；不送則 BE 走 O1 fallback：前輪 > 資源庫預設）
- [ ] **Step 3: 手測**（建輪次帶預設範本、可改、建好後 Banner 顯示 planning）
- [ ] **Step 4: Commit**
```bash
git add src/views/project/ProjectApListView.vue
git commit -m "feat(FR-038): 建輪次選流程範本（預設帶資源庫 audit_flow_template_uid）"
```

---

### Task 4: `ap_authoring` 稽核計畫填寫畫面（routed stage）

**Files:** Create `src/views/project/AuditPlanView.vue`；router + menu.json + breadcrumb

> = 既有遷移計畫 Step 2「AP 維護 view」。route 對應 stage_object.route_pattern `/project/projects/:projectUID/rounds/:roundUID/ap`。main_role=auditor（FE 依 Banner `user_can_advance` 控制可推進）。

- [ ] **Step 1: 新 route**（`/project/projects/:id/round/:roundUid/ap` → `AuditPlanView`；`menu.json` 補 route name；`meta.breadcrumb[0].parent` 指輪次列表頁；側欄高亮 `ui_routes`）
- [ ] **Step 2: AuditPlanView 三區塊**（載 `GET /audit-round/<id>/ap`，可 `POST .../ap/generate-draft`）
  - **查核控制項**：`PUT /ap/<id>/reviewed-controls`（重用 `AuditTreeNav` 勾選器）— 這是 `ap_reviewed_controls_set` precondition 的填寫點，**選了才推得動 Banner**
  - **抽查名單**：`PUT /ap/<id>/assessment-subjects`（component/inventory-item/location/party/user，全量覆寫）
  - **行程 + 方法**：`PUT /ap/<id>/tasks`（timing + EXAMINE/INTERVIEW/TEST）
- [ ] **Step 3: 頁頂掛 `<FlowPhaseBanner :project-uid :round-uid />`**（推進「完成填寫，開始稽核」= submit_ap → BE start_auditing → 進 audit）
- [ ] **Step 4: 手測**（草稿載入 / 三區塊存檔 / reviewed-controls 空時 Banner 推進 disabled + tooltip / 選後可推進進 audit）
- [ ] **Step 5: Commit**
```bash
git add src/views/project/AuditPlanView.vue src/config/router/index.js src/config/menu/menu.json
git commit -m "feat(FR-038): ap_authoring 稽核計畫填寫畫面（reviewed-controls/subjects/tasks + Banner 推進）"
```

---

### Task 5: 掛 Banner 的 views 改傳 roundUid + i18n

**Files:** `ProjectAuditorOverview.vue`、`ProjectPlanningView.vue`、`AuditReviewView.vue`、`PoamView.vue`（凡 mount `<FlowPhaseBanner>` 處）；i18n `src/config/locales/i18n/{zh-tw,en}/`

- [ ] **Step 1: 各 view 的 `<FlowPhaseBanner :ap-uid>` 改 `:round-uid`**（grep `FlowPhaseBanner` 全找；prop + 取 roundUid 來源從 route param `:roundUid`）
- [ ] **Step 2: i18n 補鍵**（新 precondition reason key：`lang.flow_engine.precondition.round_prep_tasks_done` / `ap_reviewed_controls_required`；stage label `ap_authoring`；zh-tw + en 都加，比照 [[feedback_i18n_audit_against_index_loaded_files]] 確認載入）
- [ ] **Step 3: 手測 + Commit**
```bash
git add src/views/project/ src/config/locales/i18n/
git commit -m "feat(FR-038): 掛 Banner views 改傳 roundUid + flow precondition i18n"
```

---

## 漣漪 checklist
- [ ] 路由 round-scoped（`:roundUid`）+ menu.json + breadcrumb parent + 側欄高亮 `ui_routes`（[[reference_fe_sidebar_menu_highlight]]）
- [ ] PrimeVue Dropdown null-value bug：流程範本/資源庫 Dropdown optionValue 非 null（[[feedback_pinia_persistedstate_v3_flat_api]] 無關，但 Dropdown quirk 見 FE CLAUDE.md）
- [ ] BaseService 回傳已拆 envelope；error_code 走 axios 攤平（`e?.error_code`）
- [ ] **不 commit 收尾文件**；手測 pass + user 下令才寫 changelog

## E2E（compliance-manager-test repo，另開）
建專案→建輪次（帶範本）→planning 推進（收證據 gate）→ap_authoring（reviewed-controls gate）→audit→poam→close 全鏈 BDD。

## 開工順序
Task 1（建專案畫面，獨立可先 ship）→ 2（Banner retarget）→ 3（建輪次範本）→ 4（AP 填寫畫面）→ 5（views + i18n）。
