Implemented comprehensive CQRS pattern for Sprint module: Commands: - UpdateSprintCommand: Update sprint details with validation - DeleteSprintCommand: Delete sprints (business rule: cannot delete active sprints) - StartSprintCommand: Transition sprint from Planned to Active - CompleteSprintCommand: Transition sprint from Active to Completed - AddTaskToSprintCommand: Add tasks to sprint with validation - RemoveTaskFromSprintCommand: Remove tasks from sprint Queries: - GetSprintByIdQuery: Get sprint by ID with DTO mapping - GetSprintsByProjectIdQuery: Get all sprints for a project - GetActiveSprintsQuery: Get all active sprints across projects Infrastructure: - Created IApplicationDbContext interface for Application layer DB access - Registered IApplicationDbContext in DI container - Added Microsoft.EntityFrameworkCore package to Application layer - Updated UnitOfWork to expose GetDbContext() method API: - Created SprintsController with all CRUD and lifecycle endpoints - Implemented proper HTTP methods (POST, PUT, DELETE, GET) - Added sprint status transition endpoints (start, complete) - Added task management endpoints (add/remove tasks) All tests passing. Ready for Tasks 4-6. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
40 lines
1.5 KiB
C#
40 lines
1.5 KiB
C#
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
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;
|
|
|
|
namespace ColaFlow.Modules.ProjectManagement.Application.Commands.CompleteSprint;
|
|
|
|
/// <summary>
|
|
/// Handler for CompleteSprintCommand
|
|
/// </summary>
|
|
public sealed class CompleteSprintCommandHandler(
|
|
IApplicationDbContext context,
|
|
IUnitOfWork unitOfWork)
|
|
: IRequestHandler<CompleteSprintCommand, Unit>
|
|
{
|
|
private readonly IApplicationDbContext _context = context ?? throw new ArgumentNullException(nameof(context));
|
|
private readonly IUnitOfWork _unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
|
|
|
|
public async Task<Unit> Handle(CompleteSprintCommand request, CancellationToken cancellationToken)
|
|
{
|
|
// Get sprint with tracking
|
|
var sprintId = SprintId.From(request.SprintId);
|
|
var sprint = await _context.Sprints
|
|
.FirstOrDefaultAsync(s => s.Id == sprintId, cancellationToken);
|
|
|
|
if (sprint == null)
|
|
throw new NotFoundException("Sprint", request.SprintId);
|
|
|
|
// Complete sprint (business rules enforced in domain)
|
|
sprint.Complete();
|
|
|
|
// Save changes
|
|
await _unitOfWork.SaveChangesAsync(cancellationToken);
|
|
|
|
return Unit.Value;
|
|
}
|
|
}
|