Drop the now-redundant Track.Artist string column now that every track (local and YouTube) links its credited artists through TrackArtist. TrackApplicationResponse formats the display string by joining TrackArtists ordered by position, and every read query that projects a track now includes TrackArtists/Artist so the join isn't empty at response time.
45 lines
1.3 KiB
C#
45 lines
1.3 KiB
C#
using System.Linq;
|
|
using Musify.Domain.Entities;
|
|
using Musify.Domain.ValueObjects;
|
|
|
|
namespace Musify.Application.Tracks.Responses
|
|
{
|
|
public record TrackApplicationResponse(
|
|
Guid Id,
|
|
string Title,
|
|
string? Artist,
|
|
TrackSource Source,
|
|
string? ExternalId,
|
|
ProcessingStatus AudioStatus,
|
|
int Duration,
|
|
int ListensCount,
|
|
long? OwnerUserId,
|
|
DateTime CreatedAt,
|
|
DateTime UpdatedAt)
|
|
{
|
|
public static TrackApplicationResponse FromEntity(Track track, int listensCount) =>
|
|
new(
|
|
track.Id,
|
|
track.Title,
|
|
FormatArtist(track),
|
|
track.Source,
|
|
track.ExternalId,
|
|
track.AudioTranscodeProcessingStatus,
|
|
track.Duration,
|
|
listensCount,
|
|
track.OwnerUserId,
|
|
track.CreatedAt,
|
|
track.UpdatedAt);
|
|
|
|
private static string? FormatArtist(Track track)
|
|
{
|
|
if (track.TrackArtists.Count == 0)
|
|
return null;
|
|
|
|
return string.Join(", ", track.TrackArtists
|
|
.OrderBy(trackArtist => trackArtist.Position)
|
|
.Select(trackArtist => trackArtist.Artist.Name));
|
|
}
|
|
}
|
|
}
|