"""initial_tables

Revision ID: b4983d976db2
Revises: 2613c65c3dbe
Create Date: 2025-11-20 11:57:16.385151

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = 'b4983d976db2'
down_revision: Union[str, Sequence[str], None] = '2613c65c3dbe'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    """Upgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('context_resources',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('name', sa.Text(), nullable=False),
    sa.Column('platform', sa.Text(), nullable=False),
    sa.Column('organization', sa.Text(), nullable=False),
    sa.Column('type', sa.Text(), server_default=sa.text("'integration'::text"), nullable=True),
    sa.Column('status', sa.Text(), server_default=sa.text("'active'::text"), nullable=True),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('metadata', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.CheckConstraint("status = ANY (ARRAY['active'::text, 'inactive'::text, 'pending'::text, 'error'::text])", name='valid_status'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('name', name='context_resources_name_key')
    )
    op.create_index('idx_context_resources_name', 'context_resources', ['name'], unique=False)
    op.create_index('idx_context_resources_org_platform', 'context_resources', ['organization', 'platform'], unique=False)
    op.create_index('idx_context_resources_organization', 'context_resources', ['organization'], unique=False)
    op.create_index('idx_context_resources_platform', 'context_resources', ['platform'], unique=False)
    op.create_index('idx_context_resources_status', 'context_resources', ['status'], unique=False)
    op.create_index('idx_context_resources_updated_at', 'context_resources', ['updated_at'], unique=False, postgresql_ops={'updated_at': 'DESC'})
    op.create_table('environments',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('name', sa.String(length=100), nullable=False),
    sa.Column('display_name', sa.String(length=255), nullable=True),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('tags', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'[]'::jsonb"), nullable=True),
    sa.Column('settings', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'active'::character varying"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('created_by', sa.String(length=255), nullable=True),
    sa.Column('temporal_namespace_id', sa.UUID(), nullable=True),
    sa.Column('worker_token', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=True),
    sa.Column('provisioning_workflow_id', sa.String(length=255), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('provisioned_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('execution_environment', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=False),
    sa.Column('policy_ids', sa.ARRAY(sa.String(length=255)), server_default=sa.text("'{}'::character varying[]"), nullable=True),
    sa.CheckConstraint("status::text = ANY (ARRAY['pending'::character varying, 'provisioning'::character varying, 'ready'::character varying, 'active'::character varying, 'inactive'::character varying, 'error'::character varying, 'archived'::character varying]::text[])", name='task_queues_status_check'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('organization_id', 'name', name='unique_queue_name_per_org')
    )
    op.create_index('idx_environments_execution_environment', 'environments', ['execution_environment'], unique=False, postgresql_using='gin')
    op.create_index('idx_environments_policy_ids', 'environments', ['policy_ids'], unique=False, postgresql_using='gin')
    op.create_index('idx_task_queues_name', 'environments', ['organization_id', 'name'], unique=False)
    op.create_index('idx_task_queues_namespace', 'environments', ['temporal_namespace_id'], unique=False)
    op.create_index('idx_task_queues_org', 'environments', ['organization_id'], unique=False)
    op.create_index('idx_task_queues_status', 'environments', ['organization_id', 'status'], unique=False, postgresql_where=sa.text("status::text = 'active'::text"))
    op.create_index('idx_task_queues_worker_token', 'environments', ['worker_token'], unique=False)
    op.create_table('llm_models',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('value', sa.String(), nullable=False),
    sa.Column('label', sa.String(), nullable=False),
    sa.Column('provider', sa.String(), nullable=False),
    sa.Column('logo', sa.String(), nullable=True),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('enabled', sa.Boolean(), nullable=False),
    sa.Column('recommended', sa.Boolean(), nullable=False),
    sa.Column('compatible_runtimes', sa.JSON(), nullable=False),
    sa.Column('capabilities', sa.JSON(), nullable=False),
    sa.Column('pricing', sa.JSON(), nullable=True),
    sa.Column('display_order', sa.Integer(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.Column('created_by', sa.String(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_llm_models_enabled'), 'llm_models', ['enabled'], unique=False)
    op.create_index(op.f('ix_llm_models_provider'), 'llm_models', ['provider'], unique=False)
    op.create_index(op.f('ix_llm_models_value'), 'llm_models', ['value'], unique=True)
    op.create_table('namespaces',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('namespace_name', sa.String(length=255), nullable=False),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'provisioning'::character varying"), nullable=False),
    sa.Column('temporal_host', sa.String(length=255), nullable=True),
    sa.Column('api_key_encrypted', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('namespace_name', name='namespaces_namespace_name_key')
    )
    op.create_index('idx_namespaces_organization_id', 'namespaces', ['organization_id'], unique=False)
    op.create_index('idx_namespaces_status', 'namespaces', ['status'], unique=False)
    op.create_table('orchestration_servers',
    sa.Column('id', sa.Text(), server_default=sa.text('(gen_random_uuid())::text'), nullable=False),
    sa.Column('user_id', sa.Text(), nullable=True),
    sa.Column('organization_id', sa.Text(), nullable=True),
    sa.Column('name', sa.Text(), nullable=False),
    sa.Column('endpoint', sa.Text(), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('config', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('health_check_interval_seconds', sa.Integer(), server_default=sa.text('60'), nullable=True),
    sa.Column('is_active', sa.Boolean(), server_default=sa.text('true'), nullable=True),
    sa.Column('is_default', sa.Boolean(), server_default=sa.text('false'), nullable=True),
    sa.Column('scope', sa.Text(), server_default=sa.text("'user'::text"), nullable=False),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_orchestration_servers_is_active', 'orchestration_servers', ['is_active'], unique=False)
    op.create_index('idx_orchestration_servers_is_default', 'orchestration_servers', ['is_default'], unique=False)
    op.create_index('idx_orchestration_servers_scope', 'orchestration_servers', ['scope'], unique=False)
    op.create_index('idx_orchestration_servers_user_id', 'orchestration_servers', ['user_id'], unique=False)
    op.create_table('profiles',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('email', sa.Text(), nullable=False),
    sa.Column('full_name', sa.Text(), nullable=True),
    sa.Column('avatar_url', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('email')
    )
    op.create_index('idx_profiles_email', 'profiles', ['email'], unique=False)
    op.create_table('policy_associations',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('policy_id', sa.String(length=255), nullable=False),
    sa.Column('policy_name', sa.String(length=255), nullable=False),
    sa.Column('entity_type', sa.String(length=50), nullable=False),
    sa.Column('entity_id', sa.UUID(), nullable=False),
    sa.Column('enabled', sa.Boolean(), server_default=sa.text('true'), nullable=True),
    sa.Column('priority', sa.Integer(), server_default=sa.text('0'), nullable=True),
    sa.Column('metadata', sa.JSON(), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
    sa.Column('created_by', sa.String(length=255), nullable=True),
    sa.CheckConstraint("entity_type IN ('agent', 'team', 'environment')", name='policy_associations_entity_type_check'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('policy_id', 'entity_type', 'entity_id', name='unique_policy_association'),
    schema='public'
    )
    op.create_index('idx_policy_assoc_enabled', 'policy_associations', ['enabled'], unique=False, schema='public')
    op.create_index('idx_policy_assoc_entity', 'policy_associations', ['entity_type', 'entity_id'], unique=False, schema='public')
    op.create_index('idx_policy_assoc_entity_enabled', 'policy_associations', ['entity_type', 'entity_id', 'enabled', 'priority'], unique=False, schema='public', postgresql_ops={'priority': 'DESC'})
    op.create_index('idx_policy_assoc_org', 'policy_associations', ['organization_id'], unique=False, schema='public')
    op.create_index('idx_policy_assoc_policy', 'policy_associations', ['policy_id'], unique=False, schema='public')
    op.create_index('idx_policy_assoc_priority', 'policy_associations', ['priority'], unique=False, schema='public', postgresql_ops={'priority': 'DESC'})
    op.create_table('sessions',
    sa.Column('execution_id', sa.Text(), nullable=False),
    sa.Column('session_id', sa.Text(), nullable=False),
    sa.Column('organization_id', sa.Text(), nullable=False),
    sa.Column('user_id', sa.Text(), nullable=True),
    sa.Column('messages', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'[]'::jsonb"), nullable=False),
    sa.Column('metadata', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.PrimaryKeyConstraint('execution_id')
    )
    op.create_index('idx_sessions_organization_id', 'sessions', ['organization_id'], unique=False)
    op.create_index('idx_sessions_session_id', 'sessions', ['session_id'], unique=False)
    op.create_index('idx_sessions_updated_at', 'sessions', ['updated_at'], unique=False, postgresql_ops={'updated_at': 'DESC'})
    op.create_table('skills',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('skill_type', sa.String(length=50), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('icon', sa.String(length=50), server_default=sa.text("'Tool'::character varying"), nullable=True),
    sa.Column('enabled', sa.Boolean(), server_default=sa.text('true'), nullable=True),
    sa.Column('configuration', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
    sa.CheckConstraint("skill_type IN ('file_system', 'shell', 'python', 'docker', 'sleep', 'file_generation', 'data_visualization', 'workflow_executor', 'custom')", name='toolsets_type_check'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('organization_id', 'name', name='unique_toolset_per_org')
    )
    op.create_index('idx_skills_enabled', 'skills', ['enabled'], unique=False)
    op.create_index('idx_skills_type', 'skills', ['skill_type'], unique=False)
    op.create_index(op.f('ix_skills_organization_id'), 'skills', ['organization_id'], unique=False)
    op.create_table('slash_commands',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('command', sa.Text(), nullable=False),
    sa.Column('workflow_id', sa.Text(), nullable=False),
    sa.Column('workflow_name', sa.Text(), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('enabled', sa.Boolean(), nullable=True),
    sa.Column('runner', sa.Text(), nullable=True),
    sa.Column('args', sa.JSON(), nullable=True),
    sa.Column('user_id', sa.Text(), nullable=False),
    sa.Column('project_id', sa.Text(), nullable=False),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('last_used', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_slash_commands_user_id'), 'slash_commands', ['user_id'], unique=False)
    op.create_table('temporal_namespaces',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('namespace_name', sa.String(length=255), nullable=False),
    sa.Column('account_id', sa.String(length=255), nullable=True),
    sa.Column('region', sa.String(length=50), server_default=sa.text("'aws-us-east-1'::character varying"), nullable=True),
    sa.Column('api_key_encrypted', sa.Text(), nullable=True),
    sa.Column('certificate_encrypted', sa.Text(), nullable=True),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'pending'::character varying"), nullable=True),
    sa.Column('provisioning_workflow_id', sa.String(length=255), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('provisioned_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_by', sa.String(length=255), nullable=True),
    sa.CheckConstraint("status::text = ANY (ARRAY['pending'::character varying, 'provisioning'::character varying, 'ready'::character varying, 'error'::character varying, 'archived'::character varying]::text[])", name='temporal_namespaces_status_check'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_temporal_namespaces_organization_id', 'temporal_namespaces', ['organization_id'], unique=False)
    op.create_index('idx_temporal_namespaces_status', 'temporal_namespaces', ['status'], unique=False)
    op.create_table('user_presence',
    sa.Column('id', sa.String(), nullable=False),
    sa.Column('user_id', sa.String(), nullable=False),
    sa.Column('user_email', sa.String(), nullable=True),
    sa.Column('user_name', sa.String(), nullable=True),
    sa.Column('user_avatar', sa.String(), nullable=True),
    sa.Column('agent_id', sa.String(), nullable=True),
    sa.Column('session_id', sa.String(), nullable=True),
    sa.Column('execution_id', sa.String(), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('is_typing', sa.Boolean(), nullable=False),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('last_active_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_presence_lookup', 'user_presence', ['agent_id', 'is_active', 'last_active_at'], unique=False)
    op.create_index('idx_presence_user', 'user_presence', ['user_id', 'is_active'], unique=False)
    op.create_index(op.f('ix_user_presence_agent_id'), 'user_presence', ['agent_id'], unique=False)
    op.create_index(op.f('ix_user_presence_execution_id'), 'user_presence', ['execution_id'], unique=False)
    op.create_index(op.f('ix_user_presence_session_id'), 'user_presence', ['session_id'], unique=False)
    op.create_index(op.f('ix_user_presence_user_id'), 'user_presence', ['user_id'], unique=False)
    op.create_table('workspaces',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('slug', sa.Text(), nullable=True),
    sa.Column('logo_url', sa.Text(), nullable=True),
    sa.Column('created_by', sa.UUID(), nullable=True),
    sa.Column('owner_email', sa.Text(), nullable=True),
    sa.Column('type', sa.Text(), server_default=sa.text("'hobby'::text"), nullable=False),
    sa.Column('settings', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('member_count', sa.Integer(), server_default=sa.text('1'), nullable=True),
    sa.Column('stripe_customer_id', sa.Text(), nullable=True),
    sa.Column('stripe_subscription_id', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.CheckConstraint("type = ANY (ARRAY['hobby'::text, 'enterprise'::text])", name='workspaces_type_check'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('environment_contexts',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('environment_id', sa.UUID(), nullable=False),
    sa.Column('entity_type', sa.String(length=50), server_default=sa.text("'environment'::character varying"), nullable=True),
    sa.Column('organization_id', sa.UUID(), nullable=False),
    sa.Column('knowledge_uuids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('resource_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('policy_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('environment_id', 'organization_id', name='environment_contexts_environment_id_organization_id_key')
    )
    op.create_index('idx_environment_contexts_environment_id', 'environment_contexts', ['environment_id'], unique=False)
    op.create_index('idx_environment_contexts_org_id', 'environment_contexts', ['organization_id'], unique=False)
    op.create_table('orchestration_server_health',
    sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
    sa.Column('server_id', sa.Text(), nullable=False),
    sa.Column('status', sa.Text(), nullable=False),
    sa.Column('response_time_ms', sa.Integer(), nullable=True),
    sa.Column('checked_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.CheckConstraint("status IN ('healthy', 'degraded', 'unhealthy')", name='orchestration_server_health_status_check'),
    sa.ForeignKeyConstraint(['server_id'], ['orchestration_servers.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_orchestration_server_health_checked_at', 'orchestration_server_health', [sa.literal_column('checked_at DESC')], unique=False)
    op.create_index('idx_orchestration_server_health_server_id', 'orchestration_server_health', ['server_id'], unique=False)
    op.create_table('projects',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('key', sa.String(length=50), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('settings', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'active'::character varying"), nullable=True),
    sa.Column('visibility', sa.String(length=20), server_default=sa.text("'private'::character varying"), nullable=True),
    sa.Column('owner_id', sa.String(length=255), nullable=True),
    sa.Column('owner_email', sa.String(length=255), nullable=True),
    sa.Column('environment_id', sa.UUID(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('archived_at', sa.DateTime(timezone=True), nullable=True),
    sa.CheckConstraint("status IN ('active', 'archived', 'draft')", name='projects_status_check'),
    sa.CheckConstraint("visibility IN ('private', 'org')", name='projects_visibility_check'),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='SET NULL'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('organization_id', 'key', name='unique_project_key_per_org'),
    sa.UniqueConstraint('organization_id', 'name', name='unique_project_name_per_org')
    )
    op.create_index('idx_projects_environment_id', 'projects', ['environment_id'], unique=False)
    op.create_index('idx_projects_org_id', 'projects', ['organization_id'], unique=False)
    op.create_index('idx_projects_owner', 'projects', ['owner_id'], unique=False)
    op.create_index('idx_projects_status', 'projects', ['status'], unique=False, postgresql_where=sa.text("status = 'active'"))
    op.create_index('idx_projects_visibility', 'projects', ['organization_id', 'visibility'], unique=False)
    op.create_table('skill_associations',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('skill_id', sa.UUID(), nullable=False),
    sa.Column('entity_type', sa.String(length=50), nullable=False),
    sa.Column('entity_id', sa.UUID(), nullable=False),
    sa.Column('configuration_override', sa.JSON(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.CheckConstraint("entity_type IN ('agent', 'team', 'environment')", name='toolset_associations_entity_type_check'),
    sa.ForeignKeyConstraint(['skill_id'], ['skills.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('skill_id', 'entity_type', 'entity_id', name='unique_skill_entity')
    )
    op.create_index('ix_skill_associations_entity', 'skill_associations', ['entity_type', 'entity_id'], unique=False)
    op.create_index('ix_skill_associations_org_skill', 'skill_associations', ['organization_id', 'skill_id'], unique=False)
    op.create_index(op.f('ix_skill_associations_organization_id'), 'skill_associations', ['organization_id'], unique=False)
    op.create_index('ix_skill_associations_skill_id', 'skill_associations', ['skill_id'], unique=False)
    op.create_table('slash_command_executions',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('command_id', sa.UUID(), nullable=False),
    sa.Column('args', sa.JSON(), nullable=True),
    sa.Column('workflow_id', sa.Text(), nullable=False),
    sa.Column('task_id', sa.UUID(), nullable=False),
    sa.Column('status', sa.Text(), nullable=False),
    sa.Column('started_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('error', sa.Text(), nullable=True),
    sa.Column('user_id', sa.Text(), nullable=False),
    sa.ForeignKeyConstraint(['command_id'], ['slash_commands.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('ix_slash_command_executions_command_id', 'slash_command_executions', ['command_id'], unique=False)
    op.create_index('ix_slash_command_executions_user_id', 'slash_command_executions', ['user_id'], unique=False)
    op.create_table('teams',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'idle'::character varying"), nullable=True),
    sa.Column('coordination_type', sa.String(length=50), server_default=sa.text("'sequential'::character varying"), nullable=True),
    sa.Column('configuration', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('last_active_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('state', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('visibility', sa.String(length=20), server_default=sa.text("'private'::character varying"), nullable=True),
    sa.Column('environment_id', sa.UUID(), nullable=True),
    sa.Column('skill_ids', sa.ARRAY(sa.UUID()), server_default=sa.text("'{}'::uuid[]"), nullable=True),
    sa.Column('execution_environment', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=False),
    sa.Column('policy_ids', sa.ARRAY(sa.String(length=255)), server_default=sa.text("'{}'::character varying[]"), nullable=True),
    sa.Column('runtime', sa.Enum('default', 'claude_code', name='runtimetype'), server_default='default', nullable=False),
    sa.Column('model_id', sa.String(), nullable=True),
    sa.CheckConstraint("visibility IN ('private', 'org')", name='teams_visibility_check'),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='SET NULL'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('organization_id', 'name', name='teams_organization_id_name_key'),
    sa.UniqueConstraint('organization_id', 'name', name='uq_team_org_name')
    )
    op.create_index('idx_teams_environment_id', 'teams', ['environment_id'], unique=False)
    op.create_index('idx_teams_execution_environment', 'teams', ['execution_environment'], unique=False, postgresql_using='gin')
    op.create_index('idx_teams_org', 'teams', ['organization_id'], unique=False)
    op.create_index('idx_teams_policy_ids', 'teams', ['policy_ids'], unique=False, postgresql_using='gin')
    op.create_index('idx_teams_status', 'teams', ['status'], unique=False)
    op.create_index('idx_teams_toolset_ids', 'teams', ['skill_ids'], unique=False, postgresql_using='gin')
    op.create_index('idx_teams_visibility', 'teams', ['organization_id', 'visibility'], unique=False)
    op.create_index('ix_teams_runtime', 'teams', ['runtime'], unique=False)
    op.create_table('user_profiles',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('email', sa.Text(), nullable=False),
    sa.Column('name', sa.Text(), nullable=True),
    sa.Column('first_name', sa.Text(), nullable=True),
    sa.Column('last_name', sa.Text(), nullable=True),
    sa.Column('avatar_url', sa.Text(), nullable=True),
    sa.Column('auth0_id', sa.Text(), nullable=True),
    sa.Column('workspace_type', sa.Text(), nullable=True),
    sa.Column('primary_workspace_id', sa.UUID(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.CheckConstraint("workspace_type = ANY (ARRAY['hobby'::text, 'enterprise'::text])", name='user_profiles_workspace_type_check'),
    sa.ForeignKeyConstraint(['primary_workspace_id'], ['workspaces.id'], ondelete='SET NULL'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('worker_queues',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.Text(), nullable=False),
    sa.Column('environment_id', sa.UUID(), nullable=False),
    sa.Column('name', sa.Text(), nullable=False),
    sa.Column('display_name', sa.Text(), nullable=True),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('status', sa.Text(), server_default=sa.text("'active'::text"), nullable=False),
    sa.Column('max_workers', sa.Integer(), nullable=True),
    sa.Column('heartbeat_interval', sa.Integer(), server_default=sa.text('30'), nullable=True),
    sa.Column('tags', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('settings', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('created_by', sa.Text(), nullable=True),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('environment_id', 'name', name='worker_queues_environment_id_name_key')
    )
    op.create_index('idx_worker_queues_env', 'worker_queues', ['environment_id'], unique=False)
    op.create_index('idx_worker_queues_org', 'worker_queues', ['organization_id'], unique=False)
    op.create_index('idx_worker_queues_status', 'worker_queues', ['status'], unique=False)
    op.create_table('workers',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('task_queue_id', sa.UUID(), nullable=False),
    sa.Column('worker_name', sa.String(length=255), nullable=True),
    sa.Column('worker_token', sa.UUID(), nullable=False),
    sa.Column('worker_id', sa.String(length=255), nullable=True),
    sa.Column('capabilities', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('environment', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('metadata', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'registered'::character varying"), nullable=True),
    sa.Column('last_seen_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('registered_by', sa.String(length=255), nullable=True),
    sa.CheckConstraint("status IN ('registered', 'active', 'inactive', 'offline', 'error')", name='workers_status_check'),
    sa.ForeignKeyConstraint(['task_queue_id'], ['environments.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('worker_token', name='unique_worker_token')
    )
    op.create_index('idx_workers_org', 'workers', ['organization_id'], unique=False)
    op.create_index('idx_workers_status', 'workers', ['organization_id', 'status'], unique=False)
    op.create_index('idx_workers_task_queue', 'workers', ['task_queue_id'], unique=False)
    op.create_index('idx_workers_token', 'workers', ['worker_token'], unique=False)
    op.create_table('agents',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('status', sa.String(length=50), server_default='idle', nullable=True),
    sa.Column('capabilities', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'[]'::jsonb"), nullable=True),
    sa.Column('configuration', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('model_id', sa.String(length=100), nullable=True),
    sa.Column('model_config', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('team_id', sa.UUID(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('last_active_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('state', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('runner_name', sa.String(length=100), nullable=True),
    sa.Column('visibility', sa.String(length=20), server_default='private', nullable=True),
    sa.Column('project_id', sa.UUID(), nullable=True),
    sa.Column('environment_id', sa.UUID(), nullable=True),
    sa.Column('toolset_ids', postgresql.ARRAY(sa.UUID()), server_default=sa.text("'{}'::uuid[]"), nullable=True),
    sa.Column('runtime', sa.String(length=50), server_default='default', nullable=False),
    sa.Column('execution_environment', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=False),
    sa.Column('policy_ids', postgresql.ARRAY(sa.String(length=255)), server_default=sa.text("'{}'::character varying[]"), nullable=True),
    sa.CheckConstraint("runtime IN ('default', 'claude_code')", name='chk_agents_runtime'),
    sa.CheckConstraint("visibility IN ('private', 'org')", name='agents_visibility_check'),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='SET NULL'),
    sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='SET NULL'),
    sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ondelete='SET NULL'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('organization_id', 'name', name='agents_organization_id_name_key')
    )
    op.create_index('idx_agents_environment_id', 'agents', ['environment_id'], unique=False)
    op.create_index('idx_agents_execution_environment', 'agents', ['execution_environment'], unique=False, postgresql_using='gin')
    op.create_index('idx_agents_org', 'agents', ['organization_id'], unique=False)
    op.create_index('idx_agents_org_runtime', 'agents', ['organization_id', 'runtime'], unique=False)
    op.create_index('idx_agents_policy_ids', 'agents', ['policy_ids'], unique=False, postgresql_using='gin')
    op.create_index('idx_agents_project_id', 'agents', ['project_id'], unique=False)
    op.create_index('idx_agents_runtime', 'agents', ['runtime'], unique=False)
    op.create_index('idx_agents_status', 'agents', ['status'], unique=False)
    op.create_index('idx_agents_team', 'agents', ['team_id'], unique=False)
    op.create_index('idx_agents_team_id', 'agents', ['team_id'], unique=False)
    op.create_index('idx_agents_toolset_ids', 'agents', ['toolset_ids'], unique=False, postgresql_using='gin')
    op.create_index('idx_agents_visibility', 'agents', ['organization_id', 'visibility'], unique=False)
    op.create_table('executions',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('execution_type', sa.String(length=50), nullable=False),
    sa.Column('entity_id', sa.UUID(), nullable=False),
    sa.Column('entity_name', sa.String(length=255), nullable=True),
    sa.Column('runner_name', sa.String(length=100), nullable=False),
    sa.Column('user_id', sa.String(length=255), nullable=True),
    sa.Column('user_email', sa.String(length=255), nullable=True),
    sa.Column('user_name', sa.String(length=255), nullable=True),
    sa.Column('user_avatar', sa.Text(), nullable=True),
    sa.Column('trigger_source', sa.Enum('user', 'job_cron', 'job_webhook', 'job_manual', 'system', 'api', 'chat', name='executiontriggersource'), server_default='user', nullable=False),
    sa.Column('trigger_metadata', sa.JSON(), nullable=True),
    sa.Column('prompt', sa.Text(), nullable=False),
    sa.Column('system_prompt', sa.Text(), nullable=True),
    sa.Column('config', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=True),
    sa.Column('response', sa.Text(), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('temporal_workflow_id', sa.String(length=255), nullable=True),
    sa.Column('temporal_run_id', sa.String(length=255), nullable=True),
    sa.Column('task_queue_name', sa.String(length=100), nullable=True),
    sa.Column('usage', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('execution_metadata', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('worker_queue_id', sa.UUID(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('started_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.ForeignKeyConstraint(['worker_queue_id'], ['worker_queues.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('temporal_workflow_id')
    )
    op.create_index('idx_executions_created', 'executions', [sa.literal_column('created_at DESC')], unique=False)
    op.create_index('idx_executions_entity', 'executions', ['entity_id'], unique=False)
    op.create_index('idx_executions_org', 'executions', ['organization_id'], unique=False)
    op.create_index('idx_executions_run', 'executions', ['temporal_run_id'], unique=False, postgresql_where='temporal_run_id IS NOT NULL')
    op.create_index('idx_executions_runner', 'executions', ['runner_name'], unique=False)
    op.create_index('idx_executions_status', 'executions', ['status'], unique=False)
    op.create_index('idx_executions_task_queue', 'executions', ['task_queue_name'], unique=False)
    op.create_index('idx_executions_user', 'executions', ['user_id'], unique=False)
    op.create_index('idx_executions_user_email', 'executions', ['user_email'], unique=False)
    op.create_index('idx_executions_user_id', 'executions', ['user_id'], unique=False)
    op.create_index('idx_executions_worker_queue_id', 'executions', ['worker_queue_id'], unique=False)
    op.create_index('idx_executions_workflow', 'executions', ['temporal_workflow_id'], unique=False, postgresql_where='temporal_workflow_id IS NOT NULL')
    op.create_index(op.f('ix_executions_organization_id'), 'executions', ['organization_id'], unique=False)
    op.create_index(op.f('ix_executions_trigger_source'), 'executions', ['trigger_source'], unique=False)
    op.create_index(op.f('ix_executions_user_id'), 'executions', ['user_id'], unique=False)
    op.create_index(op.f('ix_executions_worker_queue_id'), 'executions', ['worker_queue_id'], unique=False)
    op.create_table('project_contexts',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('project_id', sa.UUID(), nullable=False),
    sa.Column('entity_type', sa.String(length=50), server_default=sa.text("'project'::character varying"), nullable=True),
    sa.Column('organization_id', sa.UUID(), nullable=False),
    sa.Column('knowledge_uuids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('resource_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('policy_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('project_id', 'organization_id', name='project_contexts_project_id_organization_id_key')
    )
    op.create_index('idx_project_contexts_org_id', 'project_contexts', ['organization_id'], unique=False)
    op.create_index('idx_project_contexts_project_id', 'project_contexts', ['project_id'], unique=False)
    op.create_table('project_teams',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('project_id', sa.UUID(), nullable=False),
    sa.Column('team_id', sa.UUID(), nullable=False),
    sa.Column('role', sa.String(length=50), nullable=True),
    sa.Column('added_by', sa.String(length=255), nullable=True),
    sa.Column('added_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('project_id', 'team_id', name='unique_project_team')
    )
    op.create_index('idx_project_teams_project', 'project_teams', ['project_id'], unique=False)
    op.create_index('idx_project_teams_team', 'project_teams', ['team_id'], unique=False)
    op.create_table('team_contexts',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('team_id', sa.UUID(), nullable=False),
    sa.Column('entity_type', sa.String(length=50), server_default=sa.text("'team'::character varying"), nullable=True),
    sa.Column('organization_id', sa.UUID(), nullable=False),
    sa.Column('knowledge_uuids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('resource_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('policy_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('team_id', 'organization_id', name='team_contexts_team_id_organization_id_key')
    )
    op.create_index('idx_team_contexts_org_id', 'team_contexts', ['organization_id'], unique=False)
    op.create_index('idx_team_contexts_team_id', 'team_contexts', ['team_id'], unique=False)
    op.create_table('team_environments',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('team_id', sa.UUID(), nullable=False),
    sa.Column('environment_id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(), nullable=False),
    sa.Column('assigned_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
    sa.Column('assigned_by', sa.String(), nullable=True),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('team_id', 'environment_id', name='uq_team_environment')
    )
    op.create_index('idx_team_environments_environment_id', 'team_environments', ['environment_id'], unique=False)
    op.create_index('idx_team_environments_org_env', 'team_environments', ['organization_id', 'environment_id'], unique=False)
    op.create_index('idx_team_environments_org_id', 'team_environments', ['organization_id'], unique=False)
    op.create_index('idx_team_environments_team_id', 'team_environments', ['team_id'], unique=False)
    op.create_table('worker_heartbeats',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('worker_id', sa.String(length=255), nullable=False),
    sa.Column('hostname', sa.String(length=255), nullable=True),
    sa.Column('worker_metadata', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('last_heartbeat', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'active'::character varying"), nullable=True),
    sa.Column('tasks_processed', sa.Integer(), server_default=sa.text('0'), nullable=True),
    sa.Column('current_task_id', sa.UUID(), nullable=True),
    sa.Column('registered_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('worker_registration_id', sa.UUID(), nullable=True),
    sa.Column('worker_queue_id', sa.UUID(), nullable=True),
    sa.Column('environment_name', sa.String(length=255), nullable=True),
    sa.Column('worker_token', sa.UUID(), nullable=True),
    sa.CheckConstraint("status IN ('active', 'idle', 'busy', 'offline')", name='worker_heartbeats_status_check'),
    sa.ForeignKeyConstraint(['worker_queue_id'], ['worker_queues.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['worker_registration_id'], ['workers.id'], ondelete='SET NULL'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('organization_id', 'worker_id', name='unique_worker_instance')
    )
    op.create_index('idx_worker_heartbeats_environment', 'worker_heartbeats', ['organization_id', 'environment_name'], unique=False)
    op.create_index('idx_worker_heartbeats_last_heartbeat', 'worker_heartbeats', ['last_heartbeat'], unique=False)
    op.create_index('idx_worker_heartbeats_org', 'worker_heartbeats', ['organization_id'], unique=False)
    op.create_index('idx_worker_heartbeats_org_status', 'worker_heartbeats', ['organization_id', 'status'], unique=False)
    op.create_index('idx_worker_heartbeats_org_status_heartbeat', 'worker_heartbeats', ['organization_id', 'status', sa.literal_column('last_heartbeat DESC')], unique=False)
    op.create_index('idx_worker_heartbeats_queue', 'worker_heartbeats', ['worker_queue_id'], unique=False)
    op.create_index('idx_worker_heartbeats_queue_status_heartbeat', 'worker_heartbeats', ['worker_queue_id', 'status', sa.literal_column('last_heartbeat DESC')], unique=False)
    op.create_index('idx_worker_heartbeats_status', 'worker_heartbeats', ['organization_id', 'status'], unique=False)
    op.create_index('idx_worker_heartbeats_token', 'worker_heartbeats', ['worker_token'], unique=False)
    op.create_table('workflows',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('workspace_id', sa.UUID(), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('slug', sa.String(length=255), nullable=True),
    sa.Column('definition', postgresql.JSONB(astext_type=sa.Text()), nullable=False),
    sa.Column('definition_format', sa.String(length=10), server_default=sa.text("'json'::character varying"), nullable=True),
    sa.Column('status', sa.String(length=50), server_default=sa.text("'draft'::character varying"), nullable=True),
    sa.Column('trigger_type', sa.String(length=50), nullable=True),
    sa.Column('trigger_config', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('upstash_schedule_id', sa.String(length=255), nullable=True),
    sa.Column('upstash_webhook_id', sa.String(length=255), nullable=True),
    sa.Column('created_by', sa.UUID(), nullable=True),
    sa.Column('updated_by', sa.UUID(), nullable=True),
    sa.Column('published_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('is_test', sa.Boolean(), server_default=sa.text('false'), nullable=True),
    sa.Column('expires_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('owner_id', sa.Text(), nullable=True),
    sa.Column('owner_email', sa.Text(), nullable=True),
    sa.Column('version', sa.Integer(), server_default=sa.text('1'), nullable=True),
    sa.Column('tags', postgresql.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('metadata', postgresql.JSONB(astext_type=sa.Text()), server_default=sa.text("'{}'::jsonb"), nullable=True),
    sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.CheckConstraint("definition_format::text = ANY (ARRAY['json'::character varying::text, 'yaml'::character varying::text])", name='workflows_definition_format_check'),
    sa.CheckConstraint("status::text = ANY (ARRAY['draft'::character varying::text, 'published'::character varying::text, 'archived'::character varying::text])", name='workflows_status_check'),
    sa.CheckConstraint("trigger_type::text = ANY (ARRAY['manual'::character varying::text, 'webhook'::character varying::text, 'schedule'::character varying::text])", name='workflows_trigger_type_check'),
    sa.ForeignKeyConstraint(['created_by'], ['user_profiles.id'], ondelete='SET NULL'),
    sa.ForeignKeyConstraint(['updated_by'], ['user_profiles.id'], ondelete='SET NULL'),
    sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('slug', name='workflows_slug_key'),
    sa.UniqueConstraint('workspace_id', 'slug', name='unique_workflow_slug_per_workspace')
    )
    op.create_index('idx_workflows_is_test_expires', 'workflows', ['is_test', 'expires_at'], unique=False, postgresql_where=sa.text('is_test = true AND expires_at IS NOT NULL'))
    op.create_index('idx_workflows_slug', 'workflows', ['slug'], unique=False)
    op.create_index('idx_workflows_status', 'workflows', ['status'], unique=False)
    op.create_index('idx_workflows_workspace_id', 'workflows', ['workspace_id'], unique=False)
    op.create_table('agent_contexts',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('agent_id', sa.UUID(), nullable=False),
    sa.Column('entity_type', sa.String(length=50), server_default=sa.text("'agent'::character varying"), nullable=True),
    sa.Column('organization_id', sa.UUID(), nullable=False),
    sa.Column('knowledge_uuids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('resource_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('policy_ids', sa.ARRAY(sa.Text()), server_default=sa.text("'{}'::text[]"), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.ForeignKeyConstraint(['agent_id'], ['agents.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('agent_id', 'organization_id', name='agent_contexts_agent_id_organization_id_key')
    )
    op.create_index('idx_agent_contexts_agent_id', 'agent_contexts', ['agent_id'], unique=False)
    op.create_index('idx_agent_contexts_org_id', 'agent_contexts', ['organization_id'], unique=False)
    op.create_table('agent_environments',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('agent_id', sa.UUID(), nullable=False),
    sa.Column('environment_id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(), nullable=False),
    sa.Column('assigned_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
    sa.Column('assigned_by', sa.String(), nullable=True),
    sa.ForeignKeyConstraint(['agent_id'], ['agents.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['environment_id'], ['environments.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('agent_id', 'environment_id', name='uq_agent_environment')
    )
    op.create_index('idx_agent_environments_agent_id', 'agent_environments', ['agent_id'], unique=False)
    op.create_index('idx_agent_environments_environment_id', 'agent_environments', ['environment_id'], unique=False)
    op.create_index('idx_agent_environments_org_env', 'agent_environments', ['organization_id', 'environment_id'], unique=False)
    op.create_index('idx_agent_environments_org_id', 'agent_environments', ['organization_id'], unique=False)
    op.create_table('execution_participants',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('execution_id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(), nullable=False),
    sa.Column('user_id', sa.String(), nullable=False),
    sa.Column('user_email', sa.String(), nullable=True),
    sa.Column('user_name', sa.String(), nullable=True),
    sa.Column('user_avatar', sa.String(), nullable=True),
    sa.Column('role', sa.Enum('owner', 'collaborator', 'viewer', name='participant_role'), server_default='collaborator', nullable=False),
    sa.Column('joined_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('last_active_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.ForeignKeyConstraint(['execution_id'], ['executions.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('execution_id', 'user_id', name='unique_execution_user')
    )
    op.create_index('idx_execution_participants_execution', 'execution_participants', ['execution_id'], unique=False)
    op.create_index('idx_execution_participants_org', 'execution_participants', ['organization_id'], unique=False)
    op.create_index('idx_execution_participants_user', 'execution_participants', ['user_id'], unique=False)
    op.create_table('execution_tasks',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(), nullable=False),
    sa.Column('execution_id', sa.UUID(), nullable=False),
    sa.Column('task_number', sa.Integer(), nullable=True),
    sa.Column('task_id', sa.String(), nullable=True),
    sa.Column('task_description', sa.Text(), nullable=False),
    sa.Column('task_type', sa.String(), nullable=True),
    sa.Column('status', sa.String(), server_default=sa.text("'pending'::character varying"), nullable=False),
    sa.Column('started_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('duration_ms', sa.Integer(), nullable=True),
    sa.Column('result', sa.Text(), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('custom_metadata', sa.JSON(), server_default=sa.text("'{}'::json"), nullable=False),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.ForeignKeyConstraint(['execution_id'], ['executions.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_execution_tasks_execution_id'), 'execution_tasks', ['execution_id'], unique=False)
    op.create_index('ix_execution_tasks_org_execution', 'execution_tasks', ['organization_id', 'execution_id'], unique=False)
    op.create_index('ix_execution_tasks_org_status', 'execution_tasks', ['organization_id', 'status'], unique=False)
    op.create_index(op.f('ix_execution_tasks_organization_id'), 'execution_tasks', ['organization_id'], unique=False)
    op.create_table('execution_turns',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(), nullable=False),
    sa.Column('execution_id', sa.UUID(), nullable=False),
    sa.Column('turn_number', sa.Integer(), nullable=False),
    sa.Column('turn_id', sa.String(), nullable=True),
    sa.Column('model', sa.String(), nullable=False),
    sa.Column('model_provider', sa.String(), nullable=True),
    sa.Column('started_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('duration_ms', sa.Integer(), nullable=True),
    sa.Column('input_tokens', sa.Integer(), server_default=sa.text('0'), nullable=True),
    sa.Column('output_tokens', sa.Integer(), server_default=sa.text('0'), nullable=True),
    sa.Column('cache_read_tokens', sa.Integer(), server_default=sa.text('0'), nullable=True),
    sa.Column('cache_creation_tokens', sa.Integer(), server_default=sa.text('0'), nullable=True),
    sa.Column('total_tokens', sa.Integer(), server_default=sa.text('0'), nullable=True),
    sa.Column('input_cost', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('output_cost', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('cache_read_cost', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('cache_creation_cost', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('total_cost', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('runtime_minutes', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('model_weight', sa.Float(), server_default=sa.text('1'), nullable=True),
    sa.Column('tool_calls_weight', sa.Float(), server_default=sa.text('1'), nullable=True),
    sa.Column('aem_value', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('aem_cost', sa.Float(), server_default=sa.text('0'), nullable=True),
    sa.Column('finish_reason', sa.String(), nullable=True),
    sa.Column('response_preview', sa.Text(), nullable=True),
    sa.Column('tools_called_count', sa.Integer(), server_default=sa.text('0'), nullable=False),
    sa.Column('tools_called_names', sa.JSON(), server_default=sa.text("'[]'::json"), nullable=False),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('metrics', sa.JSON(), server_default=sa.text("'{}'::json"), nullable=False),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.ForeignKeyConstraint(['execution_id'], ['executions.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_execution_turns_execution_id'), 'execution_turns', ['execution_id'], unique=False)
    op.create_index('ix_execution_turns_org_cost', 'execution_turns', ['organization_id', 'total_cost'], unique=False)
    op.create_index('ix_execution_turns_org_created', 'execution_turns', ['organization_id', 'created_at'], unique=False)
    op.create_index('ix_execution_turns_org_execution', 'execution_turns', ['organization_id', 'execution_id'], unique=False)
    op.create_index('ix_execution_turns_org_model', 'execution_turns', ['organization_id', 'model'], unique=False)
    op.create_index(op.f('ix_execution_turns_organization_id'), 'execution_turns', ['organization_id'], unique=False)
    op.create_table('jobs',
    sa.Column('id', sa.String(length=255), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('enabled', sa.Boolean(), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('trigger_type', sa.String(length=50), nullable=False),
    sa.Column('cron_schedule', sa.String(length=255), nullable=True),
    sa.Column('cron_timezone', sa.String(length=100), nullable=True),
    sa.Column('webhook_url_path', sa.String(length=500), nullable=True),
    sa.Column('webhook_secret', sa.String(length=500), nullable=True),
    sa.Column('temporal_schedule_id', sa.String(length=255), nullable=True),
    sa.Column('planning_mode', sa.String(length=50), nullable=False),
    sa.Column('entity_type', sa.String(length=50), nullable=True),
    sa.Column('entity_id', sa.String(length=255), nullable=True),
    sa.Column('entity_name', sa.String(length=255), nullable=True),
    sa.Column('prompt_template', sa.Text(), nullable=False),
    sa.Column('system_prompt', sa.Text(), nullable=True),
    sa.Column('executor_type', sa.String(length=50), nullable=False),
    sa.Column('worker_queue_name', sa.String(length=255), nullable=True),
    sa.Column('environment_name', sa.String(length=255), nullable=True),
    sa.Column('config', sa.JSON(), nullable=True),
    sa.Column('execution_environment', sa.JSON(), nullable=True),
    sa.Column('last_execution_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('next_execution_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('total_executions', sa.Integer(), nullable=False),
    sa.Column('successful_executions', sa.Integer(), nullable=False),
    sa.Column('failed_executions', sa.Integer(), nullable=False),
    sa.Column('execution_history', sa.JSON(), nullable=True),
    sa.Column('created_by', sa.String(length=255), nullable=True),
    sa.Column('updated_by', sa.String(length=255), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('last_triggered_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('last_execution_id', sa.UUID(), nullable=True),
    sa.ForeignKeyConstraint(['last_execution_id'], ['executions.id'], ondelete='SET NULL'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('temporal_schedule_id'),
    sa.UniqueConstraint('webhook_url_path')
    )
    op.create_index('idx_jobs_created_at', 'jobs', ['created_at'], unique=False)
    op.create_index('idx_jobs_enabled', 'jobs', ['enabled'], unique=False)
    op.create_index('idx_jobs_name', 'jobs', ['organization_id', 'name'], unique=False)
    op.create_index('idx_jobs_next_execution_at', 'jobs', ['next_execution_at'], unique=False)
    op.create_index('idx_jobs_organization_id', 'jobs', ['organization_id'], unique=False)
    op.create_index('idx_jobs_status', 'jobs', ['status'], unique=False)
    op.create_index('idx_jobs_temporal_schedule_id', 'jobs', ['temporal_schedule_id'], unique=False)
    op.create_index('idx_jobs_trigger_type', 'jobs', ['trigger_type'], unique=False)
    op.create_index('idx_jobs_webhook_url_path', 'jobs', ['webhook_url_path'], unique=False)
    op.create_table('project_agents',
    sa.Column('id', sa.UUID(), server_default=sa.text('gen_random_uuid()'), nullable=False),
    sa.Column('project_id', sa.UUID(), nullable=False),
    sa.Column('agent_id', sa.UUID(), nullable=False),
    sa.Column('role', sa.String(length=50), nullable=True),
    sa.Column('added_by', sa.String(length=255), nullable=True),
    sa.Column('added_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
    sa.ForeignKeyConstraint(['agent_id'], ['agents.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('project_id', 'agent_id', name='unique_project_agent')
    )
    op.create_index('idx_project_agents_agent', 'project_agents', ['agent_id'], unique=False)
    op.create_index('idx_project_agents_project', 'project_agents', ['project_id'], unique=False)
    op.create_table('execution_tool_calls',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('organization_id', sa.String(), nullable=False),
    sa.Column('execution_id', sa.UUID(), nullable=False),
    sa.Column('turn_id', sa.UUID(), nullable=True),
    sa.Column('tool_name', sa.String(), nullable=False),
    sa.Column('tool_use_id', sa.String(), nullable=True),
    sa.Column('started_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('completed_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('duration_ms', sa.Integer(), nullable=True),
    sa.Column('tool_input', sa.JSON(), nullable=True),
    sa.Column('tool_output', sa.Text(), nullable=True),
    sa.Column('tool_output_size', sa.Integer(), nullable=True),
    sa.Column('success', sa.Boolean(), server_default=sa.text('true'), nullable=False),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('error_type', sa.String(), nullable=True),
    sa.Column('metadata', sa.JSON(), server_default=sa.text("'{}'::json"), nullable=False),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.ForeignKeyConstraint(['execution_id'], ['executions.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['turn_id'], ['execution_turns.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_execution_tool_calls_execution_id'), 'execution_tool_calls', ['execution_id'], unique=False)
    op.create_index('ix_execution_tool_calls_org_created', 'execution_tool_calls', ['organization_id', 'created_at'], unique=False)
    op.create_index('ix_execution_tool_calls_org_execution', 'execution_tool_calls', ['organization_id', 'execution_id'], unique=False)
    op.create_index('ix_execution_tool_calls_org_success', 'execution_tool_calls', ['organization_id', 'success'], unique=False)
    op.create_index('ix_execution_tool_calls_org_tool', 'execution_tool_calls', ['organization_id', 'tool_name'], unique=False)
    op.create_index(op.f('ix_execution_tool_calls_organization_id'), 'execution_tool_calls', ['organization_id'], unique=False)
    op.create_index(op.f('ix_execution_tool_calls_tool_name'), 'execution_tool_calls', ['tool_name'], unique=False)
    op.create_index(op.f('ix_execution_tool_calls_turn_id'), 'execution_tool_calls', ['turn_id'], unique=False)
    op.create_table('job_executions',
    sa.Column('id', sa.String(length=255), nullable=False),
    sa.Column('job_id', sa.String(length=255), nullable=False),
    sa.Column('organization_id', sa.String(length=255), nullable=False),
    sa.Column('trigger_type', sa.String(length=50), nullable=False),
    sa.Column('trigger_metadata', sa.JSON(), nullable=True),
    sa.Column('execution_status', sa.String(length=50), nullable=True),
    sa.Column('execution_duration_ms', sa.Integer(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('execution_id', sa.UUID(), nullable=False),
    sa.ForeignKeyConstraint(['execution_id'], ['executions.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['job_id'], ['jobs.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_job_executions_created_at', 'job_executions', ['created_at'], unique=False)
    op.create_index('idx_job_executions_execution_id', 'job_executions', ['execution_id'], unique=False)
    op.create_index('idx_job_executions_execution_status', 'job_executions', ['execution_status'], unique=False)
    op.create_index('idx_job_executions_job_id', 'job_executions', ['job_id'], unique=False)
    op.create_index('idx_job_executions_organization_id', 'job_executions', ['organization_id'], unique=False)
    op.create_index('idx_job_executions_trigger_type', 'job_executions', ['trigger_type'], unique=False)
    # ### end Alembic commands ###


def downgrade() -> None:
    """Downgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index('idx_job_executions_trigger_type', table_name='job_executions')
    op.drop_index('idx_job_executions_organization_id', table_name='job_executions')
    op.drop_index('idx_job_executions_job_id', table_name='job_executions')
    op.drop_index('idx_job_executions_execution_status', table_name='job_executions')
    op.drop_index('idx_job_executions_execution_id', table_name='job_executions')
    op.drop_index('idx_job_executions_created_at', table_name='job_executions')
    op.drop_table('job_executions')
    op.drop_index(op.f('ix_execution_tool_calls_turn_id'), table_name='execution_tool_calls')
    op.drop_index(op.f('ix_execution_tool_calls_tool_name'), table_name='execution_tool_calls')
    op.drop_index(op.f('ix_execution_tool_calls_organization_id'), table_name='execution_tool_calls')
    op.drop_index('ix_execution_tool_calls_org_tool', table_name='execution_tool_calls')
    op.drop_index('ix_execution_tool_calls_org_success', table_name='execution_tool_calls')
    op.drop_index('ix_execution_tool_calls_org_execution', table_name='execution_tool_calls')
    op.drop_index('ix_execution_tool_calls_org_created', table_name='execution_tool_calls')
    op.drop_index(op.f('ix_execution_tool_calls_execution_id'), table_name='execution_tool_calls')
    op.drop_table('execution_tool_calls')
    op.drop_index('idx_project_agents_project', table_name='project_agents')
    op.drop_index('idx_project_agents_agent', table_name='project_agents')
    op.drop_table('project_agents')
    op.drop_index('idx_jobs_webhook_url_path', table_name='jobs')
    op.drop_index('idx_jobs_trigger_type', table_name='jobs')
    op.drop_index('idx_jobs_temporal_schedule_id', table_name='jobs')
    op.drop_index('idx_jobs_status', table_name='jobs')
    op.drop_index('idx_jobs_organization_id', table_name='jobs')
    op.drop_index('idx_jobs_next_execution_at', table_name='jobs')
    op.drop_index('idx_jobs_name', table_name='jobs')
    op.drop_index('idx_jobs_enabled', table_name='jobs')
    op.drop_index('idx_jobs_created_at', table_name='jobs')
    op.drop_table('jobs')
    op.drop_index(op.f('ix_execution_turns_organization_id'), table_name='execution_turns')
    op.drop_index('ix_execution_turns_org_model', table_name='execution_turns')
    op.drop_index('ix_execution_turns_org_execution', table_name='execution_turns')
    op.drop_index('ix_execution_turns_org_created', table_name='execution_turns')
    op.drop_index('ix_execution_turns_org_cost', table_name='execution_turns')
    op.drop_index(op.f('ix_execution_turns_execution_id'), table_name='execution_turns')
    op.drop_table('execution_turns')
    op.drop_index(op.f('ix_execution_tasks_organization_id'), table_name='execution_tasks')
    op.drop_index('ix_execution_tasks_org_status', table_name='execution_tasks')
    op.drop_index('ix_execution_tasks_org_execution', table_name='execution_tasks')
    op.drop_index(op.f('ix_execution_tasks_execution_id'), table_name='execution_tasks')
    op.drop_table('execution_tasks')
    op.drop_index('idx_execution_participants_user', table_name='execution_participants')
    op.drop_index('idx_execution_participants_org', table_name='execution_participants')
    op.drop_index('idx_execution_participants_execution', table_name='execution_participants')
    op.drop_table('execution_participants')
    op.drop_index('idx_agent_environments_org_id', table_name='agent_environments')
    op.drop_index('idx_agent_environments_org_env', table_name='agent_environments')
    op.drop_index('idx_agent_environments_environment_id', table_name='agent_environments')
    op.drop_index('idx_agent_environments_agent_id', table_name='agent_environments')
    op.drop_table('agent_environments')
    op.drop_index('idx_agent_contexts_org_id', table_name='agent_contexts')
    op.drop_index('idx_agent_contexts_agent_id', table_name='agent_contexts')
    op.drop_table('agent_contexts')
    op.drop_index('idx_workflows_workspace_id', table_name='workflows')
    op.drop_index('idx_workflows_status', table_name='workflows')
    op.drop_index('idx_workflows_slug', table_name='workflows')
    op.drop_index('idx_workflows_is_test_expires', table_name='workflows', postgresql_where=sa.text('is_test = true AND expires_at IS NOT NULL'))
    op.drop_table('workflows')
    op.drop_index('idx_worker_heartbeats_token', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_status', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_queue_status_heartbeat', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_queue', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_org_status_heartbeat', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_org_status', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_org', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_last_heartbeat', table_name='worker_heartbeats')
    op.drop_index('idx_worker_heartbeats_environment', table_name='worker_heartbeats')
    op.drop_table('worker_heartbeats')
    op.drop_index('idx_team_environments_team_id', table_name='team_environments')
    op.drop_index('idx_team_environments_org_id', table_name='team_environments')
    op.drop_index('idx_team_environments_org_env', table_name='team_environments')
    op.drop_index('idx_team_environments_environment_id', table_name='team_environments')
    op.drop_table('team_environments')
    op.drop_index('idx_team_contexts_team_id', table_name='team_contexts')
    op.drop_index('idx_team_contexts_org_id', table_name='team_contexts')
    op.drop_table('team_contexts')
    op.drop_index('idx_project_teams_team', table_name='project_teams')
    op.drop_index('idx_project_teams_project', table_name='project_teams')
    op.drop_table('project_teams')
    op.drop_index('idx_project_contexts_project_id', table_name='project_contexts')
    op.drop_index('idx_project_contexts_org_id', table_name='project_contexts')
    op.drop_table('project_contexts')
    op.drop_index(op.f('ix_executions_worker_queue_id'), table_name='executions')
    op.drop_index(op.f('ix_executions_user_id'), table_name='executions')
    op.drop_index(op.f('ix_executions_trigger_source'), table_name='executions')
    op.drop_index(op.f('ix_executions_organization_id'), table_name='executions')
    op.drop_index('idx_executions_workflow', table_name='executions', postgresql_where='temporal_workflow_id IS NOT NULL')
    op.drop_index('idx_executions_worker_queue_id', table_name='executions')
    op.drop_index('idx_executions_user_id', table_name='executions')
    op.drop_index('idx_executions_user_email', table_name='executions')
    op.drop_index('idx_executions_user', table_name='executions')
    op.drop_index('idx_executions_task_queue', table_name='executions')
    op.drop_index('idx_executions_status', table_name='executions')
    op.drop_index('idx_executions_runner', table_name='executions')
    op.drop_index('idx_executions_run', table_name='executions', postgresql_where='temporal_run_id IS NOT NULL')
    op.drop_index('idx_executions_org', table_name='executions')
    op.drop_index('idx_executions_entity', table_name='executions')
    op.drop_index('idx_executions_created', table_name='executions')
    op.drop_table('executions')
    op.drop_index('idx_agents_visibility', table_name='agents')
    op.drop_index('idx_agents_toolset_ids', table_name='agents', postgresql_using='gin')
    op.drop_index('idx_agents_team_id', table_name='agents')
    op.drop_index('idx_agents_team', table_name='agents')
    op.drop_index('idx_agents_status', table_name='agents')
    op.drop_index('idx_agents_runtime', table_name='agents')
    op.drop_index('idx_agents_project_id', table_name='agents')
    op.drop_index('idx_agents_policy_ids', table_name='agents', postgresql_using='gin')
    op.drop_index('idx_agents_org_runtime', table_name='agents')
    op.drop_index('idx_agents_org', table_name='agents')
    op.drop_index('idx_agents_execution_environment', table_name='agents', postgresql_using='gin')
    op.drop_index('idx_agents_environment_id', table_name='agents')
    op.drop_table('agents')
    op.drop_index('idx_workers_token', table_name='workers')
    op.drop_index('idx_workers_task_queue', table_name='workers')
    op.drop_index('idx_workers_status', table_name='workers')
    op.drop_index('idx_workers_org', table_name='workers')
    op.drop_table('workers')
    op.drop_index('idx_worker_queues_status', table_name='worker_queues')
    op.drop_index('idx_worker_queues_org', table_name='worker_queues')
    op.drop_index('idx_worker_queues_env', table_name='worker_queues')
    op.drop_table('worker_queues')
    op.drop_table('user_profiles')
    op.drop_index('ix_teams_runtime', table_name='teams')
    op.drop_index('idx_teams_visibility', table_name='teams')
    op.drop_index('idx_teams_toolset_ids', table_name='teams', postgresql_using='gin')
    op.drop_index('idx_teams_status', table_name='teams')
    op.drop_index('idx_teams_policy_ids', table_name='teams', postgresql_using='gin')
    op.drop_index('idx_teams_org', table_name='teams')
    op.drop_index('idx_teams_execution_environment', table_name='teams', postgresql_using='gin')
    op.drop_index('idx_teams_environment_id', table_name='teams')
    op.drop_table('teams')
    op.drop_index('ix_slash_command_executions_user_id', table_name='slash_command_executions')
    op.drop_index('ix_slash_command_executions_command_id', table_name='slash_command_executions')
    op.drop_table('slash_command_executions')
    op.drop_index('ix_skill_associations_skill_id', table_name='skill_associations')
    op.drop_index(op.f('ix_skill_associations_organization_id'), table_name='skill_associations')
    op.drop_index('ix_skill_associations_org_skill', table_name='skill_associations')
    op.drop_index('ix_skill_associations_entity', table_name='skill_associations')
    op.drop_table('skill_associations')
    op.drop_index('idx_projects_visibility', table_name='projects')
    op.drop_index('idx_projects_status', table_name='projects', postgresql_where=sa.text("status = 'active'"))
    op.drop_index('idx_projects_owner', table_name='projects')
    op.drop_index('idx_projects_org_id', table_name='projects')
    op.drop_index('idx_projects_environment_id', table_name='projects')
    op.drop_table('projects')
    op.drop_index('idx_orchestration_server_health_server_id', table_name='orchestration_server_health')
    op.drop_index('idx_orchestration_server_health_checked_at', table_name='orchestration_server_health')
    op.drop_table('orchestration_server_health')
    op.drop_index('idx_environment_contexts_org_id', table_name='environment_contexts')
    op.drop_index('idx_environment_contexts_environment_id', table_name='environment_contexts')
    op.drop_table('environment_contexts')
    op.drop_table('workspaces')
    op.drop_index(op.f('ix_user_presence_user_id'), table_name='user_presence')
    op.drop_index(op.f('ix_user_presence_session_id'), table_name='user_presence')
    op.drop_index(op.f('ix_user_presence_execution_id'), table_name='user_presence')
    op.drop_index(op.f('ix_user_presence_agent_id'), table_name='user_presence')
    op.drop_index('idx_presence_user', table_name='user_presence')
    op.drop_index('idx_presence_lookup', table_name='user_presence')
    op.drop_table('user_presence')
    op.drop_index('idx_temporal_namespaces_status', table_name='temporal_namespaces')
    op.drop_index('idx_temporal_namespaces_organization_id', table_name='temporal_namespaces')
    op.drop_table('temporal_namespaces')
    op.drop_index(op.f('ix_slash_commands_user_id'), table_name='slash_commands')
    op.drop_table('slash_commands')
    op.drop_index(op.f('ix_skills_organization_id'), table_name='skills')
    op.drop_index('idx_skills_type', table_name='skills')
    op.drop_index('idx_skills_enabled', table_name='skills')
    op.drop_table('skills')
    op.drop_index('idx_sessions_updated_at', table_name='sessions', postgresql_ops={'updated_at': 'DESC'})
    op.drop_index('idx_sessions_session_id', table_name='sessions')
    op.drop_index('idx_sessions_organization_id', table_name='sessions')
    op.drop_table('sessions')
    op.drop_index('idx_policy_assoc_priority', table_name='policy_associations', schema='public', postgresql_ops={'priority': 'DESC'})
    op.drop_index('idx_policy_assoc_policy', table_name='policy_associations', schema='public')
    op.drop_index('idx_policy_assoc_org', table_name='policy_associations', schema='public')
    op.drop_index('idx_policy_assoc_entity_enabled', table_name='policy_associations', schema='public', postgresql_ops={'priority': 'DESC'})
    op.drop_index('idx_policy_assoc_entity', table_name='policy_associations', schema='public')
    op.drop_index('idx_policy_assoc_enabled', table_name='policy_associations', schema='public')
    op.drop_table('policy_associations', schema='public')
    op.drop_index('idx_profiles_email', table_name='profiles')
    op.drop_table('profiles')
    op.drop_index('idx_orchestration_servers_user_id', table_name='orchestration_servers')
    op.drop_index('idx_orchestration_servers_scope', table_name='orchestration_servers')
    op.drop_index('idx_orchestration_servers_is_default', table_name='orchestration_servers')
    op.drop_index('idx_orchestration_servers_is_active', table_name='orchestration_servers')
    op.drop_table('orchestration_servers')
    op.drop_index('idx_namespaces_status', table_name='namespaces')
    op.drop_index('idx_namespaces_organization_id', table_name='namespaces')
    op.drop_table('namespaces')
    op.drop_index(op.f('ix_llm_models_value'), table_name='llm_models')
    op.drop_index(op.f('ix_llm_models_provider'), table_name='llm_models')
    op.drop_index(op.f('ix_llm_models_enabled'), table_name='llm_models')
    op.drop_table('llm_models')
    op.drop_index('idx_task_queues_worker_token', table_name='environments')
    op.drop_index('idx_task_queues_status', table_name='environments', postgresql_where=sa.text("status::text = 'active'::text"))
    op.drop_index('idx_task_queues_org', table_name='environments')
    op.drop_index('idx_task_queues_namespace', table_name='environments')
    op.drop_index('idx_task_queues_name', table_name='environments')
    op.drop_index('idx_environments_policy_ids', table_name='environments', postgresql_using='gin')
    op.drop_index('idx_environments_execution_environment', table_name='environments', postgresql_using='gin')
    op.drop_table('environments')
    op.drop_index('idx_context_resources_updated_at', table_name='context_resources', postgresql_ops={'updated_at': 'DESC'})
    op.drop_index('idx_context_resources_status', table_name='context_resources')
    op.drop_index('idx_context_resources_platform', table_name='context_resources')
    op.drop_index('idx_context_resources_organization', table_name='context_resources')
    op.drop_index('idx_context_resources_org_platform', table_name='context_resources')
    op.drop_index('idx_context_resources_name', table_name='context_resources')
    op.drop_table('context_resources')
    # ### end Alembic commands ###
