"""Add game models: mtgonline_games, game_players, game_history Revision ID: 006 Revises: 005 Create Date: 2026-01-05 00:00:00.000000 This migration creates tables for the Core Game Engine: - mtgonline_games: Active game sessions - game_players: Player associations with games - game_history: Historical game records """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision: str = '006' down_revision: Union[str, None] = '005' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: """Create game engine tables.""" # ------------------------------------------------------------------ # 1. MTG Online Games Table (mtgonline_games) # Mirrors: app/models/models.py – class MTGOnlineGame # ------------------------------------------------------------------ op.create_table( 'mtgonline_games', sa.Column('id', sa.Integer(), primary_key=True, index=True), sa.Column('room_id', sa.Integer(), sa.ForeignKey('mtgonline_rooms.id'), nullable=False, index=True), sa.Column('host_id', sa.Integer(), sa.ForeignKey('mtgonline_users.id'), nullable=False, index=True), sa.Column('game_type', sa.String(50), nullable=False, server_default='Commander'), sa.Column('state', sa.String(20), nullable=False, server_default='WAITING'), sa.Column('is_password_protected', sa.Boolean(), nullable=False, server_default='false'), sa.Column('max_players', sa.Integer(), nullable=False, server_default='4'), sa.Column('current_players', sa.Integer(), nullable=False, server_default='0'), sa.Column('created_at', sa.DateTime(), server_default=sa.func.now()), sa.Column('started_at', sa.DateTime(), nullable=True), sa.Column('finished_at', sa.DateTime(), nullable=True), ) # ------------------------------------------------------------------ # 2. Game Players Table (game_players) # Mirrors: app/models/models.py – class GamePlayer # ------------------------------------------------------------------ op.create_table( 'game_players', sa.Column('id', sa.Integer(), primary_key=True, index=True), sa.Column('game_id', sa.Integer(), sa.ForeignKey('mtgonline_games.id', ondelete='CASCADE'), nullable=False, index=True), sa.Column('user_id', sa.Integer(), sa.ForeignKey('mtgonline_users.id'), nullable=False, index=True), sa.Column('seat_number', sa.Integer(), nullable=True), sa.Column('life_total', sa.Integer(), nullable=False, server_default='20'), sa.Column('is_ready', sa.Boolean(), nullable=False, server_default='false'), sa.Column('is_host', sa.Boolean(), nullable=False, server_default='false'), sa.Column('joined_at', sa.DateTime(), server_default=sa.func.now()), ) # Unique constraint + indexes op.create_unique_constraint( 'uq_game_player_unique', 'game_players', ['game_id', 'user_id']) op.create_index('idx_game_players_game', 'game_players', ['game_id']) op.create_index('idx_game_players_user', 'game_players', ['user_id']) # ------------------------------------------------------------------ # 3. Game History Table (game_history) # Mirrors: app/models/models.py – class GameHistory # ------------------------------------------------------------------ op.create_table( 'game_history', sa.Column('id', sa.Integer(), primary_key=True, index=True), sa.Column('game_id', sa.Integer(), sa.ForeignKey('mtgonline_games.id'), nullable=True), sa.Column('room_id', sa.Integer(), sa.ForeignKey('mtgonline_rooms.id'), nullable=True, index=True), sa.Column('game_type', sa.String(50), nullable=False, server_default='Commander'), sa.Column('winner_id', sa.Integer(), sa.ForeignKey('mtgonline_users.id'), nullable=True, index=True), sa.Column('duration_seconds', sa.Integer(), nullable=True), sa.Column('result_type', sa.String(50), nullable=True), sa.Column('replay_data', sa.JSON(), nullable=True), sa.Column('created_at', sa.DateTime(), server_default=sa.func.now()), ) def downgrade() -> None: """Drop game engine tables in reverse dependency order.""" op.drop_table('game_history') op.drop_table('game_players') op.drop_table('mtgonline_games')