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

212 lines
13 KiB
Python

"""Grundgerüst Phase 1
Revision ID: 0001
Revises:
Erstellt: 2026-10-21 22:16:40.151202
"""
from alembic import op
import sqlalchemy as sa
revision = '0001'
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
op.create_table('teams',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('slug', sa.String(length=64), nullable=False),
sa.Column('name', sa.String(length=200), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_teams')),
sa.UniqueConstraint('slug', name=op.f('uq_teams_slug'))
)
op.create_table('users',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('username', sa.String(length=64), nullable=False),
sa.Column('display_name', sa.String(length=200), nullable=False),
sa.Column('is_admin', sa.Boolean(), nullable=False),
sa.Column('external_id', sa.String(length=200), nullable=True),
sa.Column('active', sa.Boolean(), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_users')),
sa.UniqueConstraint('external_id', name=op.f('uq_users_external_id')),
sa.UniqueConstraint('username', name=op.f('uq_users_username'))
)
op.create_table('team_memberships',
sa.Column('team_id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['team_id'], ['teams.id'], name=op.f('fk_team_memberships_team_id_teams'), ondelete='CASCADE'),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_team_memberships_user_id_users'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('team_id', 'user_id', name=op.f('pk_team_memberships'))
)
op.create_table('web_sessions',
sa.Column('id', sa.String(length=64), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('csrf', sa.String(length=64), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.Column('expires_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('revoked_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_web_sessions_user_id_users'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_web_sessions'))
)
op.create_index(op.f('ix_web_sessions_user_id'), 'web_sessions', ['user_id'], unique=False)
op.create_table('workspaces',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('team_id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=200), nullable=False),
sa.Column('description', sa.Text(), nullable=False),
sa.Column('approval_mode', sa.String(length=20), nullable=False),
sa.Column('munin_key_ref', sa.String(length=200), nullable=True),
sa.Column('hugin_project', sa.String(length=64), nullable=True),
sa.Column('settings', sa.JSON(), nullable=False),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], name=op.f('fk_workspaces_created_by_users')),
sa.ForeignKeyConstraint(['team_id'], ['teams.id'], name=op.f('fk_workspaces_team_id_teams')),
sa.PrimaryKeyConstraint('id', name=op.f('pk_workspaces'))
)
op.create_index(op.f('ix_workspaces_team_id'), 'workspaces', ['team_id'], unique=False)
op.create_table('audit_events',
sa.Column('id', sa.BigInteger(), sa.Identity(always=False), nullable=False),
sa.Column('time', sa.DateTime(timezone=True), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('workspace_id', sa.Integer(), nullable=True),
sa.Column('action', sa.String(length=100), nullable=False),
sa.Column('target_kind', sa.String(length=50), nullable=False),
sa.Column('target_id', sa.String(length=100), nullable=False),
sa.Column('data', sa.JSON(), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_audit_events_user_id_users')),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], name=op.f('fk_audit_events_workspace_id_workspaces'), ondelete='SET NULL'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_audit_events'))
)
op.create_index(op.f('ix_audit_events_time'), 'audit_events', ['time'], unique=False)
op.create_index(op.f('ix_audit_events_workspace_id'), 'audit_events', ['workspace_id'], unique=False)
op.create_table('chat_sessions',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('workspace_id', sa.Integer(), nullable=False),
sa.Column('title', sa.String(length=200), nullable=False),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], name=op.f('fk_chat_sessions_created_by_users')),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], name=op.f('fk_chat_sessions_workspace_id_workspaces'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_chat_sessions'))
)
op.create_index(op.f('ix_chat_sessions_workspace_id'), 'chat_sessions', ['workspace_id'], unique=False)
op.create_table('data_sources',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('workspace_id', sa.Integer(), nullable=False),
sa.Column('kind', sa.String(length=20), nullable=False),
sa.Column('name', sa.String(length=200), nullable=False),
sa.Column('config', sa.JSON(), nullable=False),
sa.Column('credential_ref', sa.String(length=200), nullable=True),
sa.Column('status', sa.String(length=20), nullable=False),
sa.Column('status_message', sa.Text(), nullable=False),
sa.Column('last_tested', sa.DateTime(timezone=True), nullable=True),
sa.Column('exposure_confirmed_by', sa.Integer(), nullable=False),
sa.Column('exposure_confirmed_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], name=op.f('fk_data_sources_created_by_users')),
sa.ForeignKeyConstraint(['exposure_confirmed_by'], ['users.id'], name=op.f('fk_data_sources_exposure_confirmed_by_users')),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], name=op.f('fk_data_sources_workspace_id_workspaces'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_data_sources'))
)
op.create_index(op.f('ix_data_sources_workspace_id'), 'data_sources', ['workspace_id'], unique=False)
op.create_table('workspace_memberships',
sa.Column('workspace_id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('role', sa.String(length=20), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_workspace_memberships_user_id_users'), ondelete='CASCADE'),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], name=op.f('fk_workspace_memberships_workspace_id_workspaces'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('workspace_id', 'user_id', name=op.f('pk_workspace_memberships'))
)
op.create_index(op.f('ix_workspace_memberships_user_id'), 'workspace_memberships', ['user_id'], unique=False)
op.create_table('task_runs',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('workspace_id', sa.Integer(), nullable=False),
sa.Column('team_id', sa.Integer(), nullable=False),
sa.Column('chat_session_id', sa.Integer(), nullable=True),
sa.Column('parent_run_id', sa.Uuid(), nullable=True),
sa.Column('kind', sa.String(length=20), nullable=False),
sa.Column('status', sa.String(length=30), nullable=False),
sa.Column('input', sa.JSON(), nullable=False),
sa.Column('result', sa.JSON(), nullable=False),
sa.Column('error', sa.Text(), nullable=False),
sa.Column('attempts', sa.Integer(), nullable=False),
sa.Column('available_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('locked_by', sa.String(length=100), nullable=True),
sa.Column('locked_until', sa.DateTime(timezone=True), nullable=True),
sa.Column('cancel_requested', sa.Boolean(), nullable=False),
sa.Column('config_versions', sa.JSON(), nullable=False),
sa.Column('created_by', sa.Integer(), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.Column('started', sa.DateTime(timezone=True), nullable=True),
sa.Column('finished', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(['chat_session_id'], ['chat_sessions.id'], name=op.f('fk_task_runs_chat_session_id_chat_sessions'), ondelete='CASCADE'),
sa.ForeignKeyConstraint(['created_by'], ['users.id'], name=op.f('fk_task_runs_created_by_users')),
sa.ForeignKeyConstraint(['parent_run_id'], ['task_runs.id'], name=op.f('fk_task_runs_parent_run_id_task_runs')),
sa.ForeignKeyConstraint(['team_id'], ['teams.id'], name=op.f('fk_task_runs_team_id_teams')),
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], name=op.f('fk_task_runs_workspace_id_workspaces'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_task_runs'))
)
op.create_index('ix_task_runs_due', 'task_runs', ['available_at'], unique=False,
postgresql_where=sa.text("status = 'queued'"))
op.create_index(op.f('ix_task_runs_status'), 'task_runs', ['status'], unique=False)
op.create_index(op.f('ix_task_runs_team_id'), 'task_runs', ['team_id'], unique=False)
op.create_index(op.f('ix_task_runs_workspace_id'), 'task_runs', ['workspace_id'], unique=False)
op.create_table('messages',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('chat_session_id', sa.Integer(), nullable=False),
sa.Column('role', sa.String(length=20), nullable=False),
sa.Column('content', sa.Text(), nullable=False),
sa.Column('run_id', sa.Uuid(), nullable=True),
sa.Column('author_id', sa.Integer(), nullable=True),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['author_id'], ['users.id'], name=op.f('fk_messages_author_id_users')),
sa.ForeignKeyConstraint(['chat_session_id'], ['chat_sessions.id'], name=op.f('fk_messages_chat_session_id_chat_sessions'), ondelete='CASCADE'),
sa.ForeignKeyConstraint(['run_id'], ['task_runs.id'], name=op.f('fk_messages_run_id_task_runs'), ondelete='SET NULL'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_messages'))
)
op.create_index(op.f('ix_messages_chat_session_id'), 'messages', ['chat_session_id'], unique=False)
op.create_table('run_events',
sa.Column('id', sa.BigInteger(), sa.Identity(always=False), nullable=False),
sa.Column('run_id', sa.Uuid(), nullable=False),
sa.Column('seq', sa.Integer(), nullable=False),
sa.Column('type', sa.String(length=30), nullable=False),
sa.Column('data', sa.JSON(), nullable=False),
sa.Column('created', sa.DateTime(timezone=True), nullable=False),
sa.ForeignKeyConstraint(['run_id'], ['task_runs.id'], name=op.f('fk_run_events_run_id_task_runs'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('pk_run_events')),
sa.UniqueConstraint('run_id', 'seq', name=op.f('uq_run_events_run_id'))
)
def downgrade() -> None:
op.drop_table('run_events')
op.drop_index(op.f('ix_messages_chat_session_id'), table_name='messages')
op.drop_table('messages')
op.drop_index(op.f('ix_task_runs_workspace_id'), table_name='task_runs')
op.drop_index(op.f('ix_task_runs_team_id'), table_name='task_runs')
op.drop_index(op.f('ix_task_runs_status'), table_name='task_runs')
op.drop_index('ix_task_runs_due', table_name='task_runs', postgresql_where=sa.text("status = 'queued'"))
op.drop_table('task_runs')
op.drop_index(op.f('ix_workspace_memberships_user_id'), table_name='workspace_memberships')
op.drop_table('workspace_memberships')
op.drop_index(op.f('ix_data_sources_workspace_id'), table_name='data_sources')
op.drop_table('data_sources')
op.drop_index(op.f('ix_chat_sessions_workspace_id'), table_name='chat_sessions')
op.drop_table('chat_sessions')
op.drop_index(op.f('ix_audit_events_workspace_id'), table_name='audit_events')
op.drop_index(op.f('ix_audit_events_time'), table_name='audit_events')
op.drop_table('audit_events')
op.drop_index(op.f('ix_workspaces_team_id'), table_name='workspaces')
op.drop_table('workspaces')
op.drop_index(op.f('ix_web_sessions_user_id'), table_name='web_sessions')
op.drop_table('web_sessions')
op.drop_table('team_memberships')
op.drop_table('users')
op.drop_table('teams')