using Books.Api.Domain.UserAccess.Events; using EventFlow.Aggregates; namespace Books.Api.Domain.UserAccess; public class UserCompanyAccessAggregate : AggregateRoot, IEmit, IEmit, IEmit { public string UserId { get; private set; } = string.Empty; public string CompanyId { get; private set; } = string.Empty; public CompanyRole Role { get; private set; } public string GrantedBy { get; private set; } = string.Empty; public DateTimeOffset GrantedAt { get; private set; } public bool IsActive { get; private set; } public DateTimeOffset? RevokedAt { get; private set; } public string? RevokedBy { get; private set; } public UserCompanyAccessAggregate(UserCompanyAccessId id) : base(id) { } /// /// Grant access to a user for a company. /// public void GrantAccess(string userId, string companyId, CompanyRole role, string grantedBy) { if (!IsNew && IsActive) { throw new DomainException( "ACCESS_ALREADY_GRANTED", $"User '{userId}' already has access to company '{companyId}'", $"Brugeren '{userId}' har allerede adgang til virksomheden"); } // If previously revoked, we're re-granting Emit(new UserCompanyAccessGrantedEvent(userId, companyId, role, grantedBy, DateTimeOffset.UtcNow)); } /// /// Change the user's role for this company. /// public void ChangeRole(CompanyRole newRole, string changedBy) { if (!IsActive) { throw new DomainException( "ACCESS_NOT_ACTIVE", "Cannot change role - access is not active", "Kan ikke ændre rolle - adgang er ikke aktiv"); } if (Role == newRole) { throw new DomainException( "ROLE_UNCHANGED", $"User already has role '{newRole}'", $"Brugeren har allerede rollen '{newRole}'"); } Emit(new UserCompanyAccessRoleChangedEvent(Role, newRole, changedBy)); } /// /// Revoke the user's access to this company. /// public void RevokeAccess(string revokedBy) { if (!IsActive) { throw new DomainException( "ACCESS_ALREADY_REVOKED", "Access is already revoked", "Adgang er allerede tilbagekaldt"); } Emit(new UserCompanyAccessRevokedEvent(revokedBy, DateTimeOffset.UtcNow)); } public void Apply(UserCompanyAccessGrantedEvent e) { UserId = e.UserId; CompanyId = e.CompanyId; Role = e.Role; GrantedBy = e.GrantedBy; GrantedAt = e.GrantedAt; IsActive = true; RevokedAt = null; RevokedBy = null; } public void Apply(UserCompanyAccessRoleChangedEvent e) { Role = e.NewRole; } public void Apply(UserCompanyAccessRevokedEvent e) { IsActive = false; RevokedAt = e.RevokedAt; RevokedBy = e.RevokedBy; } }