using MediatR; using Microsoft.EntityFrameworkCore; using SequenceAuth.Example.Domain; using SequenceAuth.Example.Infrastructure; namespace SequenceAuth.Example.Features.Todos; public enum ChangeTodoStatusOutcome { Success, NotFound, Unauthorized } public record ChangeTodoStatusResult(ChangeTodoStatusOutcome Outcome, TodoItem? Item); public record ChangeTodoStatusCommand(Guid TodoId, Guid UserId, TodoStatus NewStatus) : IRequest; public class ChangeTodoStatusCommandHandler(AppDbContext dbContext) : IRequestHandler { public async Task Handle(ChangeTodoStatusCommand request, CancellationToken cancellationToken) { var todo = await dbContext.Todos.FirstOrDefaultAsync(t => t.Id == request.TodoId, cancellationToken); return todo switch { null => new ChangeTodoStatusResult(ChangeTodoStatusOutcome.NotFound, null), { UserId: var userId } when userId != request.UserId => new ChangeTodoStatusResult(ChangeTodoStatusOutcome.Unauthorized, null), _ => await UpdateStatusAsync(todo, request.NewStatus, cancellationToken) }; } private async Task UpdateStatusAsync(TodoItem todo, TodoStatus newStatus, CancellationToken cancellationToken) { var updatedTodo = todo with { Status = newStatus }; dbContext.Entry(todo).CurrentValues.SetValues(updatedTodo); await dbContext.SaveChangesAsync(cancellationToken); return new ChangeTodoStatusResult(ChangeTodoStatusOutcome.Success, updatedTodo); } }