# 任務：新增 Job 留言資料表

## 背景說明
Job 留言目前是透過 public.element_variables, name = 'comment' 儲存，現在要將此功能獨立拆出成專屬資料表，
以便後續查詢、管理與顯示留言紀錄。

## 前置作業 — 請先分析現有程式碼再開始

請先找到目前PUT api/1.0/flow-engine/task/comments/:task_uid 儲存留言的相關程式碼，理解：
程式路徑:api/flow_engine/routes/flow_engine_route.py JobCommentsRoute.put
目標:
   1. 目前留言資料的儲存格式與欄位
   2. 目前讀取留言的方式與時機
   3. job_execution_id 的來源與關聯的資料表

---

## 資料表規格

請依照現有專案的 schema 慣例決定放置的 schema，並建立以下資料表：
**Schema 名稱**：`compliance`
**Table 名稱**：`job_execution_comments`

| 欄位 | 型別 | 說明 |
|------|------|------|
| id | SERIAL / BIGSERIAL | 主鍵，auto increment |
| uid | UUID | 唯一識別碼，對外使用（API 傳遞用） |
| job_execution_id | UUID / FK | 關聯對應的 job execution |
| author_id | UUID | FK -> public.users.id，留言者帳號 |
| author_nickname | VARCHAR | 留言當下的使用者名稱（快照，防止改名或停用後資料遺失） |
| content | TEXT | 留言內文 |
| created_at | TIMESTAMPTZ | 建立時間 |
| updated_at | TIMESTAMPTZ | 更新時間 |

### 欄位設計說明
- `id`：內部使用，auto increment，不對外暴露
- `uid`：對外識別用（API request / response 統一使用 uid），建立時自動產生
- `author_id` 與 `author_nickname` 並存：
  - `author_id`：用於關聯查詢（頭像、個人資料）
  - `author_nickname`：快照當下姓名，user 停用或改名後歷史留言仍可正確顯示
  - 顯示邏輯：user 存在時優先用關聯資料，否則 fallback 至 `author_nickname`

---

## 任務清單

1. **SQLAlchemy 2.0 Model**
   - 依照專案現有 model 慣例建立
   - ENUM 使用 StrEnum（若有需要）

2. **Alembic Migration**
   - 建立 `job_execution_comments` table
   - 建立對應的 FK constraint

3. **Repository & Service**
   - 依照專案現有 DDD 分層慣例實作, 要遵守DDD規範
   - 至少包含：新增留言、依 job_execution_id 查詢留言清單

4. **API Endpoints**
   - 所有 API 對外一律使用 `uid`，不暴露 `id`
   - `GET    /api/1.0/grc/job-executions/<job_execution_uid>/comments` — 取得留言清單（複數：清單操作）
   - `POST   /api/1.0/grc/job-executions/<job_execution_uid>/comments` — 新增留言（複數：collection 操作）
   - `PUT    /api/1.0/grc/job/comment/<uid>` — 編輯留言（僅限本人）（單數：單筆操作）
   - `DELETE /api/1.0/grc/job/comment/<uid>` — 刪除留言（僅限本人，hard delete）（單數：單筆操作）

---

## Response 欄位說明

| 欄位 | 型別 | 說明 |
|------|------|------|
| `uid` | string | 留言 UID（對外識別） |
| `author_uid` | string \| null | 留言者 user UID（user 停用後可能為 null） |
| `author_name` | string | 顯示名稱（優先用 user.nickname，fallback 至 author_nickname） |
| `author_nickname` | string | 留言當下名稱快照 |
| `content` | string | 留言內文 |
| `created_at` | string | 建立時間（`YYYY-MM-DD HH:mm:ss`） |
| `updated_at` | string | 更新時間（`YYYY-MM-DD HH:mm:ss`） |

### Response 範例

```json
{
  "status": true,
  "data": [
    {
      "uid": "550e8400-e29b-41d4-a716-446655440001",
      "author_uid": "9d895dc8-e189-4ed6-a830-a9e468a00a04",
      "author_name": "Alice Chen",
      "author_nickname": "Alice Chen",
      "content": "已上傳截圖，請確認。",
      "created_at": "2026-03-02 10:00:00",
      "updated_at": "2026-03-02 10:00:00"
    }
  ]
}
```

---

## 注意事項
- 欄位命名統一使用 snake_case
- 遵循專案現有的錯誤處理、回應格式與權限控管慣例
- `author_nickname`、`author_uid` 在新增留言時由後端自動從 user 資料寫入，前端不需傳入
- API 層禁止直接暴露 `id`，一律以 `uid` 作為資源識別