diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 49857ca..0399af2 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -9,7 +9,55 @@ "Bash(source venv/bin/activate)", "Bash(find:*)", "Bash(ls:*)", - "Bash(openspec list:*)" + "Bash(openspec list:*)", + "Bash(curl:*)", + "Bash(source:*)", + "Bash(pytest:*)", + "Bash(git -C /home/egg/project/Tool_OCR add backend/app/routers/tasks.py backend/app/schemas/task.py backend/app/services/ocr_service.py openspec/changes/dual-track-document-processing/design.md openspec/changes/dual-track-document-processing/tasks.md backend/tests/e2e/)", + "Bash(git -C /home/egg/project/Tool_OCR commit -m \"$(cat <<''EOF''\nfix: resolve E2E test failures and add Office direct extraction design\n\n- Fix MySQL connection timeout by creating fresh DB session after OCR\n- Fix /analyze endpoint attribute errors (detect vs analyze, metadata)\n- Add processing_track field extraction to TaskDetailResponse\n- Update E2E tests to use POST for /analyze endpoint\n- Increase Office document timeout to 300s\n- Add Section 2.4 tasks for Office document direct extraction\n- Document Office → PDF → Direct track strategy in design.md\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude \nEOF\n)\")", + "Bash(pkill:*)", + "Bash(tee:*)", + "Bash(cat:*)", + "Bash(pdfinfo:*)", + "Bash(journalctl:*)", + "Bash(openspec validate:*)", + "Bash(git add:*)", + "Bash(git rm:*)", + "Bash(openspec create:*)", + "Bash(openspec --help:*)", + "Bash(openspec change --help:*)", + "Bash(xargs cat:*)", + "Bash(analyze_table_cells.py )", + "Bash(cache_cleared_test.pdf )", + "Bash(calculate_optimal_buffer.py )", + "Bash(check_font_size.py )", + "Bash(check_table_surroundings.py )", + "Bash(check_table_text_overlap.py )", + "Bash(debug_pdf_rendering.py )", + "Bash(final_fix_test.pdf )", + "Bash(inspect_generated_pdf.py:*)", + "Bash(inspect_table_columns.py )", + "Bash(log_test.pdf )", + "Bash(no_buffer_test.pdf )", + "Bash(rendering_fix_test.pdf )", + "Bash(rowheights_final_test.pdf )", + "Bash(rowheights_test.pdf )", + "Bash(scaling_test.pdf )", + "Bash(test_final_fix.py )", + "Bash(test_rendering_fix.py )", + "Bash(test_rowheights.pdf )", + "Bash(test_rowheights.py )", + "Bash(test_table_overlap_fix.py )", + "Bash(verify_chart_recognition.py )", + "Bash(verify_overlap_fix.py )", + "Bash(test_rowheights_final.sh )", + "Bash(FINAL_SCALING_FIX.pdf )", + "Bash(table_overlap_fix_output.pdf )", + "Bash(overlap_verification_output.pdf )", + "Bash(PDF_LAYOUT_RESTORATION_COMPLETE.md )", + "Bash(RENDERING_OVERLAP_FIX.md )", + "Bash(FINAL_FIX_SUMMARY.md )", + "Bash(TABLE_SCALING_FIX_SUMMARY.md )" ], "deny": [], "ask": [] diff --git a/backend/RUN_TESTS.md b/backend/RUN_TESTS.md deleted file mode 100644 index e879a57..0000000 --- a/backend/RUN_TESTS.md +++ /dev/null @@ -1,237 +0,0 @@ -# 運行測試指南 - -## ⚠️ 測試狀態 - -我已經創建了完整的測試套件,但**尚未在您的環境中運行測試**,因為需要安裝額外的依賴。 - ---- - -## 📋 已創建的測試文件 - -### 測試文件 -- ✅ `tests/conftest_v2.py` - V2 測試配置和 fixtures -- ✅ `tests/test_auth.py` - 認證端點測試(6個測試) -- ✅ `tests/test_tasks.py` - 任務管理測試(7個測試) -- ✅ `tests/test_admin.py` - 管理員功能測試(4個測試) -- ✅ `tests/test_integration.py` - 集成測試(3個測試) - -### 配置文件 -- ✅ `pytest.ini` - Pytest 配置 -- ✅ `TESTING.md` - 測試文檔 - -**總計**: 20 個測試用例 - ---- - -## 🚀 如何運行測試 - -### 方式 1: 使用虛擬環境(推薦) - -```bash -cd backend - -# 創建虛擬環境 -python3 -m venv venv -source venv/bin/activate # Linux/Mac -# 或 venv\Scripts\activate # Windows - -# 安裝所有依賴 -pip install -r requirements.txt # 如果有 -pip install pytest pytest-cov httpx - -# 運行測試 -pytest tests/test_auth.py -v -pytest tests/test_tasks.py -v -pytest tests/test_admin.py -v -pytest tests/test_integration.py -v - -# 運行所有測試並生成覆蓋率報告 -pytest tests/test_*.py --cov=app --cov-report=html -``` - -### 方式 2: 使用 Conda 環境 - -```bash -# 激活 conda 環境 -conda activate tool_ocr - -# 安裝測試依賴 -pip install pytest pytest-cov httpx - -# 運行測試 -pytest tests/test_auth.py -v -``` - -### 方式 3: 使用系統 Python(需要 --break-system-packages) - -```bash -# 安裝依賴(不推薦) -python3 -m pip install pytest httpx --break-system-packages - -# 運行測試 -python3 -m pytest tests/test_auth.py -v -``` - ---- - -## 📦 必需的依賴 - -測試需要以下依賴(大部分應該已安裝): - -``` -# 核心依賴 -fastapi -sqlalchemy -pydantic -pydantic-settings -python-jose[cryptography] -passlib[bcrypt] -pymysql -python-multipart - -# 測試依賴 -pytest -pytest-cov -httpx -``` - ---- - -## 🧪 測試範例輸出(預期) - -```bash -$ pytest tests/test_auth.py -v - -tests/test_auth.py::TestAuth::test_login_success PASSED [ 16%] -tests/test_auth.py::TestAuth::test_login_invalid_credentials PASSED [ 33%] -tests/test_auth.py::TestAuth::test_get_me PASSED [ 50%] -tests/test_auth.py::TestAuth::test_get_me_unauthorized PASSED [ 66%] -tests/test_auth.py::TestAuth::test_logout PASSED [ 83%] - -======================== 5 passed in 0.45s ========================== -``` - ---- - -## ⚙️ 測試配置 - -### pytest.ini -```ini -[pytest] -testpaths = tests -python_files = test_*.py -python_classes = Test* -python_functions = test_* -addopts = - -v - --strict-markers - --tb=short -markers = - unit: Unit tests - integration: Integration tests - slow: Slow running tests -``` - -### 測試數據庫 -- 測試使用 **SQLite 記憶體資料庫** `:memory:` -- 每個測試獨立,不影響生產資料庫 -- 測試後自動清理 - ---- - -## 🔧 常見問題 - -### 問題 1: ModuleNotFoundError: No module named 'pytest' -**解決**: -```bash -pip install pytest -``` - -### 問題 2: ModuleNotFoundError: No module named 'app' -**解決**: 確保在 backend 目錄中運行測試 -```bash -cd /home/egg/project/Tool_OCR/backend -pytest -``` - -### 問題 3: externally-managed-environment -**解決**: 使用虛擬環境或 --break-system-packages(不推薦) - -### 問題 4: conftest.py 衝突 -**解決**: -- 舊的 V1 測試使用 `conftest_old.py` -- 新的 V2 測試需要重命名為 `conftest_v2.py` -- 或者合併兩個配置文件 - ---- - -## 📊 測試覆蓋範圍 - -### 認證測試 (test_auth.py) -- ✅ 登入成功 -- ✅ 登入失敗(錯誤憑證) -- ✅ 獲取當前用戶資訊 -- ✅ 未授權訪問 -- ✅ 登出功能 -- ✅ Mock 外部認證服務 - -### 任務測試 (test_tasks.py) -- ✅ 創建任務 -- ✅ 列出任務 -- ✅ 獲取單個任務 -- ✅ 獲取統計數據 -- ✅ 刪除任務 -- ✅ 用戶隔離驗證 - -### 管理員測試 (test_admin.py) -- ✅ 系統統計 -- ✅ 用戶列表 -- ✅ 審計日誌 -- ✅ 非管理員訪問控制 - -### 集成測試 (test_integration.py) -- ✅ 完整認證和任務流程 -- ✅ 管理員工作流程 -- ✅ 任務生命週期 - ---- - -## ✅ 下一步行動 - -1. **安裝依賴**: - ```bash - cd backend - source venv/bin/activate # 或創建新的 venv - pip install pytest pytest-cov httpx - ``` - -2. **運行測試**: - ```bash - pytest tests/test_auth.py -v - ``` - -3. **查看結果**: - - 綠色 ✓ = 通過 - - 紅色 ✗ = 失敗 - - 黃色 ! = 警告 - -4. **生成覆蓋率報告**: - ```bash - pytest --cov=app --cov-report=html - open htmlcov/index.html # 查看報告 - ``` - ---- - -## 📝 注意事項 - -1. **測試未運行**: 由於依賴缺失,我無法在當前環境中執行測試 -2. **代碼完整**: 測試代碼是完整的,只需安裝依賴即可運行 -3. **Mock 服務**: 外部認證 API 已 Mock,不需要實際連接 -4. **資料庫隔離**: 使用記憶體資料庫,安全且快速 - ---- - -**創建日期**: 2025-11-16 -**狀態**: 已創建但未運行 -**待辦**: 安裝依賴並執行測試驗證 diff --git a/backend/create_test_user.py b/backend/create_test_user.py deleted file mode 100644 index c5b21c9..0000000 --- a/backend/create_test_user.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python3 -""" -Tool_OCR - Create Test User -Creates a test user for API testing -""" - -import sys -from pathlib import Path - -# Add backend to path -sys.path.insert(0, str(Path(__file__).parent)) - -from app.core.database import SessionLocal -from app.core.security import get_password_hash -from app.models.user import User - - -def create_test_user( - username: str = "admin", - email: str = "admin@example.com", - password: str = "admin123", - full_name: str = "Admin User", - is_admin: bool = True -): - """ - Create test user - - Args: - username: Username - email: Email address - password: Plain password (will be hashed) - full_name: Full name - is_admin: Is admin user - """ - db = SessionLocal() - - try: - # Check if user already exists - existing_user = db.query(User).filter(User.username == username).first() - if existing_user: - print(f"❌ User '{username}' already exists (ID: {existing_user.id})") - return False - - # Create user - user = User( - username=username, - email=email, - password_hash=get_password_hash(password), - full_name=full_name, - is_active=True, - is_admin=is_admin - ) - - db.add(user) - db.commit() - db.refresh(user) - - print(f"✅ Created user successfully:") - print(f" ID: {user.id}") - print(f" Username: {user.username}") - print(f" Email: {user.email}") - print(f" Full Name: {user.full_name}") - print(f" Is Admin: {user.is_admin}") - print(f" Is Active: {user.is_active}") - print(f"\n📝 Login credentials:") - print(f" Username: {username}") - print(f" Password: {password}") - - return True - - except Exception as e: - print(f"❌ Error creating user: {e}") - db.rollback() - return False - - finally: - db.close() - - -if __name__ == "__main__": - print("=" * 60) - print("Tool_OCR - Create Test User") - print("=" * 60) - - # Create admin user - success = create_test_user() - - # Also create a regular test user - if success: - print("\n" + "-" * 60) - create_test_user( - username="testuser", - email="test@example.com", - password="test123", - full_name="Test User", - is_admin=False - ) - - print("\n" + "=" * 60) - print("Done!") - print("=" * 60) diff --git a/backend/fix_alembic_version.py b/backend/fix_alembic_version.py deleted file mode 100644 index 157e29f..0000000 --- a/backend/fix_alembic_version.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 -"""Fix alembic version in database""" - -from sqlalchemy import create_engine, text -from app.core.config import settings - -# Create database connection -engine = create_engine(settings.database_url) - -with engine.connect() as conn: - # Delete the problematic version - conn.execute(text("DELETE FROM alembic_version WHERE version_num = '3ede847231ff'")) - conn.commit() - print("✓ Removed problematic alembic version") - - # Check current version - result = conn.execute(text("SELECT version_num FROM alembic_version")) - versions = result.fetchall() - - if versions: - print(f"Current version(s): {[v[0] for v in versions]}") - else: - print("No alembic version found in database") - # Set to the base version before our new migrations - conn.execute(text("INSERT INTO alembic_version (version_num) VALUES ('271dc036ea80')")) - conn.commit() - print("✓ Set alembic version to 271dc036ea80") - -print("\nDone!") diff --git a/backend/mark_migration_done.py b/backend/mark_migration_done.py deleted file mode 100644 index d1c5204..0000000 --- a/backend/mark_migration_done.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -Mark the current migration as complete in alembic_version table -This is needed because tables were partially created before -""" -import pymysql -from app.core.config import settings - -# Connect to database -conn = pymysql.connect( - host=settings.mysql_host, - port=settings.mysql_port, - user=settings.mysql_user, - password=settings.mysql_password, - database=settings.mysql_database -) - -try: - with conn.cursor() as cursor: - # Check if alembic_version table exists - cursor.execute("SHOW TABLES LIKE 'alembic_version'") - if not cursor.fetchone(): - # Create alembic_version table - cursor.execute(""" - CREATE TABLE alembic_version ( - version_num VARCHAR(32) NOT NULL, - PRIMARY KEY (version_num) - ) - """) - print("Created alembic_version table") - - # Check current version - cursor.execute("SELECT version_num FROM alembic_version") - current = cursor.fetchone() - - if current: - print(f"Current migration version: {current[0]}") - # Delete old version - cursor.execute("DELETE FROM alembic_version") - - # Insert new version - cursor.execute( - "INSERT INTO alembic_version (version_num) VALUES ('a7802b126240')" - ) - conn.commit() - print("✅ Marked migration a7802b126240 as complete") - -finally: - conn.close() diff --git a/openspec/changes/pdf-layout-restoration/design.md b/openspec/changes/archive/2025-11-24-pdf-layout-restoration/design.md similarity index 100% rename from openspec/changes/pdf-layout-restoration/design.md rename to openspec/changes/archive/2025-11-24-pdf-layout-restoration/design.md diff --git a/openspec/changes/pdf-layout-restoration/proposal.md b/openspec/changes/archive/2025-11-24-pdf-layout-restoration/proposal.md similarity index 100% rename from openspec/changes/pdf-layout-restoration/proposal.md rename to openspec/changes/archive/2025-11-24-pdf-layout-restoration/proposal.md diff --git a/openspec/changes/pdf-layout-restoration/specs/result-export/spec.md b/openspec/changes/archive/2025-11-24-pdf-layout-restoration/specs/result-export/spec.md similarity index 100% rename from openspec/changes/pdf-layout-restoration/specs/result-export/spec.md rename to openspec/changes/archive/2025-11-24-pdf-layout-restoration/specs/result-export/spec.md diff --git a/openspec/changes/pdf-layout-restoration/tasks.md b/openspec/changes/archive/2025-11-24-pdf-layout-restoration/tasks.md similarity index 100% rename from openspec/changes/pdf-layout-restoration/tasks.md rename to openspec/changes/archive/2025-11-24-pdf-layout-restoration/tasks.md