From 355f6c719b4f0048ebb1b18083e94c22e9695c3e Mon Sep 17 00:00:00 2001 From: sorvkumr Date: Thu, 29 Jun 2023 19:48:11 +0530 Subject: [PATCH 1/2] Project User Cqrs implementation. --- .../Controllers/ProjectUserController.cs | 48 ++++++++++++------- .../CreateProjectUserCommand.cs | 12 +++-- .../DeleteProjectUserCommand.cs | 35 ++++++++++++++ .../DeleteProjectUserCommandValidator.cs | 15 ++++++ .../UpdateProjectUserCommand.cs | 34 +++++++++++++ .../UpdateProjectUserCommandValidator.cs | 17 +++++++ .../GetProjectUsersWithUserIdPagination.cs | 36 ++++++++++++++ 7 files changed, 174 insertions(+), 23 deletions(-) create mode 100644 backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs create mode 100644 backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs create mode 100644 backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs create mode 100644 backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs create mode 100644 backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithUserIdPagination.cs diff --git a/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs b/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs index 7f06cca..e3fce6f 100644 --- a/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs +++ b/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs @@ -1,7 +1,10 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.CodeAnalysis; +using ThreeTee.Application.Cqrs.ProjectUsers.Commands.CreateProjectUser; +using ThreeTee.Application.Cqrs.ProjectUsers.Commands.DeleteProjectUser; +using ThreeTee.Application.Cqrs.ProjectUsers.Commands.UpdateProjectUser; using ThreeTee.Application.Cqrs.ProjectUsers.Queries; -using ThreeTee.Application.Interfaces; using ThreeTee.Application.Models.ProjectUser; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 @@ -13,12 +16,13 @@ namespace ThreeTee.Api.Controllers [Authorize] public class ProjectUserController : ApiControllerBase { - private readonly IProjectUserService _projectUserService; + private readonly IEntitiesContext _context; - public ProjectUserController(IProjectUserService projectUserService) + public ProjectUserController(IEntitiesContext context) { - _projectUserService = projectUserService; + _context = context; } + // GET: api/ [HttpGet] [Produces(typeof(List))] @@ -28,37 +32,45 @@ public async Task Get([FromQuery] GetProjectUsersWithPaginationQuery qu return TypedResults.Ok(items); } - [HttpGet("{id}")] + //GET PROJECT USER LIST api/ + [HttpPost("{UserId}")] [Produces(typeof(List))] - public async Task Get(Guid id) + public async Task Get(GetProjectUsersWithUserIdPaginationQuery query) { - var items = await _projectUserService.GetByProjectId(id); + var items = await Mediator.Send(query); return TypedResults.Ok(items); } // POST api/ [HttpPost] - public async Task Post([FromBody] ProjectUserUpsertRequest value) + public async Task Post([FromBody] CreateProjectUserCommand query) { - - var ret = await _projectUserService.InsertAsync(value); - if (ret == null) return TypedResults.BadRequest(); - return TypedResults.Created(ret.ProjectId.ToString()); + var items = await Mediator.Send(query); + if (items != Guid.Empty) + { return TypedResults.Created(items.ToString()); } + return TypedResults.BadRequest(); } + // PUT api/ [HttpPut] - public async Task Put(ProjectUserUpsertRequest request) + public async Task Put(UpdateProjectUserCommand query) { - var item = await _projectUserService.UpdateAsync(request); + query.OldProjectId = _context.ProjectUsers.Where(e => e.UserId == query.UserId) + ?.SingleOrDefault(e => e.ProjectId == query.ProjectId)?.ProjectId; + + var item = await Mediator.Send(query); return TypedResults.Ok(item); } - [HttpDelete("{id}")] - public async Task Delete(Guid id) + // DELETE api/ + [HttpDelete("{UserId}")] + public async Task Delete(DeleteProjectUserCommand query) { - await _projectUserService.DeleteAsync(id); + query.OldProjectId = _context.ProjectUsers.Where(e => e.UserId == query.UserId) + ?.SingleOrDefault(e => e.ProjectId == query.ProjectId)?.ProjectId; + + var item = await Mediator.Send(query); return TypedResults.NoContent(); } - } } diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/CreateProjectUser/CreateProjectUserCommand.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/CreateProjectUser/CreateProjectUserCommand.cs index d07494a..4aee58d 100644 --- a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/CreateProjectUser/CreateProjectUserCommand.cs +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/CreateProjectUser/CreateProjectUserCommand.cs @@ -1,3 +1,4 @@ +using Mapster; using MediatR; using ThreeTee.Core.Entities; @@ -20,11 +21,12 @@ public CreateProjectUserCommandHandler(IEntitiesContext context) public async Task Handle(CreateProjectUserCommand request, CancellationToken cancellationToken) { - var entity = new ProjectUser - { - ProjectId = request.ProjectId, - UserId = request.UserId, - }; + var entity = request.Adapt(); + //var entitys = new ProjectUser + //{ + // ProjectId = request.ProjectId, + // UserId = entity.UserId, + //}; // entity.AddDomainEvent(new ProjectUserCreatedEvent(entity)); diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs new file mode 100644 index 0000000..0ff2321 --- /dev/null +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs @@ -0,0 +1,35 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Net; +using ThreeTee.Application.Cqrs.ProjectUsers.Commands.UpdateProjectUser; +using ThreeTee.Core.Entities; + +namespace ThreeTee.Application.Cqrs.ProjectUsers.Commands.DeleteProjectUser; + +public record DeleteProjectUserCommand : IRequest +{ + public Guid UserId { get; set; } + public Guid ProjectId { get; set; } + public Guid? OldProjectId { get; set; } +} + +public class DeleteProjectUserCommandHandler : IRequestHandler +{ + private readonly IEntitiesContext _context; + public DeleteProjectUserCommandHandler(IEntitiesContext context) + { + _context=context; + } + public async Task Handle(DeleteProjectUserCommand request, CancellationToken cancellationToken) + { + var projectUser = _context.ProjectUsers.FirstOrDefault(p => p.UserId == request.UserId); + + if (projectUser is null) + return default; + + _context.ProjectUsers.Remove(projectUser); + await _context.SaveChangesAsync(cancellationToken); + return "Record Deleted"; + } +} + diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs new file mode 100644 index 0000000..2c9145b --- /dev/null +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; + +namespace ThreeTee.Application.Cqrs.ProjectUsers.Commands.DeleteProjectUser; + +public class DeleteProjectUserCommandValidator:AbstractValidator +{ + public DeleteProjectUserCommandValidator() + { + RuleFor(e=>e.UserId) + .NotEmpty(); + RuleFor(e => e.ProjectId == e.OldProjectId) + .NotEmpty(); + } +} + diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs new file mode 100644 index 0000000..5a6ff95 --- /dev/null +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs @@ -0,0 +1,34 @@ +using FluentValidation; +using Mapster; +using MediatR; +using Microsoft.EntityFrameworkCore; +using ThreeTee.Core.Entities; + +namespace ThreeTee.Application.Cqrs.ProjectUsers.Commands.UpdateProjectUser; + +public record UpdateProjectUserCommand : IRequest +{ + public Guid UserId { get; set; } + public Guid ProjectId { get; set; } + public Guid? OldProjectId { get; set; } +} + +public class UpdateProjectUserCommandHandler : IRequestHandler +{ + private readonly IEntitiesContext _context; + public UpdateProjectUserCommandHandler(IEntitiesContext context) + { + _context = context; + } + public async Task Handle(UpdateProjectUserCommand request, CancellationToken cancellationToken) + { + //Assign new project to User. + var entity = request.Adapt(); + + _context.ProjectUsers.Add(entity); + await _context.SaveChangesAsync(cancellationToken); + + return entity; + } +} + diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs new file mode 100644 index 0000000..f5c672a --- /dev/null +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs @@ -0,0 +1,17 @@ +using FluentValidation; + +namespace ThreeTee.Application.Cqrs.ProjectUsers.Commands.UpdateProjectUser; + +public class UpdateProjectUserCommandValidator:AbstractValidator +{ + public UpdateProjectUserCommandValidator() + { + RuleFor(v => v.UserId) + .NotEmpty(); + RuleFor(v=>v.ProjectId) + .NotEmpty(); + RuleFor(v=>v.ProjectId!=v.OldProjectId) + .NotEmpty(); + } +} + diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithUserIdPagination.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithUserIdPagination.cs new file mode 100644 index 0000000..a77448d --- /dev/null +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithUserIdPagination.cs @@ -0,0 +1,36 @@ +using Mapster; +using MapsterMapper; +using MediatR; +using ThreeTee.Application.Mappings; +using ThreeTee.Application.Models; +using ThreeTee.Application.Models.ProjectUser; + +namespace ThreeTee.Application.Cqrs.ProjectUsers.Queries; + +public record GetProjectUsersWithUserIdPaginationQuery : IRequest> +{ + public int PageNumber { get; init; } = 1; + public int PageSize { get; init; } = 10; + public Guid UserId { get; set; } +} + +public class GetProjectUsersWithUserIdPaginationQueryHandler : IRequestHandler> +{ + private readonly IEntitiesContext _context; + private readonly IMapper _mapper; + + public GetProjectUsersWithUserIdPaginationQueryHandler(IEntitiesContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task> Handle(GetProjectUsersWithUserIdPaginationQuery request, CancellationToken cancellationToken) + { + return await _context.ProjectUsers + .Where(e=>e.UserId==request.UserId) + // .OrderBy(pu=>pu.LastTouchedBy) + .ProjectToType() + .PaginatedListAsync(request.PageNumber, request.PageSize); + } +} \ No newline at end of file From 382327fe5b1923eaaa6f05538e1d3f7d2b9492c9 Mon Sep 17 00:00:00 2001 From: sorvkumr Date: Fri, 30 Jun 2023 11:42:49 +0530 Subject: [PATCH 2/2] Fixed issue for ProjectUser Module cqrs. --- .../Controllers/ProjectUserController.cs | 13 ------------ .../DeleteProjectUserCommand.cs | 20 ++++++++----------- .../DeleteProjectUserCommandValidator.cs | 2 +- .../UpdateProjectUserCommand.cs | 20 ++++++++++++------- .../UpdateProjectUserCommandValidator.cs | 6 ++++-- .../Queries/GetProjectUsersWithPagination.cs | 4 ++-- 6 files changed, 28 insertions(+), 37 deletions(-) diff --git a/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs b/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs index e3fce6f..a57ec71 100644 --- a/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs +++ b/backend/src/ThreeTee.Api/Controllers/ProjectUserController.cs @@ -16,13 +16,6 @@ namespace ThreeTee.Api.Controllers [Authorize] public class ProjectUserController : ApiControllerBase { - private readonly IEntitiesContext _context; - - public ProjectUserController(IEntitiesContext context) - { - _context = context; - } - // GET: api/ [HttpGet] [Produces(typeof(List))] @@ -55,9 +48,6 @@ public async Task Post([FromBody] CreateProjectUserCommand query) [HttpPut] public async Task Put(UpdateProjectUserCommand query) { - query.OldProjectId = _context.ProjectUsers.Where(e => e.UserId == query.UserId) - ?.SingleOrDefault(e => e.ProjectId == query.ProjectId)?.ProjectId; - var item = await Mediator.Send(query); return TypedResults.Ok(item); } @@ -66,9 +56,6 @@ public async Task Put(UpdateProjectUserCommand query) [HttpDelete("{UserId}")] public async Task Delete(DeleteProjectUserCommand query) { - query.OldProjectId = _context.ProjectUsers.Where(e => e.UserId == query.UserId) - ?.SingleOrDefault(e => e.ProjectId == query.ProjectId)?.ProjectId; - var item = await Mediator.Send(query); return TypedResults.NoContent(); } diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs index 0ff2321..f9ac4c7 100644 --- a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommand.cs @@ -1,35 +1,31 @@ using MediatR; -using Microsoft.EntityFrameworkCore; -using System.Net; -using ThreeTee.Application.Cqrs.ProjectUsers.Commands.UpdateProjectUser; -using ThreeTee.Core.Entities; namespace ThreeTee.Application.Cqrs.ProjectUsers.Commands.DeleteProjectUser; -public record DeleteProjectUserCommand : IRequest +public record DeleteProjectUserCommand : IRequest { public Guid UserId { get; set; } public Guid ProjectId { get; set; } - public Guid? OldProjectId { get; set; } } -public class DeleteProjectUserCommandHandler : IRequestHandler +public class DeleteProjectUserCommandHandler : IRequestHandler { private readonly IEntitiesContext _context; public DeleteProjectUserCommandHandler(IEntitiesContext context) { - _context=context; + _context = context; } - public async Task Handle(DeleteProjectUserCommand request, CancellationToken cancellationToken) + public async Task Handle(DeleteProjectUserCommand request, CancellationToken cancellationToken) { - var projectUser = _context.ProjectUsers.FirstOrDefault(p => p.UserId == request.UserId); + var projectUser = _context.ProjectUsers.Where(e => e.UserId == request.UserId) + .FirstOrDefault(e => e.ProjectId == request.ProjectId); if (projectUser is null) - return default; + return false; _context.ProjectUsers.Remove(projectUser); await _context.SaveChangesAsync(cancellationToken); - return "Record Deleted"; + return true; } } diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs index 2c9145b..a48c77b 100644 --- a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/DeleteProjectUser/DeleteProjectUserCommandValidator.cs @@ -8,7 +8,7 @@ public DeleteProjectUserCommandValidator() { RuleFor(e=>e.UserId) .NotEmpty(); - RuleFor(e => e.ProjectId == e.OldProjectId) + RuleFor(e => e.ProjectId) .NotEmpty(); } } diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs index 5a6ff95..9223318 100644 --- a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommand.cs @@ -1,7 +1,6 @@ using FluentValidation; using Mapster; using MediatR; -using Microsoft.EntityFrameworkCore; using ThreeTee.Core.Entities; namespace ThreeTee.Application.Cqrs.ProjectUsers.Commands.UpdateProjectUser; @@ -10,7 +9,7 @@ public record UpdateProjectUserCommand : IRequest { public Guid UserId { get; set; } public Guid ProjectId { get; set; } - public Guid? OldProjectId { get; set; } + public Guid OldProjectId { get; set; } } public class UpdateProjectUserCommandHandler : IRequestHandler @@ -22,13 +21,20 @@ public UpdateProjectUserCommandHandler(IEntitiesContext context) } public async Task Handle(UpdateProjectUserCommand request, CancellationToken cancellationToken) { - //Assign new project to User. - var entity = request.Adapt(); + //Check user for project present. If not create new one. - _context.ProjectUsers.Add(entity); - await _context.SaveChangesAsync(cancellationToken); + var projectUser = _context.ProjectUsers.Where(e => e.UserId == request.UserId) + .FirstOrDefault(e => e.ProjectId == request.ProjectId); + if (projectUser == null) + { + var entity = request.Adapt(); - return entity; + _context.ProjectUsers.Add(entity); + await _context.SaveChangesAsync(cancellationToken); + + return entity; + } + return projectUser; } } diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs index f5c672a..2198be3 100644 --- a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Commands/UpdateProjectUser/UpdateProjectUserCommandValidator.cs @@ -8,10 +8,12 @@ public UpdateProjectUserCommandValidator() { RuleFor(v => v.UserId) .NotEmpty(); - RuleFor(v=>v.ProjectId) + RuleFor(v => v.ProjectId) .NotEmpty(); - RuleFor(v=>v.ProjectId!=v.OldProjectId) + RuleFor(v => v.OldProjectId) .NotEmpty(); + RuleFor(e => e.ProjectId) + .NotEqual(v => v.OldProjectId); } } diff --git a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithPagination.cs b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithPagination.cs index f50e318..11c914f 100644 --- a/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithPagination.cs +++ b/backend/src/ThreeTee.Application/Cqrs/ProjectUsers/Queries/GetProjectUsersWithPagination.cs @@ -13,12 +13,12 @@ public record GetProjectUsersWithPaginationQuery : IRequest> +public class GetProjectUsersWithPaginationQueryHandler : IRequestHandler> { private readonly IEntitiesContext _context; private readonly IMapper _mapper; - public GetTodoItemsWithPaginationQueryHandler(IEntitiesContext context, IMapper mapper) + public GetProjectUsersWithPaginationQueryHandler(IEntitiesContext context, IMapper mapper) { _context = context; _mapper = mapper;