Refactored

This commit is contained in:
2026-03-04 23:12:08 +01:00
parent 88442f22dd
commit ef6305919d
31 changed files with 296 additions and 338 deletions

View File

@@ -0,0 +1,5 @@
using AipsCore.Application.Abstract.Command;
namespace AipsCore.Application.Models.Whiteboard.Command.AcceptUserRequestToJoin;
public record AcceptUserRequestToJoinCommand(string WhiteboardId, string UserId): ICommand;

View File

@@ -0,0 +1,40 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Domain.Abstract;
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.Enums;
using AipsCore.Domain.Models.WhiteboardMembership.External;
using AipsCore.Domain.Models.WhiteboardMembership.Validation;
namespace AipsCore.Application.Models.Whiteboard.Command.AcceptUserRequestToJoin;
public class AcceptUserRequestToJoinCommandHandler : ICommandHandler<AcceptUserRequestToJoinCommand>
{
private readonly IWhiteboardMembershipRepository _whiteboardMembershipRepository;
private readonly IUnitOfWork _unitOfWork;
public AcceptUserRequestToJoinCommandHandler(IWhiteboardMembershipRepository whiteboardMembershipRepository, IUnitOfWork unitOfWork)
{
_whiteboardMembershipRepository = whiteboardMembershipRepository;
_unitOfWork = unitOfWork;
}
public async Task Handle(AcceptUserRequestToJoinCommand command, CancellationToken cancellationToken = default)
{
var whiteboardId = new WhiteboardId(command.WhiteboardId);
var userId = new UserId(command.UserId);
var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken);
if (membership is null)
{
throw new ValidationException(WhiteboardMembershipErrors.NotFound(whiteboardId, userId));
}
membership.UpdateStatus(WhiteboardMembershipStatus.Accepted);
await _whiteboardMembershipRepository.SaveAsync(membership, cancellationToken);
await _unitOfWork.SaveChangesAsync(cancellationToken);
}
}

View File

@@ -1,11 +0,0 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
namespace AipsCore.Application.Models.Whiteboard.Command.AddUserToWhiteboard;
public record AddUserToWhiteboardCommand(
string UserId,
string WhiteboardId)
: ICommand;

View File

@@ -1,12 +0,0 @@
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.Whiteboard.ValueObjects;
namespace AipsCore.Application.Models.Whiteboard.Command.AddUserToWhiteboard;
public static class AddUserToWhiteboardCommandErrors
{
public static ValidationError WhiteboardDoesNotExist(WhiteboardId whiteboardId)
=> new ValidationError(
Code: "whiteboard_not_exists",
Message: $"Whiteboard with id '{whiteboardId}' does not exist.");
}

View File

@@ -1,65 +0,0 @@
using AipsCore.Application.Abstract;
using AipsCore.Application.Abstract.Command;
using AipsCore.Domain.Abstract;
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.External;
using AipsCore.Domain.Models.User.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.External;
using AipsCore.Domain.Models.Whiteboard.Validation;
using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.External;
namespace AipsCore.Application.Models.Whiteboard.Command.AddUserToWhiteboard;
public class AddUserToWhiteboardCommandHandler
: ICommandHandler<AddUserToWhiteboardCommand>
{
private readonly IWhiteboardRepository _whiteboardRepository;
private readonly IWhiteboardMembershipRepository _whiteboardMembershipRepository;
private readonly IUserRepository _userRepository;
private readonly IUnitOfWork _unitOfWork;
private readonly IDispatcher _dispatcher;
public AddUserToWhiteboardCommandHandler(
IWhiteboardRepository whiteboardRepository,
IWhiteboardMembershipRepository whiteboardMembershipRepository,
IUserRepository userRepository,
IUnitOfWork unitOfWork,
IDispatcher dispatcher)
{
_whiteboardRepository = whiteboardRepository;
_whiteboardMembershipRepository = whiteboardMembershipRepository;
_userRepository = userRepository;
_unitOfWork = unitOfWork;
_dispatcher = dispatcher;
}
private Domain.Models.Whiteboard.Whiteboard? _whiteboard;
private Domain.Models.User.User? _user;
public async Task Handle(AddUserToWhiteboardCommand command, CancellationToken cancellationToken = default)
{
_whiteboard = await _whiteboardRepository.GetByIdAsync(new WhiteboardId(command.WhiteboardId), cancellationToken);
_user = await _userRepository.GetByIdAsync(new UserId(command.UserId), cancellationToken);
Validate(command);
await _whiteboard!.AddUserAsync(_user!, _whiteboardMembershipRepository, cancellationToken);
await _unitOfWork.SaveChangesAsync(cancellationToken);
}
private void Validate(AddUserToWhiteboardCommand command)
{
if (_whiteboard is null)
{
throw new ValidationException(WhiteboardErrors.NotFound(new WhiteboardId(command.WhiteboardId)));
}
if (_user is null)
{
throw new ValidationException(UserErrors.NotFound(new UserId(command.UserId)));
}
}
}

