docs: fill missing XML docs and strip tracking IDs from src comments

Clears CommentChecker findings in src/ (3,280 -> 209, the remainder being false
positives like PLC-5/IEEE-754/M0.0) by adding missing summaries/params/returns,
normalising inheritdoc usage, and removing Gitea/review tracking IDs while keeping
the rationale they annotated. Comment-only: comment-stripped sources are identical
to the parent commit.
This commit is contained in:
Joseph Doherty
2026-10-15 06:14:58 -04:00
parent ebcbd81fca
commit 826312befe
430 changed files with 4434 additions and 3923 deletions
@@ -1,7 +1,7 @@
namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
/// <summary>
/// One OPC UA data-plane API key. The OPC UA data plane is machine-to-machine (#520), so a
/// One OPC UA data-plane API key. The OPC UA data plane is machine-to-machine, so a
/// consuming system authenticates with a key rather than an LDAP user, and the key resolves to a
/// <see cref="Principal"/> that <see cref="NodeAcl"/> rows grant permissions to.
/// </summary>
@@ -22,7 +22,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
/// ⚠️ <b>Revocation requires a deploy.</b> Phase 4 leaves driver-only nodes with no ConfigDb, so
/// keys reach them inside the deployment artifact exactly as <see cref="NodeAcl"/> rows do.
/// Setting <see cref="Enabled"/> to false takes effect on a node only once a new artifact reaches
/// it. This is an operational sharp edge, not an oversight — see the #520 design doc.
/// it. This is an operational sharp edge, not an oversight.
/// </para>
/// </remarks>
public sealed class ApiKey
@@ -41,7 +41,7 @@ public sealed class OtOpcUaConfigDbContext(DbContextOptions<OtOpcUaConfigDbConte
/// <summary>Gets the DbSet of node ACLs.</summary>
public DbSet<NodeAcl> NodeAcls => Set<NodeAcl>();
/// <summary>OPC UA data-plane API keys (#520). One principal per key; secret stored as a peppered hash.</summary>
/// <summary>OPC UA data-plane API keys. One principal per key; secret stored as a peppered hash.</summary>
public DbSet<ApiKey> ApiKeys => Set<ApiKey>();
/// <summary>Gets the DbSet of configuration audit logs.</summary>
public DbSet<ConfigAuditLog> ConfigAuditLogs => Set<ConfigAuditLog>();
@@ -563,14 +563,14 @@ public sealed class OtOpcUaConfigDbContext(DbContextOptions<OtOpcUaConfigDbConte
});
}
// ConfigureDriverHostStatus is GONE (Gitea #521). The DriverHostStatus table held per-host
// ConfigureDriverHostStatus is GONE. The DriverHostStatus table held per-host
// connectivity that a publisher hosted service was supposed to upsert from each driver node. That
// publisher was never written, and per-cluster mesh Phase 4 made it unwritable as designed: ConfigDb
// is registered only on the admin role, so a driver-only node has no connection to write rows with.
// Per-host connectivity now rides DriverHealthChanged.HostStatuses to /hosts over the Phase 5
// telemetry stream, which needs no DB and survives the mesh split.
//
// ConfigureDriverInstanceResilienceStatus is GONE for the same reason (Gitea #524). That table held
// ConfigureDriverInstanceResilienceStatus is GONE for the same reason. That table held
// per-(instance, host) breaker/in-flight counters and was equally never written: its doc described a
// HostedService sampler and an AdminUI left-join on DriverHostStatus, neither of which was built. The
// live data reaches the AdminUI's DriverStatusPanel as DriverResilienceStatusChanged over the
@@ -57,7 +57,7 @@ public sealed class DraftSnapshot
public IReadOnlyList<ScriptedAlarm> ScriptedAlarms { get; init; } = [];
/// <summary>User-authored scripts (shared by VirtualTags, ScriptedAlarms, and Calculation tags). Drives
/// the WP7 Calculation gates: <c>scriptId</c> existence + the calc→calc dependency-cycle check.</summary>
/// the Calculation gates: <c>scriptId</c> existence + the calc→calc dependency-cycle check.</summary>
public IReadOnlyList<Script> Scripts { get; init; } = [];
/// <summary>Gets the list of poll groups.</summary>
public IReadOnlyList<PollGroup> PollGroups { get; init; } = [];
@@ -33,7 +33,7 @@ public static class DraftValidator
ValidateReservationPreflight(draft, errors);
ValidateEquipmentIdDerivation(draft, errors);
// v3 rules (WP4). The retired rules ValidateSameClusterNamespaceBinding (Namespace entity gone)
// v3 rules. The retired rules ValidateSameClusterNamespaceBinding (Namespace entity gone)
// and ValidateGalaxyTagFullName (blob-as-identity gone) are replaced by:
ValidateRawNameCharset(draft, errors);
ValidateHistorizedTagnameLength(draft, errors);
@@ -47,7 +47,7 @@ public static class DraftValidator
}
/// <summary>
/// #520 stage 3: every <see cref="NodeAcl"/> row's scope must name something the deployed address
/// every <see cref="NodeAcl"/> row's scope must name something the deployed address
/// space actually contains.
/// </summary>
/// <remarks>
@@ -74,7 +74,7 @@ public static class DraftValidator
/// <c>AclScopePathResolver</c>'s dictionary lookups use, so a row this rule passes is a row that
/// resolver resolves. The realm check mirrors <c>NodeAclRealms.TryCanonicalize</c> instead
/// (trimmed, case-insensitive) for the same reason. Both this rule and the resolver were
/// ordinal until Gitea #533; the cross-cluster comparison below was ordinal too, which was the
/// ordinal until that was fixed; the cross-cluster comparison below was ordinal too, which was the
/// worse half — it could reject a deploy as cross-cluster over a <c>ClusterId</c> the runtime
/// would have matched, and the two spellings genuinely occur (see
/// <c>RoleParser.ClusterIdFromRole</c>). The rule now is: identifiers compare
@@ -279,7 +279,7 @@ public static class DraftValidator
/// <summary>
/// The <c>Sql</c> driver's "a pasted literal connection string is never persisted" guarantee, enforced
/// at the deploy gate (Gitea #498).
/// at the deploy gate.
/// </summary>
/// <remarks>
/// <para>A Sql driver names its credentials indirectly — <c>connectionStringRef</c> resolves from the
@@ -294,7 +294,7 @@ public static class DraftValidator
/// Discarding a secret on read is not the same as refusing to store it.</para>
/// <para><b>Two of the three surfaces are checked here.</b> The third — a node's
/// <see cref="ClusterNode.DriverConfigOverridesJson"/> — is not reachable from
/// <see cref="DraftSnapshot"/> and is gated at its save instead (#499); see
/// <see cref="DraftSnapshot"/> and is gated at its save instead; see
/// <see cref="SqlCredentialGuard"/> for why a deploy gate is the wrong instrument for a value that
/// never enters the artifact.</para>
/// <para>Checked on <b>both</b> config surfaces a Sql driver reads: the instance's
@@ -344,7 +344,7 @@ public static class DraftValidator
}
}
/// <summary>Error code for an MTConnect driver instance that has more than one <c>/raw</c> Device (#628).</summary>
/// <summary>Error code for an MTConnect driver instance that has more than one <c>/raw</c> Device.</summary>
public const string MTConnectMultipleDevicesCode = "MTConnectMultipleDevices";
/// <summary>
@@ -352,6 +352,7 @@ public static class DraftValidator
/// use, so the two can never describe different rules.
/// </summary>
/// <param name="driverLabel">The driver instance id or name to cite.</param>
/// <returns>The validation message text.</returns>
public static string MTConnectMultipleDevicesMessage(string driverLabel) =>
$"MTConnect driver '{driverLabel}' has more than one Device. MTConnect binds all tags through one agent " +
"client per driver instance and does not route by /raw Device, and with several Devices the Device's " +
@@ -359,7 +360,7 @@ public static class DraftValidator
"supply the endpoint is ambiguous. Author one MTConnect driver per agent device, each with a single Device.";
/// <summary>
/// #628 (decision (b)): an MTConnect driver instance owns exactly one agent client, so a second <c>/raw</c>
/// An MTConnect driver instance owns exactly one agent client, so a second <c>/raw</c>
/// Device under it is a genuine ambiguity — the driver ignores <c>RawTagEntry.DeviceName</c>, and
/// <c>DriverDeviceConfigMerger</c> only merges a Device's <c>DeviceConfig</c> up to the driver config when
/// there is exactly ONE Device. The normal single-Device layout (every driver gets a default
@@ -380,7 +381,7 @@ public static class DraftValidator
}
}
/// <summary>WP7 Calculation-driver deploy gates. For every tag bound to a <c>Calculation</c> driver:
/// <summary>Calculation-driver deploy gates. For every tag bound to a <c>Calculation</c> driver:
/// <list type="number">
/// <item><b>scriptId existence</b> — the tag's <c>TagConfig.scriptId</c> must be present and resolve to
/// a <see cref="Script"/> row in the draft.</item>
@@ -634,7 +635,7 @@ public static class DraftValidator
}
// The rule itself lives on UnsSegment, which the AdminUI's authoring guards also call — a second
// copy here is exactly how the two drifted apart (Gitea #535). Only the per-level wording is local.
// copy here is exactly how the two drifted apart. Only the per-level wording is local.
private static void ValidateUnsSegments(DraftSnapshot draft, List<ValidationError> errors)
{
foreach (var a in draft.UnsAreas)
@@ -4,7 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Validation;
/// <summary>
/// The one place that decides whether a persisted config blob carries a literal Sql
/// <c>connectionString</c> (Gitea #498 / #499).
/// <c>connectionString</c>.
/// </summary>
/// <remarks>
/// <para>
@@ -12,7 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Validation;
/// rule is not cosmetic: it is what keeps a NodeId parseable and stable.
/// </para>
/// <para>
/// ⚠️ <b>This exists because the rule was duplicated and drifted (Gitea #535).</b> The deploy gate
/// ⚠️ <b>This exists because the rule was duplicated and drifted.</b> The deploy gate
/// held it privately in <c>DraftValidator</c> and the AdminUI restated it on the equipment form
/// alone, so an area or line could be named <c>Packaging</c> or <c>Line 1</c>, saved, and then
/// fail the deploy with <c>UnsSegmentInvalid</c>. Because a deployment snapshots the whole