from datetime import datetime from typing import List, Optional from sqlalchemy import String, Integer, ForeignKey, DateTime, Enum as SQLEnum, func from sqlalchemy.orm import Mapped, mapped_column, relationship import enum from .database import Base class Difficulty(str, enum.Enum): EASY = "easy" MEDIUM = "medium" HARD = "hard" class Opening(Base): """Anime opening entity.""" __tablename__ = "openings" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) anime_name: Mapped[str] = mapped_column(String(255), nullable=False, index=True) op_number: Mapped[str] = mapped_column(String(20), nullable=False) # e.g., "OP1", "ED2" song_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) audio_file: Mapped[str] = mapped_column(String(512), nullable=False) # S3 key # Usage tracking last_usage: Mapped[Optional[datetime]] = mapped_column( DateTime(timezone=True), nullable=True, default=None ) # Timestamps created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now() ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now() ) # Relationships posters: Mapped[List["OpeningPoster"]] = relationship( "OpeningPoster", back_populates="opening", cascade="all, delete-orphan" ) def __repr__(self): return f"" class OpeningPoster(Base): """Poster image for an opening.""" __tablename__ = "opening_posters" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) opening_id: Mapped[int] = mapped_column( Integer, ForeignKey("openings.id", ondelete="CASCADE"), nullable=False ) poster_file: Mapped[str] = mapped_column(String(512), nullable=False) # S3 key is_default: Mapped[bool] = mapped_column(default=False) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now() ) # Relationships opening: Mapped["Opening"] = relationship("Opening", back_populates="posters") def __repr__(self): return f"" class Background(Base): """Background video entity.""" __tablename__ = "backgrounds" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(String(255), nullable=False) video_file: Mapped[str] = mapped_column(String(512), nullable=False) # S3 key difficulty: Mapped[Difficulty] = mapped_column( SQLEnum(Difficulty, native_enum=False), nullable=False, default=Difficulty.MEDIUM ) # Timestamps created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now() ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now() ) def __repr__(self): return f""