"""Initial schema - 38 tables Revision ID: 48fab1bdfec6 Revises: Create Date: 2026-01-16 07:13:08.947090 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision: str = '48fab1bdfec6' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table('failure_patterns', sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('client_id', sa.CHAR(length=36), nullable=True), sa.Column('pattern_type', sa.String(length=100), nullable=False), sa.Column('pattern_signature', sa.String(length=500), nullable=False), sa.Column('error_pattern', sa.Text(), nullable=True), sa.Column('affected_systems', sa.Text(), nullable=True), sa.Column('triggering_commands', sa.Text(), nullable=True), sa.Column('triggering_operations', sa.Text(), nullable=True), sa.Column('failure_description', sa.Text(), nullable=False), sa.Column('root_cause', sa.Text(), nullable=False), sa.Column('recommended_solution', sa.Text(), nullable=False), sa.Column('alternative_approaches', sa.Text(), nullable=True), sa.Column('occurrence_count', sa.Integer(), server_default='1', nullable=False), sa.Column('first_seen', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('last_seen', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('severity', sa.String(length=20), nullable=True), sa.Column('is_active', sa.Boolean(), server_default='1', nullable=False), sa.Column('added_to_insights', sa.Boolean(), server_default='0', nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("pattern_type IN ('command_compatibility', 'version_mismatch', 'permission_denied', 'service_unavailable', 'configuration_error', 'environmental_limitation')", name='ck_failure_patterns_type'), sa.CheckConstraint("severity IN ('blocking', 'major', 'minor', 'info')", name='ck_failure_patterns_severity'), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_failure_client', 'failure_patterns', ['client_id'], unique=False) op.create_index('idx_failure_infrastructure', 'failure_patterns', ['infrastructure_id'], unique=False) op.create_index('idx_failure_pattern_type', 'failure_patterns', ['pattern_type'], unique=False) op.create_index('idx_failure_signature', 'failure_patterns', ['pattern_signature'], unique=False) op.create_table('firewall_rules', sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('rule_name', sa.String(length=255), nullable=True), sa.Column('source_cidr', sa.String(length=100), nullable=True), sa.Column('destination_cidr', sa.String(length=100), nullable=True), sa.Column('port', sa.Integer(), nullable=True), sa.Column('protocol', sa.String(length=20), nullable=True), sa.Column('action', sa.String(length=20), nullable=True), sa.Column('rule_order', sa.Integer(), nullable=True), sa.Column('notes', sa.Text(), nullable=True), sa.Column('created_by', sa.String(length=255), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("action IN ('allow', 'deny', 'drop')", name='ck_firewall_rules_action'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_firewall_infra', 'firewall_rules', ['infrastructure_id'], unique=False) op.create_table('infrastructure_tags', sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=False), sa.Column('tag_id', sa.CHAR(length=36), nullable=False), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['tag_id'], ['tags.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('infrastructure_id', 'tag_id') ) op.create_index('idx_it_infrastructure', 'infrastructure_tags', ['infrastructure_id'], unique=False) op.create_index('idx_it_tag', 'infrastructure_tags', ['tag_id'], unique=False) op.create_table('services', sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('service_name', sa.String(length=255), nullable=False), sa.Column('service_type', sa.String(length=100), nullable=True), sa.Column('external_url', sa.String(length=500), nullable=True), sa.Column('internal_url', sa.String(length=500), nullable=True), sa.Column('port', sa.Integer(), nullable=True), sa.Column('protocol', sa.String(length=50), nullable=True), sa.Column('status', sa.String(length=50), server_default='running', nullable=False), sa.Column('version', sa.String(length=100), nullable=True), sa.Column('notes', sa.Text(), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("status IN ('running', 'stopped', 'error', 'maintenance')", name='ck_services_status'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_services_infrastructure', 'services', ['infrastructure_id'], unique=False) op.create_index('idx_services_name', 'services', ['service_name'], unique=False) op.create_index('idx_services_type', 'services', ['service_type'], unique=False) op.create_table('session_tags', sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('tag_id', sa.CHAR(length=36), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['tag_id'], ['tags.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('session_id', 'tag_id') ) op.create_index('idx_st_session', 'session_tags', ['session_id'], unique=False) op.create_index('idx_st_tag', 'session_tags', ['tag_id'], unique=False) op.create_table('tasks', sa.Column('parent_task_id', sa.CHAR(length=36), nullable=True), sa.Column('task_order', sa.Integer(), nullable=False), sa.Column('title', sa.String(length=500), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('task_type', sa.String(length=100), nullable=True), sa.Column('status', sa.String(length=50), nullable=False), sa.Column('blocking_reason', sa.Text(), nullable=True), sa.Column('session_id', sa.CHAR(length=36), nullable=True), sa.Column('client_id', sa.CHAR(length=36), nullable=True), sa.Column('project_id', sa.CHAR(length=36), nullable=True), sa.Column('assigned_agent', sa.String(length=100), nullable=True), sa.Column('estimated_complexity', sa.String(length=20), nullable=True), sa.Column('started_at', sa.DateTime(), nullable=True), sa.Column('completed_at', sa.DateTime(), nullable=True), sa.Column('task_context', sa.Text(), nullable=True), sa.Column('dependencies', sa.Text(), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("estimated_complexity IN ('trivial', 'simple', 'moderate', 'complex', 'very_complex')", name='ck_tasks_complexity'), sa.CheckConstraint("status IN ('pending', 'in_progress', 'blocked', 'completed', 'cancelled')", name='ck_tasks_status'), sa.CheckConstraint("task_type IN ('implementation', 'research', 'review', 'deployment', 'testing', 'documentation', 'bugfix', 'analysis')", name='ck_tasks_type'), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['parent_task_id'], ['tasks.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_tasks_client', 'tasks', ['client_id'], unique=False) op.create_index('idx_tasks_parent', 'tasks', ['parent_task_id'], unique=False) op.create_index('idx_tasks_project', 'tasks', ['project_id'], unique=False) op.create_index('idx_tasks_session', 'tasks', ['session_id'], unique=False) op.create_index('idx_tasks_status', 'tasks', ['status'], unique=False) op.create_table('ticket_links', sa.Column('session_id', sa.CHAR(length=36), nullable=True), sa.Column('client_id', sa.CHAR(length=36), nullable=True), sa.Column('integration_type', sa.String(length=100), nullable=False), sa.Column('ticket_id', sa.String(length=255), nullable=False), sa.Column('ticket_number', sa.String(length=100), nullable=True), sa.Column('ticket_subject', sa.String(length=500), nullable=True), sa.Column('ticket_url', sa.String(length=500), nullable=True), sa.Column('ticket_status', sa.String(length=100), nullable=True), sa.Column('link_type', sa.String(length=50), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_ticket_client', 'ticket_links', ['client_id'], unique=False) op.create_index('idx_ticket_external', 'ticket_links', ['integration_type', 'ticket_id'], unique=False) op.create_index('idx_ticket_session', 'ticket_links', ['session_id'], unique=False) op.create_table('work_items', sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('category', sa.String(length=50), nullable=False), sa.Column('title', sa.String(length=500), nullable=False), sa.Column('description', sa.Text(), nullable=False), sa.Column('status', sa.String(length=50), server_default='completed', nullable=False), sa.Column('priority', sa.String(length=20), nullable=True), sa.Column('is_billable', sa.Boolean(), server_default='0', nullable=False), sa.Column('estimated_minutes', sa.Integer(), nullable=True), sa.Column('actual_minutes', sa.Integer(), nullable=True), sa.Column('affected_systems', sa.Text(), nullable=True), sa.Column('technologies_used', sa.Text(), nullable=True), sa.Column('item_order', sa.Integer(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('completed_at', sa.DateTime(), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("category IN ('infrastructure', 'troubleshooting', 'configuration', 'development', 'maintenance', 'security', 'documentation')", name='ck_work_items_category'), sa.CheckConstraint("priority IN ('critical', 'high', 'medium', 'low')", name='ck_work_items_priority'), sa.CheckConstraint("status IN ('completed', 'in_progress', 'blocked', 'pending', 'deferred')", name='ck_work_items_status'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_work_items_category', 'work_items', ['category'], unique=False) op.create_index('idx_work_items_session', 'work_items', ['session_id'], unique=False) op.create_index('idx_work_items_status', 'work_items', ['status'], unique=False) op.create_table('billable_time', sa.Column('work_item_id', sa.CHAR(length=36), nullable=True), sa.Column('session_id', sa.CHAR(length=36), nullable=True), sa.Column('client_id', sa.CHAR(length=36), nullable=False), sa.Column('start_time', sa.TIMESTAMP(), nullable=False), sa.Column('end_time', sa.TIMESTAMP(), nullable=True), sa.Column('duration_minutes', sa.Integer(), nullable=False), sa.Column('hourly_rate', sa.Numeric(precision=10, scale=2), nullable=False), sa.Column('total_amount', sa.Numeric(precision=10, scale=2), nullable=False), sa.Column('is_billable', sa.Boolean(), server_default='1', nullable=False), sa.Column('description', sa.Text(), nullable=False), sa.Column('category', sa.String(length=50), nullable=False), sa.Column('notes', sa.Text(), nullable=True), sa.Column('invoiced_at', sa.TIMESTAMP(), nullable=True), sa.Column('invoice_id', sa.String(length=100), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("category IN ('consulting', 'development', 'support', 'maintenance', 'troubleshooting', 'project_work', 'training', 'documentation')", name='ck_billable_time_category'), sa.CheckConstraint('duration_minutes > 0', name='ck_billable_time_duration_positive'), sa.CheckConstraint('end_time IS NULL OR end_time >= start_time', name='ck_billable_time_end_after_start'), sa.CheckConstraint('hourly_rate >= 0', name='ck_billable_time_rate_non_negative'), sa.CheckConstraint('total_amount >= 0', name='ck_billable_time_amount_non_negative'), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='SET NULL'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_billable_time_billable', 'billable_time', ['is_billable'], unique=False) op.create_index('idx_billable_time_category', 'billable_time', ['category'], unique=False) op.create_index('idx_billable_time_client', 'billable_time', ['client_id'], unique=False) op.create_index('idx_billable_time_invoiced', 'billable_time', ['invoiced_at'], unique=False) op.create_index('idx_billable_time_session', 'billable_time', ['session_id'], unique=False) op.create_index('idx_billable_time_start', 'billable_time', ['start_time'], unique=False) op.create_index('idx_billable_time_work_item', 'billable_time', ['work_item_id'], unique=False) op.create_table('commands_run', sa.Column('work_item_id', sa.CHAR(length=36), nullable=False), sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('command_text', sa.Text(), nullable=False), sa.Column('host', sa.String(length=255), nullable=True), sa.Column('shell_type', sa.String(length=50), nullable=True), sa.Column('success', sa.Boolean(), nullable=True), sa.Column('output_summary', sa.Text(), nullable=True), sa.Column('exit_code', sa.Integer(), nullable=True), sa.Column('error_message', sa.Text(), nullable=True), sa.Column('failure_category', sa.String(length=100), nullable=True), sa.Column('resolution', sa.Text(), nullable=True), sa.Column('resolved', sa.Boolean(), server_default='0', nullable=False), sa.Column('execution_order', sa.Integer(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_commands_failure_category', 'commands_run', ['failure_category'], unique=False) op.create_index('idx_commands_host', 'commands_run', ['host'], unique=False) op.create_index('idx_commands_session', 'commands_run', ['session_id'], unique=False) op.create_index('idx_commands_success', 'commands_run', ['success'], unique=False) op.create_index('idx_commands_work_item', 'commands_run', ['work_item_id'], unique=False) op.create_table('credentials', sa.Column('client_id', sa.CHAR(length=36), nullable=True), sa.Column('service_id', sa.CHAR(length=36), nullable=True), sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('credential_type', sa.String(length=50), nullable=False), sa.Column('service_name', sa.String(length=255), nullable=False), sa.Column('username', sa.String(length=255), nullable=True), sa.Column('password_encrypted', sa.LargeBinary(), nullable=True), sa.Column('api_key_encrypted', sa.LargeBinary(), nullable=True), sa.Column('client_id_oauth', sa.String(length=255), nullable=True), sa.Column('client_secret_encrypted', sa.LargeBinary(), nullable=True), sa.Column('tenant_id_oauth', sa.String(length=255), nullable=True), sa.Column('public_key', sa.Text(), nullable=True), sa.Column('token_encrypted', sa.LargeBinary(), nullable=True), sa.Column('connection_string_encrypted', sa.LargeBinary(), nullable=True), sa.Column('integration_code', sa.String(length=255), nullable=True), sa.Column('external_url', sa.String(length=500), nullable=True), sa.Column('internal_url', sa.String(length=500), nullable=True), sa.Column('custom_port', sa.Integer(), nullable=True), sa.Column('role_description', sa.String(length=500), nullable=True), sa.Column('requires_vpn', sa.Boolean(), server_default='0', nullable=False), sa.Column('requires_2fa', sa.Boolean(), server_default='0', nullable=False), sa.Column('ssh_key_auth_enabled', sa.Boolean(), server_default='0', nullable=False), sa.Column('access_level', sa.String(length=100), nullable=True), sa.Column('expires_at', sa.DateTime(), nullable=True), sa.Column('last_rotated_at', sa.DateTime(), nullable=True), sa.Column('is_active', sa.Boolean(), server_default='1', nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("credential_type IN ('password', 'api_key', 'oauth', 'ssh_key', 'shared_secret', 'jwt', 'connection_string', 'certificate')", name='ck_credentials_type'), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['service_id'], ['services.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_credentials_active', 'credentials', ['is_active'], unique=False) op.create_index('idx_credentials_client', 'credentials', ['client_id'], unique=False) op.create_index('idx_credentials_service', 'credentials', ['service_id'], unique=False) op.create_index('idx_credentials_type', 'credentials', ['credential_type'], unique=False) op.create_table('database_changes', sa.Column('work_item_id', sa.CHAR(length=36), nullable=False), sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('database_name', sa.String(length=255), nullable=False), sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('change_type', sa.String(length=50), nullable=True), sa.Column('sql_executed', sa.Text(), nullable=True), sa.Column('rows_affected', sa.BigInteger(), nullable=True), sa.Column('size_freed_bytes', sa.BigInteger(), nullable=True), sa.Column('backup_taken', sa.Boolean(), server_default='0', nullable=False), sa.Column('backup_location', sa.String(length=500), nullable=True), sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("change_type IN ('schema', 'data', 'index', 'optimization', 'cleanup', 'migration')", name='ck_database_changes_type'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_db_changes_database', 'database_changes', ['database_name'], unique=False) op.create_index('idx_db_changes_work_item', 'database_changes', ['work_item_id'], unique=False) op.create_table('deployments', sa.Column('work_item_id', sa.CHAR(length=36), nullable=False), sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('service_id', sa.CHAR(length=36), nullable=True), sa.Column('deployment_type', sa.String(length=50), nullable=True), sa.Column('version', sa.String(length=100), nullable=True), sa.Column('description', sa.Text(), nullable=True), sa.Column('deployed_from', sa.String(length=500), nullable=True), sa.Column('deployed_to', sa.String(length=500), nullable=True), sa.Column('rollback_available', sa.Boolean(), server_default='0', nullable=False), sa.Column('rollback_procedure', sa.Text(), nullable=True), sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("deployment_type IN ('code', 'config', 'database', 'container', 'service_restart')", name='ck_deployments_type'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['service_id'], ['services.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_deployments_infrastructure', 'deployments', ['infrastructure_id'], unique=False) op.create_index('idx_deployments_service', 'deployments', ['service_id'], unique=False) op.create_index('idx_deployments_work_item', 'deployments', ['work_item_id'], unique=False) op.create_table('environmental_insights', sa.Column('client_id', sa.CHAR(length=36), nullable=True), sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('insight_category', sa.String(length=100), nullable=False), sa.Column('insight_title', sa.String(length=500), nullable=False), sa.Column('insight_description', sa.Text(), nullable=False), sa.Column('examples', sa.Text(), nullable=True), sa.Column('source_pattern_id', sa.CHAR(length=36), nullable=True), sa.Column('confidence_level', sa.String(length=20), nullable=True), sa.Column('verification_count', sa.Integer(), server_default='1', nullable=False), sa.Column('priority', sa.Integer(), server_default='5', nullable=False), sa.Column('last_verified', sa.DateTime(), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("confidence_level IN ('confirmed', 'likely', 'suspected')", name='ck_insights_confidence'), sa.CheckConstraint("insight_category IN ('command_constraints', 'service_configuration', 'version_limitations', 'custom_installations', 'network_constraints', 'permissions')", name='ck_insights_category'), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['source_pattern_id'], ['failure_patterns.id'], ondelete='SET NULL'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_insights_category', 'environmental_insights', ['insight_category'], unique=False) op.create_index('idx_insights_client', 'environmental_insights', ['client_id'], unique=False) op.create_index('idx_insights_infrastructure', 'environmental_insights', ['infrastructure_id'], unique=False) op.create_table('external_integrations', sa.Column('session_id', sa.CHAR(length=36), nullable=True), sa.Column('work_item_id', sa.CHAR(length=36), nullable=True), sa.Column('integration_type', sa.String(length=100), nullable=False), sa.Column('external_id', sa.String(length=255), nullable=True), sa.Column('external_url', sa.String(length=500), nullable=True), sa.Column('action', sa.String(length=50), nullable=True), sa.Column('direction', sa.String(length=20), nullable=True), sa.Column('request_data', sa.Text(), nullable=True), sa.Column('response_data', sa.Text(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('created_by', sa.String(length=255), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_ext_int_external', 'external_integrations', ['external_id'], unique=False) op.create_index('idx_ext_int_session', 'external_integrations', ['session_id'], unique=False) op.create_index('idx_ext_int_type', 'external_integrations', ['integration_type'], unique=False) op.create_table('file_changes', sa.Column('work_item_id', sa.CHAR(length=36), nullable=False), sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('file_path', sa.String(length=1000), nullable=False), sa.Column('change_type', sa.String(length=50), nullable=True), sa.Column('backup_path', sa.String(length=1000), nullable=True), sa.Column('size_bytes', sa.Integer(), nullable=True), sa.Column('description', sa.Text(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("change_type IN ('created', 'modified', 'deleted', 'renamed', 'backed_up')", name='ck_file_changes_type'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_file_changes_session', 'file_changes', ['session_id'], unique=False) op.create_index('idx_file_changes_work_item', 'file_changes', ['work_item_id'], unique=False) op.create_table('infrastructure_changes', sa.Column('work_item_id', sa.CHAR(length=36), nullable=False), sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('change_type', sa.String(length=50), nullable=True), sa.Column('target_system', sa.String(length=255), nullable=False), sa.Column('before_state', sa.Text(), nullable=True), sa.Column('after_state', sa.Text(), nullable=True), sa.Column('is_permanent', sa.Boolean(), server_default='1', nullable=False), sa.Column('rollback_procedure', sa.Text(), nullable=True), sa.Column('verification_performed', sa.Boolean(), server_default='0', nullable=False), sa.Column('verification_notes', sa.Text(), nullable=True), sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("change_type IN ('dns', 'firewall', 'routing', 'ssl', 'container', 'service_config', 'hardware', 'network', 'storage')", name='ck_infrastructure_changes_type'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_infra_changes_infrastructure', 'infrastructure_changes', ['infrastructure_id'], unique=False) op.create_index('idx_infra_changes_session', 'infrastructure_changes', ['session_id'], unique=False) op.create_index('idx_infra_changes_work_item', 'infrastructure_changes', ['work_item_id'], unique=False) op.create_table('operation_failures', sa.Column('session_id', sa.CHAR(length=36), nullable=True), sa.Column('work_item_id', sa.CHAR(length=36), nullable=True), sa.Column('operation_type', sa.String(length=100), nullable=False), sa.Column('operation_description', sa.Text(), nullable=False), sa.Column('target_system', sa.String(length=255), nullable=True), sa.Column('error_message', sa.Text(), nullable=False), sa.Column('error_code', sa.String(length=50), nullable=True), sa.Column('failure_category', sa.String(length=100), nullable=True), sa.Column('stack_trace', sa.Text(), nullable=True), sa.Column('resolution_applied', sa.Text(), nullable=True), sa.Column('resolved', sa.Boolean(), server_default='0', nullable=False), sa.Column('resolved_at', sa.TIMESTAMP(), nullable=True), sa.Column('request_data', sa.Text(), nullable=True), sa.Column('response_data', sa.Text(), nullable=True), sa.Column('environment_snapshot', sa.Text(), nullable=True), sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("operation_type IN ('api_call', 'file_operation', 'network_request', 'database_query', 'external_integration', 'service_restart')", name='ck_operation_failures_type'), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_op_failure_category', 'operation_failures', ['failure_category'], unique=False) op.create_index('idx_op_failure_resolved', 'operation_failures', ['resolved'], unique=False) op.create_index('idx_op_failure_session', 'operation_failures', ['session_id'], unique=False) op.create_index('idx_op_failure_type', 'operation_failures', ['operation_type'], unique=False) op.create_table('pending_tasks', sa.Column('client_id', sa.CHAR(length=36), nullable=True), sa.Column('project_id', sa.CHAR(length=36), nullable=True), sa.Column('work_item_id', sa.CHAR(length=36), nullable=True), sa.Column('title', sa.String(length=500), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('priority', sa.String(length=20), nullable=True), sa.Column('blocked_by', sa.Text(), nullable=True), sa.Column('assigned_to', sa.String(length=255), nullable=True), sa.Column('due_date', sa.DATE(), nullable=True), sa.Column('status', sa.String(length=50), server_default='pending', nullable=False), sa.Column('completed_at', sa.TIMESTAMP(), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("priority IN ('critical', 'high', 'medium', 'low')", name='ck_pending_tasks_priority'), sa.CheckConstraint("status IN ('pending', 'in_progress', 'blocked', 'completed', 'cancelled')", name='ck_pending_tasks_status'), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='SET NULL'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_pending_tasks_client', 'pending_tasks', ['client_id'], unique=False) op.create_index('idx_pending_tasks_priority', 'pending_tasks', ['priority'], unique=False) op.create_index('idx_pending_tasks_status', 'pending_tasks', ['status'], unique=False) op.create_table('problem_solutions', sa.Column('work_item_id', sa.CHAR(length=36), nullable=False), sa.Column('session_id', sa.CHAR(length=36), nullable=False), sa.Column('problem_description', sa.Text(), nullable=False), sa.Column('symptom', sa.Text(), nullable=True), sa.Column('error_message', sa.Text(), nullable=True), sa.Column('investigation_steps', sa.Text(), nullable=True), sa.Column('root_cause', sa.Text(), nullable=True), sa.Column('solution_applied', sa.Text(), nullable=False), sa.Column('verification_method', sa.Text(), nullable=True), sa.Column('rollback_plan', sa.Text(), nullable=True), sa.Column('recurrence_count', sa.Integer(), server_default='1', nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_problems_session', 'problem_solutions', ['session_id'], unique=False) op.create_index('idx_problems_work_item', 'problem_solutions', ['work_item_id'], unique=False) op.create_table('security_incidents', sa.Column('client_id', sa.CHAR(length=36), nullable=True), sa.Column('service_id', sa.CHAR(length=36), nullable=True), sa.Column('infrastructure_id', sa.CHAR(length=36), nullable=True), sa.Column('incident_type', sa.String(length=100), nullable=True), sa.Column('incident_date', sa.DateTime(), nullable=False), sa.Column('severity', sa.String(length=50), nullable=True), sa.Column('description', sa.Text(), nullable=False), sa.Column('findings', sa.Text(), nullable=True), sa.Column('remediation_steps', sa.Text(), nullable=True), sa.Column('status', sa.String(length=50), server_default='investigating', nullable=False), sa.Column('resolved_at', sa.DateTime(), nullable=True), sa.Column('notes', sa.Text(), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.CheckConstraint("incident_type IN ('bec', 'backdoor', 'malware', 'unauthorized_access', 'data_breach', 'phishing', 'ransomware', 'brute_force')", name='ck_security_incidents_type'), sa.CheckConstraint("severity IN ('critical', 'high', 'medium', 'low')", name='ck_security_incidents_severity'), sa.CheckConstraint("status IN ('investigating', 'contained', 'resolved', 'monitoring')", name='ck_security_incidents_status'), sa.ForeignKeyConstraint(['client_id'], ['clients.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['infrastructure_id'], ['infrastructure.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['service_id'], ['services.id'], ondelete='SET NULL'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_incidents_client', 'security_incidents', ['client_id'], unique=False) op.create_index('idx_incidents_status', 'security_incidents', ['status'], unique=False) op.create_index('idx_incidents_type', 'security_incidents', ['incident_type'], unique=False) op.create_table('service_relationships', sa.Column('from_service_id', sa.CHAR(length=36), nullable=False), sa.Column('to_service_id', sa.CHAR(length=36), nullable=False), sa.Column('relationship_type', sa.CHAR(length=50), nullable=False), sa.Column('notes', sa.Text(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("relationship_type IN ('hosted_on', 'proxied_by', 'authenticates_via', 'backend_for', 'depends_on', 'replicates_to')", name='ck_service_relationships_type'), sa.ForeignKeyConstraint(['from_service_id'], ['services.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['to_service_id'], ['services.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('from_service_id', 'to_service_id', 'relationship_type', name='uq_service_relationship') ) op.create_index('idx_service_rel_from', 'service_relationships', ['from_service_id'], unique=False) op.create_index('idx_service_rel_to', 'service_relationships', ['to_service_id'], unique=False) op.create_table('work_item_tags', sa.Column('work_item_id', sa.CHAR(length=36), nullable=False), sa.Column('tag_id', sa.CHAR(length=36), nullable=False), sa.ForeignKeyConstraint(['tag_id'], ['tags.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['work_item_id'], ['work_items.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('work_item_id', 'tag_id') ) op.create_index('idx_wit_tag', 'work_item_tags', ['tag_id'], unique=False) op.create_index('idx_wit_work_item', 'work_item_tags', ['work_item_id'], unique=False) op.create_table('credential_audit_log', sa.Column('credential_id', sa.CHAR(length=36), nullable=False), sa.Column('action', sa.String(length=50), nullable=False), sa.Column('user_id', sa.String(length=255), nullable=False), sa.Column('ip_address', sa.String(length=45), nullable=True), sa.Column('user_agent', sa.Text(), nullable=True), sa.Column('details', sa.Text(), nullable=True), sa.Column('timestamp', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("action IN ('view', 'create', 'update', 'delete', 'rotate', 'decrypt')", name='ck_credential_audit_action'), sa.ForeignKeyConstraint(['credential_id'], ['credentials.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_cred_audit_credential', 'credential_audit_log', ['credential_id'], unique=False) op.create_index('idx_cred_audit_timestamp', 'credential_audit_log', ['timestamp'], unique=False) op.create_index('idx_cred_audit_user', 'credential_audit_log', ['user_id'], unique=False) op.create_table('credential_permissions', sa.Column('credential_id', sa.CHAR(length=36), nullable=False), sa.Column('user_id', sa.String(length=255), nullable=False), sa.Column('permission_level', sa.String(length=50), nullable=True), sa.Column('granted_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), sa.Column('granted_by', sa.String(length=255), nullable=True), sa.Column('id', sa.CHAR(length=36), nullable=False), sa.CheckConstraint("permission_level IN ('read', 'write', 'admin')", name='ck_credential_permissions_level'), sa.ForeignKeyConstraint(['credential_id'], ['credentials.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('credential_id', 'user_id', name='uq_credential_user') ) op.create_index('idx_cred_perm_credential', 'credential_permissions', ['credential_id'], unique=False) op.create_index('idx_cred_perm_user', 'credential_permissions', ['user_id'], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.drop_index('idx_cred_perm_user', table_name='credential_permissions') op.drop_index('idx_cred_perm_credential', table_name='credential_permissions') op.drop_table('credential_permissions') op.drop_index('idx_cred_audit_user', table_name='credential_audit_log') op.drop_index('idx_cred_audit_timestamp', table_name='credential_audit_log') op.drop_index('idx_cred_audit_credential', table_name='credential_audit_log') op.drop_table('credential_audit_log') op.drop_index('idx_wit_work_item', table_name='work_item_tags') op.drop_index('idx_wit_tag', table_name='work_item_tags') op.drop_table('work_item_tags') op.drop_index('idx_service_rel_to', table_name='service_relationships') op.drop_index('idx_service_rel_from', table_name='service_relationships') op.drop_table('service_relationships') op.drop_index('idx_incidents_type', table_name='security_incidents') op.drop_index('idx_incidents_status', table_name='security_incidents') op.drop_index('idx_incidents_client', table_name='security_incidents') op.drop_table('security_incidents') op.drop_index('idx_problems_work_item', table_name='problem_solutions') op.drop_index('idx_problems_session', table_name='problem_solutions') op.drop_table('problem_solutions') op.drop_index('idx_pending_tasks_status', table_name='pending_tasks') op.drop_index('idx_pending_tasks_priority', table_name='pending_tasks') op.drop_index('idx_pending_tasks_client', table_name='pending_tasks') op.drop_table('pending_tasks') op.drop_index('idx_op_failure_type', table_name='operation_failures') op.drop_index('idx_op_failure_session', table_name='operation_failures') op.drop_index('idx_op_failure_resolved', table_name='operation_failures') op.drop_index('idx_op_failure_category', table_name='operation_failures') op.drop_table('operation_failures') op.drop_index('idx_infra_changes_work_item', table_name='infrastructure_changes') op.drop_index('idx_infra_changes_session', table_name='infrastructure_changes') op.drop_index('idx_infra_changes_infrastructure', table_name='infrastructure_changes') op.drop_table('infrastructure_changes') op.drop_index('idx_file_changes_work_item', table_name='file_changes') op.drop_index('idx_file_changes_session', table_name='file_changes') op.drop_table('file_changes') op.drop_index('idx_ext_int_type', table_name='external_integrations') op.drop_index('idx_ext_int_session', table_name='external_integrations') op.drop_index('idx_ext_int_external', table_name='external_integrations') op.drop_table('external_integrations') op.drop_index('idx_insights_infrastructure', table_name='environmental_insights') op.drop_index('idx_insights_client', table_name='environmental_insights') op.drop_index('idx_insights_category', table_name='environmental_insights') op.drop_table('environmental_insights') op.drop_index('idx_deployments_work_item', table_name='deployments') op.drop_index('idx_deployments_service', table_name='deployments') op.drop_index('idx_deployments_infrastructure', table_name='deployments') op.drop_table('deployments') op.drop_index('idx_db_changes_work_item', table_name='database_changes') op.drop_index('idx_db_changes_database', table_name='database_changes') op.drop_table('database_changes') op.drop_index('idx_credentials_type', table_name='credentials') op.drop_index('idx_credentials_service', table_name='credentials') op.drop_index('idx_credentials_client', table_name='credentials') op.drop_index('idx_credentials_active', table_name='credentials') op.drop_table('credentials') op.drop_index('idx_commands_work_item', table_name='commands_run') op.drop_index('idx_commands_success', table_name='commands_run') op.drop_index('idx_commands_session', table_name='commands_run') op.drop_index('idx_commands_host', table_name='commands_run') op.drop_index('idx_commands_failure_category', table_name='commands_run') op.drop_table('commands_run') op.drop_index('idx_billable_time_work_item', table_name='billable_time') op.drop_index('idx_billable_time_start', table_name='billable_time') op.drop_index('idx_billable_time_session', table_name='billable_time') op.drop_index('idx_billable_time_invoiced', table_name='billable_time') op.drop_index('idx_billable_time_client', table_name='billable_time') op.drop_index('idx_billable_time_category', table_name='billable_time') op.drop_index('idx_billable_time_billable', table_name='billable_time') op.drop_table('billable_time') op.drop_index('idx_work_items_status', table_name='work_items') op.drop_index('idx_work_items_session', table_name='work_items') op.drop_index('idx_work_items_category', table_name='work_items') op.drop_table('work_items') op.drop_index('idx_ticket_session', table_name='ticket_links') op.drop_index('idx_ticket_external', table_name='ticket_links') op.drop_index('idx_ticket_client', table_name='ticket_links') op.drop_table('ticket_links') op.drop_index('idx_tasks_status', table_name='tasks') op.drop_index('idx_tasks_session', table_name='tasks') op.drop_index('idx_tasks_project', table_name='tasks') op.drop_index('idx_tasks_parent', table_name='tasks') op.drop_index('idx_tasks_client', table_name='tasks') op.drop_table('tasks') op.drop_index('idx_st_tag', table_name='session_tags') op.drop_index('idx_st_session', table_name='session_tags') op.drop_table('session_tags') op.drop_index('idx_services_type', table_name='services') op.drop_index('idx_services_name', table_name='services') op.drop_index('idx_services_infrastructure', table_name='services') op.drop_table('services') op.drop_index('idx_it_tag', table_name='infrastructure_tags') op.drop_index('idx_it_infrastructure', table_name='infrastructure_tags') op.drop_table('infrastructure_tags') op.drop_index('idx_firewall_infra', table_name='firewall_rules') op.drop_table('firewall_rules') op.drop_index('idx_failure_signature', table_name='failure_patterns') op.drop_index('idx_failure_pattern_type', table_name='failure_patterns') op.drop_index('idx_failure_infrastructure', table_name='failure_patterns') op.drop_index('idx_failure_client', table_name='failure_patterns') op.drop_table('failure_patterns') # ### end Alembic commands ###