54 lines
1.8 KiB
C#
54 lines
1.8 KiB
C#
namespace Distribution.Features.Notifications;
|
|
|
|
public class NotificationRecipientResolver(INotificationRepository repo)
|
|
{
|
|
/// <summary>
|
|
/// Expands the rules into a de-duplicated list of active user ids, never including
|
|
/// <paramref name="actingUserId"/>.
|
|
/// </summary>
|
|
public async Task<List<Guid>> ResolveAsync(IEnumerable<RecipientRule> rules, Guid? actingUserId)
|
|
{
|
|
var ids = new HashSet<Guid>();
|
|
|
|
foreach (var rule in rules)
|
|
ids.UnionWith(await ResolveRuleAsync(rule));
|
|
|
|
if (actingUserId is { } actor)
|
|
ids.Remove(actor);
|
|
|
|
if (ids.Count == 0) return [];
|
|
return await repo.FilterActiveUserIdsAsync(ids);
|
|
}
|
|
|
|
private async Task<IEnumerable<Guid>> ResolveRuleAsync(RecipientRule rule)
|
|
{
|
|
switch (rule)
|
|
{
|
|
case UsersRule r:
|
|
return r.Ids;
|
|
|
|
case PermissionRule r:
|
|
return await repo.GetUserIdsByPermissionAsync(r.Code);
|
|
|
|
case ScopeRule r:
|
|
return await repo.GetUserIdsByScopeAsync(r.Kind, r.Id);
|
|
|
|
case PermissionInScopeRule r:
|
|
var withPermission = await repo.GetUserIdsByPermissionAsync(r.Code);
|
|
var inScope = await repo.GetUserIdsByScopeAsync(r.Kind, r.Id);
|
|
return withPermission.Intersect(inScope);
|
|
|
|
case ReportsToRule r:
|
|
var supervisor = await repo.GetReportsToUserIdAsync(r.UserId);
|
|
return supervisor is { } s ? [s] : [];
|
|
|
|
case RouteOwnerRule r:
|
|
var owner = await repo.GetRouteOwnerUserIdAsync(r.Kind, r.Id);
|
|
return owner is { } o ? [o] : [];
|
|
|
|
default:
|
|
throw new NotSupportedException($"Unknown recipient rule {rule.GetType().Name}.");
|
|
}
|
|
}
|
|
}
|