From 8c034e6e32ecd3b0902bc1910585a87183d7ca39 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:34:46 +0000 Subject: [PATCH 1/2] Initial plan From db581ba355834a514606717fb5f8f9673fc0dce6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:37:56 +0000 Subject: [PATCH 2/2] fix(database): add runtime migrations for ocr_text, ai_metadata, document_title columns Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- app/database.py | 19 ++++++++++++++++++ tests/test_database.py | 45 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/app/database.py b/app/database.py index 8a73f71b..8272a973 100644 --- a/app/database.py +++ b/app/database.py @@ -103,6 +103,25 @@ def _run_schema_migrations(engine: Any) -> None: conn.execute(text("ALTER TABLE files ADD COLUMN duplicate_of_id INTEGER")) logger.info("Migration complete: 'duplicate_of_id' column added to files") + # Migration: Add search/OCR fields to files table + if "ocr_text" not in columns: + logger.info("Migrating files: adding 'ocr_text' column") + with engine.begin() as conn: + conn.execute(text("ALTER TABLE files ADD COLUMN ocr_text TEXT")) + logger.info("Migration complete: 'ocr_text' column added to files") + + if "ai_metadata" not in columns: + logger.info("Migrating files: adding 'ai_metadata' column") + with engine.begin() as conn: + conn.execute(text("ALTER TABLE files ADD COLUMN ai_metadata TEXT")) + logger.info("Migration complete: 'ai_metadata' column added to files") + + if "document_title" not in columns: + logger.info("Migrating files: adding 'document_title' column") + with engine.begin() as conn: + conn.execute(text("ALTER TABLE files ADD COLUMN document_title VARCHAR")) + logger.info("Migration complete: 'document_title' column added to files") + # Migration: Drop unique index on filehash to allow duplicate records try: indexes = inspector.get_indexes("files") diff --git a/tests/test_database.py b/tests/test_database.py index 008b1d7e..4c11b57f 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -186,6 +186,48 @@ class TestSchemaMigrations: assert "duplicate_of_id" in columns assert columns["duplicate_of_id"]["type"].__class__.__name__ in ("INTEGER", "Integer") + assert "ocr_text" in columns + assert "ai_metadata" in columns + assert "document_title" in columns + + engine.dispose() + + def test_migration_adds_search_fields(self, tmp_path): + """Test that _run_schema_migrations adds ocr_text, ai_metadata, document_title to files table.""" + from sqlalchemy import create_engine, text + + from app.database import _run_schema_migrations + + # Create a database with the old schema (no search fields) + db_path = str(tmp_path / "migration_search_fields_test.db") + engine = create_engine(f"sqlite:///{db_path}") + with engine.begin() as conn: + conn.execute( + text( + "CREATE TABLE files (" + "id INTEGER PRIMARY KEY, " + "filename VARCHAR, " + "filehash VARCHAR, " + "original_file_path VARCHAR, " + "processed_file_path VARCHAR, " + "is_duplicate BOOLEAN DEFAULT FALSE NOT NULL, " + "duplicate_of_id INTEGER)" + ) + ) + + # Run migrations + _run_schema_migrations(engine) + + # Verify search columns were added + from sqlalchemy import inspect + + inspector = inspect(engine) + columns = {col["name"]: col for col in inspector.get_columns("files")} + + assert "ocr_text" in columns + assert "ai_metadata" in columns + assert "document_title" in columns + engine.dispose() def test_migration_drops_unique_filehash_index(self, tmp_path): @@ -299,6 +341,9 @@ class TestSchemaMigrations: assert "processed_file_path" in files_columns assert "is_duplicate" in files_columns assert "duplicate_of_id" in files_columns + assert "ocr_text" in files_columns + assert "ai_metadata" in files_columns + assert "document_title" in files_columns engine.dispose()