Commit Graph

88 Commits

Author SHA1 Message Date
Christian Krakau-Louis 9584c0263c Merge pull request #408 from christianlouis/copilot/audit-documentation-gaps
fix(mypy): add missing type annotations in meilisearch_client.py
2026-02-25 15:18:51 +01:00
copilot-swe-agent[bot] 07e7b49ac8 fix(mypy): add missing type annotations in meilisearch_client.py
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-25 14:13:13 +00:00
copilot-swe-agent[bot] c428a7ec00 feat(ui): add dark mode support with system preference detection and localStorage persistence
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-25 13:59:49 +00:00
github-actions[bot] 093076515e style: apply ruff auto-fix
- Auto-formatted code with ruff format
- Applied ruff linting fixes with --fix

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-25 13:39:01 +00:00
copilot-swe-agent[bot] a08bfb9f1a feat(helm): add Helm chart for Kubernetes deployment and update DeploymentGuide
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-25 13:31:54 +00:00
copilot-swe-agent[bot] ff96340154 fix(config): default meilisearch_url to http://meilisearch:7700 for Docker/K8s service discovery
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-25 13:27:09 +00:00
copilot-swe-agent[bot] 89d5df71c8 feat(ocr): fine-tune OCR quality criteria with stricter threshold and head-to-head comparison
- Raise quality acceptance threshold from 65→85 (configurable via TEXT_QUALITY_THRESHOLD)
- Reject text with significant issues (excessive_typos, garbage_characters,
  incoherent_text, fragmented_sentences) even when score is above threshold
  (configurable via TEXT_QUALITY_SIGNIFICANT_ISSUES)
- Add compare_text_quality() for AI-powered head-to-head comparison of
  original embedded text vs fresh OCR output
- Update process_document to pass original text to OCR task for comparison
- Update process_with_ocr to run comparison and keep the higher-quality text
- Add new settings to settings_service.py metadata
- Update docs/ConfigurationGuide.md with new settings
- Add comprehensive tests for new threshold and comparison logic

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-25 13:03:21 +00:00
copilot-swe-agent[bot] 37a3f7aae7 fix(ocr): sync workflow steps with process_with_ocr replacing legacy azure step
- Update _compute_processing_flow to recognize process_with_ocr as the OCR
  stage and remap legacy process_with_azure_document_intelligence log entries
  for backward compatibility
- Normalize legacy OCR step name in _compute_step_summary log fallback
- Add process_with_ocr to REAL_MAIN_STEPS/REAL_STEPS in step_manager,
  file_status, and file_queries (keeping legacy name for old DB entries)
- Update retry logic in api/files.py to retry failed OCR via process_with_ocr
  (handles both step names as aliases)
- Fix process_document.py to log process_with_ocr as skipped (not azure step)
  for the local text extraction path

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 22:22:06 +00:00
copilot-swe-agent[bot] 0c500e1ec6 fix(ocr): address code review: add model fallback default, remove unused variable
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 18:44:20 +00:00
copilot-swe-agent[bot] b03bfb5e02 feat(ocr): add AI-based embedded text quality check with automatic OCR fallback
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 18:41:27 +00:00
copilot-swe-agent[bot] 2b2a97c2fa fix(ocr): ensure Tesseract language data for embed_text_layer regardless of active OCR provider
Root cause: ensure_ocr_languages_from_settings() only downloaded tessdata
when the 'tesseract' provider was active, but embed_text_layer() uses
ocrmypdf (which needs tessdata) as a fallback for ALL OCR providers.

- embed_text_layer(): call ensure_tesseract_languages(language) after
  confirming ocrmypdf is on PATH, so language data is present before
  ocrmypdf is invoked (prevents exit code 3 for fra/deu/etc.)
- ensure_ocr_languages_from_settings(): extend the condition from
  'tesseract' in active_providers to also trigger when ocrmypdf is
  on PATH, enabling proactive pre-download at startup for any config
- Tests: mock shutil.which and ensure_tesseract_languages in affected
  test cases; rename azure-only test and add new test for ocrmypdf case

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 18:02:19 +00:00
copilot-swe-agent[bot] 8a2a4dc2b3 feat(ocr): auto-install Tesseract/EasyOCR languages from settings
- Add app/utils/ocr_language_manager.py: detects tessdata dir, downloads
  missing .traineddata files via wget/curl from tessdata_fast GitHub repo,
  pre-downloads EasyOCR models, exposes async background-thread helper
- TesseractOCRProvider.process() calls ensure_tesseract_languages() before
  running pytesseract; raises clear error if languages remain unavailable
