using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.MediaCollections; public class CreatePlaylistHandler(IDbContextFactory dbContextFactory) : IRequestHandler> { public async Task> Handle( CreatePlaylist request, CancellationToken cancellationToken) { await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = await Validate(dbContext, request); return await validation.Apply(profile => PersistPlaylist(dbContext, profile)); } private static async Task PersistPlaylist(TvContext dbContext, Playlist playlist) { await dbContext.Playlists.AddAsync(playlist); await dbContext.SaveChangesAsync(); return Mapper.ProjectToViewModel(playlist); } private static async Task> Validate(TvContext dbContext, CreatePlaylist request) => await ValidatePlaylistName(dbContext, request).MapT( name => new Playlist { PlaylistGroupId = request.PlaylistGroupId, Name = name }); private static async Task> ValidatePlaylistName( TvContext dbContext, CreatePlaylist request) { if (request.Name.Length > 50) { return BaseError.New($"Playlist name \"{request.Name}\" is invalid"); } Option maybeExisting = await dbContext.Playlists .FirstOrDefaultAsync(r => r.PlaylistGroupId == request.PlaylistGroupId && r.Name == request.Name) .Map(Optional); return maybeExisting.IsSome ? BaseError.New($"A playlist named \"{request.Name}\" already exists in that playlist group") : Success(request.Name); } }