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