"""initial migration

Revision ID: 1b2b1036ce38
Revises: 
Create Date: 2026-06-05 16:37:45.551464

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '1b2b1036ce38'
down_revision = None
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('balance',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('initial_charge_usd', sa.Float(), nullable=False),
    sa.Column('remaining_balance_usd', sa.Float(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('dashboards',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('user_id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(length=128), nullable=False),
    sa.Column('is_favorite', sa.Boolean(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    with op.batch_alter_table('dashboards', schema=None) as batch_op:
        batch_op.create_index('ix_dashboards_user_favorite', ['user_id', 'is_favorite'], unique=False)
        batch_op.create_index(batch_op.f('ix_dashboards_user_id'), ['user_id'], unique=False)

    op.create_table('doc_config',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('cache_lifetime', sa.Integer(), nullable=False),
    sa.Column('chunk_size', sa.Integer(), nullable=False),
    sa.Column('chunk_overlap', sa.Integer(), nullable=False),
    sa.Column('batch_size', sa.Integer(), nullable=False),
    sa.Column('top_k', sa.Integer(), nullable=False),
    sa.Column('updated_by', sa.Integer(), nullable=True),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('machines',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(length=128), nullable=False),
    sa.Column('display_name', sa.String(length=128), nullable=False),
    sa.Column('machine_type', sa.String(length=100), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('location', sa.String(length=200), nullable=True),
    sa.Column('meta', sa.JSON(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('name')
    )
    op.create_table('openai_models',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(length=100), nullable=False),
    sa.Column('model_type', sa.Enum('TEXT', 'TEXT_STREAM', 'TEXT_TO_VOICE', 'VOICE_TO_TEXT', 'TEXT_EMBED', name='model_type_enum'), nullable=False),
    sa.Column('input_cost_per_1m', sa.Float(), nullable=False),
    sa.Column('output_cost_per_1m', sa.Float(), nullable=False),
    sa.Column('cache_cost_per_1m', sa.Float(), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('name')
    )
    op.create_table('prompt_files',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('user_id', sa.Integer(), nullable=True),
    sa.Column('prompt_type', sa.Enum('TEXT', 'ANSWER_STRUCT', 'CONVERSATION', 'TEXT_TO_VOICE', 'REFERENCES', name='prompttype'), nullable=False),
    sa.Column('filename', sa.String(length=255), nullable=False),
    sa.Column('filepath', sa.String(length=500), nullable=False),
    sa.Column('uploaded_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('system_prompts',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('type', sa.Enum('TEXT', 'ANSWER_STRUCT', 'CONVERSATION', 'TEXT_TO_VOICE', 'REFERENCES', name='prompttype'), nullable=False),
    sa.Column('content', sa.Text(), nullable=False),
    sa.Column('is_active', sa.Boolean(), nullable=True),
    sa.Column('updated_by', sa.Integer(), nullable=True),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('type')
    )
    op.create_table('users',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('first_name', sa.String(length=120), nullable=True),
    sa.Column('last_name', sa.String(length=120), nullable=True),
    sa.Column('email', sa.String(length=255), nullable=True),
    sa.Column('phone', sa.String(length=50), nullable=True),
    sa.Column('password_hash', sa.String(length=255), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('role', sa.Enum('ADMIN', 'USER', name='role_enum'), nullable=False),
    sa.Column('license_type', sa.Enum('TIME_BASED', 'QUANTITY_BASED', name='license_type_enum'), nullable=True),
    sa.Column('license_expiry', sa.Date(), nullable=True),
    sa.Column('license_quantity', sa.Integer(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    with op.batch_alter_table('users', schema=None) as batch_op:
        batch_op.create_index(batch_op.f('ix_users_email'), ['email'], unique=True)
        batch_op.create_index(batch_op.f('ix_users_phone'), ['phone'], unique=True)

    op.create_table('ai_task_model_configs',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('text_model_id', sa.Integer(), nullable=True),
    sa.Column('text_stream_model_id', sa.Integer(), nullable=True),
    sa.Column('voice_to_text_model_id', sa.Integer(), nullable=True),
    sa.Column('text_to_voice_model_id', sa.Integer(), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['text_model_id'], ['openai_models.id'], ),
    sa.ForeignKeyConstraint(['text_stream_model_id'], ['openai_models.id'], ),
    sa.ForeignKeyConstraint(['text_to_voice_model_id'], ['openai_models.id'], ),
    sa.ForeignKeyConstraint(['voice_to_text_model_id'], ['openai_models.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('model_token_usage',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('model_id', sa.Integer(), nullable=False),
    sa.Column('input_tokens', sa.Integer(), nullable=True),
    sa.Column('output_tokens', sa.Integer(), nullable=True),
    sa.Column('total_cost', sa.Float(), nullable=False),
    sa.Column('user_id', sa.Integer(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['model_id'], ['openai_models.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('parameters',
    sa.Column('id', sa.String(length=36), nullable=False),
    sa.Column('machine_id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(length=200), nullable=False),
    sa.Column('tag', sa.String(length=200), nullable=False),
    sa.Column('display_name', sa.String(length=200), nullable=False),
    sa.Column('data_type', sa.String(length=50), nullable=False),
    sa.Column('unit', sa.String(length=50), nullable=True),
    sa.Column('domain', sa.Enum('PRODUCTION', 'MAINTENANCE', 'QUALITY', name='parameterdomain'), nullable=False),
    sa.Column('min_value', sa.Float(), nullable=True),
    sa.Column('max_value', sa.Float(), nullable=True),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['machine_id'], ['machines.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('machine_id', 'name', name='uq_machine_parameter_name'),
    sa.UniqueConstraint('machine_id', 'tag', name='uq_machine_parameter_tag')
    )
    op.create_table('dashboard_widgets',
    sa.Column('id', sa.String(length=36), nullable=False),
    sa.Column('dashboard_id', sa.Integer(), nullable=False),
    sa.Column('parameter_id', sa.String(length=36), nullable=True),
    sa.Column('machine_id', sa.Integer(), nullable=True),
    sa.Column('widget_type', sa.String(length=20), nullable=False),
    sa.Column('title', sa.String(length=160), nullable=True),
    sa.Column('decimal_precision', sa.Integer(), nullable=False),
    sa.Column('markdown_content', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.ForeignKeyConstraint(['dashboard_id'], ['dashboards.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['machine_id'], ['machines.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['parameter_id'], ['parameters.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    with op.batch_alter_table('dashboard_widgets', schema=None) as batch_op:
        batch_op.create_index(batch_op.f('ix_dashboard_widgets_dashboard_id'), ['dashboard_id'], unique=False)
        batch_op.create_index(batch_op.f('ix_dashboard_widgets_machine_id'), ['machine_id'], unique=False)
        batch_op.create_index(batch_op.f('ix_dashboard_widgets_parameter_id'), ['parameter_id'], unique=False)

    op.create_table('incidents',
    sa.Column('id', sa.String(length=36), nullable=False),
    sa.Column('incident_type', sa.Enum('sensor_issue', 'threshold_breach', 'instability', 'oscillation', 'machine_anomaly', name='incidentevents'), nullable=False),
    sa.Column('severity', sa.Enum('high', 'medium', 'low', name='incidentseverity'), nullable=False),
    sa.Column('machine_id', sa.Integer(), nullable=False),
    sa.Column('trigger_parameter_id', sa.String(length=36), nullable=False),
    sa.Column('trigger_value', sa.Float(), nullable=False),
    sa.Column('trigger_timestamp', sa.DateTime(), nullable=False),
    sa.Column('summary', sa.Text(), nullable=True),
    sa.Column('payload', sa.JSON(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['machine_id'], ['machines.id'], ),
    sa.ForeignKeyConstraint(['trigger_parameter_id'], ['parameters.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    with op.batch_alter_table('incidents', schema=None) as batch_op:
        batch_op.create_index(batch_op.f('ix_incidents_incident_type'), ['incident_type'], unique=False)
        batch_op.create_index(batch_op.f('ix_incidents_machine_id'), ['machine_id'], unique=False)
        batch_op.create_index(batch_op.f('ix_incidents_severity'), ['severity'], unique=False)
        batch_op.create_index(batch_op.f('ix_incidents_trigger_parameter_id'), ['trigger_parameter_id'], unique=False)
        batch_op.create_index(batch_op.f('ix_incidents_trigger_timestamp'), ['trigger_timestamp'], unique=False)

    op.create_table('parameter_values',
    sa.Column('id', sa.String(length=36), nullable=False),
    sa.Column('parameter_id', sa.String(length=36), nullable=False),
    sa.Column('value', sa.Float(), nullable=False),
    sa.Column('timestamp', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['parameter_id'], ['parameters.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('incident_analyses',
    sa.Column('id', sa.String(length=36), nullable=False),
    sa.Column('incident_id', sa.String(length=36), nullable=False),
    sa.Column('status', sa.Enum('created', 'confirmed', 'analyzing', 'completed', 'failed', name='incidentstatusenum'), nullable=False),
    sa.Column('analysis_json', sa.JSON(), nullable=False),
    sa.Column('llm_context', sa.JSON(), nullable=True),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.ForeignKeyConstraint(['incident_id'], ['incidents.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    with op.batch_alter_table('incident_analyses', schema=None) as batch_op:
        batch_op.create_index(batch_op.f('ix_incident_analyses_incident_id'), ['incident_id'], unique=False)
        batch_op.create_index(batch_op.f('ix_incident_analyses_status'), ['status'], unique=False)

    op.create_table('chat_sessions',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('session_url', sa.String(length=255), nullable=False),
    sa.Column('analysis_id', sa.String(length=36), nullable=True),
    sa.Column('user_id', sa.Integer(), nullable=False),
    sa.Column('title', sa.String(length=140), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=True),
    sa.Column('is_shared', sa.Boolean(), nullable=False),
    sa.Column('share_token', sa.String(length=64), nullable=True),
    sa.Column('shared_at', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['analysis_id'], ['incident_analyses.id'], ondelete='SET NULL'),
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('session_url')
    )
    with op.batch_alter_table('chat_sessions', schema=None) as batch_op:
        batch_op.create_index(batch_op.f('ix_chat_sessions_analysis_id'), ['analysis_id'], unique=False)
        batch_op.create_index(batch_op.f('ix_chat_sessions_is_shared'), ['is_shared'], unique=False)
        batch_op.create_index(batch_op.f('ix_chat_sessions_share_token'), ['share_token'], unique=True)

    op.create_table('chat_messages',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('user_id', sa.Integer(), nullable=False),
    sa.Column('session_id', sa.Integer(), nullable=False),
    sa.Column('sender_type', sa.Enum('USER', 'BOT', name='sendertypeenum'), nullable=False),
    sa.Column('message', sa.Text(), nullable=False),
    sa.Column('language', sa.String(length=10), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.ForeignKeyConstraint(['session_id'], ['chat_sessions.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    with op.batch_alter_table('chat_messages', schema=None) as batch_op:
        batch_op.create_index(batch_op.f('ix_chat_messages_session_id'), ['session_id'], unique=False)
        batch_op.create_index(batch_op.f('ix_chat_messages_user_id'), ['user_id'], unique=False)

    op.create_table('chat_message_images',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('chat_message_id', sa.Integer(), nullable=False),
    sa.Column('image_url', sa.String(length=255), nullable=False),
    sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
    sa.ForeignKeyConstraint(['chat_message_id'], ['chat_messages.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('id')
    )
    with op.batch_alter_table('chat_message_images', schema=None) as batch_op:
        batch_op.create_index(batch_op.f('ix_chat_message_images_chat_message_id'), ['chat_message_id'], unique=False)

    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('chat_message_images', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_chat_message_images_chat_message_id'))

    op.drop_table('chat_message_images')
    with op.batch_alter_table('chat_messages', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_chat_messages_user_id'))
        batch_op.drop_index(batch_op.f('ix_chat_messages_session_id'))

    op.drop_table('chat_messages')
    with op.batch_alter_table('chat_sessions', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_chat_sessions_share_token'))
        batch_op.drop_index(batch_op.f('ix_chat_sessions_is_shared'))
        batch_op.drop_index(batch_op.f('ix_chat_sessions_analysis_id'))

    op.drop_table('chat_sessions')
    with op.batch_alter_table('incident_analyses', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_incident_analyses_status'))
        batch_op.drop_index(batch_op.f('ix_incident_analyses_incident_id'))

    op.drop_table('incident_analyses')
    op.drop_table('parameter_values')
    with op.batch_alter_table('incidents', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_incidents_trigger_timestamp'))
        batch_op.drop_index(batch_op.f('ix_incidents_trigger_parameter_id'))
        batch_op.drop_index(batch_op.f('ix_incidents_severity'))
        batch_op.drop_index(batch_op.f('ix_incidents_machine_id'))
        batch_op.drop_index(batch_op.f('ix_incidents_incident_type'))

    op.drop_table('incidents')
    with op.batch_alter_table('dashboard_widgets', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_dashboard_widgets_parameter_id'))
        batch_op.drop_index(batch_op.f('ix_dashboard_widgets_machine_id'))
        batch_op.drop_index(batch_op.f('ix_dashboard_widgets_dashboard_id'))

    op.drop_table('dashboard_widgets')
    op.drop_table('parameters')
    op.drop_table('model_token_usage')
    op.drop_table('ai_task_model_configs')
    with op.batch_alter_table('users', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_users_phone'))
        batch_op.drop_index(batch_op.f('ix_users_email'))

    op.drop_table('users')
    op.drop_table('system_prompts')
    op.drop_table('prompt_files')
    op.drop_table('openai_models')
    op.drop_table('machines')
    op.drop_table('doc_config')
    with op.batch_alter_table('dashboards', schema=None) as batch_op:
        batch_op.drop_index(batch_op.f('ix_dashboards_user_id'))
        batch_op.drop_index('ix_dashboards_user_favorite')

    op.drop_table('dashboards')
    op.drop_table('balance')
    # ### end Alembic commands ###
