Publish curated Knowledge Hub source from 2ed833f290b439a7bc91e5fd19b042c269e3bee9
This commit is contained in:
1 parent
10f2edcd29
commit
59f15b2d08
218 files changed
+23995
-1849
No files matched your search
@@ -0,0 +1,87 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ItWorx.KnowledgeHub.Domain.Sources;
|
||||
|
||||
public enum DataSourceKind { Inventory, Gitea, KnowledgeClient, ManualIntake, LeafWiki, CuratedPackage }
|
||||
|
||||
/// <summary>Operator registration and observed evidence; credentials never enter this aggregate.</summary>
|
||||
public sealed class DataSource
|
||||
{
|
||||
private DataSource() { }
|
||||
public Guid Id { get; private set; }
|
||||
public Guid WorkspaceId { get; private set; }
|
||||
public string SourceKey { get; private set; } = "";
|
||||
public string DisplayName { get; private set; } = "";
|
||||
public DataSourceKind Kind { get; private set; }
|
||||
public bool Enabled { get; private set; } = true;
|
||||
public int ExpectedIntervalHours { get; private set; }
|
||||
public int Version { get; private set; } = 1;
|
||||
public DateTimeOffset CreatedAt { get; private set; }
|
||||
public DateTimeOffset? LastAttemptAt { get; private set; }
|
||||
public DateTimeOffset? LastSuccessAt { get; private set; }
|
||||
public DateTimeOffset? LastFailureAt { get; private set; }
|
||||
public DateTimeOffset? DataObservedAt { get; private set; }
|
||||
public long? RecordCount { get; private set; }
|
||||
public string? LastErrorCode { get; private set; }
|
||||
public string? LastCorrelationId { get; private set; }
|
||||
|
||||
public static DataSource Create(Guid workspaceId, string sourceKey, string displayName, DataSourceKind kind, int expectedIntervalHours, DateTimeOffset now)
|
||||
{
|
||||
if (workspaceId == Guid.Empty || !Enum.IsDefined(kind) || !Regex.IsMatch(sourceKey, "^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,199}$", RegexOptions.CultureInvariant))
|
||||
{
|
||||
throw new ArgumentException("Invalid source identity.");
|
||||
}
|
||||
var source = new DataSource { Id = Guid.NewGuid(), WorkspaceId = workspaceId, SourceKey = sourceKey, Kind = kind, CreatedAt = now, Version = 0 };
|
||||
source.Configure(displayName, true, expectedIntervalHours);
|
||||
return source;
|
||||
}
|
||||
|
||||
public void Configure(string displayName, bool enabled, int expectedIntervalHours)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(displayName) || displayName.Length > 120 || displayName.Any(char.IsControl) || expectedIntervalHours is < 1 or > 8760)
|
||||
{
|
||||
throw new ArgumentException("Invalid source policy.");
|
||||
}
|
||||
DisplayName = displayName.Trim();
|
||||
Enabled = enabled;
|
||||
ExpectedIntervalHours = expectedIntervalHours;
|
||||
Version++;
|
||||
}
|
||||
|
||||
public void Observe(bool success, long? recordCount, string? errorCode, string? correlationId, DateTimeOffset observedAt, DateTimeOffset? dataObservedAt = null)
|
||||
{
|
||||
if (recordCount < 0 || (!success && errorCode is not ("authentication" or "connectivity" or "validation" or "unexpected"))
|
||||
|| (LastAttemptAt is { } previous && observedAt < previous)
|
||||
|| dataObservedAt > observedAt || correlationId?.Length > 100 || correlationId?.Any(char.IsControl) == true)
|
||||
{
|
||||
throw new ArgumentException("Invalid source observation.");
|
||||
}
|
||||
LastAttemptAt = observedAt;
|
||||
LastCorrelationId = correlationId;
|
||||
if (success)
|
||||
{
|
||||
LastSuccessAt = observedAt;
|
||||
var captured = dataObservedAt ?? observedAt;
|
||||
if (DataObservedAt is null || captured >= DataObservedAt)
|
||||
{
|
||||
DataObservedAt = captured;
|
||||
RecordCount = recordCount;
|
||||
}
|
||||
LastErrorCode = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
LastFailureAt = observedAt;
|
||||
LastErrorCode = errorCode;
|
||||
}
|
||||
Version++;
|
||||
}
|
||||
|
||||
public string GetState(DateTimeOffset now)
|
||||
{
|
||||
if (!Enabled) return "Disabled";
|
||||
if (LastErrorCode is not null) return "Failed";
|
||||
if (DataObservedAt is null || DataObservedAt > now) return "Unknown";
|
||||
return now - DataObservedAt.Value > TimeSpan.FromHours(ExpectedIntervalHours) ? "Stale" : "Current";
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user