"""MCP-Verbindungen je Workspace, Datenbanken als MCP-Verbindung, Vererbung der Einstufung Revision ID: 0022 Revises: 0021 Erstellt: 2026-10-25 16:00:00 """ import sqlalchemy as sa from alembic import op revision = '0022' down_revision = '0021' branch_labels = None depends_on = None def upgrade() -> None: op.add_column('mcp_servers', sa.Column('workspace_id', sa.Integer(), nullable=True)) op.create_foreign_key('fk_mcp_servers_workspace_id_workspaces', 'mcp_servers', 'workspaces', ['workspace_id'], ['id'], ondelete='CASCADE') op.create_index('ix_mcp_servers_workspace_id', 'mcp_servers', ['workspace_id']) op.add_column('mcp_servers', sa.Column('template_id', sa.Integer(), nullable=True)) op.create_foreign_key('fk_mcp_servers_template_id_mcp_servers', 'mcp_servers', 'mcp_servers', ['template_id'], ['id'], ondelete='RESTRICT') op.add_column('mcp_servers', sa.Column('headers', sa.Text(), nullable=True)) op.add_column('mcp_servers', sa.Column('header_names', sa.JSON(), nullable=False, server_default='[]')) op.add_column('mcp_servers', sa.Column('config', sa.JSON(), nullable=False, server_default='{}')) op.add_column('mcp_servers', sa.Column('approval', sa.String(20), nullable=False, server_default='approved')) op.add_column('mcp_servers', sa.Column('approval_note', sa.Text(), nullable=False, server_default='')) op.add_column('mcp_servers', sa.Column('status_message', sa.Text(), nullable=False, server_default='')) op.add_column('mcp_servers', sa.Column('exposure_confirmed_by', sa.Integer(), nullable=True)) op.create_foreign_key('fk_mcp_servers_exposure_confirmed_by_users', 'mcp_servers', 'users', ['exposure_confirmed_by'], ['id']) op.add_column('mcp_servers', sa.Column('exposure_confirmed_at', sa.DateTime(timezone=True), nullable=True)) op.add_column('mcp_tools', sa.Column('fingerprint', sa.String(64), nullable=False, server_default='')) op.add_column('tool_definitions', sa.Column('fingerprint', sa.String(64), nullable=True)) op.create_index('ix_tool_definitions_fingerprint', 'tool_definitions', ['fingerprint']) op.add_column('tool_definitions', sa.Column('inherited_from', sa.String(100), nullable=True)) # Datenbank-Quellen gibt es nicht mehr; sie werden zu MCP-Verbindungen, sobald ein DB-Dienst für ihren # Typ registriert ist (app.mcp.databases.convert_sources). Bis dahin nicht nutzbar. op.execute("UPDATE data_sources SET status = 'new', status_message = 'Wird zur MCP-Verbindung, sobald ein " "DB-Dienst für diesen Typ registriert ist.' WHERE kind = 'database'") def downgrade() -> None: op.drop_column('tool_definitions', 'inherited_from') op.drop_index('ix_tool_definitions_fingerprint', 'tool_definitions') op.drop_column('tool_definitions', 'fingerprint') op.drop_column('mcp_tools', 'fingerprint') op.execute("DELETE FROM mcp_servers WHERE workspace_id IS NOT NULL") for name in ('exposure_confirmed_at', 'status_message', 'approval_note', 'approval', 'config', 'header_names', 'headers'): op.drop_column('mcp_servers', name) op.drop_constraint('fk_mcp_servers_exposure_confirmed_by_users', 'mcp_servers', type_='foreignkey') op.drop_column('mcp_servers', 'exposure_confirmed_by') op.drop_constraint('fk_mcp_servers_template_id_mcp_servers', 'mcp_servers', type_='foreignkey') op.drop_column('mcp_servers', 'template_id') op.drop_index('ix_mcp_servers_workspace_id', 'mcp_servers') op.drop_constraint('fk_mcp_servers_workspace_id_workspaces', 'mcp_servers', type_='foreignkey') op.drop_column('mcp_servers', 'workspace_id')