from __future__ import annotations from datetime import datetime from enum import StrEnum from typing import TYPE_CHECKING from uuid import UUID from sqlalchemy import DateTime, Enum, ForeignKey, String, func from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.orm import Mapped, mapped_column, relationship from app.core.database import Base if TYPE_CHECKING: from app.models.boss_result import BossResult from app.models.encounter import Encounter from app.models.game import Game from app.models.journal_entry import JournalEntry from app.models.user import User class RunVisibility(StrEnum): PUBLIC = "public" PRIVATE = "private" class NuzlockeRun(Base): __tablename__ = "nuzlocke_runs" id: Mapped[int] = mapped_column(primary_key=True) game_id: Mapped[int] = mapped_column(ForeignKey("games.id"), index=True) owner_id: Mapped[UUID | None] = mapped_column( ForeignKey("users.id", ondelete="SET NULL"), index=True ) name: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column( String(20), index=True ) # active, completed, failed visibility: Mapped[RunVisibility] = mapped_column( Enum( RunVisibility, name="run_visibility", create_constraint=False, values_callable=lambda e: [m.value for m in e], ), default=RunVisibility.PUBLIC, server_default="public", ) rules: Mapped[dict] = mapped_column(JSONB, default=dict) started_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now() ) completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) hof_encounter_ids: Mapped[list[int] | None] = mapped_column(JSONB, default=None) naming_scheme: Mapped[str | None] = mapped_column(String(50), nullable=True) game: Mapped[Game] = relationship(back_populates="runs") owner: Mapped[User | None] = relationship(back_populates="runs") encounters: Mapped[list[Encounter]] = relationship(back_populates="run") boss_results: Mapped[list[BossResult]] = relationship(back_populates="run") journal_entries: Mapped[list[JournalEntry]] = relationship(back_populates="run") def __repr__(self) -> str: return ( f"" )