Project Init
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
using MediatR;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.DTOs;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Modules.ProjectManagement.Application.Queries.GetEpicById;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for GetEpicByIdQuery
|
||||
/// </summary>
|
||||
public sealed class GetEpicByIdQueryHandler : IRequestHandler<GetEpicByIdQuery, EpicDto>
|
||||
{
|
||||
private readonly IProjectRepository _projectRepository;
|
||||
|
||||
public GetEpicByIdQueryHandler(IProjectRepository projectRepository)
|
||||
{
|
||||
_projectRepository = projectRepository ?? throw new ArgumentNullException(nameof(projectRepository));
|
||||
}
|
||||
|
||||
public async Task<EpicDto> Handle(GetEpicByIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var epicId = EpicId.From(request.EpicId);
|
||||
var project = await _projectRepository.GetProjectWithEpicAsync(epicId, cancellationToken);
|
||||
|
||||
if (project == null)
|
||||
throw new NotFoundException("Epic", request.EpicId);
|
||||
|
||||
var epic = project.Epics.FirstOrDefault(e => e.Id == epicId);
|
||||
if (epic == null)
|
||||
throw new NotFoundException("Epic", request.EpicId);
|
||||
|
||||
return new EpicDto
|
||||
{
|
||||
Id = epic.Id.Value,
|
||||
Name = epic.Name,
|
||||
Description = epic.Description,
|
||||
ProjectId = epic.ProjectId.Value,
|
||||
Status = epic.Status.Value,
|
||||
Priority = epic.Priority.Value,
|
||||
CreatedBy = epic.CreatedBy.Value,
|
||||
CreatedAt = epic.CreatedAt,
|
||||
UpdatedAt = epic.UpdatedAt,
|
||||
Stories = epic.Stories.Select(s => new StoryDto
|
||||
{
|
||||
Id = s.Id.Value,
|
||||
Title = s.Title,
|
||||
Description = s.Description,
|
||||
EpicId = s.EpicId.Value,
|
||||
Status = s.Status.Value,
|
||||
Priority = s.Priority.Value,
|
||||
EstimatedHours = s.EstimatedHours,
|
||||
ActualHours = s.ActualHours,
|
||||
AssigneeId = s.AssigneeId?.Value,
|
||||
CreatedBy = s.CreatedBy.Value,
|
||||
CreatedAt = s.CreatedAt,
|
||||
UpdatedAt = s.UpdatedAt,
|
||||
Tasks = new List<TaskDto>()
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using MediatR;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.DTOs;
|
||||
|
||||
namespace ColaFlow.Modules.ProjectManagement.Application.Queries.GetEpicsByProjectId;
|
||||
|
||||
/// <summary>
|
||||
/// Query to get all Epics for a Project
|
||||
/// </summary>
|
||||
public sealed record GetEpicsByProjectIdQuery(Guid ProjectId) : IRequest<List<EpicDto>>;
|
||||
@@ -0,0 +1,43 @@
|
||||
using MediatR;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.DTOs;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Modules.ProjectManagement.Application.Queries.GetEpicsByProjectId;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for GetEpicsByProjectIdQuery
|
||||
/// </summary>
|
||||
public sealed class GetEpicsByProjectIdQueryHandler : IRequestHandler<GetEpicsByProjectIdQuery, List<EpicDto>>
|
||||
{
|
||||
private readonly IProjectRepository _projectRepository;
|
||||
|
||||
public GetEpicsByProjectIdQueryHandler(IProjectRepository projectRepository)
|
||||
{
|
||||
_projectRepository = projectRepository ?? throw new ArgumentNullException(nameof(projectRepository));
|
||||
}
|
||||
|
||||
public async Task<List<EpicDto>> Handle(GetEpicsByProjectIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var projectId = ProjectId.From(request.ProjectId);
|
||||
var project = await _projectRepository.GetByIdAsync(projectId, cancellationToken);
|
||||
|
||||
if (project == null)
|
||||
throw new NotFoundException("Project", request.ProjectId);
|
||||
|
||||
return project.Epics.Select(epic => new EpicDto
|
||||
{
|
||||
Id = epic.Id.Value,
|
||||
Name = epic.Name,
|
||||
Description = epic.Description,
|
||||
ProjectId = epic.ProjectId.Value,
|
||||
Status = epic.Status.Value,
|
||||
Priority = epic.Priority.Value,
|
||||
CreatedBy = epic.CreatedBy.Value,
|
||||
CreatedAt = epic.CreatedAt,
|
||||
UpdatedAt = epic.UpdatedAt,
|
||||
Stories = new List<StoryDto>() // Don't include stories in list view
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,35 @@ public class ProjectRepository : IProjectRepository
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<Project?> GetProjectWithEpicAsync(EpicId epicId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _context.Projects
|
||||
.Include(p => p.Epics)
|
||||
.ThenInclude(e => e.Stories)
|
||||
.Where(p => p.Epics.Any(e => e.Id == epicId))
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<Project?> GetProjectWithStoryAsync(StoryId storyId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _context.Projects
|
||||
.Include(p => p.Epics)
|
||||
.ThenInclude(e => e.Stories)
|
||||
.ThenInclude(s => s.Tasks)
|
||||
.Where(p => p.Epics.Any(e => e.Stories.Any(s => s.Id == storyId)))
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<Project?> GetProjectWithTaskAsync(TaskId taskId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _context.Projects
|
||||
.Include(p => p.Epics)
|
||||
.ThenInclude(e => e.Stories)
|
||||
.ThenInclude(s => s.Tasks)
|
||||
.Where(p => p.Epics.Any(e => e.Stories.Any(s => s.Tasks.Any(t => t.Id == taskId))))
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task AddAsync(Project project, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _context.Projects.AddAsync(project, cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user