View File

@@ -1,18 +0,0 @@
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.IdValue}' is not a member of whiteboard with id '{whiteboardId.IdValue}'");
public static ValidationError WhiteboardNotFound(WhiteboardId whiteboardId)
=> new ValidationError(
Code: "whiteboard_not_found",
Message: $"Whiteboard with id '{whiteboardId.IdValue}' not found.");
}

View File

@@ -4,8 +4,10 @@ using AipsCore.Domain.Abstract;
using AipsCore.Domain.Common.Validation; using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects; using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.External; using AipsCore.Domain.Models.Whiteboard.External;
using AipsCore.Domain.Models.Whiteboard.Validation;
using AipsCore.Domain.Models.Whiteboard.ValueObjects; using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.External; using AipsCore.Domain.Models.WhiteboardMembership.External;
using AipsCore.Domain.Models.WhiteboardMembership.Validation;
namespace AipsCore.Application.Models.Whiteboard.Command.BanUserFromWhiteboard; namespace AipsCore.Application.Models.Whiteboard.Command.BanUserFromWhiteboard;
@@ -37,14 +39,14 @@ public class BanUserFromWhiteboardCommandHandler : ICommandHandler<BanUserFromWh
if (whiteboard is null) if (whiteboard is null)
{ {
throw new ValidationException(BanUserFromWhiteboardCommandErrors.WhiteboardNotFound(whiteboardId)); throw new ValidationException(WhiteboardErrors.NotFound(whiteboardId));
} }
var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken); var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken);
if (membership is null) if (membership is null)
{ {
throw new ValidationException(BanUserFromWhiteboardCommandErrors.WhiteboardMembershipNotFound(whiteboardId, userId)); throw new ValidationException(WhiteboardMembershipErrors.NotFound(whiteboardId, userId));
} }
whiteboard.BanUser(_userContext.GetCurrentUserId(), membership); whiteboard.BanUser(_userContext.GetCurrentUserId(), membership);

View File

@@ -1,18 +0,0 @@
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.");
}

View File