- EasyOCRProvider.process() logs informational message when models download
- app/main.py: calls ensure_ocr_languages_async() at startup
- app/utils/settings_sync.py: triggers language re-check after every
  settings reload so UI changes take effect without container restart
- app/api/settings.py: adds POST /api/settings/install-ocr-languages
  endpoint for on-demand language installation from the admin UI
- Dockerfile: adds wget for runtime tessdata downloads
- docs/ConfigurationGuide.md: documents automatic language download
- tests/test_ocr_language_manager.py: 29 unit tests

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 16:28:14 +00:00
copilot-swe-agent[bot] 50573ec7be fix(ocr): address code review - add subprocess security comment and type hints in tests
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 13:22:39 +00:00
copilot-swe-agent[bot] fec032643b feat(ocr): embed searchable text layer for providers without native PDF output
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 13:19:52 +00:00
copilot-swe-agent[bot] c7423834d5 fix(ocr): rewrite MistralOCRProvider to use native Mistral OCR API
- PDFs are now uploaded to Mistral Files API (POST /v1/files) and
  processed via a signed document_url, resolving the 422 error caused
  by passing data:application/pdf;base64,... to an image endpoint
- Images (JPEG/PNG/GIF/WEBP/BMP/TIFF) use base64 image_url directly
- Unsupported MIME types raise a clear ValueError
- Magic-byte fallback detects PDFs with no file extension
- Switches from openai chat completions to requests HTTP calls
- Adds helper method _upload_pdf_and_get_document()
- Adds TestMistralOCRProvider with 9 unit tests covering all paths

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-24 12:13:38 +00:00
Christian Krakau-Louis 4cc9233524 Merge branch 'main' into copilot/add-self-hosted-ocr-support 2026-02-23 23:51:43 +01:00
copilot-swe-agent[bot] a94b52ee14 feat(ai): handle temperature incompatibility for gpt-5 and o-series models, add model picker UI
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 22:12:08 +00:00
github-actions[bot] 5ee3d8cd84 style: apply ruff auto-fix
- Auto-formatted code with ruff format
- Applied ruff linting fixes with --fix

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-23 21:24:11 +00:00
copilot-swe-agent[bot] 631d43c664 fix(ocr): set default OCR languages to English + German (eng+deu / en,de)
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 21:02:07 +00:00
copilot-swe-agent[bot] 1f843fe460 feat(ocr): add self-hosted OCR engine support (Tesseract, EasyOCR) with multi-provider cross-checking
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 20:59:43 +00:00
copilot-swe-agent[bot] 044da0ff47 feat: update all OpenAI/ChatGPT refs + settings dropdown for fixed-value fields
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 20:06:57 +00:00
copilot-swe-agent[bot] dcdef44303 feat: add Portkey provider support and null-content guard to AI abstraction layer
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 19:42:03 +00:00
copilot-swe-agent[bot] d4c7fb26ac feat: add AI provider abstraction layer with OpenAI, Azure, Anthropic, Gemini, Ollama, OpenRouter, LiteLLM support
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 19:26:45 +00:00
copilot-swe-agent[bot] efb3fa7d6c fix(config): decrypt sensitive settings when loading from database
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 12:54:34 +00:00
copilot-swe-agent[bot] 862ba99802 fix(settings): rollback restores old_value instead of new_value and supports deletion fallback
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 12:15:44 +00:00
copilot-swe-agent[bot] 96fd0b8dd5 feat(settings): patch API in-memory settings on save and add Back to ENV button
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 11:42:37 +00:00
copilot-swe-agent[bot] 0188575c27 fix: isolate token_hex mock to wizard module and fix mypy annotation
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 10:01:07 +00:00
github-actions[bot] 540541eec6 style: apply ruff auto-fix
- Auto-formatted code with ruff format
- Applied ruff linting fixes with --fix

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-23 09:33:48 +00:00
copilot-swe-agent[bot] ecc8100e24 feat(settings): persist storage provider settings to DB, add export endpoint, enrich setup wizard
- dropbox/google_drive/onedrive save-settings: switch to DB as primary,
  .env write as best-effort (no longer fails when .env is absent)
- onedrive/google_drive update-settings: persist changes to DB alongside
  in-memory update; call notify_settings_updated()
- onedrive test_onedrive_token: persist rotated refresh token to DB
- settings_service: add get_settings_for_export() (db / effective modes)
- settings API: add GET /api/settings/export-env (admin-only, downloads .env)
- wizard: enrich settings with current values (DB > ENV > default) and
  value_source badges; pass setup_skipped to template; call
  notify_settings_updated() on save; add /setup/undo-skip route
- setup_wizard.html: pre-populate inputs with current_value; show
  DB/ENV/DEFAULT source badges; skip/undo-skip messaging
