# Job Evidence API 規格

> **Blueprint prefix**：`/api/1.0`
> **File**：`api/flow_engine/routes/job_evidence_route.py`
> **Auth**：JWT Required（Header：`Authorization: Bearer <token>`）

---

## API 列表

| Method | URL | 說明 |
|--------|-----|------|
| `GET`    | `/api/1.0/job-evidences` | 取得任務證明清單（by job_execution_uid） |
| `POST`   | `/api/1.0/job-evidences` | 批次新增任務證明（multipart/form-data） |
| `GET`    | `/api/1.0/job-evidence/<uid>` | 查詢單筆任務證明（RefControlProofDoc 格式） |
| `POST`   | `/api/1.0/job-evidence` | 單筆新增任務證明（multipart/form-data） |
| `DELETE` | `/api/1.0/job-evidence/<uid>` | 單筆刪除任務證明 |

---

## 1. GET `/api/1.0/job-evidences`

> **Route class**：`JobEvidencesRoute`
> **用途**：取得指定 job execution 的所有證明清單。

### Request

| 位置 | 欄位 | 必填 | 說明 |
|------|------|------|------|
| Query | `job_execution_uid` | 是 | Job Execution UID |

```
GET /api/1.0/job-evidences?job_execution_uid=<job_execution_uid>
```

### Response `200`

```json
{
  "status": true,
  "data": [
    {
      "uid": "abc123",
      "main_workflow_execution_id": 1,
      "workflow_execution_id": 10,
      "job_execution_id": 100,
      "evidence_type": "file",
      "content_hash": "sha256:abcdef...",
      "hash_algorithm": "sha256",
      "file_id": 55,
      "file": {
        "uid": "file-uid-001",
        "file_name": "evidence.pdf",
        "file_ext": "pdf",
        "save_file_name": "evidence_20260101.pdf",
        "size": 204800,
        "mimetype": "application/pdf",
        "path": "/static/file/answer/evidence_20260101.pdf"
      },
      "ref_id": null,
      "created_user": "alice",
      "created_at": "2026-01-01 10:00:00",
      "updated_user": "alice",
      "updated_at": "2026-01-01 10:00:00"
    }
  ]
}
```

### Response 欄位說明

| 欄位 | 型別 | 說明 |
|------|------|------|
| `uid` | string | 證明 UID |
| `main_workflow_execution_id` | integer | 主流程 ID |
| `workflow_execution_id` | integer | 子流程 ID |
| `job_execution_id` | integer | 任務 ID |
| `evidence_type` | string | 證明類型（`file` / `link` / `text` / `system`） |
| `content_hash` | string | 檔案雜湊值 |
| `hash_algorithm` | string | 雜湊演算法（如 `sha256`） |
| `file_id` | integer \| null | 關聯上傳檔案 ID |
| `file` | object \| null | 上傳檔案詳細（見 UploadFile 物件） |
| `ref_id` | string \| null | 關聯參考 ID |
| `created_user` | string | 建立者 |
| `created_at` | string | 建立時間（`YYYY-MM-DD HH:mm:ss`） |
| `updated_user` | string | 更新者 |
| `updated_at` | string | 更新時間（`YYYY-MM-DD HH:mm:ss`） |

#### UploadFile 物件

| 欄位 | 型別 | 說明 |
|------|------|------|
| `uid` | string | 檔案 UID |
| `file_name` | string | 原始檔名 |
| `file_ext` | string | 副檔名 |
| `save_file_name` | string | 儲存檔名 |
| `size` | integer | 檔案大小（bytes） |
| `mimetype` | string | MIME 類型 |
| `checksum` | string | 檔案校驗碼 |
| `path` | string | 檔案路徑 |

---

## 2. POST `/api/1.0/job-evidences`

> **Route class**：`JobEvidencesRoute`
> **用途**：批次上傳多個證明檔案（一次可附多個 `file`）。

### Request

**Content-Type**：`multipart/form-data`

| 欄位 | 型別 | 必填 | 說明 |
|------|------|------|------|
| `json` | file part | 是 | JSON 字串，包含 `job_execution_uid`、`evidence_type`、`ref_id` |
| `file` | file part（多檔） | 否 | 多個上傳檔案 |

`json` part 內容：

