Skip to content

Commit

Permalink
Merge pull request #12 from bentran1vn/Features/Group/Create
Browse files Browse the repository at this point in the history
Features/group/create
  • Loading branch information
PhucNghi176 authored Oct 9, 2024
2 parents ef5adc0 + 692cf5b commit 92ffb45
Show file tree
Hide file tree
Showing 21 changed files with 259 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using MBS_COMMAND.Domain.Abstractions.Repositories;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;

namespace MBS_COMMAND.API.DependencyInjection.Extensions;

public class CurrentUserService : ICurrentUserService
{
private readonly ClaimsPrincipal? _claimsPrincipal;

public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
_claimsPrincipal = httpContextAccessor?.HttpContext?.User;

}

public string? UserId => _claimsPrincipal?.FindFirstValue(ClaimTypes.NameIdentifier);

public string? UserName => _claimsPrincipal?.FindFirstValue(ClaimTypes.Name);

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Antree_Ecommerce_BE.API.DependencyInjection.Extensions;
namespace MBS_COMMAND.API.DependencyInjection.Extensions;

public static class ServiceCollectionExtensions
{
Expand Down
4 changes: 3 additions & 1 deletion MBS-COMMAND.API/Program.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Antree_Ecommerce_BE.API.DependencyInjection.Extensions;
using Carter;
using MBS_COMMAND.API.DependencyInjection.Extensions;
using MBS_COMMAND.API.Middlewares;
using MBS_COMMAND.Application.DependencyInjection.Extensions;
using MBS_COMMAND.Domain.Abstractions.Repositories;
using MBS_COMMAND.Infrastucture.DependencyInjection.Extensions;
using MBS_COMMAND.Infrastucture.DependencyInjection.Options;
using MBS_COMMAND.Persistence.DependencyInjection.Extensions;
Expand Down Expand Up @@ -76,6 +76,8 @@

// Add Middleware => Remember using middleware
builder.Services.AddTransient<ExceptionHandlingMiddleware>();
builder.Services.AddTransient<ICurrentUserService,CurrentUserService>();
builder.Services.AddHttpContextAccessor();

var app = builder.Build();

Expand Down
11 changes: 6 additions & 5 deletions MBS-COMMAND.API/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"ConnectionStrings": {
"ConnectionStrings": "Server=103.162.14.116;Database=PRN_SUPER;Uid=sa;Pwd=MyStrongPassword123@;Trust Server Certificate=True;",
// "ConnectionStrings": "Server=103.162.14.116;Database=PRN_SUPER;Uid=sa;Pwd=MyStrongPassword123@;Trust Server Certificate=True;",
"ConnectionStrings": "Server=(local);Database=PRN_SUPER;Uid=sa;Pwd=12345;Trust Server Certificate=True;",
"Redis": "103.162.14.116:6379,password=MyStrongPassword123@,abortConnect=false"
},
"JwtOption": {
Expand All @@ -10,11 +11,11 @@
"ExpireMin": 5
},
"MasstransitConfiguration": {
"Host": "103.162.14.116",
"VHost": "myHost",
"Host": "localhost",
"VHost": "phucnghi",
"Port": 5672,
"UserName": "sa",
"Password": "MyStrongPassword123@"
"UserName": "guest",
"Password": "guest"
},
"MessageBusOptions": {
"retryLimit": 3,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using MBS_COMMAND.Contract.Abstractions.Messages;
using MBS_COMMAND.Contract.Abstractions.Shared;
using MBS_COMMAND.Contract.Services.Groups;
using MBS_COMMAND.Domain.Abstractions;
using MBS_COMMAND.Domain.Abstractions.Repositories;
using MBS_COMMAND.Domain.Entities;

namespace MBS_COMMAND.Application.UserCases.Commands.Groups;

public sealed class AddListMemberToGroupCommandHandler(IRepositoryBase<User, Guid> userRepository, IRepositoryBase<Group, Guid> groupRepository, IUnitOfWork unitOfWork) : ICommandHandler<Command.AddListMemberToGroup>
{
public async Task<Result> Handle(Command.AddListMemberToGroup request, CancellationToken cancellationToken)
{
//validate all MemberId
Dictionary<Guid, string> MembersNotFound = [];
var G = await groupRepository.FindSingleAsync(x => x.Id == request.GroupId, cancellationToken);
if (G == null)
return Result.Failure(new Error("404", "Group Not Found"));
foreach (var memberId in request.MemberId)
{
var user = await userRepository.FindByIdAsync(memberId);
if (user == null)
{
MembersNotFound.Add(memberId, "Member Not Found");
}
else
{
G.Members!.Add(new Group_Student_Mapping { StudentId = user!.Id, GroupId = G.Id });
groupRepository.Update(G);
try
{
await unitOfWork.SaveChangesAsync(cancellationToken);
}
catch
{
MembersNotFound.Add(memberId, "Member already joined group");
}
}

}
var returns = string.Join(", ", MembersNotFound.Select(x => $"MemberId: {x.Key}, Error: {x.Value}"));


return MembersNotFound.Count > 0 ? Result.Failure(new Error("422", returns)) : Result.Success();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using MBS_COMMAND.Contract.Abstractions.Messages;
using MBS_COMMAND.Contract.Abstractions.Shared;
using MBS_COMMAND.Contract.Services.Groups;
using MBS_COMMAND.Domain.Abstractions;
using MBS_COMMAND.Domain.Abstractions.Repositories;
using MBS_COMMAND.Domain.Entities;

namespace MBS_COMMAND.Application.UserCases.Commands.Groups;

public sealed class AddMemberToGroupCommandHandler(IRepositoryBase<Group, Guid> groupRepository, IRepositoryBase<User, Guid> userRepository, IUnitOfWork unitOfWork) : ICommandHandler<Command.AddMemberToGroup>
{
public async Task<Result> Handle(Command.AddMemberToGroup request, CancellationToken cancellationToken)
{
var U = await userRepository.FindByIdAsync(request.MemberId);
if (U == null)
return Result.Failure(new Error("404", "User Not Found"));
var G = await groupRepository.FindSingleAsync(x => x.Id == request.GroupId, cancellationToken);
if (G == null)
return Result.Failure(new Error("404", "Group Not Found"));
if (G.Members!.Any(x => x.StudentId == U.Id))
return Result.Failure(new Error("422", "Member already joined group"));
G.Members!.Add(new Group_Student_Mapping { StudentId = U.Id, GroupId = G.Id });
groupRepository.Update(G);
await unitOfWork.SaveChangesAsync(cancellationToken);
return Result.Success();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using MBS_AUTHORIZATION.Domain.Entities;
using MBS_COMMAND.Contract.Abstractions.Messages;
using MBS_COMMAND.Contract.Abstractions.Messages;
using MBS_COMMAND.Contract.Abstractions.Shared;
using MBS_COMMAND.Contract.Services.Groups;
using MBS_COMMAND.Domain.Abstractions.Repositories;
Expand All @@ -16,6 +15,7 @@ public CreateGroupCommandHandler(IRepositoryBase<Group, Guid> repositoryBase, IR
{
_groupRepository = repositoryBase;
_userRepository = userRepository;

}

public async Task<Result> Handle(Command.CreateGroupCommand request, CancellationToken cancellationToken)
Expand All @@ -30,7 +30,9 @@ public async Task<Result> Handle(Command.CreateGroupCommand request, Cancellatio
Stack = request.Stacks,

};
G.Members!.Add(new Group_Student_Mapping { StudentId = M.Id, GroupId = G.Id });
_groupRepository.Add(G);

return Result.Success();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using MBS_COMMAND.Contract.Abstractions.Messages;
using MBS_COMMAND.Contract.Abstractions.Shared;
using MBS_COMMAND.Contract.Services.Groups;
using MBS_COMMAND.Domain.Abstractions;
using MBS_COMMAND.Domain.Abstractions.Repositories;
using MBS_COMMAND.Domain.Entities;

namespace MBS_COMMAND.Application.UserCases.Commands.Groups;

public sealed class RemoveListMemberFromGroupCommandHandler(IRepositoryBase<Group, Guid> groupRepository, IRepositoryBase<User, Guid> userRepository, IUnitOfWork unitOfWork) : ICommandHandler<Command.RemoveListMemberFromGroup>
{
public async Task<Result> Handle(Command.RemoveListMemberFromGroup request, CancellationToken cancellationToken)
{
Dictionary<Guid, string> MembersNotFound = [];
var G = await groupRepository.FindSingleAsync(x => x.Id == request.GroupId, cancellationToken);
if (G == null)
return Result.Failure(new Error("404", "Group Not Found"));
if (request.MemberId.Contains((Guid)G.LeaderId))
return Result.Failure(new Error("422", "Mentor cannot be removed from group"));
foreach (var memberId in request.MemberId)
{
var user = await userRepository.FindByIdAsync(memberId);
if (user == null)
{
MembersNotFound.Add(memberId, "Member Not Found");
}
else
{
var member = G.Members!.FirstOrDefault(x => x.StudentId == user!.Id);
if (member == null)
{
MembersNotFound.Add(memberId, "Member Not Found in Group");
}
else
{
G.Members!.Remove(member);
groupRepository.Update(G);
try
{
await unitOfWork.SaveChangesAsync(cancellationToken);
}
catch
{
MembersNotFound.Add(memberId, "Member already removed from group");
}
}
}

}
var returns = string.Join(", ", MembersNotFound.Select(x => $"MemberId: {x.Key}, Error: {x.Value}"));
return MembersNotFound.Count > 0 ? Result.Failure(new Error("422", returns)) : Result.Success();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using MBS_COMMAND.Contract.Abstractions.Messages;
using MBS_COMMAND.Contract.Abstractions.Shared;
using MBS_COMMAND.Contract.Services.Groups;
using MBS_COMMAND.Domain.Abstractions;
using MBS_COMMAND.Domain.Abstractions.Repositories;
using MBS_COMMAND.Domain.Entities;

namespace MBS_COMMAND.Application.UserCases.Commands.Groups;

public sealed class RemoveMemberFromGroupCommandHandler(IRepositoryBase<Group, Guid> groupRepository, IRepositoryBase<User, Guid> userRepository, IUnitOfWork unitOfWork, ICurrentUserService currentUserService) : ICommandHandler<Command.RemoveMemberFromGroup>
{
public async Task<Result> Handle(Command.RemoveMemberFromGroup request, CancellationToken cancellationToken)
{
var CurrentUserId = currentUserService.UserId;

var U = await userRepository.FindByIdAsync(request.MemberId);
if (U == null)
return Result.Failure(new Error("404", "User Not Found"));
var G = await groupRepository.FindSingleAsync(x => x.Id == request.GroupId, cancellationToken);
if (G == null)
return Result.Failure(new Error("404", "Group Not Found"));
if (CurrentUserId != null && G.LeaderId.ToString() == CurrentUserId)
return Result.Failure(new Error("403", "Leader cannot be removed from group"));
var member = G.Members!.FirstOrDefault(x => x.StudentId == U.Id);
if (member == null)
return Result.Failure(new Error("422", "Member are not found in group"));
G.Members!.Remove(member);
groupRepository.Update(G);
await unitOfWork.SaveChangesAsync(cancellationToken);
return Result.Success();
}
}
1 change: 0 additions & 1 deletion MBS_COMMAND.Contract/Abstractions/Shared/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public Error(string code, string message)
}
public string Code { get; }
public string Message { get; }

public static implicit operator string(Error error) => error.Code;

public static bool operator ==(Error? a, Error? b)
Expand Down
6 changes: 5 additions & 1 deletion MBS_COMMAND.Contract/Services/Groups/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ namespace MBS_COMMAND.Contract.Services.Groups;

public static class Command
{
public record CreateGroupCommand(string Name,Guid MentorId,string Stacks) : ICommand;
public record CreateGroupCommand(string Name, Guid MentorId, string Stacks) : ICommand;
public record AddListMemberToGroup(Guid GroupId, List<Guid> MemberId) : ICommand;
public record RemoveListMemberFromGroup(Guid GroupId, List<Guid> MemberId) : ICommand;
public record AddMemberToGroup(Guid GroupId, Guid MemberId) : ICommand;
public record RemoveMemberFromGroup(Guid GroupId, Guid MemberId) : ICommand;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace MBS_COMMAND.Domain.Abstractions.Repositories;

public interface ICurrentUserService
{
string? UserId { get; }
string? UserName { get; }
}
7 changes: 3 additions & 4 deletions MBS_COMMAND.Domain/Entities/Group.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using MBS_AUTHORIZATION.Domain.Entities;
using MBS_COMMAND.Domain.Abstractions.Aggregates;
using MBS_COMMAND.Domain.Abstractions.Entities;
using MBS_COMMAND.Domain.Abstractions.Entities;

namespace MBS_COMMAND.Domain.Entities;

Expand All @@ -9,14 +7,15 @@ public class Group : Entity<Guid>, IAuditableEntity
public string Name { get; set; }
public Guid? MentorId { get; set; }
public virtual User? Mentor { get; set; }

public Guid? LeaderId { get; set; }
public virtual User? Leader { get; set; }
public string Stack { get; set; }
public Guid? ProjectId { get; set; }
public virtual Project? Project { get; set; }
public DateTimeOffset CreatedOnUtc { get; set; }
public DateTimeOffset? ModifiedOnUtc { get; set; }
public virtual ICollection<Group_Student_Mapping>? Members { get; set; } = [];


}

Expand Down
4 changes: 1 addition & 3 deletions MBS_COMMAND.Domain/Entities/Group_Student_Mapping.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using MBS_AUTHORIZATION.Domain.Entities;

namespace MBS_COMMAND.Domain.Entities;
namespace MBS_COMMAND.Domain.Entities;

public class Group_Student_Mapping
{
Expand Down
4 changes: 0 additions & 4 deletions MBS_COMMAND.Domain/Entities/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ public class Project : Entity<Guid>, IAuditableEntity
{
public string Name { get ; set ; }
public string Description { get ; set ; }




public DateTimeOffset CreatedOnUtc { get ; set ; }
public DateTimeOffset? ModifiedOnUtc { get ; set ; }
}
3 changes: 1 addition & 2 deletions MBS_COMMAND.Domain/Entities/Schedule.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using MBS_AUTHORIZATION.Domain.Entities;
using MBS_COMMAND.Domain.Abstractions.Entities;
using MBS_COMMAND.Domain.Abstractions.Entities;

namespace MBS_COMMAND.Domain.Entities;

Expand Down
3 changes: 1 addition & 2 deletions MBS_COMMAND.Domain/Entities/Slot.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using MBS_AUTHORIZATION.Domain.Entities;
using MBS_COMMAND.Domain.Abstractions.Entities;
using MBS_COMMAND.Domain.Abstractions.Entities;

namespace MBS_COMMAND.Domain.Entities;

Expand Down
3 changes: 1 addition & 2 deletions MBS_COMMAND.Domain/Entities/Transaction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using MBS_AUTHORIZATION.Domain.Entities;
using MBS_COMMAND.Domain.Abstractions.Entities;
using MBS_COMMAND.Domain.Abstractions.Entities;

namespace MBS_COMMAND.Domain.Entities;

Expand Down
12 changes: 9 additions & 3 deletions MBS_COMMAND.Domain/Entities/User.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using MBS_COMMAND.Domain.Abstractions.Entities;
using MBS_COMMAND.Domain.Abstractions.Aggregates;
using MBS_COMMAND.Domain.Abstractions.Entities;
using MBS_COMMAND.Domain.Entities;

namespace MBS_AUTHORIZATION.Domain.Entities;
namespace MBS_COMMAND.Domain.Entities;

public class User : Entity<Guid>, IAuditableEntity
public class User : AggregateRoot<Guid>, IAuditableEntity
{
public string Email { get; set; }
public string? FullName { get; set; }
Expand All @@ -16,5 +17,10 @@ public class User : Entity<Guid>, IAuditableEntity
public virtual User? Mentor { get; set; }
public DateTimeOffset CreatedOnUtc { get; set; }
public DateTimeOffset? ModifiedOnUtc { get; set; }

public virtual ICollection<Group_Student_Mapping>? Groups { get; set; } = [];



public virtual IReadOnlyCollection<MentorSkills> MentorSkillsList { get; set; } = default!;
}
1 change: 0 additions & 1 deletion MBS_COMMAND.Persistence/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using MBS_AUTHORIZATION.Domain.Entities;
using MBS_COMMAND.Domain.Entities;
using Microsoft.EntityFrameworkCore;

Expand Down
Loading

0 comments on commit 92ffb45

Please sign in to comment.