Files
OCR/openspec/changes/archive/2025-11-18-migrate-to-external-api-authentication/FRONTEND_IMPLEMENTATION.md
egg cd3cbea49d chore: project cleanup and prepare for dual-track processing refactor
- Removed all test files and directories
- Deleted outdated documentation (will be rewritten)
- Cleaned up temporary files, logs, and uploads
- Archived 5 completed OpenSpec proposals
- Created new dual-track-document-processing proposal with complete OpenSpec structure
  - Dual-track architecture: OCR track (PaddleOCR) + Direct track (PyMuPDF)
  - UnifiedDocument model for consistent output
  - Support for structure-preserving translation
- Updated .gitignore to prevent future test/temp files

This is a major cleanup preparing for the complete refactoring of the document processing pipeline.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 20:02:31 +08:00

11 KiB
Raw Blame History

前端實作完成 - External Authentication & Task History

實作日期

2025-11-14

狀態

前端核心功能完成

  • V2 認證服務整合
  • 登入頁面更新
  • 任務歷史頁面
  • 導航整合

📋 已完成項目

1. V2 API 服務層

檔案:frontend/src/services/apiV2.ts

核心功能:

class ApiClientV2 {
  // 認證管理
  async login(data: LoginRequest): Promise<LoginResponseV2>
  async logout(sessionId?: number): Promise<void>
  async getMe(): Promise<UserInfo>
  async listSessions(): Promise<SessionInfo[]>

  // 任務管理
  async createTask(data: TaskCreate): Promise<Task>
  async listTasks(params): Promise<TaskListResponse>
  async getTaskStats(): Promise<TaskStats>
  async getTask(taskId: string): Promise<TaskDetail>
  async updateTask(taskId: string, data: TaskUpdate): Promise<Task>
  async deleteTask(taskId: string): Promise<void>

  // 輔助方法
  async downloadTaskFile(url: string, filename: string): Promise<void>
}

特色:

  • 自動 token 管理localStorage
  • 401 自動重定向到登入
  • Session 過期檢測
  • 用戶資訊快取

檔案:frontend/src/types/apiV2.ts

完整類型定義:

  • UserInfo, LoginResponseV2, SessionInfo
  • Task, TaskCreate, TaskUpdate, TaskDetail
  • TaskStats, TaskListResponse, TaskFilters
  • TaskStatus 枚舉

2. 登入頁面更新

檔案:frontend/src/pages/LoginPage.tsx

變更:

// 舊版V1
await apiClient.login({ username, password })
setUser({ id: 1, username })

// 新版V2
const response = await apiClientV2.login({ username, password })
setUser({
  id: response.user.id,
  username: response.user.email,
  email: response.user.email,
  displayName: response.user.display_name
})

功能:

  • 整合外部 Azure AD 認證
  • 顯示用戶顯示名稱
  • 錯誤訊息處理
  • 保持原有 UI 設計

3. 任務歷史頁面

檔案:frontend/src/pages/TaskHistoryPage.tsx

核心功能:

  1. 統計儀表板

    • 總計、待處理、處理中、已完成、失敗
    • 卡片式呈現
    • 即時更新
  2. 篩選功能

    • 按狀態篩選(全部/pending/processing/completed/failed
    • 未來可擴展:日期範圍、檔名搜尋
  3. 任務列表

    • 分頁顯示(每頁 20 筆)
    • 欄位:檔案名稱、狀態、建立時間、完成時間、處理時間
    • 操作:查看詳情、刪除
  4. 狀態徽章

    pending     灰色 + 時鐘圖標
    processing  藍色 + 旋轉圖標
    completed   綠色 + 勾選圖標
    failed      紅色 + X 圖標
    
  5. 分頁控制

    • 上一頁/下一頁
    • 顯示當前範圍1-20 / 共 45 個)
    • 自動禁用按鈕

UI 組件使用:

  • Card - 統計卡片和主容器
  • Table - 任務列表表格
  • Badge - 狀態標籤
  • Button - 操作按鈕
  • Select - 狀態篩選下拉選單

4. 路由整合

檔案:frontend/src/App.tsx