```json
{
  "job_execution_uid": "<job_execution_uid>",
  "evidence_type": "file",
  "ref_id": null
}
```

| 欄位 | 型別 | 必填 | 說明 |
|------|------|------|------|
| `job_execution_uid` | string | 是 | 關聯的 Job Execution UID |
| `evidence_type` | string | 是 | 證明類型（`file` / `link` / `text` / `system`） |
| `ref_id` | string \| null | 否 | 關聯參考 ID |

### Response `200`

回傳所有新增成功的證明物件陣列，格式同 **§1 Response**。

```json
{
  "status": true,
  "data": [ { ...JobEvidenceResponse... }, { ...JobEvidenceResponse... } ]
}
```

---

## 3. GET `/api/1.0/job-evidence/<uid>`

> **Route class**：`JobEvidenceRoute`
> **用途**：依 uid 查詢單筆證明，以 `RefControlProofDoc` 格式回傳（含控制項關聯資訊）。

### Path Parameter

| 參數 | 說明 |
|------|------|
| `uid` | 任務證明 UID |

```
GET /api/1.0/job-evidence/abc123
```

### Response `200`

```json
{
  "status": true,
  "data": {
    "main_workflow_execution_id": "1",
    "main_workflow_execution_name": "2026 CMMC 稽核",
    "workflow_execution_id": "10",
    "workflow_execution_name": "AC-1 存取控制",
    "ref_control_id": "AC-1",
    "ref_control_proof_docs": {}
  }
}
```

### Response 欄位說明（RefControlProofDoc）

| 欄位 | 型別 | 說明 |
|------|------|------|
| `main_workflow_execution_id` | string | 主流程 ID |
| `main_workflow_execution_name` | string | 主流程名稱 |
| `workflow_execution_id` | string | 子流程 ID |
| `workflow_execution_name` | string | 子流程名稱 |
| `ref_control_id` | string | 關聯控制項 ID |
| `ref_control_proof_docs` | object | 關聯證明文件（key-value） |

---

## 4. POST `/api/1.0/job-evidence`

> **Route class**：`JobEvidenceRoute`
> **用途**：單筆上傳一個證明檔案。

### Request

**Content-Type**：`multipart/form-data`

| 欄位 | 型別 | 必填 | 說明 |
|------|------|------|------|
| `json` | file part | 是 | JSON 字串，包含 `job_execution_uid`、`evidence_type`、`ref_id` |
| `file` | file part（單檔） | 否 | 上傳檔案 |

`json` part 內容（同 §2）：

```json
{
  "job_execution_uid": "<job_execution_uid>",
  "evidence_type": "file",
  "ref_id": null
}
```

### Response `200`

回傳**單筆**新增的證明物件，格式同 **§1 Response 的單筆項目**。

```json
{
  "status": true,
  "data": {
    "uid": "abc123",
    "evidence_type": "file",
    ...
  }
}
```

---

## 5. DELETE `/api/1.0/job-evidence/<uid>`

> **Route class**：`JobEvidenceRoute`
> **用途**：刪除單筆任務證明。

### Path Parameter

| 參數 | 說明 |
|------|------|
| `uid` | 任務證明 UID |

```
DELETE /api/1.0/job-evidence/abc123
```

### Response `200`

```json
{
  "status": true,
  "data": true
}
```

---

## 附錄：Evidence Type Enum

| 值 | 說明 |
|----|------|
| `file` | 上傳檔案 |
| `link` | 外部連結 |
| `text` | 文字說明 |
| `system` | 系統自動產生 |

---

## 附錄：Multipart 請求範例（curl）

### 批次新增

```bash
curl -X POST /api/1.0/job-evidences \
  -H "Authorization: Bearer <token>" \
  -F 'json={"job_execution_uid":"<uid>","evidence_type":"file","ref_id":null};type=application/json' \
  -F 'file=@/path/to/file1.pdf' \
  -F 'file=@/path/to/file2.png'
```

### 單筆新增

```bash
curl -X POST /api/1.0/job-evidence \
  -H "Authorization: Bearer <token>" \
  -F 'json={"job_execution_uid":"<uid>","evidence_type":"file","ref_id":null};type=application/json' \
  -F 'file=@/path/to/file.pdf'
```
