From 6e2e4a830f63d36d47d9cd2aa0e44550d7120499 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 21:34:15 +0000 Subject: [PATCH] fix(migrations): rebase audit_logs migration onto main's 027_ensure_shared_links_table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add 027_ensure_shared_links_table.py from main branch - Renumber 027_add_audit_logs → 028_add_audit_logs - Update down_revision to chain from 027_ensure_shared_links_table - Restore all model imports in migrations/env.py (were dropped in previous PR) - Restore shared_links in db_migrate.py _TABLE_ORDER Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- app/utils/db_migrate.py | 1 + migrations/env.py | 15 +++++ .../versions/027_ensure_shared_links_table.py | 62 +++++++++++++++++++ ...dd_audit_logs.py => 028_add_audit_logs.py} | 8 +-- 4 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 migrations/versions/027_ensure_shared_links_table.py rename migrations/versions/{027_add_audit_logs.py => 028_add_audit_logs.py} (90%) diff --git a/app/utils/db_migrate.py b/app/utils/db_migrate.py index 5d11ee36..3424009d 100644 --- a/app/utils/db_migrate.py +++ b/app/utils/db_migrate.py @@ -35,6 +35,7 @@ _TABLE_ORDER = [ "audit_logs", "saved_searches", "webhook_configs", + "shared_links", ] diff --git a/migrations/env.py b/migrations/env.py index d421d3c7..67fc3ad3 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -20,14 +20,29 @@ from app.database import Base # Ensure all models are imported so Base.metadata is populated. from app.models import ( # noqa: F401 + ApiToken, ApplicationSettings, AuditLog, + BackupRecord, DocumentMetadata, FileProcessingStep, FileRecord, + InAppNotification, + LocalUser, + Pipeline, + PipelineStep, ProcessingLog, SavedSearch, + ScheduledJob, SettingsAuditLog, + SharedLink, + SubscriptionPlan, + UserImapAccount, + UserIntegration, + UserNotificationPreference, + UserNotificationTarget, + UserProfile, + WebhookConfig, ) # Alembic Config object – provides access to values in alembic.ini. diff --git a/migrations/versions/027_ensure_shared_links_table.py b/migrations/versions/027_ensure_shared_links_table.py new file mode 100644 index 00000000..2a333582 --- /dev/null +++ b/migrations/versions/027_ensure_shared_links_table.py @@ -0,0 +1,62 @@ +"""Ensure shared_links table exists for databases that skipped migration 025. + +Databases that were already at revision 025_add_user_notifications or +026_add_scheduled_jobs before 025_add_shared_links was inserted into the +migration chain will never have had the ``shared_links`` table created. +This migration creates the table idempotently so those databases are +repaired on the next ``alembic upgrade head``. + +Revision ID: 027_ensure_shared_links_table +Revises: 026_add_scheduled_jobs +Create Date: 2026-03-09 +""" + +from typing import Union + +import sqlalchemy as sa +from alembic import op + +revision: str = "027_ensure_shared_links_table" +down_revision: Union[str, None] = "026_add_scheduled_jobs" +depends_on: Union[str, None] = None + + +def upgrade() -> None: + """Create shared_links table if it does not already exist.""" + conn = op.get_bind() + inspector = sa.inspect(conn) + if "shared_links" not in inspector.get_table_names(): + op.create_table( + "shared_links", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("token", sa.String(64), nullable=False), + sa.Column("file_id", sa.Integer(), nullable=False), + sa.Column("owner_id", sa.String(), nullable=False), + sa.Column("label", sa.String(255), nullable=True), + sa.Column("expires_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("max_views", sa.Integer(), nullable=True), + sa.Column("view_count", sa.Integer(), nullable=False, server_default="0"), + sa.Column("password_hash", sa.String(128), nullable=True), + sa.Column("is_active", sa.Boolean(), nullable=False, server_default="1"), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()), + sa.Column("revoked_at", sa.DateTime(timezone=True), nullable=True), + sa.ForeignKeyConstraint(["file_id"], ["files.id"]), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("token"), + ) + op.create_index("ix_shared_links_id", "shared_links", ["id"]) + op.create_index("ix_shared_links_token", "shared_links", ["token"]) + op.create_index("ix_shared_links_file_id", "shared_links", ["file_id"]) + op.create_index("ix_shared_links_owner_id", "shared_links", ["owner_id"]) + + +def downgrade() -> None: + """Drop shared_links table only if this migration created it.""" + conn = op.get_bind() + inspector = sa.inspect(conn) + if "shared_links" in inspector.get_table_names(): + op.drop_index("ix_shared_links_owner_id", "shared_links") + op.drop_index("ix_shared_links_file_id", "shared_links") + op.drop_index("ix_shared_links_token", "shared_links") + op.drop_index("ix_shared_links_id", "shared_links") + op.drop_table("shared_links") diff --git a/migrations/versions/027_add_audit_logs.py b/migrations/versions/028_add_audit_logs.py similarity index 90% rename from migrations/versions/027_add_audit_logs.py rename to migrations/versions/028_add_audit_logs.py index 5fe0280c..58114e7a 100644 --- a/migrations/versions/027_add_audit_logs.py +++ b/migrations/versions/028_add_audit_logs.py @@ -1,7 +1,7 @@ """Add audit_logs table for comprehensive compliance audit logging. -Revision ID: 027_add_audit_logs -Revises: 026_add_scheduled_jobs +Revision ID: 028_add_audit_logs +Revises: 027_ensure_shared_links_table Create Date: 2026-03-09 """ @@ -10,8 +10,8 @@ from typing import Union import sqlalchemy as sa from alembic import op -revision: str = "027_add_audit_logs" -down_revision: Union[str, None] = "026_add_scheduled_jobs" +revision: str = "028_add_audit_logs" +down_revision: Union[str, None] = "027_ensure_shared_links_table" depends_on: Union[str, None] = None