"""add training models

Revision ID: 9245f8845fe1
Revises: 001
Create Date: 2025-09-21 22:11:03.319902

"""
from typing import Sequence, Union

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

# revision identifiers, used by Alembic.
revision: str = '9245f8845fe1'
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('training_scenes',
    sa.Column('name', sa.String(length=100), nullable=False, comment='场景名称'),
    sa.Column('description', sa.Text(), nullable=True, comment='场景描述'),
    sa.Column('category', sa.String(length=50), nullable=False, comment='场景分类'),
    sa.Column('ai_config', sa.JSON(), nullable=True, comment='AI配置（如Coze Bot ID等）'),
    sa.Column('prompt_template', sa.Text(), nullable=True, comment='提示词模板'),
    sa.Column('evaluation_criteria', sa.JSON(), nullable=True, comment='评估标准'),
    sa.Column('status', sa.Enum('DRAFT', 'ACTIVE', 'INACTIVE', name='trainingscenestatus'), nullable=False, comment='场景状态'),
    sa.Column('is_public', sa.Boolean(), nullable=False, comment='是否公开'),
    sa.Column('required_level', sa.Integer(), nullable=True, comment='所需用户等级'),
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.Column('is_deleted', sa.Boolean(), nullable=False),
    sa.Column('deleted_at', sa.DateTime(), nullable=True),
    sa.Column('created_by', sa.Integer(), nullable=True),
    sa.Column('updated_by', sa.Integer(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_training_scenes_id'), 'training_scenes', ['id'], unique=False)
    op.create_table('training_sessions',
    sa.Column('user_id', sa.Integer(), nullable=False, comment='用户ID'),
    sa.Column('scene_id', sa.Integer(), nullable=False, comment='场景ID'),
    sa.Column('coze_conversation_id', sa.String(length=100), nullable=True, comment='Coze会话ID'),
    sa.Column('start_time', sa.DateTime(), nullable=False, comment='开始时间'),
    sa.Column('end_time', sa.DateTime(), nullable=True, comment='结束时间'),
    sa.Column('duration_seconds', sa.Integer(), nullable=True, comment='持续时长（秒）'),
    sa.Column('status', sa.Enum('CREATED', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED', 'ERROR', name='trainingsessionstatus'), nullable=False, comment='会话状态'),
    sa.Column('session_config', sa.JSON(), nullable=True, comment='会话配置'),
    sa.Column('total_score', sa.Float(), nullable=True, comment='总分'),
    sa.Column('evaluation_result', sa.JSON(), nullable=True, comment='评估结果详情'),
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.Column('created_by', sa.Integer(), nullable=True),
    sa.Column('updated_by', sa.Integer(), nullable=True),
    sa.ForeignKeyConstraint(['scene_id'], ['training_scenes.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_training_sessions_id'), 'training_sessions', ['id'], unique=False)
    op.create_index(op.f('ix_training_sessions_user_id'), 'training_sessions', ['user_id'], unique=False)
    op.create_table('training_messages',
    sa.Column('session_id', sa.Integer(), nullable=False, comment='会话ID'),
    sa.Column('role', sa.Enum('USER', 'ASSISTANT', 'SYSTEM', name='messagerole'), nullable=False, comment='消息角色'),
    sa.Column('type', sa.Enum('TEXT', 'VOICE', 'SYSTEM', name='messagetype'), nullable=False, comment='消息类型'),
    sa.Column('content', sa.Text(), nullable=False, comment='消息内容'),
    sa.Column('voice_url', sa.String(length=500), nullable=True, comment='语音文件URL'),
    sa.Column('voice_duration', sa.Float(), nullable=True, comment='语音时长（秒）'),
    sa.Column('message_metadata', sa.JSON(), nullable=True, comment='消息元数据'),
    sa.Column('coze_message_id', sa.String(length=100), nullable=True, comment='Coze消息ID'),
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.ForeignKeyConstraint(['session_id'], ['training_sessions.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_training_messages_id'), 'training_messages', ['id'], unique=False)
    op.create_table('training_reports',
    sa.Column('session_id', sa.Integer(), nullable=False, comment='会话ID'),
    sa.Column('user_id', sa.Integer(), nullable=False, comment='用户ID'),
    sa.Column('overall_score', sa.Float(), nullable=False, comment='总体得分'),
    sa.Column('dimension_scores', sa.JSON(), nullable=False, comment='各维度得分'),
    sa.Column('strengths', sa.JSON(), nullable=False, comment='优势点'),
    sa.Column('weaknesses', sa.JSON(), nullable=False, comment='待改进点'),
    sa.Column('suggestions', sa.JSON(), nullable=False, comment='改进建议'),
    sa.Column('detailed_analysis', sa.Text(), nullable=True, comment='详细分析'),
    sa.Column('transcript', sa.Text(), nullable=True, comment='对话文本记录'),
    sa.Column('statistics', sa.JSON(), nullable=True, comment='统计数据'),
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('created_at', sa.DateTime(), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.Column('created_by', sa.Integer(), nullable=True),
    sa.Column('updated_by', sa.Integer(), nullable=True),
    sa.ForeignKeyConstraint(['session_id'], ['training_sessions.id'], ),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('session_id')
    )
    op.create_index(op.f('ix_training_reports_id'), 'training_reports', ['id'], unique=False)
    op.create_index(op.f('ix_training_reports_user_id'), 'training_reports', ['user_id'], unique=False)
    op.create_table('user_teams',
    sa.Column('user_id', sa.Integer(), nullable=False),
    sa.Column('team_id', sa.Integer(), nullable=False),
    sa.Column('role', sa.String(length=50), nullable=False),
    sa.Column('joined_at', sa.DateTime(), nullable=False),
    sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ondelete='CASCADE'),
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
    sa.PrimaryKeyConstraint('user_id', 'team_id'),
    sa.UniqueConstraint('user_id', 'team_id', name='uq_user_team')
    )
    op.alter_column('course_materials', 'course_id',
               existing_type=mysql.INTEGER(),
               comment='课程ID',
               existing_comment='è¯¾ç¨‹ID',
               existing_nullable=False)
    op.alter_column('course_materials', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='资料名称',
               existing_comment='èµ„æ–™å\x90\x8dç§°',
               existing_nullable=False)
    op.alter_column('course_materials', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='资料描述',
               existing_comment='èµ„æ–™æ\x8f\x8fè¿°',
               existing_nullable=True)
    op.alter_column('course_materials', 'file_url',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=500),
               comment='文件URL',
               existing_comment='æ–‡ä»¶URL',
               existing_nullable=False)
    op.alter_column('course_materials', 'file_type',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=50),
               comment='文件类型',
               existing_comment='æ–‡ä»¶ç±»åž‹',
               existing_nullable=False)
    op.alter_column('course_materials', 'file_size',
               existing_type=mysql.INTEGER(),
               comment='文件大小(字节)',
               existing_comment='æ–‡ä»¶å¤§å°\x8f(å\xad—èŠ‚)',
               existing_nullable=False)
    op.alter_column('course_materials', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='排序顺序',
               existing_comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.drop_index('idx_course_materials_course_id', table_name='course_materials')
    op.drop_index('idx_course_materials_is_deleted', table_name='course_materials')
    op.create_index(op.f('ix_course_materials_id'), 'course_materials', ['id'], unique=False)
    op.drop_table_comment(
        'course_materials',
        existing_comment='è¯¾ç¨‹èµ„æ–™è¡¨',
        schema=None
    )
    op.alter_column('courses', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='课程名称',
               existing_comment='è¯¾ç¨‹å\x90\x8dç§°',
               existing_nullable=False)
    op.alter_column('courses', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='课程描述',
               existing_comment='è¯¾ç¨‹æ\x8f\x8fè¿°',
               existing_nullable=True)
    op.alter_column('courses', 'category',
               existing_type=mysql.ENUM('technology', 'management', 'business', 'general', collation='utf8mb4_unicode_ci'),
               comment='课程分类',
               existing_comment='è¯¾ç¨‹åˆ†ç±»',
               existing_nullable=False,
               existing_server_default=sa.text("'general'"))
    op.alter_column('courses', 'status',
               existing_type=mysql.ENUM('draft', 'published', 'archived', collation='utf8mb4_unicode_ci'),
               comment='课程状态',
               existing_comment='è¯¾ç¨‹çŠ¶æ€\x81',
               existing_nullable=False,
               existing_server_default=sa.text("'draft'"))
    op.alter_column('courses', 'cover_image',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=500),
               comment='封面图片URL',
               existing_comment='å°\x81é\x9d¢å›¾ç‰‡URL',
               existing_nullable=True)
    op.alter_column('courses', 'duration_hours',
               existing_type=mysql.FLOAT(),
               comment='课程时长(小时)',
               existing_comment='è¯¾ç¨‹æ—¶é•¿(å°\x8fæ—¶)',
               existing_nullable=True)
    op.alter_column('courses', 'difficulty_level',
               existing_type=mysql.INTEGER(),
               comment='难度等级(1-5)',
               existing_comment='éš¾åº¦ç\xad‰çº§(1-5)',
               existing_nullable=True)
    op.alter_column('courses', 'tags',
               existing_type=mysql.JSON(),
               comment='标签列表',
               existing_comment='æ\xa0‡ç\xad¾åˆ—è¡¨',
               existing_nullable=True)
    op.alter_column('courses', 'published_at',
               existing_type=mysql.DATETIME(),
               comment='发布时间',
               existing_comment='å\x8f‘å¸ƒæ—¶é—´',
               existing_nullable=True)
    op.alter_column('courses', 'publisher_id',
               existing_type=mysql.INTEGER(),
               comment='发布人ID',
               existing_comment='å\x8f‘å¸ƒäººID',
               existing_nullable=True)
    op.alter_column('courses', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='排序顺序',
               existing_comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.alter_column('courses', 'is_featured',
               existing_type=mysql.TINYINT(display_width=1),
               comment='是否推荐',
               existing_comment='æ˜¯å\x90¦æŽ¨è\x8d\x90',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.drop_index('idx_courses_category', table_name='courses')
    op.drop_index('idx_courses_is_deleted', table_name='courses')
    op.drop_index('idx_courses_status', table_name='courses')
    op.create_index(op.f('ix_courses_id'), 'courses', ['id'], unique=False)
    op.drop_table_comment(
        'courses',
        existing_comment='è¯¾ç¨‹è¡¨',
        schema=None
    )
    op.alter_column('growth_paths', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='路径名称',
               existing_comment='è·¯å¾„å\x90\x8dç§°',
               existing_nullable=False)
    op.alter_column('growth_paths', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='路径描述',
               existing_comment='è·¯å¾„æ\x8f\x8fè¿°',
               existing_nullable=True)
    op.alter_column('growth_paths', 'target_role',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=100),
               comment='目标角色',
               existing_comment='ç›®æ\xa0‡è§’è‰²',
               existing_nullable=True)
    op.alter_column('growth_paths', 'courses',
               existing_type=mysql.JSON(),
               comment='课程列表[{course_id, order, is_required}]',
               existing_comment='è¯¾ç¨‹åˆ—è¡¨[{course_id, order, is_required}]',
               existing_nullable=True)
    op.alter_column('growth_paths', 'estimated_duration_days',
               existing_type=mysql.INTEGER(),
               comment='预计完成天数',
               existing_comment='é¢„è®¡å®Œæˆ\x90å¤©æ•°',
               existing_nullable=True)
    op.alter_column('growth_paths', 'is_active',
               existing_type=mysql.TINYINT(display_width=1),
               comment='是否启用',
               existing_comment='æ˜¯å\x90¦å\x90¯ç”¨',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('growth_paths', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='排序顺序',
               existing_comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.drop_index('idx_growth_paths_is_active', table_name='growth_paths')
    op.drop_index('idx_growth_paths_is_deleted', table_name='growth_paths')
    op.create_index(op.f('ix_growth_paths_id'), 'growth_paths', ['id'], unique=False)
    op.drop_table_comment(
        'growth_paths',
        existing_comment='æˆ\x90é•¿è·¯å¾„è¡¨',
        schema=None
    )
    op.alter_column('knowledge_points', 'course_id',
               existing_type=mysql.INTEGER(),
               comment='课程ID',
               existing_comment='è¯¾ç¨‹ID',
               existing_nullable=False)
    op.alter_column('knowledge_points', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='知识点名称',
               existing_comment='çŸ¥è¯†ç‚¹å\x90\x8dç§°',
               existing_nullable=False)
    op.alter_column('knowledge_points', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='知识点描述',
               existing_comment='çŸ¥è¯†ç‚¹æ\x8f\x8fè¿°',
               existing_nullable=True)
    op.alter_column('knowledge_points', 'parent_id',
               existing_type=mysql.INTEGER(),
               comment='父知识点ID',
               existing_comment='çˆ¶çŸ¥è¯†ç‚¹ID',
               existing_nullable=True)
    op.alter_column('knowledge_points', 'level',
               existing_type=mysql.INTEGER(),
               comment='层级深度',
               existing_comment='å±‚çº§æ·±åº¦',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('knowledge_points', 'path',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=500),
               comment='路径(如: 1.2.3)',
               existing_comment='è·¯å¾„(å¦‚: 1.2.3)',
               existing_nullable=True)
    op.alter_column('knowledge_points', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='排序顺序',
               existing_comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.alter_column('knowledge_points', 'weight',
               existing_type=mysql.FLOAT(),
               comment='权重',
               existing_comment='æ\x9dƒé‡\x8d',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('knowledge_points', 'is_required',
               existing_type=mysql.TINYINT(display_width=1),
               comment='是否必修',
               existing_comment='æ˜¯å\x90¦å¿…ä¿®',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('knowledge_points', 'estimated_hours',
               existing_type=mysql.FLOAT(),
               comment='预计学习时间(小时)',
               existing_comment='é¢„è®¡å\xad¦ä¹\xa0æ—¶é—´(å°\x8fæ—¶)',
               existing_nullable=True)
    op.drop_index('idx_knowledge_points_course_id', table_name='knowledge_points')
    op.drop_index('idx_knowledge_points_is_deleted', table_name='knowledge_points')
    op.drop_index('idx_knowledge_points_parent_id', table_name='knowledge_points')
    op.create_index(op.f('ix_knowledge_points_id'), 'knowledge_points', ['id'], unique=False)
    op.drop_table_comment(
        'knowledge_points',
        existing_comment='çŸ¥è¯†ç‚¹è¡¨',
        schema=None
    )
    op.drop_index('ix_teams_is_deleted', table_name='teams')
    op.drop_index('ix_teams_parent_id', table_name='teams')
    op.create_foreign_key(None, 'teams', 'users', ['leader_id'], ['id'], ondelete='SET NULL')
    op.create_foreign_key(None, 'teams', 'teams', ['parent_id'], ['id'], ondelete='CASCADE')
    op.drop_column('teams', 'deleted_at')
    op.drop_column('teams', 'created_by')
    op.drop_column('teams', 'updated_by')
    op.drop_column('teams', 'is_deleted')
    op.add_column('users', sa.Column('bio', sa.Text(), nullable=True))
    op.add_column('users', sa.Column('is_verified', sa.Boolean(), nullable=False))
    op.add_column('users', sa.Column('last_login_at', sa.DateTime(), nullable=True))
    op.add_column('users', sa.Column('password_changed_at', sa.DateTime(), nullable=True))
    op.alter_column('users', 'username',
               existing_type=mysql.VARCHAR(length=50),
               comment=None,
               existing_comment='用户名',
               existing_nullable=False)
    op.alter_column('users', 'email',
               existing_type=mysql.VARCHAR(length=100),
               comment=None,
               existing_comment='邮箱',
               existing_nullable=False)
    op.alter_column('users', 'phone',
               existing_type=mysql.VARCHAR(length=20),
               comment=None,
               existing_comment='手机号',
               existing_nullable=True)
    op.alter_column('users', 'password_hash',
               existing_type=mysql.VARCHAR(length=200),
               comment=None,
               existing_comment='密码哈希',
               existing_nullable=False)
    op.alter_column('users', 'full_name',
               existing_type=mysql.VARCHAR(length=100),
               comment=None,
               existing_comment='全名',
               existing_nullable=True)
    op.alter_column('users', 'avatar_url',
               existing_type=mysql.VARCHAR(length=500),
               comment=None,
               existing_comment='头像URL',
               existing_nullable=True)
    op.alter_column('users', 'role',
               existing_type=mysql.VARCHAR(length=20),
               nullable=False,
               comment=None,
               existing_comment='角色: trainee(学员), manager(管理者), admin(管理员)')
    op.alter_column('users', 'is_active',
               existing_type=mysql.TINYINT(display_width=1),
               nullable=False,
               comment=None,
               existing_comment='是否激活')
    op.alter_column('users', 'id',
               existing_type=mysql.BIGINT(),
               type_=sa.Integer(),
               existing_nullable=False,
               autoincrement=True)
    op.create_unique_constraint(None, 'users', ['phone'])
    op.drop_column('users', 'position')
    op.drop_column('users', 'is_superuser')
    op.drop_column('users', 'locked_until')
    op.drop_column('users', 'login_count')
    op.drop_column('users', 'failed_login_count')
    op.drop_column('users', 'department')
    op.drop_column('users', 'created_by')
    op.drop_column('users', 'updated_by')
    op.drop_column('users', 'last_login')
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('users', sa.Column('last_login', mysql.VARCHAR(length=100), nullable=True, comment='最后登录时间'))
    op.add_column('users', sa.Column('updated_by', mysql.BIGINT(), autoincrement=False, nullable=True))
    op.add_column('users', sa.Column('created_by', mysql.BIGINT(), autoincrement=False, nullable=True))
    op.add_column('users', sa.Column('department', mysql.VARCHAR(length=100), nullable=True, comment='部门'))
    op.add_column('users', sa.Column('failed_login_count', mysql.VARCHAR(length=100), nullable=True, comment='失败登录次数'))
    op.add_column('users', sa.Column('login_count', mysql.VARCHAR(length=100), nullable=True, comment='登录次数'))
    op.add_column('users', sa.Column('locked_until', mysql.VARCHAR(length=100), nullable=True, comment='锁定到期时间'))
    op.add_column('users', sa.Column('is_superuser', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True, comment='是否超级管理员'))
    op.add_column('users', sa.Column('position', mysql.VARCHAR(length=100), nullable=True, comment='职位'))
    op.drop_constraint(None, 'users', type_='unique')
    op.alter_column('users', 'id',
               existing_type=sa.Integer(),
               type_=mysql.BIGINT(),
               existing_nullable=False,
               autoincrement=True)
    op.alter_column('users', 'is_active',
               existing_type=mysql.TINYINT(display_width=1),
               nullable=True,
               comment='是否激活')
    op.alter_column('users', 'role',
               existing_type=mysql.VARCHAR(length=20),
               nullable=True,
               comment='角色: trainee(学员), manager(管理者), admin(管理员)')
    op.alter_column('users', 'avatar_url',
               existing_type=mysql.VARCHAR(length=500),
               comment='头像URL',
               existing_nullable=True)
    op.alter_column('users', 'full_name',
               existing_type=mysql.VARCHAR(length=100),
               comment='全名',
               existing_nullable=True)
    op.alter_column('users', 'password_hash',
               existing_type=mysql.VARCHAR(length=200),
               comment='密码哈希',
               existing_nullable=False)
    op.alter_column('users', 'phone',
               existing_type=mysql.VARCHAR(length=20),
               comment='手机号',
               existing_nullable=True)
    op.alter_column('users', 'email',
               existing_type=mysql.VARCHAR(length=100),
               comment='邮箱',
               existing_nullable=False)
    op.alter_column('users', 'username',
               existing_type=mysql.VARCHAR(length=50),
               comment='用户名',
               existing_nullable=False)
    op.drop_column('users', 'password_changed_at')
    op.drop_column('users', 'last_login_at')
    op.drop_column('users', 'is_verified')
    op.drop_column('users', 'bio')
    op.add_column('teams', sa.Column('is_deleted', mysql.TINYINT(display_width=1), server_default=sa.text("'0'"), autoincrement=False, nullable=False))
    op.add_column('teams', sa.Column('updated_by', mysql.INTEGER(), autoincrement=False, nullable=True))
    op.add_column('teams', sa.Column('created_by', mysql.INTEGER(), autoincrement=False, nullable=True))
    op.add_column('teams', sa.Column('deleted_at', mysql.DATETIME(), nullable=True))
    op.drop_constraint(None, 'teams', type_='foreignkey')
    op.drop_constraint(None, 'teams', type_='foreignkey')
    op.create_index('ix_teams_parent_id', 'teams', ['parent_id'], unique=False)
    op.create_index('ix_teams_is_deleted', 'teams', ['is_deleted'], unique=False)
    op.create_table_comment(
        'knowledge_points',
        'çŸ¥è¯†ç‚¹è¡¨',
        existing_comment=None,
        schema=None
    )
    op.drop_index(op.f('ix_knowledge_points_id'), table_name='knowledge_points')
    op.create_index('idx_knowledge_points_parent_id', 'knowledge_points', ['parent_id'], unique=False)
    op.create_index('idx_knowledge_points_is_deleted', 'knowledge_points', ['is_deleted'], unique=False)
    op.create_index('idx_knowledge_points_course_id', 'knowledge_points', ['course_id'], unique=False)
    op.alter_column('knowledge_points', 'estimated_hours',
               existing_type=mysql.FLOAT(),
               comment='é¢„è®¡å\xad¦ä¹\xa0æ—¶é—´(å°\x8fæ—¶)',
               existing_comment='预计学习时间(小时)',
               existing_nullable=True)
    op.alter_column('knowledge_points', 'is_required',
               existing_type=mysql.TINYINT(display_width=1),
               comment='æ˜¯å\x90¦å¿…ä¿®',
               existing_comment='是否必修',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('knowledge_points', 'weight',
               existing_type=mysql.FLOAT(),
               comment='æ\x9dƒé‡\x8d',
               existing_comment='权重',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('knowledge_points', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_comment='排序顺序',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.alter_column('knowledge_points', 'path',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=500),
               comment='è·¯å¾„(å¦‚: 1.2.3)',
               existing_comment='路径(如: 1.2.3)',
               existing_nullable=True)
    op.alter_column('knowledge_points', 'level',
               existing_type=mysql.INTEGER(),
               comment='å±‚çº§æ·±åº¦',
               existing_comment='层级深度',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('knowledge_points', 'parent_id',
               existing_type=mysql.INTEGER(),
               comment='çˆ¶çŸ¥è¯†ç‚¹ID',
               existing_comment='父知识点ID',
               existing_nullable=True)
    op.alter_column('knowledge_points', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='çŸ¥è¯†ç‚¹æ\x8f\x8fè¿°',
               existing_comment='知识点描述',
               existing_nullable=True)
    op.alter_column('knowledge_points', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='çŸ¥è¯†ç‚¹å\x90\x8dç§°',
               existing_comment='知识点名称',
               existing_nullable=False)
    op.alter_column('knowledge_points', 'course_id',
               existing_type=mysql.INTEGER(),
               comment='è¯¾ç¨‹ID',
               existing_comment='课程ID',
               existing_nullable=False)
    op.create_table_comment(
        'growth_paths',
        'æˆ\x90é•¿è·¯å¾„è¡¨',
        existing_comment=None,
        schema=None
    )
    op.drop_index(op.f('ix_growth_paths_id'), table_name='growth_paths')
    op.create_index('idx_growth_paths_is_deleted', 'growth_paths', ['is_deleted'], unique=False)
    op.create_index('idx_growth_paths_is_active', 'growth_paths', ['is_active'], unique=False)
    op.alter_column('growth_paths', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_comment='排序顺序',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.alter_column('growth_paths', 'is_active',
               existing_type=mysql.TINYINT(display_width=1),
               comment='æ˜¯å\x90¦å\x90¯ç”¨',
               existing_comment='是否启用',
               existing_nullable=False,
               existing_server_default=sa.text("'1'"))
    op.alter_column('growth_paths', 'estimated_duration_days',
               existing_type=mysql.INTEGER(),
               comment='é¢„è®¡å®Œæˆ\x90å¤©æ•°',
               existing_comment='预计完成天数',
               existing_nullable=True)
    op.alter_column('growth_paths', 'courses',
               existing_type=mysql.JSON(),
               comment='è¯¾ç¨‹åˆ—è¡¨[{course_id, order, is_required}]',
               existing_comment='课程列表[{course_id, order, is_required}]',
               existing_nullable=True)
    op.alter_column('growth_paths', 'target_role',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=100),
               comment='ç›®æ\xa0‡è§’è‰²',
               existing_comment='目标角色',
               existing_nullable=True)
    op.alter_column('growth_paths', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='è·¯å¾„æ\x8f\x8fè¿°',
               existing_comment='路径描述',
               existing_nullable=True)
    op.alter_column('growth_paths', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='è·¯å¾„å\x90\x8dç§°',
               existing_comment='路径名称',
               existing_nullable=False)
    op.create_table_comment(
        'courses',
        'è¯¾ç¨‹è¡¨',
        existing_comment=None,
        schema=None
    )
    op.drop_index(op.f('ix_courses_id'), table_name='courses')
    op.create_index('idx_courses_status', 'courses', ['status'], unique=False)
    op.create_index('idx_courses_is_deleted', 'courses', ['is_deleted'], unique=False)
    op.create_index('idx_courses_category', 'courses', ['category'], unique=False)
    op.alter_column('courses', 'is_featured',
               existing_type=mysql.TINYINT(display_width=1),
               comment='æ˜¯å\x90¦æŽ¨è\x8d\x90',
               existing_comment='是否推荐',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.alter_column('courses', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_comment='排序顺序',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.alter_column('courses', 'publisher_id',
               existing_type=mysql.INTEGER(),
               comment='å\x8f‘å¸ƒäººID',
               existing_comment='发布人ID',
               existing_nullable=True)
    op.alter_column('courses', 'published_at',
               existing_type=mysql.DATETIME(),
               comment='å\x8f‘å¸ƒæ—¶é—´',
               existing_comment='发布时间',
               existing_nullable=True)
    op.alter_column('courses', 'tags',
               existing_type=mysql.JSON(),
               comment='æ\xa0‡ç\xad¾åˆ—è¡¨',
               existing_comment='标签列表',
               existing_nullable=True)
    op.alter_column('courses', 'difficulty_level',
               existing_type=mysql.INTEGER(),
               comment='éš¾åº¦ç\xad‰çº§(1-5)',
               existing_comment='难度等级(1-5)',
               existing_nullable=True)
    op.alter_column('courses', 'duration_hours',
               existing_type=mysql.FLOAT(),
               comment='è¯¾ç¨‹æ—¶é•¿(å°\x8fæ—¶)',
               existing_comment='课程时长(小时)',
               existing_nullable=True)
    op.alter_column('courses', 'cover_image',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=500),
               comment='å°\x81é\x9d¢å›¾ç‰‡URL',
               existing_comment='封面图片URL',
               existing_nullable=True)
    op.alter_column('courses', 'status',
               existing_type=mysql.ENUM('draft', 'published', 'archived', collation='utf8mb4_unicode_ci'),
               comment='è¯¾ç¨‹çŠ¶æ€\x81',
               existing_comment='课程状态',
               existing_nullable=False,
               existing_server_default=sa.text("'draft'"))
    op.alter_column('courses', 'category',
               existing_type=mysql.ENUM('technology', 'management', 'business', 'general', collation='utf8mb4_unicode_ci'),
               comment='è¯¾ç¨‹åˆ†ç±»',
               existing_comment='课程分类',
               existing_nullable=False,
               existing_server_default=sa.text("'general'"))
    op.alter_column('courses', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='è¯¾ç¨‹æ\x8f\x8fè¿°',
               existing_comment='课程描述',
               existing_nullable=True)
    op.alter_column('courses', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='è¯¾ç¨‹å\x90\x8dç§°',
               existing_comment='课程名称',
               existing_nullable=False)
    op.create_table_comment(
        'course_materials',
        'è¯¾ç¨‹èµ„æ–™è¡¨',
        existing_comment=None,
        schema=None
    )
    op.drop_index(op.f('ix_course_materials_id'), table_name='course_materials')
    op.create_index('idx_course_materials_is_deleted', 'course_materials', ['is_deleted'], unique=False)
    op.create_index('idx_course_materials_course_id', 'course_materials', ['course_id'], unique=False)
    op.alter_column('course_materials', 'sort_order',
               existing_type=mysql.INTEGER(),
               comment='æŽ’åº\x8fé¡ºåº\x8f',
               existing_comment='排序顺序',
               existing_nullable=False,
               existing_server_default=sa.text("'0'"))
    op.alter_column('course_materials', 'file_size',
               existing_type=mysql.INTEGER(),
               comment='æ–‡ä»¶å¤§å°\x8f(å\xad—èŠ‚)',
               existing_comment='文件大小(字节)',
               existing_nullable=False)
    op.alter_column('course_materials', 'file_type',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=50),
               comment='æ–‡ä»¶ç±»åž‹',
               existing_comment='文件类型',
               existing_nullable=False)
    op.alter_column('course_materials', 'file_url',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=500),
               comment='æ–‡ä»¶URL',
               existing_comment='文件URL',
               existing_nullable=False)
    op.alter_column('course_materials', 'description',
               existing_type=mysql.TEXT(collation='utf8mb4_unicode_ci'),
               comment='èµ„æ–™æ\x8f\x8fè¿°',
               existing_comment='资料描述',
               existing_nullable=True)
    op.alter_column('course_materials', 'name',
               existing_type=mysql.VARCHAR(collation='utf8mb4_unicode_ci', length=200),
               comment='èµ„æ–™å\x90\x8dç§°',
               existing_comment='资料名称',
               existing_nullable=False)
    op.alter_column('course_materials', 'course_id',
               existing_type=mysql.INTEGER(),
               comment='è¯¾ç¨‹ID',
               existing_comment='课程ID',
               existing_nullable=False)
    op.drop_table('user_teams')
    op.drop_index(op.f('ix_training_reports_user_id'), table_name='training_reports')
    op.drop_index(op.f('ix_training_reports_id'), table_name='training_reports')
    op.drop_table('training_reports')
    op.drop_index(op.f('ix_training_messages_id'), table_name='training_messages')
    op.drop_table('training_messages')
    op.drop_index(op.f('ix_training_sessions_user_id'), table_name='training_sessions')
    op.drop_index(op.f('ix_training_sessions_id'), table_name='training_sessions')
    op.drop_table('training_sessions')
    op.drop_index(op.f('ix_training_scenes_id'), table_name='training_scenes')
    op.drop_table('training_scenes')
    # ### end Alembic commands ###