Convert Projects module to MediatR commands/queries
Replaces IProjectService/ProjectService. IProjectMemberService is left in place for now — ProjectMembersController still depends on it until the next task converts it too. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
using MediatR;
|
||||
using Mws.Application.Common;
|
||||
using Mws.Domain.Projects;
|
||||
|
||||
namespace Mws.Application.Projects;
|
||||
|
||||
public record ArchiveProjectCommand(Guid UserId, Guid ProjectId) : IRequest;
|
||||
|
||||
public class ArchiveProjectHandler(IUnitOfWork uow) : IRequestHandler<ArchiveProjectCommand>
|
||||
{
|
||||
public async Task Handle(ArchiveProjectCommand command, CancellationToken ct)
|
||||
{
|
||||
var project = await ProjectAccess.GetForUserOrThrowAsync(uow, command.UserId, command.ProjectId, ct);
|
||||
|
||||
if (await uow.Projects.GetMemberRoleAsync(command.ProjectId, command.UserId, ct) != MemberRole.Owner)
|
||||
{
|
||||
throw new ForbiddenException("Only the project owner can archive the project");
|
||||
}
|
||||
|
||||
project.Status = ProjectStatus.Archived;
|
||||
project.UpdatedAt = DateTime.UtcNow;
|
||||
await uow.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using AutoMapper;
|
||||
using MediatR;
|
||||
using Mws.Application.Common;
|
||||
using Mws.Domain.Projects;
|
||||
|
||||
namespace Mws.Application.Projects;
|
||||
|
||||
public record CreateProjectCommand(Guid UserId, CreateProjectRequest Request) : IRequest<ProjectDto>;
|
||||
|
||||
public class CreateProjectHandler(IUnitOfWork uow, IMapper mapper) : IRequestHandler<CreateProjectCommand, ProjectDto>
|
||||
{
|
||||
public async Task<ProjectDto> Handle(CreateProjectCommand command, CancellationToken ct)
|
||||
{
|
||||
var request = command.Request;
|
||||
if (string.IsNullOrWhiteSpace(request.Name))
|
||||
{
|
||||
throw new BadRequestException("Project name is required");
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var project = new Project
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = request.Name.Trim(),
|
||||
Description = request.Description,
|
||||
Status = ProjectStatus.Active,
|
||||
CreatedAt = now,
|
||||
UpdatedAt = now,
|
||||
};
|
||||
|
||||
project.Members.Add(new ProjectMember
|
||||
{
|
||||
ProjectId = project.Id,
|
||||
UserId = command.UserId,
|
||||
Role = MemberRole.Owner,
|
||||
});
|
||||
|
||||
uow.Projects.Add(project);
|
||||
await uow.SaveChangesAsync(ct);
|
||||
return mapper.Map<ProjectDto>(project);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using AutoMapper;
|
||||
using MediatR;
|
||||
using Mws.Application.Common;
|
||||
using Mws.Domain.Projects;
|
||||
|
||||
namespace Mws.Application.Projects;
|
||||
|
||||
public record UpdateProjectCommand(Guid UserId, Guid ProjectId, UpdateProjectRequest Request) : IRequest<ProjectDto>;
|
||||
|
||||
public class UpdateProjectHandler(IUnitOfWork uow, IMapper mapper) : IRequestHandler<UpdateProjectCommand, ProjectDto>
|
||||
{
|
||||
public async Task<ProjectDto> Handle(UpdateProjectCommand command, CancellationToken ct)
|
||||
{
|
||||
var project = await ProjectAccess.GetForUserOrThrowAsync(uow, command.UserId, command.ProjectId, ct);
|
||||
|
||||
if (MemberRole.Owner != await uow.Projects.GetMemberRoleAsync(command.ProjectId, command.UserId, ct))
|
||||
{
|
||||
throw new ForbiddenException("Only the project owner can update the project");
|
||||
}
|
||||
|
||||
var request = command.Request;
|
||||
if (string.IsNullOrWhiteSpace(request.Name))
|
||||
{
|
||||
throw new BadRequestException("Project name is required");
|
||||
}
|
||||
|
||||
project.Name = request.Name.Trim();
|
||||
project.Description = request.Description;
|
||||
project.Status = request.Status;
|
||||
project.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
await uow.SaveChangesAsync(ct);
|
||||
return mapper.Map<ProjectDto>(project);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user