From db122da75370fd9179c2df87140ea7a44ecc6a4c Mon Sep 17 00:00:00 2001 From: Veljko Tosic Date: Mon, 9 Feb 2026 22:24:33 +0100 Subject: [PATCH] Expanded on existing whiteboard --- .../CreateWhiteboardCommand.cs | 11 ++- .../CreateWhiteboardCommandHandler.cs | 10 ++- .../Validation/Rules/DateInFutureRule.cs | 11 ++- .../Common/Validation/Rules/DateInPastRule.cs | 11 ++- .../Whiteboard/Enums/WhiteboardJoinPolicy.cs | 8 ++ .../Whiteboard/Enums/WhiteboardState.cs | 8 ++ .../ValueObjects/WhiteboardCreatedAt.cs | 23 +++++ .../ValueObjects/WhiteboardDeletedAt.cs | 23 +++++ .../ValueObjects/WhiteboardMaxParticipants.cs | 25 ++++++ .../Domain/Models/Whiteboard/Whiteboard.cs | 89 +++++++++++++++++-- .../Persistence/Whiteboard/Whiteboard.cs | 15 +++- .../Whiteboard/WhiteboardRepository.cs | 23 ++++- 12 files changed, 237 insertions(+), 20 deletions(-) create mode 100644 dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardJoinPolicy.cs create mode 100644 dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardState.cs create mode 100644 dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardCreatedAt.cs create mode 100644 dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardDeletedAt.cs create mode 100644 dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardMaxParticipants.cs diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommand.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommand.cs index 616d7c2..39bad4f 100644 --- a/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommand.cs +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommand.cs @@ -1,7 +1,16 @@ using System.Windows.Input; using AipsCore.Application.Abstract.Command; +using AipsCore.Domain.Models.Whiteboard.Enums; using AipsCore.Domain.Models.Whiteboard.ValueObjects; namespace AipsCore.Application.Models.Whiteboard.Command.CreateWhiteboard; -public record CreateWhiteboardCommand(string OwnerId, string Title) : ICommand; \ No newline at end of file +public record CreateWhiteboardCommand( + string OwnerId, + string Title, + DateTime CreatedAt, + DateTime DeletedAt, + int MaxParticipants, + WhiteboardJoinPolicy JoinPolicy, + WhiteboardState State) + : ICommand; \ No newline at end of file diff --git a/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommandHandler.cs b/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommandHandler.cs index 3d3323f..6c613db 100644 --- a/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommandHandler.cs +++ b/dotnet/AipsCore/Application/Models/Whiteboard/Command/CreateWhiteboard/CreateWhiteboardCommandHandler.cs @@ -20,7 +20,15 @@ public class CreateWhiteboardCommandHandler : ICommandHandler "Date must be in the future"; public override bool Validate() { - return _date > _now; + if (_date is not null) + { + return _date > _now; + } + + return true; } } \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Common/Validation/Rules/DateInPastRule.cs b/dotnet/AipsCore/Domain/Common/Validation/Rules/DateInPastRule.cs index 2120aa6..03f0471 100644 --- a/dotnet/AipsCore/Domain/Common/Validation/Rules/DateInPastRule.cs +++ b/dotnet/AipsCore/Domain/Common/Validation/Rules/DateInPastRule.cs @@ -4,10 +4,10 @@ namespace AipsCore.Domain.Common.Validation.Rules; public class DateInPastRule : AbstractRule { - private readonly DateTime _date; + private readonly DateTime? _date; private readonly DateTime _now; - public DateInPastRule(DateTime date) + public DateInPastRule(DateTime? date) { _date = date; _now = DateTime.Now; @@ -17,6 +17,11 @@ public class DateInPastRule : AbstractRule protected override string ErrorMessage => "Date must be in the past"; public override bool Validate() { - return _date < _now; + if (_date is not null) + { + return _date < _now; + } + + return true; } } \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardJoinPolicy.cs b/dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardJoinPolicy.cs new file mode 100644 index 0000000..6703733 --- /dev/null +++ b/dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardJoinPolicy.cs @@ -0,0 +1,8 @@ +namespace AipsCore.Domain.Models.Whiteboard.Enums; + +public enum WhiteboardJoinPolicy +{ + FreeToJoin, + RequestToJoin, + Private +} \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardState.cs b/dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardState.cs new file mode 100644 index 0000000..1ecc4bc --- /dev/null +++ b/dotnet/AipsCore/Domain/Models/Whiteboard/Enums/WhiteboardState.cs @@ -0,0 +1,8 @@ +namespace AipsCore.Domain.Models.Whiteboard.Enums; + +public enum WhiteboardState +{ + Active, + Inactive, + Deleted +} \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardCreatedAt.cs b/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardCreatedAt.cs new file mode 100644 index 0000000..fad51ed --- /dev/null +++ b/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardCreatedAt.cs @@ -0,0 +1,23 @@ +using AipsCore.Domain.Abstract.Rule; +using AipsCore.Domain.Abstract.ValueObject; +using AipsCore.Domain.Common.Validation.Rules; + +namespace AipsCore.Domain.Models.Whiteboard.ValueObjects; + +public record WhiteboardCreatedAt : AbstractValueObject +{ + public DateTime CreatedAtValue { get; init; } + + public WhiteboardCreatedAt(DateTime CreatedAtValue) + { + this.CreatedAtValue = CreatedAtValue; + Validate(); + } + + protected override ICollection GetValidationRules() + { + return [ + new DateInPastRule(CreatedAtValue) + ]; + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardDeletedAt.cs b/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardDeletedAt.cs new file mode 100644 index 0000000..b440ffb --- /dev/null +++ b/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardDeletedAt.cs @@ -0,0 +1,23 @@ +using AipsCore.Domain.Abstract.Rule; +using AipsCore.Domain.Abstract.ValueObject; +using AipsCore.Domain.Common.Validation.Rules; + +namespace AipsCore.Domain.Models.Whiteboard.ValueObjects; + +public record WhiteboardDeletedAt : AbstractValueObject +{ + public DateTime? DeletedAtValue { get; init; } + + public WhiteboardDeletedAt(DateTime? DeletedAtValue) + { + this.DeletedAtValue = DeletedAtValue; + Validate(); + } + + protected override ICollection GetValidationRules() + { + return [ + new DateInPastRule(DeletedAtValue) + ]; + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardMaxParticipants.cs b/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardMaxParticipants.cs new file mode 100644 index 0000000..8ded4ea --- /dev/null +++ b/dotnet/AipsCore/Domain/Models/Whiteboard/ValueObjects/WhiteboardMaxParticipants.cs @@ -0,0 +1,25 @@ +using AipsCore.Domain.Abstract.Rule; +using AipsCore.Domain.Abstract.ValueObject; +using AipsCore.Domain.Common.Validation.Rules; + +namespace AipsCore.Domain.Models.Whiteboard.ValueObjects; + +public record WhiteboardMaxParticipants : AbstractValueObject +{ + private const int MinMaxParticipants = 1; + private const int MaxMaxParticipants = 100; + public int MaxParticipantsValue { get; init; } + + public WhiteboardMaxParticipants(int MaxParticipantsValue) + { + this.MaxParticipantsValue = MaxParticipantsValue; + Validate(); + } + protected override ICollection GetValidationRules() + { + return [ + new MinValueRule(MaxParticipantsValue, MinMaxParticipants), + new MaxValueRule(MaxParticipantsValue, MaxMaxParticipants) + ]; + } +} \ No newline at end of file diff --git a/dotnet/AipsCore/Domain/Models/Whiteboard/Whiteboard.cs b/dotnet/AipsCore/Domain/Models/Whiteboard/Whiteboard.cs index 3c30185..3613686 100644 --- a/dotnet/AipsCore/Domain/Models/Whiteboard/Whiteboard.cs +++ b/dotnet/AipsCore/Domain/Models/Whiteboard/Whiteboard.cs @@ -1,4 +1,5 @@ using AipsCore.Domain.Models.User.ValueObjects; +using AipsCore.Domain.Models.Whiteboard.Enums; using AipsCore.Domain.Models.Whiteboard.ValueObjects; namespace AipsCore.Domain.Models.Whiteboard; @@ -9,40 +10,114 @@ public class Whiteboard public UserId WhiteboardOwnerId { get; private set; } public WhiteboardCode Code { get; private set; } public WhiteboardTitle Title { get; private set; } + public WhiteboardCreatedAt CreatedAt { get; private set; } + public WhiteboardDeletedAt DeletedAt { get; private set; } + public WhiteboardMaxParticipants MaxParticipants { get; private set; } + public WhiteboardJoinPolicy JoinPolicy { get; private set; } + public WhiteboardState State { get; private set; } - public Whiteboard(WhiteboardId id, User.User whiteboardOwner, WhiteboardCode code, WhiteboardTitle title) + public Whiteboard( + WhiteboardId id, + User.User whiteboardOwner, + WhiteboardCode code, + WhiteboardTitle title, + WhiteboardCreatedAt createdAt, + WhiteboardDeletedAt deletedAt, + WhiteboardMaxParticipants maxParticipants, + WhiteboardJoinPolicy joinPolicy, + WhiteboardState state) { Id = id; WhiteboardOwnerId = whiteboardOwner.Id; Code = code; Title = title; + CreatedAt = createdAt; + DeletedAt = deletedAt; + MaxParticipants = maxParticipants; + JoinPolicy = joinPolicy; + State = state; } - public Whiteboard(WhiteboardId id, UserId whiteboardOwnerId, WhiteboardCode code, WhiteboardTitle title) + public Whiteboard( + WhiteboardId id, + UserId whiteboardOwnerId, + WhiteboardCode code, + WhiteboardTitle title, + WhiteboardCreatedAt createdAt, + WhiteboardDeletedAt deletedAt, + WhiteboardMaxParticipants maxParticipants, + WhiteboardJoinPolicy joinPolicy, + WhiteboardState state) { Id = id; WhiteboardOwnerId = whiteboardOwnerId; Code = code; - Title = title; + Title = title; + CreatedAt = createdAt; + DeletedAt = deletedAt; + MaxParticipants = maxParticipants; + JoinPolicy = joinPolicy; + State = state; } - public static Whiteboard Create(string id, string ownerId, string code, string title) + public static Whiteboard Create( + string id, + string ownerId, + string code, + string title, + DateTime createdAt, + DateTime? deletedAt, + int maxParticipants, + WhiteboardJoinPolicy joinPolicy, + WhiteboardState state) { var whiteboardId = new WhiteboardId(id); var whiteboardOwnerId = new UserId(ownerId); var whiteboardCode = new WhiteboardCode(code); var whiteboardTitle = new WhiteboardTitle(title); + var whiteboardCreatedAt = new WhiteboardCreatedAt(createdAt); + var whiteboardDeletedAt = new WhiteboardDeletedAt(deletedAt); + var whiteboardMaxParticipants = new WhiteboardMaxParticipants(maxParticipants); - return new Whiteboard(whiteboardId, whiteboardOwnerId, whiteboardCode, whiteboardTitle); + return new Whiteboard( + whiteboardId, + whiteboardOwnerId, + whiteboardCode, + whiteboardTitle, + whiteboardCreatedAt, + whiteboardDeletedAt, + whiteboardMaxParticipants, + joinPolicy, + state); } - public static Whiteboard Create(string ownerId, string code, string title) + public static Whiteboard Create( + string ownerId, + string code, + string title, + DateTime createdAt, + DateTime? deletedAt, + int maxParticipants, + WhiteboardJoinPolicy joinPolicy, + WhiteboardState state) { var whiteboardId = WhiteboardId.Any(); var whiteboardOwnerId = new UserId(ownerId); var whiteboardCode = new WhiteboardCode(code); var whiteboardTitle = new WhiteboardTitle(title); + var whiteboardCreatedAt = new WhiteboardCreatedAt(createdAt); + var whiteboardDeletedAt = new WhiteboardDeletedAt(deletedAt); + var whiteboardMaxParticipants = new WhiteboardMaxParticipants(maxParticipants); - return new Whiteboard(whiteboardId, whiteboardOwnerId, whiteboardCode, whiteboardTitle); + return new Whiteboard( + whiteboardId, + whiteboardOwnerId, + whiteboardCode, + whiteboardTitle, + whiteboardCreatedAt, + whiteboardDeletedAt, + whiteboardMaxParticipants, + joinPolicy, + state); } } \ No newline at end of file diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs index df8a199..d44b0fd 100644 --- a/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs +++ b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/Whiteboard.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using AipsCore.Domain.Models.Whiteboard.Enums; namespace AipsCore.Infrastructure.Persistence.Whiteboard; @@ -8,7 +9,9 @@ public class Whiteboard public Guid Id { get; set; } [Required] - public Guid WhiteboardOwnerId { get; set; } + public Guid OwnerId { get; set; } + + public User.User Owner { get; set; } = null!; [Required] [MaxLength(8)] @@ -19,4 +22,14 @@ public class Whiteboard [MaxLength(32)] [MinLength(3)] public string Title { get; set; } = null!; + + public DateTime CreatedAt { get; set; } + + public DateTime? DeletedAt { get; set; } + + public int MaxParticipants { get; set; } + + public WhiteboardJoinPolicy JoinPolicy { get; set; } + + public WhiteboardState State { get; set; } } \ No newline at end of file diff --git a/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs index 0620cd7..5d447f5 100644 --- a/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs +++ b/dotnet/AipsCore/Infrastructure/Persistence/Whiteboard/WhiteboardRepository.cs @@ -22,9 +22,14 @@ public class WhiteboardRepository : IWhiteboardRepository return Domain.Models.Whiteboard.Whiteboard.Create( whiteboardEntity.Id.ToString(), - whiteboardEntity.WhiteboardOwnerId.ToString(), + whiteboardEntity.OwnerId.ToString(), whiteboardEntity.Code, - whiteboardEntity.Title); + whiteboardEntity.Title, + whiteboardEntity.CreatedAt, + whiteboardEntity.DeletedAt, + whiteboardEntity.MaxParticipants, + whiteboardEntity.JoinPolicy, + whiteboardEntity.State); } public async Task Save(Domain.Models.Whiteboard.Whiteboard whiteboard, CancellationToken cancellationToken = default) @@ -33,9 +38,14 @@ public class WhiteboardRepository : IWhiteboardRepository if (whiteboardEntity is not null) { - whiteboardEntity.WhiteboardOwnerId = new Guid(whiteboard.WhiteboardOwnerId.IdValue); + whiteboardEntity.OwnerId = new Guid(whiteboard.WhiteboardOwnerId.IdValue); whiteboardEntity.Code = whiteboard.Code.CodeValue; whiteboardEntity.Title = whiteboard.Title.TitleValue; + whiteboardEntity.CreatedAt = whiteboard.CreatedAt.CreatedAtValue; + whiteboardEntity.DeletedAt = whiteboard.DeletedAt.DeletedAtValue; + whiteboardEntity.MaxParticipants = whiteboard.MaxParticipants.MaxParticipantsValue; + whiteboardEntity.JoinPolicy = whiteboard.JoinPolicy; + whiteboardEntity.State = whiteboard.State; _context.Whiteboards.Update(whiteboardEntity); } @@ -44,9 +54,14 @@ public class WhiteboardRepository : IWhiteboardRepository whiteboardEntity = new Whiteboard() { Id = new Guid(whiteboard.Id.IdValue), - WhiteboardOwnerId = new Guid(whiteboard.WhiteboardOwnerId.IdValue), + OwnerId = new Guid(whiteboard.WhiteboardOwnerId.IdValue), Code = whiteboard.Code.CodeValue, Title = whiteboard.Title.TitleValue, + CreatedAt = whiteboard.CreatedAt.CreatedAtValue, + DeletedAt = whiteboard.DeletedAt.DeletedAtValue, + MaxParticipants = whiteboard.MaxParticipants.MaxParticipantsValue, + JoinPolicy = whiteboard.JoinPolicy, + State = whiteboard.State }; _context.Whiteboards.Add(whiteboardEntity);