Add user authentication with login/signup/protected routes, boss pokemon detail fields and result team tracking, moves and abilities selector components and API, run ownership and visibility controls, and various UI improvements across encounters, run list, and journal pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
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),
|
|
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"<NuzlockeRun(id={self.id}, name='{self.name}', status='{self.status}')>"
|
|
)
|