Files
social-media/backend/src/Socialize.Api/Modules/Approvals/Services/ApprovalWorkflowRules.cs

98 lines
3.0 KiB
C#

using Socialize.Api.Modules.Identity.Contracts;
namespace Socialize.Api.Modules.Approvals.Services;
public static class ApprovalModes
{
public const string None = "None";
public const string Optional = "Optional";
public const string Required = "Required";
public const string MultiLevel = "Multi-level";
}
public static class ApprovalWorkflowRules
{
public static bool BlocksManualApprovedOrScheduledStatus(string approvalMode)
{
return approvalMode is ApprovalModes.Required or ApprovalModes.MultiLevel;
}
public static bool IsApprovalCompletionStatus(string status)
{
return status is "Approved" or "Scheduled";
}
public static string GetFinalApprovalStatus(bool schedulePostsAutomaticallyOnApproval, DateTimeOffset? plannedPublishDate)
{
return schedulePostsAutomaticallyOnApproval && plannedPublishDate.HasValue
? "Scheduled"
: "Approved";
}
public static bool HasRequiredStepApprovals(int approvedDecisionCount, int requiredApproverCount)
{
return approvedDecisionCount >= Math.Max(1, requiredApproverCount);
}
public static bool CanApproveWorkflowStep(
bool isAdministrator,
bool hasWorkspaceAccess,
IReadOnlyCollection<string> userRoles,
Guid userId,
string? targetType,
string? targetValue)
{
if (isAdministrator)
{
return true;
}
if (!hasWorkspaceAccess ||
string.IsNullOrWhiteSpace(targetType) ||
string.IsNullOrWhiteSpace(targetValue))
{
return false;
}
return targetType switch
{
ApprovalStepTargetTypes.Role => userRoles.Contains(targetValue),
ApprovalStepTargetTypes.Membership => MatchesMembershipTarget(userRoles, targetValue),
ApprovalStepTargetTypes.Member => ParseMemberTargetIds(targetValue).Contains(userId),
_ => false,
};
}
public static IReadOnlyCollection<Guid> ParseMemberTargetIds(string? targetValue)
{
if (string.IsNullOrWhiteSpace(targetValue))
{
return [];
}
return targetValue
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Select(value => Guid.TryParse(value, out Guid memberUserId) ? memberUserId : Guid.Empty)
.Where(memberUserId => memberUserId != Guid.Empty)
.Distinct()
.ToArray();
}
public static string FormatMemberTargetValue(IEnumerable<Guid> memberUserIds)
{
return string.Join(",", memberUserIds.Distinct().OrderBy(memberUserId => memberUserId));
}
private static bool MatchesMembershipTarget(
IReadOnlyCollection<string> userRoles,
string targetValue)
{
return targetValue switch
{
ApprovalMembershipTargets.Client => userRoles.Contains(KnownRoles.Client),
ApprovalMembershipTargets.Team => !userRoles.Contains(KnownRoles.Client),
_ => false,
};
}
}