AlbumApplicationResponse used to carry YouTubeAlbumId/ThumbnailUrl as two always-present-but-usually-null fields for the sake of a single flat shape. Since one of these fields IS genuinely exclusive to external albums, an inheritance split reads better than the flattened shape: AlbumApplicationResponse now holds only the fields shared by every album, and ExternalAlbumApplicationResponse adds ExternalId (renamed from YouTubeAlbumId, matching the source-generalized naming used everywhere else) and ThumbnailUrl. [JsonPolymorphic]/[JsonDerivedType] are required here, not optional: without them System.Text.Json serializes strictly by the declared CLR type at each call site (both the bare return type and nested inside AlbumSearchItemResponse.Album), so an ExternalAlbumApplicationResponse instance would silently lose its extra fields on the wire. This also gives every response a "source" discriminator field for free, consistent with AlbumSearchItemResponse.Source, and the generated OpenAPI schema now models it as a proper oneOf/discriminator instead of nullable fields.
23 lines
1.0 KiB
C#
23 lines
1.0 KiB
C#
using Musify.Application.Contracts;
|
|
using Musify.Domain.ValueObjects;
|
|
|
|
namespace Musify.Application.Albums.Responses
|
|
{
|
|
/// <summary>One item of a combined local/external album listing. Exactly one of
|
|
/// <see cref="Album"/> or <see cref="YouTubeAlbum"/> is populated: <see cref="Album"/> for
|
|
/// anything already in the catalog (locally created albums and external albums materialized
|
|
/// earlier), <see cref="YouTubeAlbum"/> for a live external search hit that hasn't been
|
|
/// materialized yet, so it has no album id.</summary>
|
|
public record AlbumSearchItemResponse(
|
|
TrackSource Source,
|
|
AlbumApplicationResponse? Album,
|
|
YouTubeAlbumResult? YouTubeAlbum)
|
|
{
|
|
public static AlbumSearchItemResponse FromAlbum(AlbumApplicationResponse album) =>
|
|
new(album is ExternalAlbumApplicationResponse ? TrackSource.YouTube : TrackSource.Local, album, null);
|
|
|
|
public static AlbumSearchItemResponse FromYouTubeAlbum(YouTubeAlbumResult album) =>
|
|
new(TrackSource.YouTube, null, album);
|
|
}
|
|
}
|