- Fixed LoginResponse: added expires_in field - Renamed format to file_format across FileInfo interface - Updated ProcessRequest: replaced confidence_threshold with detect_layout - Modified ProcessResponse: added message and total_files, removed task_id - Removed non-existent getTaskStatus API call - Fixed getOCRResult parameter from taskId to fileId - Commented out translation config APIs pending backend implementation Documentation: - Added API_REFERENCE.md: Complete API endpoint inventory - Added API_FIX_SUMMARY.md: Detailed before/after comparison of all fixes - Added FRONTEND_API.md: Frontend integration documentation - Added FRONTEND_QUICK_START.md: Quick start guide - Added FRONTEND_UPGRADE_SUMMARY.md: Upgrade summary 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
20 KiB
20 KiB
Tool_OCR API Reference & Issues Report
文件資訊
- 建立日期: 2025-01-13
- 版本: v0.1.0
- 目的: 完整記錄所有 API 端點及前後端不一致問題
目錄
API 端點清單
1. 認證 API (Authentication)
POST /api/v1/auth/login
- 功能: 使用者登入
- 請求 Body:
{ username: string, password: string } - 回應:
{ access_token: string, token_type: string, // "bearer" expires_in: number // Token 過期時間(秒) } - 後端實作: ✅ backend/app/routers/auth.py:24
- 前端使用: ✅ frontend/src/services/api.ts:106
- 狀態: ⚠️ 有問題 - 前端型別缺少
expires_in欄位
2. 檔案上傳 API (File Upload)
POST /api/v1/upload
- 功能: 上傳檔案進行 OCR 處理
- 請求 Body:
multipart/form-datafiles: File[] - 檔案列表 (PNG, JPG, JPEG, PDF)batch_name: string (optional) - 批次名稱
- 回應:
{ 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
- 前端使用: ✅ frontend/src/services/api.ts:128
- 狀態: ⚠️ 有問題 - 前端型別用
format,後端用file_format
3. OCR 處理 API (OCR Processing)
POST /api/v1/ocr/process
- 功能: 觸發 OCR 批次處理
- 請求 Body:
{ batch_id: number, lang: string, // "ch", "en", "japan", "korean" detect_layout: boolean // ⚠️ 後端用 detect_layout,前端用 confidence_threshold } - 回應:
{ message: string, // ⚠️ 後端有此欄位 batch_id: number, total_files: number, // ⚠️ 後端有此欄位 status: string // "processing" // task_id: string // ❌ 前端期待此欄位,但後端沒有 } - 後端實作: ✅ backend/app/routers/ocr.py:95
- 前端使用: ✅ frontend/src/services/api.ts:148
- 狀態: ⚠️ 有問題 - 請求/回應模型不匹配
GET /api/v1/batch/{batch_id}/status
- 功能: 取得批次處理狀態
- 路徑參數:
batch_id: number - 批次 ID
- 回應:
{ 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
- 前端使用: ✅ frontend/src/services/api.ts:172
- 狀態: ✅ 正常
GET /api/v1/ocr/result/{file_id}
- 功能: 取得 OCR 結果
- 路徑參數:
file_id: number - 檔案 ID
- 回應:
{ 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
- 前端使用: ✅ frontend/src/services/api.ts:164
- ⚠️ 注意: 前端使用
taskId作為參數名稱,實際應該是file_id
- ⚠️ 注意: 前端使用
- 狀態: ⚠️ 有問題 - 前端參數名稱誤導
❌ GET /api/v1/ocr/status/{task_id}
- 功能: 取得任務狀態 (前端期待但不存在)
- 狀態: ❌ 不存在 - 前端呼叫此端點但後端沒有實作
- 前端使用: frontend/src/services/api.ts:156
- 問題: 前端會收到 404 錯誤
4. 匯出 API (Export)
POST /api/v1/export
- 功能: 匯出 OCR 結果
- 請求 Body:
{ 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
- 前端使用: ✅ frontend/src/services/api.ts:182
- 狀態: ✅ 正常
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
- 前端使用: ✅ frontend/src/services/api.ts:192
- 狀態: ✅ 正常
GET /api/v1/export/rules
- 功能: 取得匯出規則清單
- 回應:
[ { 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
- 前端使用: ✅ frontend/src/services/api.ts:204
- 狀態: ✅ 正常
POST /api/v1/export/rules
- 功能: 建立匯出規則
- 請求 Body:
{ rule_name: string, description: string | null, config_json: object, css_template: string | null } - 回應: 同 GET
/api/v1/export/rules的單個物件 - 後端實作: ✅ backend/app/routers/export.py:220
- 前端使用: ✅ frontend/src/services/api.ts:212
- 狀態: ✅ 正常
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
- 前端使用: ✅ frontend/src/services/api.ts:220
- 狀態: ✅ 正常
DELETE /api/v1/export/rules/{rule_id}
- 功能: 刪除匯出規則
- 路徑參數:
rule_id: number - 規則 ID
- 回應:
{ message: "Export rule deleted successfully" } - 後端實作: ✅ backend/app/routers/export.py:295
- 前端使用: ✅ frontend/src/services/api.ts:228
- 狀態: ✅ 正常
GET /api/v1/export/css-templates
- 功能: 取得 CSS 模板清單
- 回應:
[ { name: string, description: string, filename: string // ⚠️ Schema 有定義,但實際回傳沒有 } ] - 後端實作: ✅ backend/app/routers/export.py:326
- 實際回傳:
[{ name, description }] - Schema 定義:
[{ name, description, filename }]
- 實際回傳:
- 前端使用: ✅ frontend/src/services/api.ts:235
- 狀態: ⚠️ 有問題 - 缺少
filename欄位
5. 翻譯 API (Translation - RESERVED)
GET /api/v1/translate/status
- 功能: 取得翻譯功能狀態
- 回應:
{ status: "RESERVED", message: string, planned_phase: string, features: string[] } - 後端實作: ✅ backend/app/routers/translation.py:28
- 前端使用: ❌ 未使用
- 狀態: ✅ 正常 (預留功能)
GET /api/v1/translate/languages
- 功能: 取得支援的語言清單
- 回應:
[ { code: string, name: string, native_name: string } ] - 後端實作: ✅ backend/app/routers/translation.py:43
- 前端使用: ❌ 未使用
- 狀態: ✅ 正常 (預留功能)
POST /api/v1/translate/document
- 功能: 翻譯文件 (未實作)
- 請求 Body:
{ 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 (Stub)
- 前端使用: ✅ frontend/src/services/api.ts:247
- 狀態: ⚠️ 預留功能 - 前端會收到 501 錯誤
❌ GET /api/v1/translate/configs
- 功能: 取得翻譯設定 (前端期待但不存在)
- 狀態: ❌ 不存在 - 前端呼叫此端點但後端沒有實作
- 前端使用: frontend/src/services/api.ts:258
- 問題: 前端會收到 404 錯誤
❌ POST /api/v1/translate/configs
- 功能: 建立翻譯設定 (前端期待但不存在)
- 狀態: ❌ 不存在 - 前端呼叫此端點但後端沒有實作
- 前端使用: frontend/src/services/api.ts:269
- 問題: 前端會收到 404 錯誤
6. 其他端點
GET /health
- 功能: 健康檢查
- 回應:
{ status: "healthy", service: "Tool_OCR", version: "0.1.0" } - 後端實作: ✅ backend/app/main.py:84
- 前端使用: ❌ 未使用
- 狀態: ✅ 正常
GET /
- 功能: API 資訊
- 回應:
{ message: "Tool_OCR API", version: "0.1.0", docs_url: "/docs", health_check: "/health" } - 後端實作: ✅ backend/app/main.py:95
- 前端使用: ❌ 未使用
- 狀態: ✅ 正常
前後端不一致問題
問題 1: 登入回應結構不一致
嚴重程度: 🟡 中等
問題描述:
- 後端回傳包含
expires_in欄位 (Token 過期時間) - 前端
LoginResponse型別定義缺少此欄位
影響:
- 前端無法實作 Token 自動續期功能
- 無法提前提醒使用者 Token 即將過期
位置:
問題 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
- 後端路由: 不存在
問題 3: OCR 處理請求/回應模型不符
嚴重程度: 🔴 高
問題描述:
-
請求欄位不匹配:
- 前端傳送
confidence_threshold(信心度閾值) - 後端接受
detect_layout(版面偵測開關)
- 前端傳送
-
回應欄位不匹配:
- 前端期待
task_id(用於追蹤任務) - 後端回傳
message,total_files(但沒有task_id)
- 前端期待
影響:
- 前端無法正確傳遞參數給後端
- 前端無法取得
task_id進行後續狀態查詢 - 型別檢查會失敗
- 可能導致驗證錯誤
位置:
- 前端請求: frontend/src/types/api.ts:37-41
- 前端回應: frontend/src/types/api.ts:43-47
- 後端請求: backend/app/schemas/ocr.py:120-133
- 後端回應: backend/app/schemas/ocr.py:136-151
問題 4: 上傳檔案欄位命名不一致
嚴重程度: 🟡 中等
問題描述:
- 後端使用
file_format回傳檔案格式 - 前端型別定義使用
format
影響:
- 前端無法直接使用後端回傳的
file_format欄位 - 需要額外的欄位映射或轉換
- UI 顯示檔案格式時可能為 undefined
位置:
問題 5: CSS 模板清單缺少 filename
嚴重程度: 🟡 中等
問題描述:
- 前端
CSSTemplate型別期待包含filename欄位 - 後端 Schema
CSSTemplateResponse也定義了filename - 但後端實際回傳只有
name和description
影響:
- 前端無法使用
filename作為<option>的 key/value - 渲染時
filename為 undefined - 前端需要額外邏輯處理或使用
name代替
位置:
- 前端型別: frontend/src/types/api.ts:132-136
- 後端 Schema: backend/app/schemas/export.py:91-104
- 後端實作: backend/app/routers/export.py:333-338
- PDF 服務: backend/app/services/pdf_generator.py:485-496
根本原因:
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
- 前端 POST: frontend/src/services/api.ts:269-275
- 後端路由: 不存在
修正建議
建議 1: 統一登入回應模型
優先順序: P2 (中優先)
方案 A - 前端新增 expires_in (推薦):
// 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 - 統一使用批次狀態 (推薦):
- 前端刪除
getTaskStatus()方法 - 統一使用
getBatchStatus()輪詢批次狀態 - 修改
ProcessResponse移除task_id
方案 B - 後端新增任務狀態端點:
- 新增
GET /api/v1/ocr/status/{task_id}端點 ProcessResponse真正回傳task_id- 實作任務級別的狀態追蹤
建議: 採用方案 A,因為目前架構已經有批次級別的狀態管理
建議 3: 校正 OCR 處理請求/回應
優先順序: P1 (高優先)
方案 A - 前端配合後端 (推薦):
// 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 (推薦):
// 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:
# backend/app/schemas/ocr.py
file_format: str = Field(..., alias='format')
建議 5: 補充 CSS 模板 filename
優先順序: P2 (中優先)
方案 A - 修改 PDF Generator 回傳結構 (推薦):
# 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 - 前端移除相關呼叫 (推薦):
- 移除或註解
getTranslationConfigs()和createTranslationConfig() - UI 顯示「即將推出」訊息
方案 B - 後端補上 Stub 端點:
# 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 - 立即修正 (影響核心功能)
- ✅ 建議 2: 統一 OCR 任務追蹤策略
- ✅ 建議 3: 校正 OCR 處理請求/回應模型
P2 - 近期修正 (影響使用體驗)
- ✅ 建議 1: 統一登入回應模型
- ✅ 建議 4: 對齊上傳檔案欄位命名
- ✅ 建議 5: 補充 CSS 模板 filename
P3 - 可延後 (預留功能)
- ⏸️ 建議 6: 處理翻譯設定 Stub (Phase 5 再處理)
文件維護
更新記錄:
- 2025-01-13: 初始版本,完整盤點所有 API 端點及問題
維護責任:
- 每次 API 變更時必須更新此文件
- 新增 API 端點時補充到對應章節
- 修正問題後更新狀態
附錄: 快速檢查清單
新增 API 端點時的檢查項目
- 後端 Schema 定義是否完整?
- 前端 TypeScript 型別是否匹配?
- 欄位命名是否一致 (camelCase vs snake_case)?
- 回應結構是否符合前端期待?
- 錯誤處理是否完整?
- API 文件是否更新?
- 是否有對應的測試?
API 修改時的檢查項目
- 前後端是否同步修改?
- 是否有破壞性變更 (Breaking Change)?
- 相關文件是否更新?
- 現有功能是否受影響?
- 是否需要版本遷移?