Files
leocrm/alembic/versions/0094_fix_gin_indexes_and_plugins_dedup.py
T
Agent Zero 3eb11b1745 Phase 1: Migrationsaudit + Forward-Migrationen 0093-0096
Audit (docs/migration_history_audit.md):
- files.size_bytes: INTEGER (Alembic) vs BIGINT (Produktion/Plugin)
- GIN-Indizes: Fehlendes USING GIN in Alembic 0002
- guest_users: ix_guest_users_email_tenant fehlt UNIQUE in Alembic 0059
- plugins.name: Doppelter Unique-Index in Produktion

Forward-Migrationen:
- 0093: files.size_bytes INTEGER → BIGINT
- 0094: GIN-Indizes reparieren + plugins.name doppelten Index entfernen
- 0095: guest_users email+tenant_id UNIQUE INDEX (mit Dubletten-Check)
- 0096: Workspace tenant_integrity (tenant-bound FKs)

Tests: 41/41 bestanden (17 Workspace + 24 Command)
Alembic Head: 0096
2026-08-03 13:29:16 +02:00

54 lines
1.8 KiB
Python

"""Fix GIN indexes and remove duplicate plugins.name index.
Alembic 0002 created search indexes without USING GIN.
Production already has GIN indexes (corrected by later migrations or manual).
This migration ensures GIN indexes exist for both fresh install and existing DBs.
Also removes the redundant ix_plugins_name unique index (plugins_name_key
already enforces uniqueness from the column definition).
Revision ID: 0094
Revises: 0093
"""
from __future__ import annotations
from alembic import op
revision = "0094"
down_revision = "0093"
branch_labels = None
depends_on = None
# GIN indexes that should exist with USING GIN
GIN_INDEXES = [
("contacts", "ix_contacts_search_tsv", "search_tsv"),
("audit_log", "ix_audit_log_search_tsv", "search_tsv"),
("calendar_entries", "ix_cal_entries_search_tsv", "search_tsv"),
("comm_messages", "ix_comm_messages_search_tsv", "search_tsv"),
("files", "ix_files_content_tsv", "content_tsv"),
("mails", "ix_mails_body_tsv", "body_tsv"),
("tags", "ix_tags_search_tsv", "search_tsv"),
]
def upgrade() -> None:
# Fix GIN indexes: drop and recreate with USING GIN (idempotent)
for table, index_name, column in GIN_INDEXES:
op.execute(f"DROP INDEX IF EXISTS {index_name}")
op.execute(
f"CREATE INDEX IF NOT EXISTS {index_name} "
f"ON {table} USING gin ({column})"
)
# Remove redundant plugins.name index (plugins_name_key already enforces uniqueness)
op.execute("DROP INDEX IF EXISTS ix_plugins_name")
def downgrade() -> None:
# Recreate the dropped index without GIN (not truly reversible to wrong state)
op.execute(
"CREATE INDEX IF NOT EXISTS ix_plugins_name ON plugins (name)"
)
# GIN indexes cannot be meaningfully downgraded to non-GIN