using AutoMapper; using MediatR; using mws.backend.dotnet.application.Audit; using mws.backend.dotnet.application.Common; namespace mws.backend.dotnet.application.Tasks; public record UpdateTaskCommand(Guid UserId, Guid TaskId, UpdateTaskRequest Request) : IRequest, IAuditableRequest { public string Action => "Task.Update"; public string EntityType => "Task"; public Guid? EntityId => TaskId; public string? EntityName => Request.Title; } public class UpdateTaskHandler(IUnitOfWork uow, IMapper mapper) : IRequestHandler { public async Task Handle(UpdateTaskCommand command, CancellationToken ct) { var task = await TaskAccess.GetTaskForUserAsync(uow, command.UserId, command.TaskId, ct); var request = command.Request; if (string.IsNullOrWhiteSpace(request.Title)) { throw new BadRequestException("Task title is required"); } if (request.AssigneeId.HasValue && !await uow.Projects.IsMemberAsync(task.ProjectId, request.AssigneeId.Value, ct)) { throw new BadRequestException("Assignee must be a member of the project"); } task.Title = request.Title.Trim(); task.Description = request.Description; task.Status = request.Status; task.Priority = request.Priority; task.AssigneeId = request.AssigneeId; task.DueDate = request.DueDate; task.UpdatedAt = DateTime.UtcNow; await uow.SaveChangesAsync(ct); return await TaskAccess.GetDtoAsync(uow, mapper, task.Id, ct); } }