@@ -4,8 +4,10 @@ using AipsCore.Domain.Abstract;
using AipsCore.Domain.Common.Validation; using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects; using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.External; using AipsCore.Domain.Models.Whiteboard.External;
using AipsCore.Domain.Models.Whiteboard.Validation;
using AipsCore.Domain.Models.Whiteboard.ValueObjects; using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.External; using AipsCore.Domain.Models.WhiteboardMembership.External;
using AipsCore.Domain.Models.WhiteboardMembership.Validation;
namespace AipsCore.Application.Models.Whiteboard.Command.KickUserFromWhiteboard; namespace AipsCore.Application.Models.Whiteboard.Command.KickUserFromWhiteboard;
@@ -37,14 +39,14 @@ public class KickUserFromWhiteboardCommandHandler : ICommandHandler<KickUserFrom
if (whiteboard is null) if (whiteboard is null)
{ {
throw new ValidationException(KickUserFromWhiteboardCommandErrors.WhiteboardNotFound(whiteboardId)); throw new ValidationException(WhiteboardErrors.NotFound(whiteboardId));
} }
var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken); var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken);
if (membership is null) if (membership is null)
{ {
throw new ValidationException(KickUserFromWhiteboardCommandErrors.WhiteboardMembershipNotFound(whiteboardId, userId)); throw new ValidationException(WhiteboardMembershipErrors.NotFound(whiteboardId, userId));
} }
whiteboard.KickUser(_userContext.GetCurrentUserId(), membership); whiteboard.KickUser(_userContext.GetCurrentUserId(), membership);

View File

@@ -0,0 +1,5 @@
using AipsCore.Application.Abstract.Command;
namespace AipsCore.Application.Models.Whiteboard.Command.RejectUserRequestToJoin;
public record RejectUserRequestToJoinCommand(string WhiteboardId, string UserId): ICommand;

View File

@@ -0,0 +1,40 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Domain.Abstract;
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.Enums;
using AipsCore.Domain.Models.WhiteboardMembership.External;
using AipsCore.Domain.Models.WhiteboardMembership.Validation;
namespace AipsCore.Application.Models.Whiteboard.Command.RejectUserRequestToJoin;
public class RejectUserRequestToJoinCommandHandler : ICommandHandler<RejectUserRequestToJoinCommand>
{
private readonly IWhiteboardMembershipRepository _whiteboardMembershipRepository;
private readonly IUnitOfWork _unitOfWork;
public RejectUserRequestToJoinCommandHandler(IWhiteboardMembershipRepository whiteboardMembershipRepository, IUnitOfWork unitOfWork)
{
_whiteboardMembershipRepository = whiteboardMembershipRepository;
_unitOfWork = unitOfWork;
}
public async Task Handle(RejectUserRequestToJoinCommand command, CancellationToken cancellationToken = default)
{
var whiteboardId = new WhiteboardId(command.WhiteboardId);
var userId = new UserId(command.UserId);
var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken);
if (membership is null)
{
throw new ValidationException(WhiteboardMembershipErrors.NotFound(whiteboardId, userId));
}
membership.UpdateStatus(WhiteboardMembershipStatus.Rejected);
await _whiteboardMembershipRepository.SaveAsync(membership, cancellationToken);
await _unitOfWork.SaveChangesAsync(cancellationToken);
}
}

View File

@@ -1,18 +0,0 @@
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.");
}

View File

@@ -4,8 +4,10 @@ using AipsCore.Domain.Abstract;
using AipsCore.Domain.Common.Validation; using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects; using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.External; using AipsCore.Domain.Models.Whiteboard.External;
using AipsCore.Domain.Models.Whiteboard.Validation;
using AipsCore.Domain.Models.Whiteboard.ValueObjects; using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.External; using AipsCore.Domain.Models.WhiteboardMembership.External;
using AipsCore.Domain.Models.WhiteboardMembership.Validation;
namespace AipsCore.Application.Models.Whiteboard.Command.UnbanUserFromWhiteboard; namespace AipsCore.Application.Models.Whiteboard.Command.UnbanUserFromWhiteboard;
@@ -37,14 +39,14 @@ public class UnbanUserFromWhiteboardCommandHandler : ICommandHandler<UnbanUserFr
if (whiteboard is null) if (whiteboard is null)
{ {
throw new ValidationException(UnbanUserFromWhiteboardCommandErrors.WhiteboardNotFound(whiteboardId)); throw new ValidationException(WhiteboardErrors.NotFound(whiteboardId));
} }
var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken); var membership = await _whiteboardMembershipRepository.GetByWhiteboardAndUserAsync(whiteboardId, userId, cancellationToken);
if (membership is null) if (membership is null)
{ {
throw new ValidationException(UnbanUserFromWhiteboardCommandErrors.WhiteboardMembershipNotFound(whiteboardId, userId)); throw new ValidationException(WhiteboardMembershipErrors.NotFound(whiteboardId, userId));
} }
whiteboard.UnbanUser(_userContext.GetCurrentUserId(), membership); whiteboard.UnbanUser(_userContext.GetCurrentUserId(), membership);

