using ErsatzTV.Core; using ErsatzTV.Core.Domain.Scheduling; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Scheduling; public class CreateBlockHandler(IDbContextFactory dbContextFactory) : IRequestHandler> { public async Task> Handle( CreateBlock request, CancellationToken cancellationToken) { await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = await Validate(dbContext, request); return await validation.Apply(profile => PersistBlock(dbContext, profile)); } private static async Task PersistBlock(TvContext dbContext, Block block) { await dbContext.Blocks.AddAsync(block); await dbContext.SaveChangesAsync(); return Mapper.ProjectToViewModel(block); } private static async Task> Validate(TvContext dbContext, CreateBlock request) => await ValidateBlockName(dbContext, request).MapT( name => new Block { BlockGroupId = request.BlockGroupId, Name = name, Minutes = 30 }); private static async Task> ValidateBlockName( TvContext dbContext, CreateBlock request) { if (request.Name.Length > 50) { return BaseError.New($"Block name \"{request.Name}\" is invalid"); } Option maybeExisting = await dbContext.Blocks .FirstOrDefaultAsync(r => r.BlockGroupId == request.BlockGroupId && r.Name == request.Name) .Map(Optional); return maybeExisting.IsSome ? BaseError.New($"A block named \"{request.Name}\" already exists in that block group") : Success(request.Name); } }