sqlinsight-pro/src/SQLInsight.Core/Data/Replication.cs
Søren Eggert Lundsteen Olsen a01ec374a4 Review 1.2: keep SQL Server's error message out of the replication reason
When the distribution database could not be read, SQL Server's message
(which names the agent's login) was appended to Unavailable. That text is
the rules' "not measurable" reason and is returned unredacted by
/rule-states and /replication. It is now UnavailableDetail: shown on the
local instance page and [udeladt] in the API unless
ApiIncludesSensitiveEvidence. The agent list is also capped (TOP 500).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 11:33:25 +02:00

45 lines
1.8 KiB
C#

namespace SQLInsight.Core.Data;
/// <summary>A distribution agent's latest run, from MSdistribution_history.</summary>
/// <param name="RunStatus">1 start, 2 succeed, 3 in progress, 4 idle, 5 retry, 6 fail.</param>
/// <param name="Comment">The agent's message; can name servers and objects.</param>
public sealed record DistributionAgent(string Name, string? PublisherDatabase, int? RunStatus, DateTimeOffset? LastRunAt, long? DeliveryLatencyMs, string? Comment)
{
public bool Failed => RunStatus is 5 or 6;
public string StatusText => RunStatus switch
{
1 => "startet",
2 => "lykkedes",
3 => "i gang",
4 => "venter (intet at levere)",
5 => "prøver igen",
6 => "fejlede",
_ => "ukendt",
};
}
/// <summary>Replication as seen from the distributor, every 15 minutes.</summary>
public sealed record ReplicationSnapshot
{
public required DateTimeOffset CapturedAt { get; init; }
/// <summary>The instance is a distributor (has a distribution database).</summary>
public bool IsDistributor { get; init; }
public string? DistributionDatabase { get; init; }
/// <summary>Why the distribution database could not be read (typically no SELECT rights); null when it could.</summary>
public string? Unavailable { get; init; }
/// <summary>SQL Server's error message when it could not be read. Names the agent's login: sensitive (local UI only).</summary>
public string? UnavailableDetail { get; init; }
public IReadOnlyList<DistributionAgent> Agents { get; init; } = [];
/// <summary>Rows in MSrepl_errors the last 24 hours.</summary>
public int ErrorsLastDay { get; init; }
/// <summary>Delivery latency above this (ms) is a finding.</summary>
public long LatencyThresholdMs { get; init; } = 300_000;
}