feat(backend): search albums on YouTube Music

Two read-only endpoints: the album search and the album detail with its
tracklist. Both go through the same single-flight cache as the song search,
and the detail one especially benefits since it costs two upstream calls, the
browse id lookup and the album itself, for metadata that never changes.
Paginator handling is now shared between the song and album searches.
This commit is contained in:
2026-07-20 20:36:28 +02:00
parent ed7fca5366
commit 0afb365427
5 changed files with 237 additions and 15 deletions
@@ -0,0 +1,21 @@
using ErrorOr;
using Mediator;
using Musify.Application.Contracts;
namespace Musify.Application.YouTube
{
public record GetYouTubeAlbumQuery(string AlbumId)
: IQuery<ErrorOr<YouTubeAlbumDetail>>;
public class GetYouTubeAlbumQueryHandler(IYouTubeMusicService youTubeMusicService)
: IQueryHandler<GetYouTubeAlbumQuery, ErrorOr<YouTubeAlbumDetail>>
{
public async ValueTask<ErrorOr<YouTubeAlbumDetail>> Handle(GetYouTubeAlbumQuery request, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(request.AlbumId))
return Error.Validation(description: "The album id must not be empty.");
return await youTubeMusicService.GetAlbumAsync(request.AlbumId, cancellationToken);
}
}
}