"""initial schema

Revision ID: 161f8829d93f
Revises: 
Create Date: 2025-09-11 15:16:39.153056

"""
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 = '161f8829d93f'
down_revision: Union[str, Sequence[str], None] = None
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('contact',
    sa.Column('email', sa.String(length=300), nullable=True),
    sa.Column('first_name', sa.String(length=100), nullable=False),
    sa.Column('middle_name', sa.String(length=100), nullable=True),
    sa.Column('last_name', sa.String(length=100), nullable=False),
    sa.Column('primary_phone', sa.String(length=45), nullable=True),
    sa.Column('gender', sa.Enum('MALE', 'FEMALE', name='gender'), nullable=True),
    sa.Column('status', sa.Enum('ACTIVE', 'INACTIVE', 'APPROVAL_PENDING', 'MERGED', name='contactstatus'), nullable=True),
    sa.Column('source', sa.Enum('GRID', 'CRM', 'EXTERNAL', name='contactsource'), nullable=False),
    sa.Column('grid_contact_id', sa.Integer(), nullable=True),
    sa.Column('crm_contact_guid', sa.String(length=36), nullable=True),
    sa.Column('account_id', sa.String(length=36), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id', name=op.f('contact_pkey'))
    )
    op.create_index(op.f('contact_id_idx'), 'contact', ['id'], unique=False)
    op.create_table('source',
    sa.Column('name', sa.String(length=200), nullable=False),
    sa.Column('connection_config', sa.JSON(), nullable=True),
    sa.Column('metadata', sa.JSON(), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id', name=op.f('source_pkey'))
    )
    op.create_index(op.f('source_id_idx'), 'source', ['id'], unique=False)
    op.create_index(op.f('source_name_idx'), 'source', ['name'], unique=False)
    op.create_table('vector',
    sa.Column('source_type', sa.String(length=20), nullable=False),
    sa.Column('source_id', sa.Integer(), nullable=False),
    sa.Column('model', sa.String(length=100), nullable=False),
    sa.Column('qdrant_point_id', sa.String(length=100), nullable=True),
    sa.Column('metadata', sa.JSON(), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id', name=op.f('vector_pkey')),
    sa.UniqueConstraint('qdrant_point_id', name=op.f('vector_qdrant_point_id_key'))
    )
    op.create_index('idx_vector_source', 'vector', ['source_type', 'source_id'], unique=False)
    op.create_index(op.f('vector_id_idx'), 'vector', ['id'], unique=False)
    op.create_table('collection',
    sa.Column('name', sa.String(length=200), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('metadata', sa.JSON(), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('owner_id', sa.Integer(), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['owner_id'], ['contact.id'], name=op.f('collection_owner_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('collection_pkey')),
    sa.UniqueConstraint('name', name='uq_collection_name')
    )
    op.create_index(op.f('collection_id_idx'), 'collection', ['id'], unique=False)
    op.create_index(op.f('collection_name_idx'), 'collection', ['name'], unique=False)
    op.create_index(op.f('collection_owner_id_idx'), 'collection', ['owner_id'], unique=False)
    op.create_table('conversation',
    sa.Column('uuid', sa.UUID(), nullable=False),
    sa.Column('title', sa.String(length=255), nullable=True),
    sa.Column('contact_id', sa.Integer(), nullable=False),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('conversation_type', sa.Enum('TRAVEL_GUIDE', 'MSA_CHAT', name='conversationtype'), nullable=False),
    sa.Column('audio_file_url', sa.String(length=1024), nullable=True),
    sa.Column('transcription_json_url', sa.String(length=1024), nullable=True),
    sa.Column('repaired_json_url', sa.String(length=1024), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['contact_id'], ['contact.id'], name=op.f('conversation_contact_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('conversation_pkey'))
    )
    op.create_index(op.f('conversation_id_idx'), 'conversation', ['id'], unique=False)
    op.create_index(op.f('conversation_uuid_idx'), 'conversation', ['uuid'], unique=True)
    op.create_table('document',
    sa.Column('title', sa.String(length=500), nullable=False),
    sa.Column('source_id', sa.Integer(), nullable=False),
    sa.Column('parent_document_id', sa.Integer(), nullable=True),
    sa.Column('uploaded_by_id', sa.Integer(), nullable=True),
    sa.Column('file_path_s3', sa.String(length=2048), nullable=True),
    sa.Column('file_hash', sa.String(length=255), nullable=True),
    sa.Column('file_size', sa.Integer(), nullable=True),
    sa.Column('version', sa.Integer(), nullable=False),
    sa.Column('is_latest', sa.Boolean(), nullable=False),
    sa.Column('metadata', sa.JSON(), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['parent_document_id'], ['document.id'], name=op.f('document_parent_document_id_fkey')),
    sa.ForeignKeyConstraint(['source_id'], ['source.id'], name=op.f('document_source_id_fkey')),
    sa.ForeignKeyConstraint(['uploaded_by_id'], ['contact.id'], name=op.f('document_uploaded_by_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('document_pkey')),
    sa.UniqueConstraint('title', name='uq_document_title')
    )
    op.create_index(op.f('document_id_idx'), 'document', ['id'], unique=False)
    op.create_index(op.f('document_parent_document_id_idx'), 'document', ['parent_document_id'], unique=False)
    op.create_index(op.f('document_source_id_idx'), 'document', ['source_id'], unique=False)
    op.create_index(op.f('document_status_idx'), 'document', ['status'], unique=False)
    op.create_index(op.f('document_title_idx'), 'document', ['title'], unique=False)
    op.create_index(op.f('document_uploaded_by_id_idx'), 'document', ['uploaded_by_id'], unique=False)
    op.create_table('chunk_config',
    sa.Column('document_id', sa.Integer(), nullable=True),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('strategy', sa.String(length=50), nullable=False),
    sa.Column('chunk_size', sa.Integer(), nullable=False),
    sa.Column('chunk_overlap', sa.Integer(), nullable=False),
    sa.Column('internal_qa_enabled', sa.Boolean(), nullable=False),
    sa.Column('external_qa_enabled', sa.Boolean(), nullable=False),
    sa.Column('internal_qa_prompt', sa.Text(), nullable=True),
    sa.Column('external_qa_prompt', sa.Text(), nullable=True),
    sa.Column('metadata', sa.JSON(), nullable=True),
    sa.Column('is_template', sa.Boolean(), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['document_id'], ['document.id'], name=op.f('chunk_config_document_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('chunk_config_pkey'))
    )
    op.create_index(op.f('chunk_config_id_idx'), 'chunk_config', ['id'], unique=False)
    op.create_table('collection_document',
    sa.Column('collection_id', sa.Integer(), nullable=False),
    sa.Column('document_id', sa.Integer(), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['collection_id'], ['collection.id'], name=op.f('collection_document_collection_id_fkey')),
    sa.ForeignKeyConstraint(['document_id'], ['document.id'], name=op.f('collection_document_document_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('collection_document_pkey')),
    sa.UniqueConstraint('collection_id', 'document_id', name='uq_collection_document')
    )
    op.create_index(op.f('collection_document_id_idx'), 'collection_document', ['id'], unique=False)
    op.create_table('conversation_compare',
    sa.Column('conversation_id', sa.Integer(), nullable=False),
    sa.Column('question_index', sa.Integer(), nullable=False),
    sa.Column('question_text', sa.Text(), nullable=False),
    sa.Column('msa_answer_text', sa.Text(), nullable=True),
    sa.Column('ai_answer_text', sa.Text(), nullable=True),
    sa.Column('msa_speaker_label', sa.String(length=32), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['conversation_id'], ['conversation.id'], name=op.f('conversation_compare_conversation_id_fkey'), ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id', name=op.f('conversation_compare_pkey')),
    sa.UniqueConstraint('conversation_id', 'question_index', name='uq_sim_compare_conversation_qidx')
    )
    op.create_index(op.f('conversation_compare_id_idx'), 'conversation_compare', ['id'], unique=False)
    op.create_index('ix_sim_compare_conversation_created', 'conversation_compare', ['conversation_id', 'created_at'], unique=False)
    op.create_index('ix_sim_compare_conversation_sequence', 'conversation_compare', ['conversation_id', 'question_index'], unique=False)
    op.create_table('conversation_message',
    sa.Column('content', sa.Text(), nullable=False),
    sa.Column('conversation_id', sa.Integer(), nullable=False),
    sa.Column('role', sa.Enum('USER', 'ASSISTANT', 'SYSTEM', name='messagerole'), nullable=False),
    sa.Column('status', sa.Enum('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', name='messagestatus'), nullable=False),
    sa.Column('message_type', sa.Enum('TEXT', name='messagetype'), nullable=False),
    sa.Column('sequence_number', sa.Integer(), nullable=False),
    sa.Column('llm_response_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('is_upvoted', sa.Boolean(), nullable=True),
    sa.Column('is_resolved', sa.Boolean(), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['conversation_id'], ['conversation.id'], name=op.f('conversation_message_conversation_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('conversation_message_pkey')),
    sa.UniqueConstraint('conversation_id', 'sequence_number', name='uq_conversation_message_sequence')
    )
    op.create_index(op.f('conversation_message_id_idx'), 'conversation_message', ['id'], unique=False)
    op.create_index('ix_conversation_message_conversation_created', 'conversation_message', ['conversation_id', 'created_at'], unique=False)
    op.create_index('ix_conversation_message_conversation_sequence', 'conversation_message', ['conversation_id', 'sequence_number'], unique=False)
    op.create_index('ix_conversation_message_llm_response_gin', 'conversation_message', ['llm_response_data'], unique=False, postgresql_using='gin')
    op.create_table('qa_pair',
    sa.Column('document_id', sa.Integer(), nullable=False),
    sa.Column('question', sa.Text(), nullable=False),
    sa.Column('answer', sa.Text(), nullable=False),
    sa.Column('provenance', sa.String(length=50), nullable=False),
    sa.Column('confidence_score', sa.Float(), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['document_id'], ['document.id'], name=op.f('qa_pair_document_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('qa_pair_pkey'))
    )
    op.create_index(op.f('qa_pair_document_id_idx'), 'qa_pair', ['document_id'], unique=False)
    op.create_index(op.f('qa_pair_id_idx'), 'qa_pair', ['id'], unique=False)
    op.create_table('chunk',
    sa.Column('document_id', sa.Integer(), nullable=False),
    sa.Column('chunk_config_id', sa.Integer(), nullable=True),
    sa.Column('text', sa.Text(), nullable=False),
    sa.Column('text_hash', sa.String(length=64), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['chunk_config_id'], ['chunk_config.id'], name=op.f('chunk_chunk_config_id_fkey')),
    sa.ForeignKeyConstraint(['document_id'], ['document.id'], name=op.f('chunk_document_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('chunk_pkey'))
    )
    op.create_index(op.f('chunk_document_id_idx'), 'chunk', ['document_id'], unique=False)
    op.create_index(op.f('chunk_id_idx'), 'chunk', ['id'], unique=False)
    op.create_index(op.f('chunk_text_hash_idx'), 'chunk', ['text_hash'], unique=False)
    op.create_table('conversation_message_metadata',
    sa.Column('message_id', sa.Integer(), nullable=False),
    sa.Column('model_name', sa.String(length=100), nullable=True),
    sa.Column('token_count_input', sa.Integer(), nullable=True),
    sa.Column('token_count_output', sa.Integer(), nullable=True),
    sa.Column('processing_time_ms', sa.Integer(), nullable=True),
    sa.Column('retrieval_context', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['message_id'], ['conversation_message.id'], name=op.f('conversation_message_metadata_message_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('conversation_message_metadata_pkey')),
    sa.UniqueConstraint('message_id', name=op.f('conversation_message_metadata_message_id_key'))
    )
    op.create_index(op.f('conversation_message_metadata_id_idx'), 'conversation_message_metadata', ['id'], unique=False)
    op.create_index('ix_conversation_message_metadata_retrieval_gin', 'conversation_message_metadata', ['retrieval_context'], unique=False, postgresql_using='gin')
    op.create_table('integration_config',
    sa.Column('source_id', sa.Integer(), nullable=False),
    sa.Column('chunk_config_id', sa.Integer(), nullable=True),
    sa.Column('external_id', sa.String(length=255), nullable=True),
    sa.Column('target_collection_ids', postgresql.ARRAY(sa.Integer()), nullable=True),
    sa.Column('sync_frequency', sa.String(length=20), nullable=False),
    sa.Column('sync_enabled', sa.Boolean(), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['chunk_config_id'], ['chunk_config.id'], name=op.f('integration_config_chunk_config_id_fkey')),
    sa.ForeignKeyConstraint(['source_id'], ['source.id'], name=op.f('integration_config_source_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('integration_config_pkey'))
    )
    op.create_index(op.f('integration_config_id_idx'), 'integration_config', ['id'], unique=False)
    op.create_index(op.f('integration_config_source_id_idx'), 'integration_config', ['source_id'], unique=False)
    op.create_table('message_component',
    sa.Column('component_type', sa.String(), nullable=False),
    sa.Column('payload', postgresql.JSONB(astext_type=sa.Text()), nullable=False),
    sa.Column('position', sa.Integer(), nullable=False),
    sa.Column('message_id', sa.Integer(), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['message_id'], ['conversation_message.id'], name=op.f('message_component_message_id_fkey'), ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id', name=op.f('message_component_pkey')),
    sa.UniqueConstraint('message_id', 'position', name='uq_message_component_position')
    )
    op.create_index('ix_message_component_message_id', 'message_component', ['message_id'], unique=False)
    op.create_index('ix_message_component_position', 'message_component', ['message_id', 'position'], unique=False)
    op.create_index(op.f('message_component_id_idx'), 'message_component', ['id'], unique=False)
    op.create_table('message_feedback',
    sa.Column('message_id', sa.Integer(), nullable=False),
    sa.Column('conversation_id', sa.Integer(), nullable=False),
    sa.Column('contact_id', sa.Integer(), nullable=False),
    sa.Column('feedback_type', sa.Enum('THUMBS_DOWN', 'THUMBS_UP', name='feedbacktype'), nullable=False),
    sa.Column('user_query', sa.Text(), nullable=False),
    sa.Column('message_content', sa.Text(), nullable=False),
    sa.Column('user_feedback', sa.Text(), nullable=True),
    sa.Column('llm_synthesized_correction', sa.Text(), nullable=True),
    sa.Column('review_status', sa.Enum('PENDING', 'REVIEWED', 'CORRECTED', name='reviewstatus'), nullable=False),
    sa.Column('reviewed_by', sa.String(length=255), nullable=True),
    sa.Column('reviewed_at', sa.DateTime(), nullable=True),
    sa.Column('metadata_json', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['contact_id'], ['contact.id'], name=op.f('message_feedback_contact_id_fkey')),
    sa.ForeignKeyConstraint(['conversation_id'], ['conversation.id'], name=op.f('message_feedback_conversation_id_fkey')),
    sa.ForeignKeyConstraint(['message_id'], ['conversation_message.id'], name=op.f('message_feedback_message_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('message_feedback_pkey'))
    )
    op.create_index('ix_message_feedback_contact_id', 'message_feedback', ['contact_id'], unique=False)
    op.create_index('ix_message_feedback_conversation_id', 'message_feedback', ['conversation_id'], unique=False)
    op.create_index('ix_message_feedback_created_at', 'message_feedback', ['created_at'], unique=False)
    op.create_index('ix_message_feedback_feedback_type', 'message_feedback', ['feedback_type'], unique=False)
    op.create_index('ix_message_feedback_message_id', 'message_feedback', ['message_id'], unique=False)
    op.create_index('ix_message_feedback_metadata_gin', 'message_feedback', ['metadata_json'], unique=False, postgresql_using='gin')
    op.create_index('ix_message_feedback_review_status', 'message_feedback', ['review_status'], unique=False)
    op.create_index('ix_message_feedback_reviewed_at', 'message_feedback', ['reviewed_at'], unique=False)
    op.create_index(op.f('message_feedback_contact_id_idx'), 'message_feedback', ['contact_id'], unique=False)
    op.create_index(op.f('message_feedback_conversation_id_idx'), 'message_feedback', ['conversation_id'], unique=False)
    op.create_index(op.f('message_feedback_id_idx'), 'message_feedback', ['id'], unique=False)
    op.create_index(op.f('message_feedback_message_id_idx'), 'message_feedback', ['message_id'], unique=False)
    op.create_table('feedback',
    sa.Column('manager_id', sa.Integer(), nullable=False),
    sa.Column('chunk_id', sa.Integer(), nullable=True),
    sa.Column('qa_pair_id', sa.Integer(), nullable=True),
    sa.Column('message_id', sa.Integer(), nullable=True),
    sa.Column('assigned_reviewer_id', sa.Integer(), nullable=True),
    sa.Column('authority_domain', sa.String(length=255), nullable=True),
    sa.Column('confidence_level', sa.String(length=50), nullable=True),
    sa.Column('feedback_type', sa.String(length=50), nullable=False),
    sa.Column('query', sa.Text(), nullable=True),
    sa.Column('provided_response', sa.Text(), nullable=True),
    sa.Column('correction', sa.Text(), nullable=True),
    sa.Column('requires_review', sa.Boolean(), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('admin_notes', sa.Text(), nullable=True),
    sa.Column('reviewed_at', sa.TIMESTAMP(timezone=True), nullable=True),
    sa.Column('routed', sa.Boolean(), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['assigned_reviewer_id'], ['contact.id'], name=op.f('feedback_assigned_reviewer_id_fkey')),
    sa.ForeignKeyConstraint(['chunk_id'], ['chunk.id'], name=op.f('feedback_chunk_id_fkey')),
    sa.ForeignKeyConstraint(['manager_id'], ['contact.id'], name=op.f('feedback_manager_id_fkey')),
    sa.ForeignKeyConstraint(['message_id'], ['conversation_message.id'], name=op.f('feedback_message_id_fkey')),
    sa.ForeignKeyConstraint(['qa_pair_id'], ['qa_pair.id'], name=op.f('feedback_qa_pair_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('feedback_pkey'))
    )
    op.create_index(op.f('feedback_assigned_reviewer_id_idx'), 'feedback', ['assigned_reviewer_id'], unique=False)
    op.create_index(op.f('feedback_chunk_id_idx'), 'feedback', ['chunk_id'], unique=False)
    op.create_index(op.f('feedback_id_idx'), 'feedback', ['id'], unique=False)
    op.create_index(op.f('feedback_manager_id_idx'), 'feedback', ['manager_id'], unique=False)
    op.create_index(op.f('feedback_message_id_idx'), 'feedback', ['message_id'], unique=False)
    op.create_index(op.f('feedback_qa_pair_id_idx'), 'feedback', ['qa_pair_id'], unique=False)
    op.create_index(op.f('feedback_status_idx'), 'feedback', ['status'], unique=False)
    op.create_table('qa_pair_chunk_association',
    sa.Column('qa_pair_id', sa.Integer(), nullable=False),
    sa.Column('chunk_id', sa.Integer(), nullable=False),
    sa.ForeignKeyConstraint(['chunk_id'], ['chunk.id'], name=op.f('qa_pair_chunk_association_chunk_id_fkey')),
    sa.ForeignKeyConstraint(['qa_pair_id'], ['qa_pair.id'], name=op.f('qa_pair_chunk_association_qa_pair_id_fkey')),
    sa.PrimaryKeyConstraint('qa_pair_id', 'chunk_id', name=op.f('qa_pair_chunk_association_pkey'))
    )
    op.create_table('augmentation',
    sa.Column('feedback_id', sa.Integer(), nullable=False),
    sa.Column('original_chunk_id', sa.Integer(), nullable=True),
    sa.Column('original_qa_pair_id', sa.Integer(), nullable=True),
    sa.Column('generated_chunk_id', sa.Integer(), nullable=True),
    sa.Column('generated_qa_pair_id', sa.Integer(), nullable=True),
    sa.Column('action_type', sa.String(length=50), nullable=False),
    sa.Column('change_summary', sa.JSON(), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['feedback_id'], ['feedback.id'], name=op.f('augmentation_feedback_id_fkey')),
    sa.ForeignKeyConstraint(['generated_chunk_id'], ['chunk.id'], name=op.f('augmentation_generated_chunk_id_fkey')),
    sa.ForeignKeyConstraint(['generated_qa_pair_id'], ['qa_pair.id'], name=op.f('augmentation_generated_qa_pair_id_fkey')),
    sa.ForeignKeyConstraint(['original_chunk_id'], ['chunk.id'], name=op.f('augmentation_original_chunk_id_fkey')),
    sa.ForeignKeyConstraint(['original_qa_pair_id'], ['qa_pair.id'], name=op.f('augmentation_original_qa_pair_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('augmentation_pkey'))
    )
    op.create_index(op.f('augmentation_feedback_id_idx'), 'augmentation', ['feedback_id'], unique=False)
    op.create_index(op.f('augmentation_id_idx'), 'augmentation', ['id'], unique=False)
    op.create_index(op.f('augmentation_status_idx'), 'augmentation', ['status'], unique=False)
    op.create_table('feedback_analysis',
    sa.Column('feedback_id', sa.Integer(), nullable=False),
    sa.Column('analysis_type', sa.String(length=50), nullable=False),
    sa.Column('llm_response', sa.JSON(), nullable=True),
    sa.Column('confidence_score', sa.Float(), nullable=True),
    sa.Column('model_used', sa.String(length=255), nullable=True),
    sa.Column('analyzed_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False),
    sa.Column('approved', sa.Boolean(), nullable=False),
    sa.Column('reason_to_reject', sa.Text(), nullable=True),
    sa.Column('id', sa.Integer(), 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.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
    sa.ForeignKeyConstraint(['feedback_id'], ['feedback.id'], name=op.f('feedback_analysis_feedback_id_fkey')),
    sa.PrimaryKeyConstraint('id', name=op.f('feedback_analysis_pkey'))
    )
    op.create_index(op.f('feedback_analysis_feedback_id_idx'), 'feedback_analysis', ['feedback_id'], unique=False)
    op.create_index(op.f('feedback_analysis_id_idx'), 'feedback_analysis', ['id'], unique=False)
    # ### end Alembic commands ###


def downgrade() -> None:
    """Downgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('feedback_analysis_id_idx'), table_name='feedback_analysis')
    op.drop_index(op.f('feedback_analysis_feedback_id_idx'), table_name='feedback_analysis')
    op.drop_table('feedback_analysis')
    op.drop_index(op.f('augmentation_status_idx'), table_name='augmentation')
    op.drop_index(op.f('augmentation_id_idx'), table_name='augmentation')
    op.drop_index(op.f('augmentation_feedback_id_idx'), table_name='augmentation')
    op.drop_table('augmentation')
    op.drop_table('qa_pair_chunk_association')
    op.drop_index(op.f('feedback_status_idx'), table_name='feedback')
    op.drop_index(op.f('feedback_qa_pair_id_idx'), table_name='feedback')
    op.drop_index(op.f('feedback_message_id_idx'), table_name='feedback')
    op.drop_index(op.f('feedback_manager_id_idx'), table_name='feedback')
    op.drop_index(op.f('feedback_id_idx'), table_name='feedback')
    op.drop_index(op.f('feedback_chunk_id_idx'), table_name='feedback')
    op.drop_index(op.f('feedback_assigned_reviewer_id_idx'), table_name='feedback')
    op.drop_table('feedback')
    op.drop_index(op.f('message_feedback_message_id_idx'), table_name='message_feedback')
    op.drop_index(op.f('message_feedback_id_idx'), table_name='message_feedback')
    op.drop_index(op.f('message_feedback_conversation_id_idx'), table_name='message_feedback')
    op.drop_index(op.f('message_feedback_contact_id_idx'), table_name='message_feedback')
    op.drop_index('ix_message_feedback_reviewed_at', table_name='message_feedback')
    op.drop_index('ix_message_feedback_review_status', table_name='message_feedback')
    op.drop_index('ix_message_feedback_metadata_gin', table_name='message_feedback', postgresql_using='gin')
    op.drop_index('ix_message_feedback_message_id', table_name='message_feedback')
    op.drop_index('ix_message_feedback_feedback_type', table_name='message_feedback')
    op.drop_index('ix_message_feedback_created_at', table_name='message_feedback')
    op.drop_index('ix_message_feedback_conversation_id', table_name='message_feedback')
    op.drop_index('ix_message_feedback_contact_id', table_name='message_feedback')
    op.drop_table('message_feedback')
    op.drop_index(op.f('message_component_id_idx'), table_name='message_component')
    op.drop_index('ix_message_component_position', table_name='message_component')
    op.drop_index('ix_message_component_message_id', table_name='message_component')
    op.drop_table('message_component')
    op.drop_index(op.f('integration_config_source_id_idx'), table_name='integration_config')
    op.drop_index(op.f('integration_config_id_idx'), table_name='integration_config')
    op.drop_table('integration_config')
    op.drop_index('ix_conversation_message_metadata_retrieval_gin', table_name='conversation_message_metadata', postgresql_using='gin')
    op.drop_index(op.f('conversation_message_metadata_id_idx'), table_name='conversation_message_metadata')
    op.drop_table('conversation_message_metadata')
    op.drop_index(op.f('chunk_text_hash_idx'), table_name='chunk')
    op.drop_index(op.f('chunk_id_idx'), table_name='chunk')
    op.drop_index(op.f('chunk_document_id_idx'), table_name='chunk')
    op.drop_table('chunk')
    op.drop_index(op.f('qa_pair_id_idx'), table_name='qa_pair')
    op.drop_index(op.f('qa_pair_document_id_idx'), table_name='qa_pair')
    op.drop_table('qa_pair')
    op.drop_index('ix_conversation_message_llm_response_gin', table_name='conversation_message', postgresql_using='gin')
    op.drop_index('ix_conversation_message_conversation_sequence', table_name='conversation_message')
    op.drop_index('ix_conversation_message_conversation_created', table_name='conversation_message')
    op.drop_index(op.f('conversation_message_id_idx'), table_name='conversation_message')
    op.drop_table('conversation_message')
    op.drop_index('ix_sim_compare_conversation_sequence', table_name='conversation_compare')
    op.drop_index('ix_sim_compare_conversation_created', table_name='conversation_compare')
    op.drop_index(op.f('conversation_compare_id_idx'), table_name='conversation_compare')
    op.drop_table('conversation_compare')
    op.drop_index(op.f('collection_document_id_idx'), table_name='collection_document')
    op.drop_table('collection_document')
    op.drop_index(op.f('chunk_config_id_idx'), table_name='chunk_config')
    op.drop_table('chunk_config')
    op.drop_index(op.f('document_uploaded_by_id_idx'), table_name='document')
    op.drop_index(op.f('document_title_idx'), table_name='document')
    op.drop_index(op.f('document_status_idx'), table_name='document')
    op.drop_index(op.f('document_source_id_idx'), table_name='document')
    op.drop_index(op.f('document_parent_document_id_idx'), table_name='document')
    op.drop_index(op.f('document_id_idx'), table_name='document')
    op.drop_table('document')
    op.drop_index(op.f('conversation_uuid_idx'), table_name='conversation')
    op.drop_index(op.f('conversation_id_idx'), table_name='conversation')
    op.drop_table('conversation')
    op.drop_index(op.f('collection_owner_id_idx'), table_name='collection')
    op.drop_index(op.f('collection_name_idx'), table_name='collection')
    op.drop_index(op.f('collection_id_idx'), table_name='collection')
    op.drop_table('collection')
    op.drop_index(op.f('vector_id_idx'), table_name='vector')
    op.drop_index('idx_vector_source', table_name='vector')
    op.drop_table('vector')
    op.drop_index(op.f('source_name_idx'), table_name='source')
    op.drop_index(op.f('source_id_idx'), table_name='source')
    op.drop_table('source')
    op.drop_index(op.f('contact_id_idx'), table_name='contact')
    op.drop_table('contact')
    # ### end Alembic commands ###