新增路由:

<Route path="tasks" element={<TaskHistoryPage />} />

路由結構:

/login                  - 登入頁面(公開)
/                       - 根路徑(重定向到 /upload
  /upload               - 上傳檔案
  /processing           - 處理進度
  /results              - 查看結果
  /tasks                - 任務歷史 (NEW!)
  /export               - 導出文件
  /settings             - 系統設定

5. 導航更新

檔案:frontend/src/components/Layout.tsx

新增導航項:

{
  to: '/tasks',
  label: '任務歷史',
  icon: History,
  description: '查看任務記錄'
}

Logout 邏輯更新:

const handleLogout = async () => {
  try {
    // 優先使用 V2 API
    if (apiClientV2.isAuthenticated()) {
      await apiClientV2.logout()
    } else {
      apiClient.logout()
    }
  } finally {
    logout()  // 清除本地狀態
  }
}

用戶資訊顯示:

  • 顯示名稱:user.displayName || user.username
  • Emailuser.email || user.username
  • 頭像:首字母大寫

6. 類型擴展

檔案:frontend/src/types/api.ts

擴展 User 介面:

export interface User {
  id: number
  username: string
  email?: string          // NEW
  displayName?: string | null  // NEW
}

🎨 UI/UX 特色

任務歷史頁面設計亮點:

  1. 響應式卡片佈局

    • Grid 5 欄(桌面)/ 1 欄(手機)
    • 統計數據卡片 hover 效果
  2. 清晰的狀態視覺化

    • 彩色徽章
    • 動畫圖標processing 狀態旋轉)
    • 語意化顏色
  3. 操作反饋

    • 載入動畫Loader2
    • 空狀態提示
    • 錯誤警告
  4. 用戶友好

    • 確認刪除對話框
    • 刷新按鈕
    • 分頁資訊明確

🔄 向後兼容

V1 與 V2 並存策略

認證服務:

  • V1: apiClient (原有本地認證)
  • V2: apiClientV2 (新外部認證)

登入流程:

  • 新用戶使用 V2 API 登入
  • 舊 session 仍可使用 V1 API

Logout 處理:

if (apiClientV2.isAuthenticated()) {
  await apiClientV2.logout()  // 呼叫後端 /api/v2/auth/logout
} else {
  apiClient.logout()  // 僅清除本地 token
}

📱 使用流程

1. 登入

用戶訪問 /login
→ 輸入 email + password
→ apiClientV2.login() 呼叫外部 API
→ 接收 access_token + user info
→ 存入 localStorage
→ 重定向到 /upload

2. 查看任務歷史

用戶點擊「任務歷史」導航
→ 訪問 /tasks
→ apiClientV2.listTasks() 獲取任務列表
→ apiClientV2.getTaskStats() 獲取統計
→ 顯示任務表格 + 統計卡片

3. 篩選任務

用戶選擇狀態篩選器completed
→ setStatusFilter('completed')
→ useEffect 觸發重新 fetchTasks()
→ 呼叫 apiClientV2.listTasks({ status: 'completed' })
→ 更新任務列表

4. 刪除任務

用戶點擊刪除按鈕
→ 確認對話框
→ apiClientV2.deleteTask(taskId)
→ 重新載入任務列表和統計

5. 分頁導航

用戶點擊「下一頁」
→ setPage(page + 1)
→ useEffect 觸發 fetchTasks()
→ 呼叫 listTasks({ page: 2 })
→ 更新任務列表

🧪 測試指南

手動測試步驟:

1. 測試登入

# 啟動後端
cd backend
source venv/bin/activate
python -m app.main

# 啟動前端
cd frontend
npm run dev

# 訪問 http://localhost:5173/login
# 輸入 Azure AD 憑證
# 確認登入成功並顯示用戶名稱

2. 測試任務歷史

# 登入後點擊側邊欄「任務歷史」
# 確認統計卡片顯示正確數字
# 確認任務列表載入
# 測試狀態篩選
# 測試分頁功能

3. 測試任務刪除

# 在任務列表點擊刪除按鈕
# 確認刪除確認對話框
# 確認刪除後列表更新
# 確認統計數字更新

