using MediatR; using ColaFlow.Modules.ProjectManagement.Application.Common.Interfaces; using ColaFlow.Modules.ProjectManagement.Domain.Repositories; using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects; using ColaFlow.Modules.ProjectManagement.Domain.Exceptions; using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate; namespace ColaFlow.Modules.ProjectManagement.Application.Commands.DeleteTask; /// /// Handler for DeleteTaskCommand /// public sealed class DeleteTaskCommandHandler( IProjectRepository projectRepository, IUnitOfWork unitOfWork) : IRequestHandler { private readonly IProjectRepository _projectRepository = projectRepository ?? throw new ArgumentNullException(nameof(projectRepository)); private readonly IUnitOfWork _unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork)); public async Task Handle(DeleteTaskCommand request, CancellationToken cancellationToken) { // Get the project containing the task (Global Query Filter ensures tenant isolation) var taskId = TaskId.From(request.TaskId); var project = await _projectRepository.GetProjectWithTaskAsync(taskId, cancellationToken); if (project == null) throw new NotFoundException("Task", request.TaskId); // Find the story containing the task Story? parentStory = null; foreach (var epic in project.Epics) { foreach (var story in epic.Stories) { var task = story.Tasks.FirstOrDefault(t => t.Id.Value == request.TaskId); if (task != null) { parentStory = story; break; } } if (parentStory != null) break; } if (parentStory == null) throw new NotFoundException("Task", request.TaskId); // Remove task from story parentStory.RemoveTask(taskId); // Update project _projectRepository.Update(project); await _unitOfWork.SaveChangesAsync(cancellationToken); return Unit.Value; } }