import uuid from datetime import datetime from sqlalchemy import String, Integer, Text, Boolean, DateTime, JSON from sqlalchemy.orm import Mapped, mapped_column from app.database import Base import enum class GameStatus(str, enum.Enum): waiting = "waiting" playing = "playing" paused = "paused" completed = "completed" class PlayerStatus(str, enum.Enum): active = "active" left = "left" eliminated = "eliminated" class MessageType(str, enum.Enum): public = "public" private = "private" system = "system" clue = "clue" class GameSession(Base): __tablename__ = "game_sessions" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) script_id: Mapped[str] = mapped_column(String(36)) status: Mapped[str] = mapped_column(String(20), default=GameStatus.waiting.value) phase: Mapped[str] = mapped_column(String(100), default="") phase_index: Mapped[int] = mapped_column(Integer, default=0) started_at: Mapped[datetime] = mapped_column(DateTime, nullable=True) completed_at: Mapped[datetime] = mapped_column(DateTime, nullable=True) config: Mapped[str] = mapped_column(JSON, default=dict) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) class SessionPlayer(Base): __tablename__ = "session_players" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) session_id: Mapped[str] = mapped_column(String(36)) user_id: Mapped[str] = mapped_column(String(36), nullable=True) role_id: Mapped[str] = mapped_column(String(100)) role_name: Mapped[str] = mapped_column(String(100), default="") is_human: Mapped[bool] = mapped_column(Boolean, default=True) is_ready: Mapped[bool] = mapped_column(Boolean, default=False) avatar_url: Mapped[str] = mapped_column(Text, nullable=True) status: Mapped[str] = mapped_column(String(20), default=PlayerStatus.active.value) joined_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) class ChatMessage(Base): __tablename__ = "chat_messages" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) session_id: Mapped[str] = mapped_column(String(36)) sender_role_id: Mapped[str] = mapped_column(String(100)) sender_name: Mapped[str] = mapped_column(String(100), default="") message_type: Mapped[str] = mapped_column(String(20), default=MessageType.public.value) content: Mapped[str] = mapped_column(Text) target_role_id: Mapped[str] = mapped_column(String(100), nullable=True) clue_id: Mapped[str] = mapped_column(String(100), nullable=True) phase_index: Mapped[int] = mapped_column(Integer, default=0) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) class ClueState(Base): __tablename__ = "clues_state" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) session_id: Mapped[str] = mapped_column(String(36)) clue_id: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column(String(20), default="unreleased") revealed_by: Mapped[str] = mapped_column(String(100), nullable=True) released_at: Mapped[datetime] = mapped_column(DateTime, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) class Vote(Base): __tablename__ = "votes" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) session_id: Mapped[str] = mapped_column(String(36)) round: Mapped[int] = mapped_column(Integer, default=1) voter_id: Mapped[str] = mapped_column(String(36)) target_id: Mapped[str] = mapped_column(String(36)) reason: Mapped[str] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)