feat: recommend server-generated mixes from Musify and YouTube Music

Mixes are their own concept, not playlists: they live in their own
Mixes/MixItems tables, cannot be edited and never show up among the
user's playlists. Each item is either a Musify track or a YouTube Music
reference, so YouTube songs stream directly instead of being downloaded.

A daily Hangfire job seeds the mixes from the listening history: one
discovery mix, one daily mix and one per top artist.

The per-user YouTube filler query was already in the working tree and
rides along here because it shares files with this change.
This commit is contained in:
2026-07-21 18:13:07 +02:00
parent 2cb51f540e
commit 90e842d084
36 changed files with 2667 additions and 13 deletions
@@ -0,0 +1,27 @@
using Musify.Domain.Entities;
namespace Musify.Application.Mixes.Responses
{
public record MixApplicationResponse(
Guid Id,
string Title,
string? Subtitle,
DateOnly GeneratedOn,
int ItemCount,
IReadOnlyList<MixItemApplicationResponse> Items)
{
public const int CoverItemCount = 4;
public static MixApplicationResponse FromEntity(
Mix mix,
int itemCount,
IReadOnlyList<MixItem> items) =>
new(
mix.Id,
mix.Title,
mix.Subtitle,
mix.GeneratedOn,
itemCount,
[.. items.Select(MixItemApplicationResponse.FromEntity)]);
}
}