71 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Collections.Immutable;
 | |
| using System.Linq;
 | |
| using System.Text.Json.Serialization;
 | |
| 
 | |
| namespace StellaOps.Concelier.Models;
 | |
| 
 | |
| /// <summary>
 | |
| /// Describes the origin of a canonical field and how/when it was captured.
 | |
| /// </summary>
 | |
| public sealed record AdvisoryProvenance
 | |
| {
 | |
|     public static AdvisoryProvenance Empty { get; } = new("unknown", "unspecified", string.Empty, DateTimeOffset.UnixEpoch);
 | |
| 
 | |
|     [JsonConstructor]
 | |
|     public AdvisoryProvenance(
 | |
|         string source,
 | |
|         string kind,
 | |
|         string value,
 | |
|         string? decisionReason,
 | |
|         DateTimeOffset recordedAt,
 | |
|         ImmutableArray<string> fieldMask)
 | |
|         : this(source, kind, value, recordedAt, fieldMask.IsDefault ? null : fieldMask.AsEnumerable(), decisionReason)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     public AdvisoryProvenance(
 | |
|         string source,
 | |
|         string kind,
 | |
|         string value,
 | |
|         DateTimeOffset recordedAt,
 | |
|         IEnumerable<string>? fieldMask = null,
 | |
|         string? decisionReason = null)
 | |
|     {
 | |
|         Source = Validation.EnsureNotNullOrWhiteSpace(source, nameof(source));
 | |
|         Kind = Validation.EnsureNotNullOrWhiteSpace(kind, nameof(kind));
 | |
|         Value = Validation.TrimToNull(value);
 | |
|         DecisionReason = Validation.TrimToNull(decisionReason);
 | |
|         RecordedAt = recordedAt.ToUniversalTime();
 | |
|         FieldMask = NormalizeFieldMask(fieldMask);
 | |
|     }
 | |
| 
 | |
|     public string Source { get; }
 | |
| 
 | |
|     public string Kind { get; }
 | |
| 
 | |
|     public string? Value { get; }
 | |
| 
 | |
|     public string? DecisionReason { get; }
 | |
| 
 | |
|     public DateTimeOffset RecordedAt { get; }
 | |
| 
 | |
|     public ImmutableArray<string> FieldMask { get; }
 | |
| 
 | |
|     private static ImmutableArray<string> NormalizeFieldMask(IEnumerable<string>? fieldMask)
 | |
|     {
 | |
|         if (fieldMask is null)
 | |
|         {
 | |
|             return ImmutableArray<string>.Empty;
 | |
|         }
 | |
| 
 | |
|         var buffer = fieldMask
 | |
|             .Where(static value => !string.IsNullOrWhiteSpace(value))
 | |
|             .Select(static value => value.Trim().ToLowerInvariant())
 | |
|             .Distinct(StringComparer.Ordinal)
 | |
|             .OrderBy(static value => value, StringComparer.Ordinal)
 | |
|             .ToImmutableArray();
 | |
| 
 | |
|         return buffer.IsDefault ? ImmutableArray<string>.Empty : buffer;
 | |
|     }
 | |
| }
 |