View File

@@ -6,5 +6,6 @@ namespace AipsCore.Domain.Models.Whiteboard.External;
public interface IWhiteboardRepository public interface IWhiteboardRepository
: IAbstractRepository<Whiteboard, WhiteboardId>, ISoftDeletableRepository<WhiteboardId> : IAbstractRepository<Whiteboard, WhiteboardId>, ISoftDeletableRepository<WhiteboardId>
{ {
Task<bool> WhiteboardCodeExists(WhiteboardCode whiteboardCode); Task<bool> WhiteboardCodeExistsAsync(WhiteboardCode whiteboardCode);
Task<Whiteboard?> GetByCodeAsync(WhiteboardCode whiteboardCode, CancellationToken cancellationToken = default);
} }

View File

@@ -7,6 +7,38 @@ namespace AipsCore.Domain.Models.Whiteboard.Validation;
public class WhiteboardErrors : AbstractErrors<Whiteboard, WhiteboardId> public class WhiteboardErrors : AbstractErrors<Whiteboard, WhiteboardId>
{ {
public static ValidationError NotFound(WhiteboardCode whiteboardCode)
{
const string code = "not_found";
string message = $"Whiteboard with code '{whiteboardCode.CodeValue}' was not found!";
return CreateValidationError(code,message);
}
public static ValidationError CannotJoin(WhiteboardCode whiteboardCode)
{
const string code = "cannot_join_whiteboard";
string message = $"Cannot join the whiteboard with code '{whiteboardCode.CodeValue}'";
return CreateValidationError(code,message);
}
public static ValidationError UserBanned(UserId userId)
{
const string code = "user_banned_from_whiteboard";
string message = $"User with id '{userId}' is banned from this whiteboard.";
return CreateValidationError(code,message);
}
public static ValidationError UserAlreadyTryingToJoin(UserId userId)
{
const string code = "user_already_trying_to_join_whiteboard";
string message = $"User with id '{userId}' is already trying to join the whiteboard.";
return CreateValidationError(code,message);
}
public static ValidationError UserAlreadyAdded(UserId userId) public static ValidationError UserAlreadyAdded(UserId userId)
{ {
string code = "user_already_added"; string code = "user_already_added";

View File

@@ -36,7 +36,7 @@ public record WhiteboardCode : AbstractValueObject
{ {
whiteboardCode = Generate(); whiteboardCode = Generate();
codeExists = await whiteboardRepository.WhiteboardCodeExists(whiteboardCode); codeExists = await whiteboardRepository.WhiteboardCodeExistsAsync(whiteboardCode);
} while (codeExists); } while (codeExists);
return whiteboardCode; return whiteboardCode;

View File

@@ -1,42 +1,47 @@
using System.Runtime.InteropServices.Swift;
using AipsCore.Domain.Abstract;
using AipsCore.Domain.Common.Validation; using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.Enums; using AipsCore.Domain.Models.Whiteboard.Enums;
using AipsCore.Domain.Models.Whiteboard.Validation; using AipsCore.Domain.Models.Whiteboard.Validation;
using AipsCore.Domain.Models.Whiteboard.ValueObjects; using AipsCore.Domain.Models.WhiteboardMembership.Enums;
using AipsCore.Domain.Models.WhiteboardMembership.External;
namespace AipsCore.Domain.Models.Whiteboard; namespace AipsCore.Domain.Models.Whiteboard;
public partial class Whiteboard : DomainModel<WhiteboardId> public partial class Whiteboard
{ {
public async Task AddUserAsync( public WhiteboardMembership.WhiteboardMembership RequestJoin(UserId userId)
User.User user,
IWhiteboardMembershipRepository membershipRepository,
CancellationToken cancellationToken = default)
{ {
var membership return WhiteboardMembership.WhiteboardMembership.Create(
= await membershipRepository.GetByWhiteboardAndUserAsync(this.Id, user.Id, cancellationToken); Id.IdValue,
userId.IdValue,
if (membership is not null)
{
throw new ValidationException(WhiteboardErrors.UserAlreadyAdded(user.Id));
}
membership = WhiteboardMembership.WhiteboardMembership.Create(
this.Id.IdValue,
user.Id.IdValue,
false, false,
false, DetermineJoinStatus(),
this.GetCanJoin(), DateTime.UtcNow);
DateTime.UtcNow
);
await membershipRepository.AddAsync(membership, cancellationToken);
} }
private bool GetCanJoin() public void RequestReJoin(WhiteboardMembership.WhiteboardMembership membership)
{ {
return this.JoinPolicy == WhiteboardJoinPolicy.FreeToJoin; switch (membership.Status)
{
case WhiteboardMembershipStatus.Banned:
throw new ValidationException(WhiteboardErrors.UserBanned(membership.UserId));
case WhiteboardMembershipStatus.Pending:
throw new ValidationException(WhiteboardErrors.UserAlreadyTryingToJoin(membership.UserId));
case WhiteboardMembershipStatus.Accepted:
break;
default:
membership.UpdateStatus(DetermineJoinStatus());
break;
}
}
private WhiteboardMembershipStatus DetermineJoinStatus()
{
return JoinPolicy switch
{
WhiteboardJoinPolicy.FreeToJoin => WhiteboardMembershipStatus.Accepted,
WhiteboardJoinPolicy.RequestToJoin => WhiteboardMembershipStatus.Pending,
WhiteboardJoinPolicy.Private => throw new ValidationException(WhiteboardErrors.CannotJoin(Code)),
_ => throw new ArgumentOutOfRangeException()
};
} }
} }

View File

@@ -1,18 +0,0 @@
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.Validation;
namespace AipsCore.Domain.Models.Whiteboard;
public partial class Whiteboard
{
public void BanUser(UserId currentUserId, WhiteboardMembership.WhiteboardMembership whiteboardMembership)
{
if (WhiteboardOwnerId != currentUserId)
{
throw new ValidationException(WhiteboardErrors.OnlyOwnerCanBanOtherUsers(currentUserId));
}
whiteboardMembership.Ban();
}
}

View File

@@ -6,6 +6,11 @@ public partial class Whiteboard
{ {
public bool CanUserDelete(UserId userId) public bool CanUserDelete(UserId userId)
{ {
return WhiteboardOwnerId.IdValue == userId.IdValue; return IsOwner(userId);
}
public bool ShouldRequestToJoin(UserId userId)
{
return !IsOwner(userId);
} }
} }

View File

@@ -1,18 +0,0 @@
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.Validation;
namespace AipsCore.Domain.Models.Whiteboard;
public partial class Whiteboard
{
public void KickUser(UserId currentUserId, WhiteboardMembership.WhiteboardMembership whiteboardMembership)
{
if (WhiteboardOwnerId != currentUserId)
{
throw new ValidationException(WhiteboardErrors.OnlyOwnerCanKickOtherUsers(currentUserId));
}
whiteboardMembership.Kick();
}
}

View File

@@ -0,0 +1,43 @@
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.Validation;
namespace AipsCore.Domain.Models.Whiteboard;
public partial class Whiteboard
{
public void BanUser(UserId currentUserId, WhiteboardMembership.WhiteboardMembership whiteboardMembership)
{
if (IsOwner(currentUserId))
{
throw new ValidationException(WhiteboardErrors.OnlyOwnerCanBanOtherUsers(currentUserId));
}
whiteboardMembership.Ban();
}
public void UnbanUser(UserId currentUserId, WhiteboardMembership.WhiteboardMembership whiteboardMembership)
{
if (IsOwner(currentUserId))
{
throw new ValidationException(WhiteboardErrors.OnlyOwnerCanUnbanOtherUsers(currentUserId));
}
whiteboardMembership.Unban();
}
public void KickUser(UserId currentUserId, WhiteboardMembership.WhiteboardMembership whiteboardMembership)
{
if (IsOwner(currentUserId))
{
throw new ValidationException(WhiteboardErrors.OnlyOwnerCanKickOtherUsers(currentUserId));
}
whiteboardMembership.Kick();
}
private bool IsOwner(UserId userId)
{
return WhiteboardOwnerId.IdValue == userId.IdValue;
}
}

View File

@@ -1,18 +0,0 @@
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.Validation;
namespace AipsCore.Domain.Models.Whiteboard;
public partial class Whiteboard
{
public void UnbanUser(UserId currentUserId, WhiteboardMembership.WhiteboardMembership whiteboardMembership)
{
if (WhiteboardOwnerId != currentUserId)
{
throw new ValidationException(WhiteboardErrors.OnlyOwnerCanUnbanOtherUsers(currentUserId));
}
whiteboardMembership.Unban();
}
}

View File

@@ -0,0 +1,13 @@
namespace AipsCore.Domain.Models.WhiteboardMembership.Enums;
public enum WhiteboardMembershipStatus
{
Pending,
Accepted,
Active,
Inactive,
Rejected,
Cancelled,
Kicked,
Banned
}

View File

@@ -0,0 +1,18 @@
using AipsCore.Domain.Abstract.Validation;
using AipsCore.Domain.Common.Validation;
using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
namespace AipsCore.Domain.Models.WhiteboardMembership.Validation;
public class WhiteboardMembershipErrors : AbstractErrors<WhiteboardMembership, WhiteboardMembershipId>
{
public static ValidationError NotFound(WhiteboardId whiteboardId, UserId userId)
{
const string code = "whiteboard_membership_not_found";
string message = $"Whiteboard membership with whiteboard id {whiteboardId.IdValue} and user id {userId.IdValue} not found.";
return CreateValidationError(code, message);
}
}

View File

@@ -1,20 +0,0 @@
using AipsCore.Domain.Abstract.Rule;
using AipsCore.Domain.Abstract.ValueObject;
namespace AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
public record WhiteboardMembershipCanJoin : AbstractValueObject
{
public bool CanJoinValue { get; init; }
public WhiteboardMembershipCanJoin(bool CanJoinValue)
{
this.CanJoinValue = CanJoinValue;
Validate();
}
protected override ICollection<IRule> GetValidationRules()
{
return [];
}
}

View File

@@ -1,20 +0,0 @@
using AipsCore.Domain.Abstract.Rule;
using AipsCore.Domain.Abstract.ValueObject;
namespace AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
public record WhiteboardMembershipIsBanned : AbstractValueObject
{
public bool IsBannedValue { get; init; }
public WhiteboardMembershipIsBanned(bool IsBannedValue)
{
this.IsBannedValue = IsBannedValue;
Validate();
}
protected override ICollection<IRule> GetValidationRules()
{
return [];
}
}

View File

@@ -1,11 +0,0 @@
using AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
namespace AipsCore.Domain.Models.WhiteboardMembership;
public partial class WhiteboardMembership
{
public void Ban()
{
IsBanned = new WhiteboardMembershipIsBanned(true);
}
}

View File

@@ -1,11 +0,0 @@
using AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
namespace AipsCore.Domain.Models.WhiteboardMembership;
public partial class WhiteboardMembership
{
public void Kick()
{
CanJoin = new WhiteboardMembershipCanJoin(false);
}
}

View File

@@ -0,0 +1,26 @@
using AipsCore.Domain.Models.WhiteboardMembership.Enums;
namespace AipsCore.Domain.Models.WhiteboardMembership;
public partial class WhiteboardMembership
{
public void Ban()
{
Status = WhiteboardMembershipStatus.Banned;
}
public void Unban()
{
Status = WhiteboardMembershipStatus.Cancelled;
}
public void Kick()
{
Status = WhiteboardMembershipStatus.Kicked;
}
public void UpdateStatus(WhiteboardMembershipStatus newStatus)
{
Status = newStatus;
}
}

View File

@@ -1,11 +0,0 @@
using AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
namespace AipsCore.Domain.Models.WhiteboardMembership;
public partial class WhiteboardMembership
{
public void Unban()
{
IsBanned = new WhiteboardMembershipIsBanned(false);
}
}

View File

@@ -1,6 +1,7 @@
using AipsCore.Domain.Abstract; using AipsCore.Domain.Abstract;
using AipsCore.Domain.Models.User.ValueObjects; using AipsCore.Domain.Models.User.ValueObjects;
using AipsCore.Domain.Models.Whiteboard.ValueObjects; using AipsCore.Domain.Models.Whiteboard.ValueObjects;
using AipsCore.Domain.Models.WhiteboardMembership.Enums;
using AipsCore.Domain.Models.WhiteboardMembership.ValueObjects; using AipsCore.Domain.Models.WhiteboardMembership.ValueObjects;
namespace AipsCore.Domain.Models.WhiteboardMembership; namespace AipsCore.Domain.Models.WhiteboardMembership;
@@ -9,97 +10,84 @@ public partial class WhiteboardMembership : DomainModel<WhiteboardMembershipId>
{ {
public WhiteboardId WhiteboardId { get; private set; } public WhiteboardId WhiteboardId { get; private set; }
public UserId UserId { get; private set; } public UserId UserId { get; private set; }
public WhiteboardMembershipIsBanned IsBanned { get; private set; }
public WhiteboardMembershipEditingEnabled EditingEnabled { get; private set; } public WhiteboardMembershipEditingEnabled EditingEnabled { get; private set; }
public WhiteboardMembershipCanJoin CanJoin { get; private set; } public WhiteboardMembershipStatus Status { get; private set; }
public WhiteboardMembershipLastInteractedAt LastInteractedAt { get; private set; } public WhiteboardMembershipLastInteractedAt LastInteractedAt { get; private set; }
public WhiteboardMembership( public WhiteboardMembership(
WhiteboardMembershipId id, WhiteboardMembershipId id,
Whiteboard.Whiteboard owner, Whiteboard.Whiteboard whiteboard,
User.User user, User.User user,
WhiteboardMembershipIsBanned isBanned,
WhiteboardMembershipEditingEnabled editingEnabled, WhiteboardMembershipEditingEnabled editingEnabled,
WhiteboardMembershipCanJoin canJoin, WhiteboardMembershipStatus status,
WhiteboardMembershipLastInteractedAt lastInteractedAt) WhiteboardMembershipLastInteractedAt lastInteractedAt)
: base(id) : base(id)
{ {
WhiteboardId = owner.Id; WhiteboardId = whiteboard.Id;
UserId = user.Id; UserId = user.Id;
IsBanned = isBanned;
EditingEnabled = editingEnabled; EditingEnabled = editingEnabled;
CanJoin = canJoin; Status = status;
LastInteractedAt = lastInteractedAt; LastInteractedAt = lastInteractedAt;
} }
public WhiteboardMembership( public WhiteboardMembership(
WhiteboardMembershipId id, WhiteboardMembershipId id,
WhiteboardId ownerId, WhiteboardId whiteboardId,
UserId userId, UserId userId,
WhiteboardMembershipIsBanned isBanned,
WhiteboardMembershipEditingEnabled editingEnabled, WhiteboardMembershipEditingEnabled editingEnabled,
WhiteboardMembershipCanJoin canJoin, WhiteboardMembershipStatus status,
WhiteboardMembershipLastInteractedAt lastInteractedAt) WhiteboardMembershipLastInteractedAt lastInteractedAt)
: base(id) : base(id)
{ {
WhiteboardId = ownerId; WhiteboardId = whiteboardId;
UserId = userId; UserId = userId;
IsBanned = isBanned;
EditingEnabled = editingEnabled; EditingEnabled = editingEnabled;
CanJoin = canJoin; Status = status;
LastInteractedAt = lastInteractedAt; LastInteractedAt = lastInteractedAt;
} }
public static WhiteboardMembership Create( public static WhiteboardMembership Create(
string id, string id,
string ownerId, string whiteboardId,
string userId, string userId,
bool isBanned,
bool editingEnabled, bool editingEnabled,
bool canJoin, WhiteboardMembershipStatus status,
DateTime lastInteractedAt) DateTime lastInteractedAt)
{ {
var whiteboardMembershipId = new WhiteboardMembershipId(id); var whiteboardMembershipId = new WhiteboardMembershipId(id);
var whiteboardId = new WhiteboardId(ownerId); var whiteboardIdVo = new WhiteboardId(whiteboardId);
var userIdVo = new UserId(userId); var userIdVo = new UserId(userId);
var isBannedVo = new WhiteboardMembershipIsBanned(isBanned);
var editingEnabledVo = new WhiteboardMembershipEditingEnabled(editingEnabled); var editingEnabledVo = new WhiteboardMembershipEditingEnabled(editingEnabled);
var canJoinVo = new WhiteboardMembershipCanJoin(canJoin);
var lastInteractedAtVo = new WhiteboardMembershipLastInteractedAt(lastInteractedAt); var lastInteractedAtVo = new WhiteboardMembershipLastInteractedAt(lastInteractedAt);
return new WhiteboardMembership( return new WhiteboardMembership(
whiteboardMembershipId, whiteboardMembershipId,
whiteboardId, whiteboardIdVo,
userIdVo, userIdVo,
isBannedVo,
editingEnabledVo, editingEnabledVo,
canJoinVo, status,
lastInteractedAtVo); lastInteractedAtVo);
} }
public static WhiteboardMembership Create( public static WhiteboardMembership Create(
string ownerId, string whiteboardId,
string userId, string userId,
bool isBanned,
bool editingEnabled, bool editingEnabled,
bool canJoin, WhiteboardMembershipStatus status,
DateTime lastInteractedAt) DateTime lastInteractedAt)
{ {
var whiteboardMembershipId = WhiteboardMembershipId.Any(); var whiteboardMembershipId = WhiteboardMembershipId.Any();
var whiteboardId = new WhiteboardId(ownerId); var whiteboardIdVo = new WhiteboardId(whiteboardId);
var userIdVo = new UserId(userId); var userIdVo = new UserId(userId);
var isBannedVo = new WhiteboardMembershipIsBanned(isBanned);
var editingEnabledVo = new WhiteboardMembershipEditingEnabled(editingEnabled); var editingEnabledVo = new WhiteboardMembershipEditingEnabled(editingEnabled);
var canJoinVo = new WhiteboardMembershipCanJoin(canJoin);
var lastInteractedAtVo = new WhiteboardMembershipLastInteractedAt(lastInteractedAt); var lastInteractedAtVo = new WhiteboardMembershipLastInteractedAt(lastInteractedAt);
return new WhiteboardMembership( return new WhiteboardMembership(
whiteboardMembershipId, whiteboardMembershipId,
whiteboardId, whiteboardIdVo,
userIdVo, userIdVo,
isBannedVo,
editingEnabledVo, editingEnabledVo,
canJoinVo, status,
lastInteractedAtVo); lastInteractedAtVo);
} }
} }