# FR-038 子項目：證據蒐集任務執行（evidence task execution）

> **定位**：FR-038 衍生子項目，**非新開 FR-039**。FR-038（OSCAL 重新設計 / 規劃頁 v2 遷移弧）尚未測完且龐大，本項是遷移過程暴露的衍生缺口，歸在 FR-038 弧內。
> **日期**：2026-06-17　**branch**：`feature/oscal-refactor`

## 1. 問題與根因

證據蒐集整合進專案規劃頁後，「待辦任務 / 任務佇列 / 更正 prompt」三個清單恆空。

DB 實證（DEV）：
- 新建專案的 per-AO prep-job 全 `TODO` 且 **0 指派** → 兩清單空。
- 已指派的專案（如 274，118 筆）所有 prep-job **仍 TODO** → 任務佇列（篩 `PROCESSING`）整表 `processing_rows=0` → 全空。
- `vw_user_job_queue` 已於 2026-06-15（Wave 2B Q1.4）rebind 到 v2 資料，**讀路徑已是新架構**，空的是資料流不流動。

**更深層根因**：流程範本快照時間序顯示，round 流程原本是 `planning → task_execution(執行任務) → audit`；`task_execution` 階段（precondition `all_tasks_completed`、按鈕「啟動稽核」）就是「所有人執行 per-AO 證據蒐集」的階段。最近 FR-038 把 BPMN 裡的 `task_execution` **換成 `ap_authoring`**（2026-06-16），證據蒐集塞進 planning，於是「進入執行任務階段 → 批次把任務轉 PROCESSING」這個觸發點整個消失。`compliance.stage_objects` 裡 `task_execution`（id=2，is_active=t）仍在，但活的流程不再經過它。

## 2. 鎖定的決策

| # | 決策 |
|---|------|
| 觸發模型 | **集體觸發**：PM 在規劃頁按「開始執行任務」→ 該專案**所有已指派且 TODO** 的 prep-job 批次 `TODO→PROCESSING`。**放棄 per-task 開始按鈕**。不動 BPMN 階段鏈（維持 `planning → ap_authoring`），`task_execution` stage_object 維持休眠。 |
| 可逆性 | 批次觸發**可逆、持續可按、idempotent**：後補指派的 TODO job 再按一次帶進 PROCESSING。 |
| 通知 | PM 觸發後**發通知給被指派人**（V1 有）：按 assignee 聚合張數，複用 `WorkflowExecutionService.notify_users_batch_assigned`。 |
| 覆核 | **不走覆核**，執行者提交即 `COMPLETED`（三態狀態機）；`task_assignees.is_approver` 保留不接。 |
| 證據落地 | **沿用 `compliance.job_evidences` + 現有上傳 API**，零新表零新欄位。per-AO 溯源走 `job → workflow_execution → workflow_execution_control_mapping(control_id, ao_part_id)`。 |
| 軟 gate | 啟動稽核/推進前算 prep-job 進度，未全完成**警告但可續**，不硬擋。 |
| 清單定位 | 保留兩個、語意分工：待辦=`TODO+PROCESSING`、佇列=`PROCESSING`。 |

## 3. 狀態機

```
規劃頁指派 (update_job 寫 task_assignees)            → job TODO        ［待辦任務］
PM 按「開始執行任務」(新 start_task_execution，批次)  → 已指派 prep-job 一起 PROCESSING + 通知  ［待辦+佇列］
執行者上傳 ≥1 證據 + 提交 (複用 complete_job)         → 該 job COMPLETED                       ［退出兩清單］
        └─ 沒附件 → NO_EVIDENCE 擋下（複用既有就緒檢查）
```

## 4. BE 改動（DDD 分層）

**現成可複用（不重寫）**
- 上傳證據：`JobEvidenceService.add_job_evidence` + `POST /job-evidence/<uid>`。
- 提交完成：`WorkflowExecutionService.complete_job`（已要求 `PROCESSING` 前置 + 觸發後續通知）。
- NO_EVIDENCE 就緒檢查 + 完成彙總通知：`JobBatchCompleteService`。
- 批次指派通知：`WorkflowExecutionService.notify_users_batch_assigned(user_job_counts)`。

**唯一新增的狀態轉換**
- `start_task_execution(project_uid, curr_user)`（app service，`@transaction`，manager 守門）：
  - 找該專案所有「`task_assignees` 有列且 `job_executions.status='TODO'`」的 prep-job。
  - 批次設 `job.status=PROCESSING + start_time=now()`；對應 `workflow_execution.status` 也轉 `PROCESSING`。
  - idempotent：已 `PROCESSING` 的跳過。
  - 按 assignee 聚合 `(user, count)`，呼叫 `notify_users_batch_assigned`。
  - 回傳 `{activated_count}`。
- Route：`POST /grc/projects/<project_uid>/start-task-execution`。

**提交（複用，不新寫核心）**
- Route：`POST /grc/job-executions/<job_uid>/submit`，內部走 `JobBatchCompleteService` 單筆就緒檢查 + `complete_job` + 通知。參與者守門。

**軟 gate 進度（唯讀）**
- 獨立 infra query（比照 `JobBatchCompleteQuery`）算該專案 prep-job `{total, completed, in_progress, not_started}`；規劃頁 app service 唯讀 method 曝出。

**Error code / 權限 / transaction**
- 寫入類（start / submit / upload）走 `assert_project_participant`；start 另查 manager 角色。
- 新 GRC error code（批次無對象 / 權限）依 `GRC_<HTTP><序號>` 命名。
- app service public method 皆 `@transaction`。

## 5. FE 改動

- 規劃頁：**PM-only「開始執行任務」按鈕**（批次觸發）+ 進度顯示。
- 執行者側上傳/提交 UI **沿用既有**（依 `job.status` 顯示：PROCESSING→上傳+提交、COMPLETED→唯讀、TODO→尚未開放）。
- 待辦/佇列兩頁確認 status 參數（待辦=`TODO+PROCESSING`、佇列=`PROCESSING`），勿濾掉 TODO。

## 6. Scope

- **做**：`start_task_execution`（批次+通知）、單筆 submit route、進度查詢、規劃頁批次按鈕、兩清單接線、軟 gate 警示。
- **不做**：覆核流程、復活 `task_execution` BPMN 階段、多輪證據分輪、批次任務 Excel 匯入匯出（2A dark）、新證據表。

## 7. 溯源 / 多輪註記

證據綁 project 層 per-AO job（啟動專案一次性建）。多輪重稽核的「證據分輪凍結」留作後續，本子項按單輪處理。
