"""Playlist-Sound relationship model for managing sound order in playlists.""" from datetime import datetime from typing import TYPE_CHECKING, Optional from zoneinfo import ZoneInfo from sqlalchemy import DateTime, ForeignKey, Integer, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import db if TYPE_CHECKING: from app.models.playlist import Playlist from app.models.sound import Sound class PlaylistSound(db.Model): """Model for playlist-sound relationships with ordering.""" __tablename__ = "playlist_sound" id: Mapped[int] = mapped_column(Integer, primary_key=True) playlist_id: Mapped[int] = mapped_column( Integer, ForeignKey("playlist.id"), nullable=False ) sound_id: Mapped[int] = mapped_column( Integer, ForeignKey("sound.id"), nullable=False ) order: Mapped[int] = mapped_column(Integer, nullable=False) added_at: Mapped[datetime] = mapped_column( DateTime, default=lambda: datetime.now(tz=ZoneInfo("UTC")), nullable=False, ) # Relationships playlist: Mapped["Playlist"] = relationship( "Playlist", back_populates="playlist_sounds" ) sound: Mapped["Sound"] = relationship( "Sound", back_populates="playlist_sounds" ) # Constraints __table_args__ = ( UniqueConstraint( "playlist_id", "sound_id", name="unique_playlist_sound" ), UniqueConstraint("playlist_id", "order", name="unique_playlist_order"), ) def __repr__(self) -> str: """String representation of the playlist-sound relationship.""" return f"" def to_dict(self) -> dict: """Convert playlist-sound relationship to dictionary representation.""" return { "id": self.id, "playlist_id": self.playlist_id, "sound_id": self.sound_id, "order": self.order, "added_at": self.added_at.isoformat() if self.added_at else None, "sound": self.sound.to_dict() if self.sound else None, }