Restructure solution layout by module
This commit is contained in:
101
src/Policy/StellaOps.Policy.Engine/Domain/PolicyPackRecord.cs
Normal file
101
src/Policy/StellaOps.Policy.Engine/Domain/PolicyPackRecord.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Policy.Engine.Domain;
|
||||
|
||||
internal sealed class PolicyPackRecord
|
||||
{
|
||||
private readonly ConcurrentDictionary<int, PolicyRevisionRecord> revisions = new();
|
||||
|
||||
public PolicyPackRecord(string packId, string? displayName, DateTimeOffset createdAt)
|
||||
{
|
||||
PackId = packId ?? throw new ArgumentNullException(nameof(packId));
|
||||
DisplayName = displayName;
|
||||
CreatedAt = createdAt;
|
||||
}
|
||||
|
||||
public string PackId { get; }
|
||||
|
||||
public string? DisplayName { get; }
|
||||
|
||||
public DateTimeOffset CreatedAt { get; }
|
||||
|
||||
public ImmutableArray<PolicyRevisionRecord> GetRevisions()
|
||||
=> revisions.Values
|
||||
.OrderBy(r => r.Version)
|
||||
.ToImmutableArray();
|
||||
|
||||
public PolicyRevisionRecord GetOrAddRevision(int version, Func<int, PolicyRevisionRecord> factory)
|
||||
=> revisions.GetOrAdd(version, factory);
|
||||
|
||||
public bool TryGetRevision(int version, out PolicyRevisionRecord revision)
|
||||
=> revisions.TryGetValue(version, out revision!);
|
||||
|
||||
public int GetNextVersion()
|
||||
=> revisions.IsEmpty ? 1 : revisions.Keys.Max() + 1;
|
||||
}
|
||||
|
||||
internal sealed class PolicyRevisionRecord
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, PolicyActivationApproval> approvals = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public PolicyRevisionRecord(int version, bool requiresTwoPerson, PolicyRevisionStatus status, DateTimeOffset createdAt)
|
||||
{
|
||||
Version = version;
|
||||
RequiresTwoPersonApproval = requiresTwoPerson;
|
||||
Status = status;
|
||||
CreatedAt = createdAt;
|
||||
}
|
||||
|
||||
public int Version { get; }
|
||||
|
||||
public bool RequiresTwoPersonApproval { get; }
|
||||
|
||||
public PolicyRevisionStatus Status { get; private set; }
|
||||
|
||||
public DateTimeOffset CreatedAt { get; }
|
||||
|
||||
public DateTimeOffset? ActivatedAt { get; private set; }
|
||||
|
||||
public ImmutableArray<PolicyActivationApproval> Approvals
|
||||
=> approvals.Values
|
||||
.OrderBy(approval => approval.ApprovedAt)
|
||||
.ToImmutableArray();
|
||||
|
||||
public void SetStatus(PolicyRevisionStatus status, DateTimeOffset timestamp)
|
||||
{
|
||||
Status = status;
|
||||
if (status == PolicyRevisionStatus.Active)
|
||||
{
|
||||
ActivatedAt = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public PolicyActivationApprovalStatus AddApproval(PolicyActivationApproval approval)
|
||||
{
|
||||
if (!approvals.TryAdd(approval.ActorId, approval))
|
||||
{
|
||||
return PolicyActivationApprovalStatus.Duplicate;
|
||||
}
|
||||
|
||||
return approvals.Count >= 2
|
||||
? PolicyActivationApprovalStatus.ThresholdReached
|
||||
: PolicyActivationApprovalStatus.Pending;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum PolicyRevisionStatus
|
||||
{
|
||||
Draft,
|
||||
Approved,
|
||||
Active
|
||||
}
|
||||
|
||||
internal sealed record PolicyActivationApproval(string ActorId, DateTimeOffset ApprovedAt, string? Comment);
|
||||
|
||||
internal enum PolicyActivationApprovalStatus
|
||||
{
|
||||
Pending,
|
||||
ThresholdReached,
|
||||
Duplicate
|
||||
}
|
||||
Reference in New Issue
Block a user