- settings.html: replace single Audit Log button with Setup Wizard link,
  Export .env dropdown, and Audit Log button group

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-23 02:41:04 +00:00
copilot-swe-agent[bot] 90e5e0037c feat(settings): per-option save, live worker sync, audit log, and rollback
A) Per-option Save Button
- Add per-setting Save button in settings.html (visible only when value changed)
- Button calls POST /api/settings/{key} directly; existing bulk Save retained
- Add Audit Log link in settings page header

B) Immediate Worker Sync
- New app/utils/settings_sync.py with notify_settings_updated() (Redis version key)
  and register_settings_reload_signal() (Celery task_prerun handler)
- Register signal in celery_worker.py at startup
- All API write paths call notify_settings_updated() after successful saves

C) Audit Log
- Add SettingsAuditLog model (key, old_value, new_value, changed_by, changed_at, action)
- save_setting_to_db / delete_setting_from_db accept changed_by and write audit entries
- New get_audit_log() service function (masks sensitive values)
- New GET /api/settings/audit-log endpoint (admin-only)
- New GET /admin/settings/audit-log view + audit_log.html template
- Visible to all admins (per clarified requirement)

D) Config Rollback / History
- New get_setting_history() and rollback_setting() service functions
- New GET /api/settings/{key}/history endpoint
- New POST /api/settings/{key}/rollback/{history_id} endpoint
- Rollback buttons in audit_log.html with confirmation dialog
- Tests: 25 new tests covering audit log, rollback, worker sync helpers, and API endpoints

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-23 02:28:08 +00:00
copilot-swe-agent[bot] e632e0333f fix(api): return 200 with value=None for unknown setting keys in GET endpoint
`GET /api/settings/{key}` was calling `validate_setting_key()` which raises
HTTP 404 for keys not in SETTING_METADATA. The test expects 200 with value=None
for unknown keys.