4. 測試 Logout

# 點擊側邊欄登出按鈕
# 確認清除 localStorage
# 確認重定向到登入頁面
# 再次登入確認一切正常

🔧 已知限制

目前未實作項目:

  1. 任務詳情頁面 (/tasks/:taskId)

    • 顯示完整任務資訊
    • 下載結果檔案JSON/Markdown/PDF
    • 查看任務文件列表
  2. 進階篩選

    • 日期範圍選擇器
    • 檔案名稱搜尋
    • 多條件組合篩選
  3. 批次操作

    • 批次刪除任務
    • 批次下載結果
  4. 即時更新

    • WebSocket 連接
    • 任務狀態即時推送
    • 自動刷新處理中的任務
  5. 錯誤詳情

    • 展開查看 error_message
    • 失敗任務重試功能

💡 未來擴展建議

短期優化1-2 週):

  1. 任務詳情頁面

    // frontend/src/pages/TaskDetailPage.tsx
    const task = await apiClientV2.getTask(taskId)
    // 顯示完整資訊 + 下載按鈕
    
  2. 檔案下載

    const handleDownload = async (path: string, filename: string) => {
      await apiClientV2.downloadTaskFile(path, filename)
    }
    
  3. 日期範圍篩選

    <DateRangePicker
      from={dateFrom}
      to={dateTo}
      onChange={(range) => {
        setDateFrom(range.from)
        setDateTo(range.to)
      }}
    />
    

中期功能1 個月):

  1. 即時狀態更新

    • 使用 WebSocket 或 Server-Sent Events
    • 自動更新 processing 任務狀態
  2. 批次操作

    • 複選框選擇多個任務
    • 批次刪除/下載
  3. 搜尋功能

    • 檔案名稱模糊搜尋
    • 全文搜尋(需後端支援)

長期規劃3 個月):

  1. 任務視覺化

    • 時間軸視圖
    • 甘特圖(處理進度)
    • 統計圖表ECharts
  2. 通知系統

    • 任務完成通知
    • 錯誤警報
    • 瀏覽器通知 API
  3. 導出功能

    • 任務報表導出Excel/PDF
    • 統計資料導出

📝 程式碼範例

在其他頁面使用 V2 API

// Example: 在 UploadPage 創建任務
import { apiClientV2 } from '@/services/apiV2'

const handleUpload = async (file: File) => {
  try {
    // 創建任務
    const task = await apiClientV2.createTask({
      filename: file.name,
      file_type: file.type
    })

    console.log('Task created:', task.task_id)

    // TODO: 上傳檔案到雲端存儲
    // TODO: 更新任務狀態為 processing
    // TODO: 呼叫 OCR 服務
  } catch (error) {
    console.error('Upload failed:', error)
  }
}

監聽任務狀態變化

// Example: 輪詢任務狀態
const pollTaskStatus = async (taskId: string) => {
  const interval = setInterval(async () => {
    try {
      const task = await apiClientV2.getTask(taskId)

      if (task.status === 'completed') {
        clearInterval(interval)
        alert('任務完成!')
      } else if (task.status === 'failed') {
        clearInterval(interval)
        alert(`任務失敗:${task.error_message}`)
      }
    } catch (error) {
      clearInterval(interval)
      console.error('Poll error:', error)
    }
  }, 5000) // 每 5 秒檢查一次
}

完成清單

  • V2 API 服務層(apiV2.ts
  • V2 類型定義(apiV2.ts
  • 登入頁面整合 V2
  • 任務歷史頁面
  • 統計儀表板
  • 狀態篩選
  • 分頁功能
  • 任務刪除
  • 路由整合
  • 導航更新
  • Logout 更新
  • 用戶資訊顯示
  • 任務詳情頁面(待實作)
  • 檔案下載(待實作)
  • 即時狀態更新(待實作)
  • 批次操作(待實作)

實作完成日期2025-11-14 實作人員Claude Code 前端框架React + TypeScript + Vite UI 庫Tailwind CSS + shadcn/ui 狀態管理Zustand HTTP 客戶端Axios