# Tool_OCR API Reference & Issues Report

## 文件資訊
- **建立日期**: 2025-01-13
- **版本**: v0.1.0
- **目的**: 完整記錄所有 API 端點及前後端不一致問題

---

## 目錄
1. [API 端點清單](#api-端點清單)
2. [前後端不一致問題](#前後端不一致問題)
3. [修正建議](#修正建議)

---

## API 端點清單

### 1. 認證 API (Authentication)

#### POST `/api/v1/auth/login`
- **功能**: 使用者登入
- **請求 Body**:
  ```typescript
  {
    username: string,
    password: string
  }
  ```
- **回應**:
  ```typescript
  {
    access_token: string,
    token_type: string,        // "bearer"
    expires_in: number         // Token 過期時間(秒)
  }
  ```
- **後端實作**: ✅ [backend/app/routers/auth.py:24](backend/app/routers/auth.py#L24)
- **前端使用**: ✅ [frontend/src/services/api.ts:106](frontend/src/services/api.ts#L106)
- **狀態**: ⚠️ **有問題** - 前端型別缺少 `expires_in` 欄位

---

### 2. 檔案上傳 API (File Upload)

#### POST `/api/v1/upload`
- **功能**: 上傳檔案進行 OCR 處理
- **請求 Body**: `multipart/form-data`
  - `files`: File[] - 檔案列表 (PNG, JPG, JPEG, PDF)
  - `batch_name`: string (optional) - 批次名稱
- **回應**:
  ```typescript
  {
    batch_id: number,
    files: [
      {
        id: number,
        batch_id: number,
        filename: string,
        original_filename: string,
        file_size: number,
        file_format: string,      // ⚠️ 後端用 file_format
        status: string,
        error: string | null,
        created_at: string,
        processing_time: number | null
      }
    ]
  }
  ```
- **後端實作**: ✅ [backend/app/routers/ocr.py:39](backend/app/routers/ocr.py#L39)
- **前端使用**: ✅ [frontend/src/services/api.ts:128](frontend/src/services/api.ts#L128)
- **狀態**: ⚠️ **有問題** - 前端型別用 `format`，後端用 `file_format`

---

### 3. OCR 處理 API (OCR Processing)

#### POST `/api/v1/ocr/process`
- **功能**: 觸發 OCR 批次處理
- **請求 Body**:
  ```typescript
  {
    batch_id: number,
    lang: string,             // "ch", "en", "japan", "korean"
    detect_layout: boolean    // ⚠️ 後端用 detect_layout，前端用 confidence_threshold
  }
  ```
- **回應**:
  ```typescript
  {
    message: string,          // ⚠️ 後端有此欄位
    batch_id: number,
    total_files: number,      // ⚠️ 後端有此欄位
    status: string            // "processing"
    // task_id: string        // ❌ 前端期待此欄位，但後端沒有
  }
  ```
- **後端實作**: ✅ [backend/app/routers/ocr.py:95](backend/app/routers/ocr.py#L95)
- **前端使用**: ✅ [frontend/src/services/api.ts:148](frontend/src/services/api.ts#L148)
- **狀態**: ⚠️ **有問題** - 請求/回應模型不匹配

---

#### GET `/api/v1/batch/{batch_id}/status`
- **功能**: 取得批次處理狀態
- **路徑參數**:
  - `batch_id`: number - 批次 ID
- **回應**:
  ```typescript
  {
    batch: {
      id: number,
      user_id: number,
      batch_name: string | null,
      status: string,
      total_files: number,
      completed_files: number,
      failed_files: number,
      progress_percentage: number,
      created_at: string,
      started_at: string | null,
      completed_at: string | null
    },
    files: [
      {
        id: number,
        batch_id: number,
        filename: string,
        original_filename: string,
        file_size: number,
        file_format: string,
        status: string,
        error: string | null,
        created_at: string,
        processing_time: number | null
      }
    ]
  }
  ```
- **後端實作**: ✅ [backend/app/routers/ocr.py:148](backend/app/routers/ocr.py#L148)
- **前端使用**: ✅ [frontend/src/services/api.ts:172](frontend/src/services/api.ts#L172)
- **狀態**: ✅ **正常**

---

#### GET `/api/v1/ocr/result/{file_id}`
- **功能**: 取得 OCR 結果
- **路徑參數**:
  - `file_id`: number - 檔案 ID
- **回應**:
  ```typescript
  {
    file_id: number,
    filename: string,
    status: string,
    markdown_content: string | null,
    json_data: {
      total_text_regions: number,
      average_confidence: number,
      detected_language: string,
      layout_data: object | null,
      images_metadata: array | null
    } | null,
    confidence: number | null,
    processing_time: number | null
  }
  ```
- **後端實作**: ✅ [backend/app/routers/ocr.py:182](backend/app/routers/ocr.py#L182)
- **前端使用**: ✅ [frontend/src/services/api.ts:164](frontend/src/services/api.ts#L164)
  - ⚠️ **注意**: 前端使用 `taskId` 作為參數名稱，實際應該是 `file_id`
- **狀態**: ⚠️ **有問題** - 前端參數名稱誤導

---

#### ❌ GET `/api/v1/ocr/status/{task_id}`
- **功能**: 取得任務狀態 (前端期待但不存在)
- **狀態**: ❌ **不存在** - 前端呼叫此端點但後端沒有實作
- **前端使用**: [frontend/src/services/api.ts:156](frontend/src/services/api.ts#L156)
- **問題**: 前端會收到 404 錯誤

---

### 4. 匯出 API (Export)

#### POST `/api/v1/export`
- **功能**: 匯出 OCR 結果
- **請求 Body**:
  ```typescript
  {
    batch_id: number,
    format: "txt" | "json" | "excel" | "markdown" | "pdf" | "zip",
    rule_id: number | null,
    css_template: string,           // "default", "academic", "business"
    include_formats: string[] | null,
    options: {
      confidence_threshold: number | null,
      include_metadata: boolean,
      filename_pattern: string | null,
      css_template: string | null
    } | null
  }
  ```
- **回應**: File download (Blob)
- **後端實作**: ✅ [backend/app/routers/export.py:38](backend/app/routers/export.py#L38)
- **前端使用**: ✅ [frontend/src/services/api.ts:182](frontend/src/services/api.ts#L182)
- **狀態**: ✅ **正常**

---

#### GET `/api/v1/export/pdf/{file_id}`
- **功能**: 產生單一檔案的 PDF
- **路徑參數**:
  - `file_id`: number - 檔案 ID
- **查詢參數**:
  - `css_template`: string - CSS 模板名稱
- **回應**: PDF file (Blob)
- **後端實作**: ✅ [backend/app/routers/export.py:144](backend/app/routers/export.py#L144)
- **前端使用**: ✅ [frontend/src/services/api.ts:192](frontend/src/services/api.ts#L192)
- **狀態**: ✅ **正常**

---

#### GET `/api/v1/export/rules`
- **功能**: 取得匯出規則清單
- **回應**:
  ```typescript
  [
    {
      id: number,
      user_id: number,
      rule_name: string,
      description: string | null,
      config_json: object,
      css_template: string | null,
      created_at: string,
      updated_at: string
    }
  ]
  ```
- **後端實作**: ✅ [backend/app/routers/export.py:206](backend/app/routers/export.py#L206)
- **前端使用**: ✅ [frontend/src/services/api.ts:204](frontend/src/services/api.ts#L204)
- **狀態**: ✅ **正常**

---

#### POST `/api/v1/export/rules`
- **功能**: 建立匯出規則
- **請求 Body**:
  ```typescript
  {
    rule_name: string,
    description: string | null,
    config_json: object,
    css_template: string | null
  }
  ```
- **回應**: 同 GET `/api/v1/export/rules` 的單個物件
- **後端實作**: ✅ [backend/app/routers/export.py:220](backend/app/routers/export.py#L220)
- **前端使用**: ✅ [frontend/src/services/api.ts:212](frontend/src/services/api.ts#L212)
- **狀態**: ✅ **正常**

---

#### PUT `/api/v1/export/rules/{rule_id}`
- **功能**: 更新匯出規則
- **路徑參數**:
  - `rule_id`: number - 規則 ID
- **請求 Body**: 同 POST `/api/v1/export/rules` (所有欄位可選)
- **回應**: 同 GET `/api/v1/export/rules` 的單個物件
- **後端實作**: ✅ [backend/app/routers/export.py:254](backend/app/routers/export.py#L254)
- **前端使用**: ✅ [frontend/src/services/api.ts:220](frontend/src/services/api.ts#L220)
- **狀態**: ✅ **正常**

---

#### DELETE `/api/v1/export/rules/{rule_id}`
- **功能**: 刪除匯出規則
- **路徑參數**:
  - `rule_id`: number - 規則 ID
- **回應**:
  ```typescript
  {
    message: "Export rule deleted successfully"
  }
  ```
- **後端實作**: ✅ [backend/app/routers/export.py:295](backend/app/routers/export.py#L295)
- **前端使用**: ✅ [frontend/src/services/api.ts:228](frontend/src/services/api.ts#L228)
- **狀態**: ✅ **正常**

---

#### GET `/api/v1/export/css-templates`
- **功能**: 取得 CSS 模板清單
- **回應**:
  ```typescript
  [
    {
      name: string,
      description: string,
      filename: string         // ⚠️ Schema 有定義，但實際回傳沒有
    }
  ]
  ```
- **後端實作**: ✅ [backend/app/routers/export.py:326](backend/app/routers/export.py#L326)
  - 實際回傳: `[{ name, description }]`
  - Schema 定義: `[{ name, description, filename }]`
- **前端使用**: ✅ [frontend/src/services/api.ts:235](frontend/src/services/api.ts#L235)
- **狀態**: ⚠️ **有問題** - 缺少 `filename` 欄位

---

### 5. 翻譯 API (Translation - RESERVED)

#### GET `/api/v1/translate/status`
- **功能**: 取得翻譯功能狀態
- **回應**:
  ```typescript
  {
    status: "RESERVED",
    message: string,
    planned_phase: string,
    features: string[]
  }
  ```
- **後端實作**: ✅ [backend/app/routers/translation.py:28](backend/app/routers/translation.py#L28)
- **前端使用**: ❌ 未使用
- **狀態**: ✅ **正常** (預留功能)

---

#### GET `/api/v1/translate/languages`
- **功能**: 取得支援的語言清單
- **回應**:
  ```typescript
  [
    {
      code: string,
      name: string,
      native_name: string
    }
  ]
  ```
- **後端實作**: ✅ [backend/app/routers/translation.py:43](backend/app/routers/translation.py#L43)
- **前端使用**: ❌ 未使用
- **狀態**: ✅ **正常** (預留功能)

---

#### POST `/api/v1/translate/document`
- **功能**: 翻譯文件 (未實作)
- **請求 Body**:
  ```typescript
  {
    file_id: number,
    source_lang: string,
    target_lang: string,
    engine_type: "argos" | "ernie" | "google" | "deepl",
    preserve_structure: boolean,
    engine_config: object | null
  }
  ```
- **回應**: HTTP 501 Not Implemented
- **後端實作**: ✅ [backend/app/routers/translation.py:56](backend/app/routers/translation.py#L56) (Stub)
- **前端使用**: ✅ [frontend/src/services/api.ts:247](frontend/src/services/api.ts#L247)
- **狀態**: ⚠️ **預留功能** - 前端會收到 501 錯誤

---

#### ❌ GET `/api/v1/translate/configs`
- **功能**: 取得翻譯設定 (前端期待但不存在)
- **狀態**: ❌ **不存在** - 前端呼叫此端點但後端沒有實作
- **前端使用**: [frontend/src/services/api.ts:258](frontend/src/services/api.ts#L258)
- **問題**: 前端會收到 404 錯誤

---

#### ❌ POST `/api/v1/translate/configs`
- **功能**: 建立翻譯設定 (前端期待但不存在)
- **狀態**: ❌ **不存在** - 前端呼叫此端點但後端沒有實作
- **前端使用**: [frontend/src/services/api.ts:269](frontend/src/services/api.ts#L269)
- **問題**: 前端會收到 404 錯誤

---

### 6. 其他端點

#### GET `/health`
- **功能**: 健康檢查
- **回應**:
  ```typescript
  {
    status: "healthy",
    service: "Tool_OCR",
    version: "0.1.0"
  }
  ```
- **後端實作**: ✅ [backend/app/main.py:84](backend/app/main.py#L84)
- **前端使用**: ❌ 未使用
- **狀態**: ✅ **正常**

---

#### GET `/`
- **功能**: API 資訊
- **回應**:
  ```typescript
  {
    message: "Tool_OCR API",
    version: "0.1.0",
    docs_url: "/docs",
    health_check: "/health"
  }
  ```
- **後端實作**: ✅ [backend/app/main.py:95](backend/app/main.py#L95)
- **前端使用**: ❌ 未使用
- **狀態**: ✅ **正常**

---

## 前後端不一致問題

### 問題 1: 登入回應結構不一致

**嚴重程度**: 🟡 中等

**問題描述**:
- 後端回傳包含 `expires_in` 欄位 (Token 過期時間)
- 前端 `LoginResponse` 型別定義缺少此欄位

**影響**:
- 前端無法實作 Token 自動續期功能
- 無法提前提醒使用者 Token 即將過期

**位置**:
- 後端: [backend/app/routers/auth.py:66-70](backend/app/routers/auth.py#L66-L70)
- 前端: [frontend/src/types/api.ts:12-15](frontend/src/types/api.ts#L12-L15)

---

### 問題 2: OCR 任務狀態 API 不存在

**嚴重程度**: 🔴 高

**問題描述**:
- 前端嘗試呼叫 `/api/v1/ocr/status/{taskId}` 取得任務進度
- 後端僅提供 `/api/v1/batch/{batch_id}/status` 與 `/api/v1/ocr/result/{file_id}`
- 沒有對應的任務狀態追蹤端點

**影響**:
- 前端 `getTaskStatus()` 呼叫會收到 404 錯誤
- 無法實作即時進度輪詢功能
- 使用者無法看到處理進度

**位置**:
- 前端呼叫: [frontend/src/services/api.ts:156-159](frontend/src/services/api.ts#L156-L159)
- 後端路由: 不存在

---

### 問題 3: OCR 處理請求/回應模型不符

**嚴重程度**: 🔴 高

**問題描述**:
1. **請求欄位不匹配**:
   - 前端傳送 `confidence_threshold` (信心度閾值)
   - 後端接受 `detect_layout` (版面偵測開關)

2. **回應欄位不匹配**:
   - 前端期待 `task_id` (用於追蹤任務)
   - 後端回傳 `message`, `total_files` (但沒有 `task_id`)

**影響**:
- 前端無法正確傳遞參數給後端
- 前端無法取得 `task_id` 進行後續狀態查詢
- 型別檢查會失敗
- 可能導致驗證錯誤

**位置**:
- 前端請求: [frontend/src/types/api.ts:37-41](frontend/src/types/api.ts#L37-L41)
- 前端回應: [frontend/src/types/api.ts:43-47](frontend/src/types/api.ts#L43-L47)
- 後端請求: [backend/app/schemas/ocr.py:120-133](backend/app/schemas/ocr.py#L120-L133)
- 後端回應: [backend/app/schemas/ocr.py:136-151](backend/app/schemas/ocr.py#L136-L151)

---

### 問題 4: 上傳檔案欄位命名不一致

**嚴重程度**: 🟡 中等

**問題描述**:
- 後端使用 `file_format` 回傳檔案格式
- 前端型別定義使用 `format`

**影響**:
- 前端無法直接使用後端回傳的 `file_format` 欄位
- 需要額外的欄位映射或轉換
- UI 顯示檔案格式時可能為 undefined

**位置**:
- 前端: [frontend/src/types/api.ts:32](frontend/src/types/api.ts#L32)
- 後端: [backend/app/schemas/ocr.py:19](backend/app/schemas/ocr.py#L19)

---

### 問題 5: CSS 模板清單缺少 filename

**嚴重程度**: 🟡 中等

**問題描述**:
- 前端 `CSSTemplate` 型別期待包含 `filename` 欄位
- 後端 Schema `CSSTemplateResponse` 也定義了 `filename`
- 但後端實際回傳只有 `name` 和 `description`

**影響**:
- 前端無法使用 `filename` 作為 `<option>` 的 key/value
- 渲染時 `filename` 為 undefined
- 前端需要額外邏輯處理或使用 `name` 代替

**位置**:
- 前端型別: [frontend/src/types/api.ts:132-136](frontend/src/types/api.ts#L132-L136)
- 後端 Schema: [backend/app/schemas/export.py:91-104](backend/app/schemas/export.py#L91-L104)
- 後端實作: [backend/app/routers/export.py:333-338](backend/app/routers/export.py#L333-L338)
- PDF 服務: [backend/app/services/pdf_generator.py:485-496](backend/app/services/pdf_generator.py#L485-L496)

**根本原因**:
`PDFGenerator.get_available_templates()` 只回傳 `{name: description}` 的 dict，沒有包含 filename

---

### 問題 6: 翻譯設定端點未實作

**嚴重程度**: 🟢 低 (預留功能)

**問題描述**:
- 前端嘗試呼叫 `/api/v1/translate/configs` (GET/POST)
- 後端翻譯路由僅實作 `/status`, `/languages`, `/document`
- 沒有 configs 相關端點

**影響**:
- 前端呼叫會收到 404 錯誤
- 無法管理翻譯設定
- 但因為翻譯功能整體都是 Phase 5 預留功能，影響較小

**位置**:
- 前端 GET: [frontend/src/services/api.ts:258-262](frontend/src/services/api.ts#L258-L262)
- 前端 POST: [frontend/src/services/api.ts:269-275](frontend/src/services/api.ts#L269-L275)
- 後端路由: 不存在

---

## 修正建議

### 建議 1: 統一登入回應模型

**優先順序**: P2 (中優先)

**方案 A - 前端新增 expires_in** (推薦):
```typescript
// frontend/src/types/api.ts
export interface LoginResponse {
  access_token: string
  token_type: string
  expires_in: number  // 新增此欄位
}
```

**方案 B - 後端移除 expires_in**:
- 如果不需要 Token 過期管理，可移除此欄位
- 不推薦，因為這是常見的 JWT 最佳實踐

---

### 建議 2: 統一 OCR 任務追蹤策略

**優先順序**: P1 (高優先)

**方案 A - 統一使用批次狀態** (推薦):
1. 前端刪除 `getTaskStatus()` 方法
2. 統一使用 `getBatchStatus()` 輪詢批次狀態
3. 修改 `ProcessResponse` 移除 `task_id`

**方案 B - 後端新增任務狀態端點**:
1. 新增 `GET /api/v1/ocr/status/{task_id}` 端點
2. `ProcessResponse` 真正回傳 `task_id`
3. 實作任務級別的狀態追蹤

**建議**: 採用方案 A，因為目前架構已經有批次級別的狀態管理

---

### 建議 3: 校正 OCR 處理請求/回應

**優先順序**: P1 (高優先)

**方案 A - 前端配合後端** (推薦):
```typescript
// frontend/src/types/api.ts
export interface ProcessRequest {
  batch_id: number
  lang?: string
  detect_layout?: boolean  // 改為 detect_layout
}

export interface ProcessResponse {
  message: string          // 新增
  batch_id: number
  total_files: number      // 新增
  status: string
  // 移除 task_id
}
```

**方案 B - 後端配合前端**:
- 支援 `confidence_threshold` 參數
- 回應包含 `task_id`
- 需要較大改動，不推薦

---

### 建議 4: 對齊上傳檔案欄位命名

**優先順序**: P2 (中優先)

**方案 A - 前端改用 file_format** (推薦):
```typescript
// frontend/src/types/api.ts
export interface FileInfo {
  id: number
  filename: string
  file_size: number
  file_format: string  // 改名為 file_format
  status: 'pending' | 'processing' | 'completed' | 'failed'
}
```

**方案 B - 後端使用 Pydantic Alias**:
```python
# backend/app/schemas/ocr.py
file_format: str = Field(..., alias='format')
```

---

### 建議 5: 補充 CSS 模板 filename

**優先順序**: P2 (中優先)

**方案 A - 修改 PDF Generator 回傳結構** (推薦):
```python
# backend/app/services/pdf_generator.py
def get_available_templates(self) -> Dict[str, Dict[str, str]]:
    """Get list of available CSS templates with filename"""
    return {
        "default": {
            "description": "通用排版模板，適合大多數文檔",
            "filename": "default.css"
        },
        "academic": {
            "description": "學術論文模板，適合研究報告",
            "filename": "academic.css"
        },
        "business": {
            "description": "商業報告模板，適合企業文檔",
            "filename": "business.css"
        },
    }
```

**方案 B - 前端使用 name 作為 filename**:
- 因為實際上模板名稱就是識別碼
- 不需要額外的 filename

---

### 建議 6: 處理翻譯設定 Stub

**優先順序**: P3 (低優先)

**方案 A - 前端移除相關呼叫** (推薦):
1. 移除或註解 `getTranslationConfigs()` 和 `createTranslationConfig()`
2. UI 顯示「即將推出」訊息

**方案 B - 後端補上 Stub 端點**:
```python
# backend/app/routers/translation.py
@router.get("/configs")
async def get_translation_configs():
    raise HTTPException(status_code=501, detail="Feature reserved for Phase 5")

@router.post("/configs")
async def create_translation_config():
    raise HTTPException(status_code=501, detail="Feature reserved for Phase 5")
```

---

## 實作優先順序總結

### P1 - 立即修正 (影響核心功能)
1. ✅ **建議 2**: 統一 OCR 任務追蹤策略
2. ✅ **建議 3**: 校正 OCR 處理請求/回應模型

### P2 - 近期修正 (影響使用體驗)
3. ✅ **建議 1**: 統一登入回應模型
4. ✅ **建議 4**: 對齊上傳檔案欄位命名
5. ✅ **建議 5**: 補充 CSS 模板 filename

### P3 - 可延後 (預留功能)
6. ⏸️ **建議 6**: 處理翻譯設定 Stub (Phase 5 再處理)

---

## 文件維護

**更新記錄**:
- 2025-01-13: 初始版本，完整盤點所有 API 端點及問題

**維護責任**:
- 每次 API 變更時必須更新此文件
- 新增 API 端點時補充到對應章節
- 修正問題後更新狀態

---

## 附錄: 快速檢查清單

### 新增 API 端點時的檢查項目
- [ ] 後端 Schema 定義是否完整?
- [ ] 前端 TypeScript 型別是否匹配?
- [ ] 欄位命名是否一致 (camelCase vs snake_case)?
- [ ] 回應結構是否符合前端期待?
- [ ] 錯誤處理是否完整?
- [ ] API 文件是否更新?
- [ ] 是否有對應的測試?

### API 修改時的檢查項目
- [ ] 前後端是否同步修改?
- [ ] 是否有破壞性變更 (Breaking Change)?
- [ ] 相關文件是否更新?
- [ ] 現有功能是否受影響?
- [ ] 是否需要版本遷移?