Added `validate_setting_key_format()` to `input_validation.py` that validates
only the key format without the SETTING_METADATA existence check. Updated
`get_setting` to use the format-only validator; POST/DELETE endpoints continue
using the full `validate_setting_key()` for write-side security.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-22 20:04:57 +00:00
copilot-swe-agent[bot] 3035802c16 feat(security): add comprehensive input validation and sanitization (#172)
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-22 16:02:00 +00:00
copilot-swe-agent[bot] 886bcd3c9b fix: include exc_info in log_task_progress debug message
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-17 11:41:56 +00:00
copilot-swe-agent[bot] 13a3c41482 fix: make log_task_progress resilient to DB errors and fix test assertions
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-17 11:40:34 +00:00
copilot-swe-agent[bot] 53a9efa56d feat: add strict mypy type-checking for app/utils/ module
- Add [[tool.mypy.overrides]] section for app/utils/** with disallow_untyped_defs=true
- Add type annotations to all functions in app/utils/ (12 files)
- Fix type annotations in app/config.py and app/database.py (imported by utils)
- All 85 source files now pass mypy type checking

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-14 00:27:52 +00:00
copilot-swe-agent[bot] fc4f5631ee test: increase coverage for imap_tasks.py and fix config_validator.py
- Add comprehensive tests for imap_tasks.py covering:
  - Lock acquire/release mechanisms
  - pull_all_inboxes task with various scenarios
  - pull_inbox for Gmail and non-Gmail with edge cases
  - find_all_mail_xlist functionality
  - Extended fetch_attachments tests for all MIME types
  - Edge cases: invalid JSON, missing Message-ID, already processed, etc.
- Achieve 98.26% coverage for imap_tasks.py (up from 48.78%)

- Fix config_validator.py to include validate_auth_config export
- Update tests to verify all exports including validate_auth_config
- Note: config_validator.py file is shadowed by config_validator/ directory
  in Python's module resolution, so it cannot be directly imported or tested.
  The package's __init__.py (which has 100% coverage) is what's actually used.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-13 23:42:49 +00:00
copilot-swe-agent[bot] b42c6f5f64 fix: resolve all Ruff linting errors
- Fix PLW2901: Use different variable name for stripped lines in loop
- Fix E721: Use 'is' instead of '==' for type comparisons
- Add noqa comments for intentional security warnings (S321, S507, S110, S603)

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-13 16:12:39 +00:00
copilot-swe-agent[bot] 4897cb6655 fix: apply Phase 1-2 correctness and constant extraction from PR #273
- Replace datetime.utcnow() with datetime.now(timezone.utc) in 4 files
- Extract duplicate literals to constants in 5 files
  - models.py: "files.id" → _FILES_ID_FK
  - upload_to_email.py: "logo.png" → _LOGO_FILENAME
  - general.py: "%B %d, %Y" → _DATE_DISPLAY_FORMAT
  - files.py: "File not found" → _FILE_NOT_FOUND
  - upload_to_google_drive.py: Google token URL → _GOOGLE_TOKEN_URL

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-13 11:25:30 +00:00
copilot-swe-agent[bot] 43bc58770d refactor: consolidate linting tools into Ruff
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-13 09:10:52 +00:00
copilot-swe-agent[bot] dff32e08e1 test: add comprehensive tests for critical untested files and fix deprecated warnings
- Add tests for migrate_logs_to_steps.py, upload_to_paperless.py, dropbox API,
  upload_to_dropbox.py, upload_to_nextcloud.py, upload_to_onedrive.py,
  upload_with_rclone.py, and config_validator.py
- Fix PydanticDeprecatedSince20: @validator → @field_validator in config.py, url_upload.py
- Fix PydanticDeprecatedSince20: class Config → model_config = SettingsConfigDict
- Fix PydanticDeprecatedSince211: filter Pydantic internals in settings_display.py
- Fix MovedIn20Warning: use sqlalchemy.orm.declarative_base instead of ext.declarative

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-12 17:32:17 +00:00
copilot-swe-agent[bot] ff9a3ff49f style: fix code formatting with black, isort, and flake8
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-12 03:21:41 +00:00
copilot-swe-agent[bot] cc98039246 fix(deps): upgrade PyPDF2 to pypdf >= 3.9.0 to fix CVE-2023-36464
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-12 02:52:17 +00:00
Christian Krakau-Louis 9a2c2d20b1 feat(duplication): implement duplicate file handling and detection across processing steps 2026-02-12 02:38:00 +01:00
Christian Krakau-Louis 70757e5644 feat(step-timeout): add automatic recovery for stalled processing steps
- Implement step timeout detection to prevent files from getting stuck in 'pending' state
- Add monitor_stalled_steps periodic task running every minute (Celery Beat)
- Automatically mark in-progress steps as failed if they exceed timeout (default: 10 minutes)
- Add step_timeout configuration setting (default: 600 seconds)
- Recover stalled steps with error message indicating when timeout was triggered
- Fix duplicate check to exclude self-comparison (file not duplicate of itself)

When processing crashes or hangs:
1. Worker detects stalled steps (in_progress for >10 minutes)
2. Marks them as failed with timeout error message
3. Updates UI to show failure status
4. Allows file to be retried or handled by user

This prevents files from being indefinitely stuck in processing state and provides
visibility into what went wrong.
2026-02-12 02:38:00 +01:00
Christian Krakau-Louis 4c11cfd6dd feat(deduplication): implement configurable duplicate file detection
- Add enable_deduplication and show_deduplication_step config options
- Rename hash_file step to check_for_duplicates
- Make deduplication step conditional based on configuration
- Add is_duplicate and duplicate_of_id fields to FileRecord model
- Create database migration for new deduplication fields
- Update process_document task to log deduplication results
- Update step visualization to show/hide step based on config
- Update status calculations to include deduplication step conditionally
- Default: deduplication enabled, step displayed
- Can be configured to hide from UI while still processing
2026-02-12 02:38:00 +01:00
Christian Krakau-Louis 83c65f3c40 feat: enhance processing status tracking and UI display for file details 2026-02-12 01:07:22 +01:00
copilot-swe-agent[bot] 73a0222e56 feat(storage): implement immutable original/processed file storage and collision handling
- Add original_file_path and processed_file_path columns to FileRecord model
- Create database migration for new fields
- Implement get_unique_filepath_with_counter() with -0001 suffix format
- Update process_document to save immutable copy to /workdir/original
- Add force_cloud_ocr parameter to process_document for forced OCR
- Update embed_metadata to use new collision handling
- Update metadata JSON to include file path references
- Add /files/{file_id}/reprocess-with-cloud-ocr API endpoint
- Update processed_file_path in database during embedding

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-11 20:10:19 +00:00
copilot-swe-agent[bot] 65b6dc6985 feat: Add comprehensive tests and migration utility for status table
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-11 19:48:17 +00:00
copilot-swe-agent[bot] ad74bc852d feat: Add explicit FileProcessingStep table for status tracking
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-11 19:45:09 +00:00
copilot-swe-agent[bot] 4fb696e1eb fix: correct file status and metrics to use latest status per step
- Fix _compute_status_from_logs to track latest status per unique step
- Fix _compute_step_summary to count only latest status per step
- Add comprehensive tests for both fixes
- Resolves issue where completed files showed as "Processing"
- Resolves issue where metrics showed incorrect counts

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-02-11 18:33:41 +00:00