Files
AudiOhm/backend/app/models/playlist_track.py
T
root a89c7894cf Initial commit: AudiOhm - Alternative Spotify avec streaming YouTube
Backend:
- FastAPI avec PostgreSQL et Redis
- Authentification JWT complète
- API REST pour musique, playlists, recherche
- Streaming audio via yt-dlp
- SQLAlchemy 2.0 async

Frontend:
- Flutter avec thème néon cyberpunk
- State management Riverpod
- Layout adaptatif desktop/mobile
- Lecteur audio avec mini-player

Infrastructure:
- Docker Compose (PostgreSQL + Redis)
- Scripts d'installation automatisés
- Scripts de build pour exécutables

Fichiers ajoutés:
- BUILD_CLIENT_*.bat/sh: Scripts de compilation
- BUILD_CLIENT_README.md: Documentation compilation
- CHECK_FLUTTER.sh: Vérificateur d'environnement
- requirements.txt mis à jour pour Python 3.13
- Modèles SQLAlchemy corrigés (metadata -> extra_metadata)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-18 20:08:36 +00:00

97 lines
2.7 KiB
Python

"""Playlist-Track association model."""
import uuid
from datetime import datetime
from typing import TYPE_CHECKING
from sqlalchemy import Integer, ForeignKey, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.database import Base
if TYPE_CHECKING:
from app.models.playlist import Playlist
from app.models.track import Track
from app.models.user import User
class PlaylistTrack(Base):
"""Association model for Playlist-Track many-to-many relationship."""
__tablename__ = "playlist_tracks"
__table_args__ = (
UniqueConstraint("playlist_id", "position", name="uq_playlist_position"),
)
# Primary key
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
index=True,
)
# Foreign keys
playlist_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("playlists.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
track_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("tracks.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
# Position in playlist (starts at 0)
position: Mapped[int] = mapped_column(
Integer,
nullable=False,
)
# User who added this track to playlist
added_by: Mapped[uuid.UUID | None] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="SET NULL"),
nullable=True,
)
# Timestamp when track was added
added_at: Mapped[datetime] = mapped_column(
default=datetime.utcnow,
nullable=False,
)
# Relationships
playlist: Mapped["Playlist"] = relationship(
"Playlist",
back_populates="playlist_tracks",
lazy="selectin",
)
track: Mapped["Track"] = relationship(
"Track",
lazy="selectin",
)
added_by_user: Mapped["User"] = relationship(
"User",
back_populates="added_playlist_tracks",
lazy="selectin",
foreign_keys=[added_by],
)
def __repr__(self) -> str:
return f"<PlaylistTrack playlist={self.playlist_id} track={self.track_id} pos={self.position}>"
def to_dict(self) -> dict:
"""Convert playlist-track model to dictionary."""
return {
"id": str(self.id),
"playlist_id": str(self.playlist_id),
"track_id": str(self.track_id),
"position": self.position,
"added_by": str(self.added_by) if self.added_by else None,
"added_at": self.added_at.isoformat(),
}