"""Like endpoints. Likes are an append-only event-log — never updated in place.""" import uuid from fastapi import APIRouter, Query from app.api.deps import AlbumRepoDep, ArtistRepoDep, CurrentUser, LikeRepoDep from app.api.schemas.like import LikeEvent, LikeState from app.api.schemas.pagination import PagedResponse from app.api.schemas.track import TrackOut from app.api.v1.tracks import _build_track_out router = APIRouter(prefix="/likes", tags=["likes"]) @router.post("", status_code=201) async def add_like( body: LikeEvent, like_repo: LikeRepoDep, user: CurrentUser, ) -> LikeState: like = await like_repo.add(user_id=user.id, track_id=body.track_id, value=body.value) return LikeState(track_id=like.track_id, value=like.value, updated_at=like.created_at) @router.get("") async def get_likes( like_repo: LikeRepoDep, artist_repo: ArtistRepoDep, album_repo: AlbumRepoDep, user: CurrentUser, limit: int = Query(50, ge=1, le=200), offset: int = Query(0, ge=0), ) -> PagedResponse[TrackOut]: tracks = await like_repo.list_liked_tracks(user_id=user.id, limit=limit, offset=offset) total = await like_repo.count_liked_tracks(user_id=user.id) artist_ids = list({t.artist_id for t in tracks}) album_ids = list({t.album_id for t in tracks if t.album_id is not None}) artists_map = {a.id: a for a in await artist_repo.get_many(artist_ids)} albums_map = {a.id: a for a in await album_repo.get_many(album_ids)} items = await _build_track_out(tracks, artists_map, albums_map) return PagedResponse(items=items, total=total, limit=limit, offset=offset) @router.get("/state") async def get_likes_state( like_repo: LikeRepoDep, user: CurrentUser, track_ids: str = Query(default=""), ) -> list[LikeState]: ids: list[uuid.UUID] = [] if track_ids: try: ids = [uuid.UUID(tid.strip()) for tid in track_ids.split(",") if tid.strip()] except ValueError: return [] likes = await like_repo.get_latest_state(user_id=user.id, track_ids=ids) return [ LikeState(track_id=lk.track_id, value=lk.value, updated_at=lk.created_at) for lk in likes ]