-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Team Management Domain + Delete User + Activate User (#4)
* added domain for team management module (domain, contracts, migrations ...) * added delete user endpoint, command, command handler, domain logic and endpoint tests * added activate user endpoint, command, command handler, domain logic and endpoint tests * added missing endpoint tests (login, get account details) * added missing data generators, extension methods and private binder * fixed bug - reset callback counters between tests * additional fixes (dependency tests ...) * refactoring (naming, structure ...)
- Loading branch information
1 parent
121c9c7
commit b5ac482
Showing
100 changed files
with
3,571 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 4 additions & 3 deletions
7
...Modules/TeamManagement/TeamUp.TeamManagement.Application/Users/UserCreatedEventHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
...Modules/TeamManagement/TeamUp.TeamManagement.Application/Users/UserDeletedEventHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using RailwayResult; | ||
using RailwayResult.FunctionalExtensions; | ||
|
||
using TeamUp.Common.Application; | ||
using TeamUp.TeamManagement.Contracts; | ||
using TeamUp.TeamManagement.Contracts.Teams; | ||
using TeamUp.TeamManagement.Domain.Aggregates.Teams; | ||
using TeamUp.TeamManagement.Domain.Aggregates.Teams.DomainEvents; | ||
using TeamUp.TeamManagement.Domain.Aggregates.Users; | ||
using TeamUp.UserAccess.Contracts.DeleteAccount; | ||
|
||
namespace TeamUp.TeamManagement.Application.Users; | ||
|
||
internal class UserDeletedEventHandler : IIntegrationEventHandler<UserDeletedIntegrationEvent> | ||
{ | ||
private readonly IUserRepository _userRepository; | ||
private readonly ITeamRepository _teamRepository; | ||
private readonly IUnitOfWork<TeamManagementModuleId> _unitOfWork; | ||
|
||
public UserDeletedEventHandler(IUserRepository userRepository, ITeamRepository teamRepository, IUnitOfWork<TeamManagementModuleId> unitOfWork) | ||
{ | ||
_userRepository = userRepository; | ||
_teamRepository = teamRepository; | ||
_unitOfWork = unitOfWork; | ||
} | ||
|
||
public async Task<Result> Handle(UserDeletedIntegrationEvent integrationEvent, CancellationToken ct) | ||
{ | ||
var teams = await _teamRepository.GetTeamsByUserIdAsync(integrationEvent.UserId, ct); | ||
|
||
foreach (var team in teams) | ||
{ | ||
team.GetTeamMemberByUserId(integrationEvent.UserId) | ||
.Ensure(TeamRules.MemberCanChangeOwnership) | ||
.Tap(initiator => | ||
{ | ||
if (team.Members.Count == 1) | ||
{ | ||
//remove team if user that is being removed is the only member | ||
_teamRepository.RemoveTeam(team); | ||
} | ||
else | ||
{ | ||
//change ownership when removing user that is owner of the team | ||
var newOwner = team.GetHighestNonOwnerTeamMember()!; | ||
initiator.UpdateRole(TeamRole.Admin); | ||
newOwner.UpdateRole(TeamRole.Owner); | ||
team.AddDomainEvent(new TeamOwnershipChangedDomainEvent(initiator, newOwner)); | ||
} | ||
}); | ||
|
||
//db will cascade delete member, but number of members needs to be updated manually | ||
team.DecreaseNumberOfMembers(); | ||
} | ||
|
||
//delete user | ||
var user = await _userRepository.GetUserByIdAsync(integrationEvent.UserId, ct); | ||
if (user is not null) | ||
{ | ||
_userRepository.RemoveUser(user); | ||
} | ||
|
||
return await _unitOfWork.SaveChangesAsync(ct); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Events/EventConstants.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace TeamUp.TeamManagement.Contracts.Events; | ||
|
||
public static class EventConstants | ||
{ | ||
public const int EVENT_DESCRIPTION_MAX_SIZE = 30; | ||
|
||
public const int EVENT_REPLY_MESSAGE_MAX_SIZE = 80; | ||
} |
5 changes: 5 additions & 0 deletions
5
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Events/EventId.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Contracts; | ||
|
||
namespace TeamUp.TeamManagement.Contracts.Events; | ||
|
||
public sealed record EventId : TypedId<EventId>; |
5 changes: 5 additions & 0 deletions
5
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Events/EventResponseId.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Contracts; | ||
|
||
namespace TeamUp.TeamManagement.Contracts.Events; | ||
|
||
public sealed record EventResponseId : TypedId<EventResponseId>; |
8 changes: 8 additions & 0 deletions
8
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Events/EventStatus.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace TeamUp.TeamManagement.Contracts.Events; | ||
|
||
public enum EventStatus | ||
{ | ||
Open = 0, | ||
Closed = 1, | ||
Canceled = 2, | ||
} |
9 changes: 9 additions & 0 deletions
9
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Events/ReplyType.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace TeamUp.TeamManagement.Contracts.Events; | ||
|
||
public enum ReplyType | ||
{ | ||
No = 0, | ||
Maybe = 1, | ||
Delay = 2, | ||
Yes = 3 | ||
} |
5 changes: 5 additions & 0 deletions
5
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Invitations/InvitationId.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Contracts; | ||
|
||
namespace TeamUp.TeamManagement.Contracts.Invitations; | ||
|
||
public sealed record InvitationId : TypedId<InvitationId>; |
5 changes: 5 additions & 0 deletions
5
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Teams/EventTypeId.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Contracts; | ||
|
||
namespace TeamUp.TeamManagement.Contracts.Teams; | ||
|
||
public sealed record EventTypeId : TypedId<EventTypeId>; |
4 changes: 2 additions & 2 deletions
4
...mUp.TeamManagement.Contracts/Constants.cs → ...nagement.Contracts/Teams/TeamConstants.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Teams/TeamId.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Contracts; | ||
|
||
namespace TeamUp.TeamManagement.Contracts.Teams; | ||
|
||
public sealed record TeamId : TypedId<TeamId>; |
5 changes: 5 additions & 0 deletions
5
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Teams/TeamMemberId.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Contracts; | ||
|
||
namespace TeamUp.TeamManagement.Contracts.Teams; | ||
|
||
public sealed record TeamMemberId : TypedId<TeamMemberId>; |
9 changes: 9 additions & 0 deletions
9
src/Modules/TeamManagement/TeamUp.TeamManagement.Contracts/Teams/TeamRole.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace TeamUp.TeamManagement.Contracts.Teams; | ||
|
||
public enum TeamRole | ||
{ | ||
Member = 0, | ||
Coordinator = 1, | ||
Admin = 2, | ||
Owner = 3 | ||
} |
5 changes: 5 additions & 0 deletions
5
...p.TeamManagement.Domain/Aggregates/Events/DomainEvents/EventResponseCreatedDomainEvent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Domain; | ||
|
||
namespace TeamUp.TeamManagement.Domain.Aggregates.Events.DomainEvents; | ||
|
||
public sealed record EventResponseCreatedDomainEvent(EventResponse Response) : IDomainEvent; |
5 changes: 5 additions & 0 deletions
5
...p.TeamManagement.Domain/Aggregates/Events/DomainEvents/EventResponseUpdatedDomainEvent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Domain; | ||
|
||
namespace TeamUp.TeamManagement.Domain.Aggregates.Events.DomainEvents; | ||
|
||
public sealed record EventResponseUpdatedDomainEvent(EventResponse Response) : IDomainEvent; |
5 changes: 5 additions & 0 deletions
5
...mUp.TeamManagement.Domain/Aggregates/Events/DomainEvents/EventStatusChangedDomainEvent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using TeamUp.Common.Domain; | ||
|
||
namespace TeamUp.TeamManagement.Domain.Aggregates.Events.DomainEvents; | ||
|
||
public sealed record EventStatusChangedDomainEvent(Event Event) : IDomainEvent; |
109 changes: 109 additions & 0 deletions
109
src/Modules/TeamManagement/TeamUp.TeamManagement.Domain/Aggregates/Events/Event.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
using RailwayResult; | ||
using RailwayResult.Errors; | ||
using RailwayResult.FunctionalExtensions; | ||
|
||
using TeamUp.Common.Contracts; | ||
using TeamUp.Common.Domain; | ||
using TeamUp.TeamManagement.Contracts.Events; | ||
using TeamUp.TeamManagement.Contracts.Teams; | ||
using TeamUp.TeamManagement.Domain.Aggregates.Events.DomainEvents; | ||
|
||
namespace TeamUp.TeamManagement.Domain.Aggregates.Events; | ||
|
||
public sealed class Event : AggregateRoot<Event, EventId> | ||
{ | ||
private readonly List<EventResponse> _eventResponses = []; | ||
|
||
public EventTypeId EventTypeId { get; private set; } | ||
public TeamId TeamId { get; } | ||
|
||
public DateTime FromUtc { get; private set; } | ||
public DateTime ToUtc { get; private set; } | ||
public string Description { get; private set; } | ||
public EventStatus Status { get; private set; } | ||
public TimeSpan MeetTime { get; private set; } | ||
public TimeSpan ReplyClosingTimeBeforeMeetTime { get; private set; } | ||
public IReadOnlyList<EventResponse> EventResponses => _eventResponses.AsReadOnly(); | ||
|
||
#pragma warning disable CS8618 // EF Core constructor | ||
private Event() : base() { } | ||
#pragma warning restore CS8618 | ||
|
||
internal Event( | ||
EventId id, | ||
EventTypeId eventTypeId, | ||
TeamId teamId, | ||
DateTime fromUtc, | ||
DateTime toUtc, | ||
string description, | ||
EventStatus status, | ||
TimeSpan meetTime, | ||
TimeSpan replyClosingTimeBeforeMeetTime) : base(id) | ||
{ | ||
EventTypeId = eventTypeId; | ||
TeamId = teamId; | ||
FromUtc = fromUtc; | ||
ToUtc = toUtc; | ||
Description = description; | ||
Status = status; | ||
MeetTime = meetTime; | ||
ReplyClosingTimeBeforeMeetTime = replyClosingTimeBeforeMeetTime; | ||
} | ||
|
||
public Result SetMemberResponse(IDateTimeProvider dateTimeProvider, TeamMemberId memberId, EventReply reply) | ||
{ | ||
static bool TimeForResponsesHasNotExpired(IDateTimeProvider dateTimeProvider, DateTime responseCloseTime) => dateTimeProvider.UtcNow < responseCloseTime; | ||
|
||
return Status | ||
.Ensure(status => status.IsOpenForResponses(), EventErrors.NotOpenForResponses) | ||
.Then(_ => GetResponseCloseTime()) | ||
.Ensure(responseCloseTime => TimeForResponsesHasNotExpired(dateTimeProvider, responseCloseTime), EventErrors.TimeForResponsesExpired) | ||
.Then(_ => _eventResponses.Find(er => er.TeamMemberId == memberId)) | ||
.Tap(response => | ||
{ | ||
if (response is null) | ||
_eventResponses.Add(EventResponse.Create(dateTimeProvider, memberId, Id, reply)); | ||
else | ||
response.UpdateReply(dateTimeProvider, reply); | ||
}) | ||
.ToResult(); | ||
} | ||
|
||
public void UpdateStatus(EventStatus status) | ||
{ | ||
if (Status == status) | ||
return; | ||
|
||
Status = status; | ||
AddDomainEvent(new EventStatusChangedDomainEvent(this)); | ||
} | ||
|
||
private DateTime GetResponseCloseTime() => FromUtc - MeetTime - ReplyClosingTimeBeforeMeetTime; | ||
|
||
public static Result<Event> Create( | ||
EventTypeId eventTypeId, | ||
TeamId teamId, | ||
DateTime fromUtc, | ||
DateTime toUtc, | ||
string description, | ||
TimeSpan meetTime, | ||
TimeSpan replyClosingTimeBeforeMeetTime, | ||
IDateTimeProvider dateTimeProvider) | ||
{ | ||
return fromUtc | ||
.Ensure(from => from < toUtc, EventErrors.CannotEndBeforeStart) | ||
.Ensure(from => from > dateTimeProvider.DateTimeOffsetUtcNow, EventErrors.CannotStartInPast) | ||
.Ensure<DateTime, ValidationError>(_ => description.Length <= EventConstants.EVENT_DESCRIPTION_MAX_SIZE, EventErrors.EventDescriptionMaxSize) | ||
.Then(_ => new Event( | ||
EventId.New(), | ||
eventTypeId, | ||
teamId, | ||
fromUtc, | ||
toUtc, | ||
description, | ||
EventStatus.Open, | ||
meetTime, | ||
replyClosingTimeBeforeMeetTime | ||
)); | ||
} | ||
} |
Oops, something went wrong.