"""первая схема: курсанты, группы, сессии, транскрипт, отметки, оценки Revision ID: ff5de7dfe4ce Revises: Create Date: 2026-09-15 19:51:15.671575 """ from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql revision = 'ff5de7dfe4ce' down_revision = None branch_labels = None depends_on = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table('groups', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('name', sa.String(length=120), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('name') ) op.create_table('llm_cache', sa.Column('context_hash', sa.String(length=64), nullable=False), sa.Column('model', sa.String(length=80), nullable=False), sa.Column('prompt', sa.Text(), nullable=False), sa.Column('response', sa.Text(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), sa.PrimaryKeyConstraint('context_hash') ) op.create_table('scenarios', sa.Column('id', sa.String(length=80), nullable=False), sa.Column('title', sa.String(length=200), nullable=False), sa.Column('incident_type', sa.String(length=20), nullable=False), sa.Column('level', sa.String(length=4), nullable=False), sa.Column('topics', postgresql.JSONB(astext_type=sa.Text()), nullable=False), sa.Column('modes', postgresql.JSONB(astext_type=sa.Text()), nullable=False), sa.Column('status', sa.String(length=16), nullable=False), sa.Column('body', postgresql.JSONB(astext_type=sa.Text()), 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.PrimaryKeyConstraint('id') ) op.create_table('trainees', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('name', sa.String(length=120), nullable=False), sa.Column('group_id', sa.Uuid(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ondelete='SET NULL'), sa.PrimaryKeyConstraint('id') ) op.create_table('sessions', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('scenario_id', sa.String(length=80), nullable=False), sa.Column('trainee_id', sa.Uuid(), nullable=True), sa.Column('group_id', sa.Uuid(), nullable=True), sa.Column('mode', sa.String(length=16), nullable=False), sa.Column('attempt', sa.Integer(), nullable=False), sa.Column('started_at', sa.DateTime(timezone=True), nullable=True), sa.Column('ended_at', sa.DateTime(timezone=True), nullable=True), sa.Column('end_reason', sa.String(length=16), nullable=True), sa.Column('kio', postgresql.JSONB(astext_type=sa.Text()), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['scenario_id'], ['scenarios.id'], ondelete='RESTRICT'), sa.ForeignKeyConstraint(['trainee_id'], ['trainees.id'], ondelete='SET NULL'), sa.PrimaryKeyConstraint('id') ) op.create_index('ix_sessions_group_created', 'sessions', ['group_id', 'created_at'], unique=False) op.create_index('ix_sessions_trainee_scenario', 'sessions', ['trainee_id', 'scenario_id'], unique=False) op.create_table('findings', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('session_id', sa.Uuid(), nullable=False), sa.Column('code', sa.String(length=4), nullable=False), sa.Column('source', sa.String(length=16), nullable=False), sa.Column('summary', sa.Text(), nullable=False), sa.Column('fact', sa.Text(), nullable=False), sa.Column('norm', sa.Text(), nullable=True), sa.Column('ref', sa.String(length=80), nullable=True), sa.Column('competency', sa.String(length=24), nullable=True), sa.Column('transcript_ref', sa.String(length=40), nullable=True), sa.Column('at', sa.DateTime(timezone=True), nullable=True), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_index('ix_findings_session_code', 'findings', ['session_id', 'code'], unique=False) op.create_table('hint_uses', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('session_id', sa.Uuid(), nullable=False), sa.Column('checklist_id', sa.String(length=60), nullable=False), sa.Column('question', sa.Text(), nullable=False), sa.Column('at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_table('instructor_notes', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('session_id', sa.Uuid(), nullable=False), sa.Column('transcript_ref', sa.String(length=40), nullable=False), sa.Column('text', sa.Text(), nullable=False), sa.Column('author', sa.String(length=120), nullable=False), sa.Column('at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) op.create_table('scores', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('session_id', sa.Uuid(), nullable=False), sa.Column('score_auto', sa.Float(), nullable=False), sa.Column('score_final', sa.Float(), nullable=False), sa.Column('overridden_by', sa.String(length=120), nullable=True), sa.Column('override_comment', sa.Text(), nullable=True), sa.Column('report', postgresql.JSONB(astext_type=sa.Text()), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('session_id') ) op.create_table('self_assessments', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('session_id', sa.Uuid(), nullable=False), sa.Column('missed', postgresql.JSONB(astext_type=sa.Text()), nullable=False), sa.Column('comment', sa.Text(), nullable=False), sa.Column('submitted_at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('session_id') ) op.create_table('utterances', sa.Column('id', sa.Uuid(), nullable=False), sa.Column('session_id', sa.Uuid(), nullable=False), sa.Column('ref', sa.String(length=40), nullable=False), sa.Column('speaker', sa.String(length=10), nullable=False), sa.Column('text', sa.Text(), nullable=False), sa.Column('mood', sa.String(length=16), nullable=True), sa.Column('at', sa.DateTime(timezone=True), nullable=False), sa.ForeignKeyConstraint(['session_id'], ['sessions.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('session_id', 'ref', name='uq_utterance_ref') ) op.create_index('ix_utterances_session', 'utterances', ['session_id', 'at'], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.drop_index('ix_utterances_session', table_name='utterances') op.drop_table('utterances') op.drop_table('self_assessments') op.drop_table('scores') op.drop_table('instructor_notes') op.drop_table('hint_uses') op.drop_index('ix_findings_session_code', table_name='findings') op.drop_table('findings') op.drop_index('ix_sessions_trainee_scenario', table_name='sessions') op.drop_index('ix_sessions_group_created', table_name='sessions') op.drop_table('sessions') op.drop_table('trainees') op.drop_table('scenarios') op.drop_table('llm_cache') op.drop_table('groups') # ### end Alembic commands ###