bifroest/app/migrations/versions/0022_workspace_mcp.py
2026-10-27 08:34:17 +01:00

61 lines
3.6 KiB
Python

"""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')