From d1bf7d3558e96b94185f700065b1fdc6786c4eb3 Mon Sep 17 00:00:00 2001 From: Veljko Tosic Date: Wed, 11 Feb 2026 21:58:34 +0100 Subject: [PATCH] Commands and handlers --- .../BanUserFromWhiteboardCommand.cs | 5 ++ .../BanUserFromWhiteboardCommandErrors.cs | 18 ++++++ .../BanUserFromWhiteboardCommandHandler.cs | 55 +++++++++++++++++++ .../KickUserFromWhiteboardCommand.cs | 5 ++ .../KickUserFromWhiteboardCommandErrors.cs | 18 ++++++ .../KickUserFromWhiteboardCommandHandler.cs | 55 +++++++++++++++++++ .../UnbanUserFromWhiteboardCommand.cs | 5 ++ .../UnbanUserFromWhiteboardCommandErrors.cs | 18 ++++++ .../UnbanUserFromWhiteboardCommandHandler.cs | 55 +++++++++++++++++++ 9 files changed, 234 insertions(+) create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommand.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandErrors.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandHandler.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommand.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandErrors.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandHandler.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommand.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandErrors.cs create mode 100644 dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandHandler.cs diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommand.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommand.cs new file mode 100644 index 0000000..e654922 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommand.cs @@ -0,0 +1,5 @@ +using AipsCore.Application.Abstract.Command; + +namespace AipsCore.Application.Models.Whiteboard.Command.BanUserFromWhiteboard; + +public record BanUserFromWhiteboardCommand(string CallerId, string UserId, string WhiteboardId) : ICommand; \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandErrors.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandErrors.cs new file mode 100644 index 0000000..b4a2f97 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandErrors.cs @@ -0,0 +1,18 @@ +using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.ValueObjects; +using AipsCore.Domain.Models.Whiteboard.ValueObjects; + +namespace AipsCore.Application.Models.Whiteboard.Command.BanUserFromWhiteboard; + +public static class BanUserFromWhiteboardCommandErrors +{ + public static ValidationError WhiteboardMembershipNotFound(WhiteboardId whiteboardId, UserId userId) + => new ValidationError( + Code: "whiteboard_membership_not_found", + Message: $"User with id '{userId}' is not a member of whiteboard with id '{whiteboardId}'"); + + public static ValidationError WhiteboardNotFound(WhiteboardId whiteboardId) + => new ValidationError( + Code: "whiteboard_not_found", + Message: $"Whiteboard with id '{whiteboardId}' not found."); +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandHandler.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandHandler.cs new file mode 100644 index 0000000..efcc9a9 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/BanUserFromWhiteboard/BanUserFromWhiteboardCommandHandler.cs @@ -0,0 +1,55 @@ +using AipsCore.Application.Abstract.Command; +using AipsCore.Application.Abstract.UserContext; +using AipsCore.Domain.Abstract; +using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.ValueObjects; +using AipsCore.Domain.Models.Whiteboard.External; +using AipsCore.Domain.Models.Whiteboard.ValueObjects; +using AipsCore.Domain.Models.WhiteboardMembership.External; + +namespace AipsCore.Application.Models.Whiteboard.Command.BanUserFromWhiteboard; + +public class BanUserFromWhiteboardCommandHandler : ICommandHandler +{ + private readonly IWhiteboardRepository _whiteboardRepository; + private readonly IWhiteboardMembershipRepository _whiteboardMembershipRepository; + private readonly IUserContext _userContext; + private readonly IUnitOfWork _unitOfWork; + + public BanUserFromWhiteboardCommandHandler( + IWhiteboardRepository whiteboardRepository, + IWhiteboardMembershipRepository whiteboardMembershipRepository, + IUserContext userContext, + IUnitOfWork unitOfWork) + { + _whiteboardMembershipRepository = whiteboardMembershipRepository; + _userContext = userContext; + _unitOfWork = unitOfWork; + _whiteboardRepository = whiteboardRepository; + } + + public async Task Handle(BanUserFromWhiteboardCommand command, CancellationToken cancellationToken = default) + { + var whiteboardId = new WhiteboardId(command.WhiteboardId); + var userId = new UserId(command.UserId); + + var whiteboard = await _whiteboardRepository.GetByIdAsync(whiteboardId, cancellationToken); + + if (whiteboard is null) + { + throw new ValidationException(BanUserFromWhiteboardCommandErrors.WhiteboardNotFound(whiteboardId)); + } + + var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken); + + if (membership is null) + { + throw new ValidationException(BanUserFromWhiteboardCommandErrors.WhiteboardMembershipNotFound(whiteboardId, userId)); + } + + whiteboard.BanUser(_userContext.GetCurrentUserId(), membership); + + await _whiteboardMembershipRepository.SaveAsync(membership, cancellationToken); + await _unitOfWork.SaveChangesAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommand.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommand.cs new file mode 100644 index 0000000..647f83a --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommand.cs @@ -0,0 +1,5 @@ +using AipsCore.Application.Abstract.Command; + +namespace AipsCore.Application.Models.Whiteboard.Command.KickUserFromWhiteboard; + +public record KickUserFromWhiteboardCommand(string UserId, string WhiteboardId) : ICommand; \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandErrors.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandErrors.cs new file mode 100644 index 0000000..dbc5489 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandErrors.cs @@ -0,0 +1,18 @@ +using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.ValueObjects; +using AipsCore.Domain.Models.Whiteboard.ValueObjects; + +namespace AipsCore.Application.Models.Whiteboard.Command.KickUserFromWhiteboard; + +public static class KickUserFromWhiteboardCommandErrors +{ + public static ValidationError WhiteboardMembershipNotFound(WhiteboardId whiteboardId, UserId userId) + => new ValidationError( + Code: "whiteboard_membership_not_found", + Message: $"User with id '{userId}' is not a member of whiteboard with id '{whiteboardId}'"); + + public static ValidationError WhiteboardNotFound(WhiteboardId whiteboardId) + => new ValidationError( + Code: "whiteboard_not_found", + Message: $"Whiteboard with id '{whiteboardId}' not found."); +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandHandler.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandHandler.cs new file mode 100644 index 0000000..b30b825 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/KickUserFromWhiteboard/KickUserFromWhiteboardCommandHandler.cs @@ -0,0 +1,55 @@ +using AipsCore.Application.Abstract.Command; +using AipsCore.Application.Abstract.UserContext; +using AipsCore.Domain.Abstract; +using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.ValueObjects; +using AipsCore.Domain.Models.Whiteboard.External; +using AipsCore.Domain.Models.Whiteboard.ValueObjects; +using AipsCore.Domain.Models.WhiteboardMembership.External; + +namespace AipsCore.Application.Models.Whiteboard.Command.KickUserFromWhiteboard; + +public class KickUserFromWhiteboardCommandHandler : ICommandHandler +{ + private readonly IWhiteboardRepository _whiteboardRepository; + private readonly IWhiteboardMembershipRepository _whiteboardMembershipRepository; + private readonly IUserContext _userContext; + private readonly IUnitOfWork _unitOfWork; + + public KickUserFromWhiteboardCommandHandler( + IWhiteboardRepository whiteboardRepository, + IWhiteboardMembershipRepository whiteboardMembershipRepository, + IUserContext userContext, + IUnitOfWork unitOfWork) + { + _whiteboardMembershipRepository = whiteboardMembershipRepository; + _userContext = userContext; + _unitOfWork = unitOfWork; + _whiteboardRepository = whiteboardRepository; + } + + public async Task Handle(KickUserFromWhiteboardCommand command, CancellationToken cancellationToken = default) + { + var whiteboardId = new WhiteboardId(command.WhiteboardId); + var userId = new UserId(command.UserId); + + var whiteboard = await _whiteboardRepository.GetByIdAsync(whiteboardId, cancellationToken); + + if (whiteboard is null) + { + throw new ValidationException(KickUserFromWhiteboardCommandErrors.WhiteboardNotFound(whiteboardId)); + } + + var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken); + + if (membership is null) + { + throw new ValidationException(KickUserFromWhiteboardCommandErrors.WhiteboardMembershipNotFound(whiteboardId, userId)); + } + + whiteboard.KickUser(_userContext.GetCurrentUserId(), membership); + + await _whiteboardMembershipRepository.SaveAsync(membership, cancellationToken); + await _unitOfWork.SaveChangesAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommand.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommand.cs new file mode 100644 index 0000000..f0a1be2 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommand.cs @@ -0,0 +1,5 @@ +using AipsCore.Application.Abstract.Command; + +namespace AipsCore.Application.Models.Whiteboard.Command.UnbanUserFromWhiteboard; + +public record UnbanUserFromWhiteboardCommand(string UserId, string WhiteboardId) : ICommand; \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandErrors.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandErrors.cs new file mode 100644 index 0000000..f04e3d9 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandErrors.cs @@ -0,0 +1,18 @@ +using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.ValueObjects; +using AipsCore.Domain.Models.Whiteboard.ValueObjects; + +namespace AipsCore.Application.Models.Whiteboard.Command.UnbanUserFromWhiteboard; + +public static class UnbanUserFromWhiteboardCommandErrors +{ + public static ValidationError WhiteboardMembershipNotFound(WhiteboardId whiteboardId, UserId userId) + => new ValidationError( + Code: "whiteboard_membership_not_found", + Message: $"User with id '{userId}' is not a member of whiteboard with id '{whiteboardId}'"); + + public static ValidationError WhiteboardNotFound(WhiteboardId whiteboardId) + => new ValidationError( + Code: "whiteboard_not_found", + Message: $"Whiteboard with id '{whiteboardId}' not found."); +} \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandHandler.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandHandler.cs new file mode 100644 index 0000000..326a5b3 --- /dev/null +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/UnbanUserFromWhiteboard/UnbanUserFromWhiteboardCommandHandler.cs @@ -0,0 +1,55 @@ +using AipsCore.Application.Abstract.Command; +using AipsCore.Application.Abstract.UserContext; +using AipsCore.Domain.Abstract; +using AipsCore.Domain.Common.Validation; +using AipsCore.Domain.Models.User.ValueObjects; +using AipsCore.Domain.Models.Whiteboard.External; +using AipsCore.Domain.Models.Whiteboard.ValueObjects; +using AipsCore.Domain.Models.WhiteboardMembership.External; + +namespace AipsCore.Application.Models.Whiteboard.Command.UnbanUserFromWhiteboard; + +public class UnbanUserFromWhiteboardCommandHandler : ICommandHandler +{ + private readonly IWhiteboardRepository _whiteboardRepository; + private readonly IWhiteboardMembershipRepository _whiteboardMembershipRepository; + private readonly IUserContext _userContext; + private readonly IUnitOfWork _unitOfWork; + + public UnbanUserFromWhiteboardCommandHandler( + IWhiteboardRepository whiteboardRepository, + IWhiteboardMembershipRepository whiteboardMembershipRepository, + IUserContext userContext, + IUnitOfWork unitOfWork) + { + _whiteboardRepository = whiteboardRepository; + _whiteboardMembershipRepository = whiteboardMembershipRepository; + _userContext = userContext; + _unitOfWork = unitOfWork; + } + + public async Task Handle(UnbanUserFromWhiteboardCommand command, CancellationToken cancellationToken = default) + { + var whiteboardId = new WhiteboardId(command.WhiteboardId); + var userId = new UserId(command.UserId); + + var whiteboard = await _whiteboardRepository.GetByIdAsync(whiteboardId, cancellationToken); + + if (whiteboard is null) + { + throw new ValidationException(UnbanUserFromWhiteboardCommandErrors.WhiteboardNotFound(whiteboardId)); + } + + var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken); + + if (membership is null) + { + throw new ValidationException(UnbanUserFromWhiteboardCommandErrors.WhiteboardMembershipNotFound(whiteboardId, userId)); + } + + whiteboard.UnbanUser(_userContext.GetCurrentUserId(), membership); + + await _whiteboardMembershipRepository.SaveAsync(membership, cancellationToken); + await _unitOfWork.SaveChangesAsync(cancellationToken); + } +} \ No newline at end of file