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
@@ -4,7 +4,7 @@ using System.Text.Json.Nodes;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers;
/// <summary>
/// Preserve-unknown save for the typed driver forms (#576). A form deserialises the stored DriverConfig
/// Preserve-unknown save for the typed driver forms. A form deserialises the stored DriverConfig
/// into a typed options object and re-serialises it on save, which erases every key the type does not
/// model (a newer option, a hand-edited key, <c>rawTags</c>, a device's extra keys…). This overlays only
/// the paths the form OWNS onto the ORIGINAL JSON object: an owned path is replaced by the form's value,
@@ -16,9 +16,10 @@ internal static class DriverConfigJsonOverlay
/// <param name="originalJson">The stored config as loaded; blank or non-object input yields <paramref name="typedJson"/> unchanged.</param>
/// <param name="typedJson">The form's own serialised options.</param>
/// <param name="ownedPaths">Dot-separated, case-insensitive property paths the form edits (e.g. <c>transport</c>, <c>probe.enabled</c>).</param>
/// <returns>The merged JSON document.</returns>
/// <param name="timeSpanToMs">
/// (TimeSpan-string path, integer-millisecond path) pairs. The typed options serialise durations as
/// <c>"00:00:05"</c> but the driver factories bind <c>*Ms</c> integers (#576); each pair is rewritten
/// <c>"00:00:05"</c> but the driver factories bind <c>*Ms</c> integers; each pair is rewritten
/// in the typed output (and the legacy TimeSpan path becomes owned, so a stale one is removed).
/// </param>
public static string Apply(string? originalJson, string typedJson, IEnumerable<string> ownedPaths,
@@ -4,13 +4,16 @@ using System.Text.Json.Nodes;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers;
/// <summary>
/// Shared millisecond helpers for the AB forms (#576): the driver factories bind <c>*Ms</c> integers
/// Shared millisecond helpers for the AB forms: the driver factories bind <c>*Ms</c> integers
/// while the forms edit whole seconds, so a sub-second stored value must survive an edit of an
/// unrelated field.
/// </summary>
internal static class DriverConfigMs
{
/// <summary>Reads an integer-millisecond key at <paramref name="path"/> from <paramref name="json"/>, or null.</summary>
/// <param name="json">The driver config JSON, which may be null or blank.</param>
/// <param name="path">The dot-separated key path to read.</param>
/// <returns>The integer value, or null when the key is absent or not an integer.</returns>
public static int? Read(string? json, string path)
{
if (string.IsNullOrWhiteSpace(json)) return null;
@@ -27,13 +30,18 @@ internal static class DriverConfigMs
catch (JsonException) { return null; }
}
/// <summary>Whole seconds for display (truncating, like the pre-#576 forms).</summary>
/// <summary>Whole seconds for display (truncating, like the earlier forms).</summary>
/// <param name="t">The duration to convert.</param>
/// <returns>The whole seconds in <paramref name="t"/>.</returns>
public static int ToSeconds(TimeSpan t) => (int)t.TotalSeconds;
/// <summary>
/// The duration to save: the loaded value when the operator left the seconds field unchanged
/// (keeps 500 ms from collapsing to 0 s), else the edited whole seconds.
/// </summary>
/// <param name="seconds">The whole seconds currently shown in the form.</param>
/// <param name="loaded">The duration originally loaded from config, if any.</param>
/// <returns>The duration to persist.</returns>
public static TimeSpan Save(int seconds, TimeSpan? loaded)
=> loaded is { } l && ToSeconds(l) == seconds ? l : TimeSpan.FromSeconds(seconds);
}
@@ -31,7 +31,7 @@ namespace ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers.Forms;
/// </para>
/// <para>
/// <b>Preserving what this form does not author.</b> The inbound blob's keys are retained in a bag
/// and the typed fields are written over it, so (a) the <c>Sparkplug</c> sub-object — P2, Task 21+ —
/// and the typed fields are written over it, so (a) the <c>Sparkplug</c> sub-object (a later phase)
/// survives a load→save untouched, and (b) any key a newer driver adds is not silently dropped by an
/// older AdminUI. <c>RawTags</c> is the one key deliberately REMOVED: the deploy artifact injects it
/// via <c>DriverDeviceConfigMerger</c>, and a form-authored copy would be dead weight.
@@ -149,7 +149,7 @@ public sealed class MqttDriverFormModel
public string SparkplugHostId { get; set; } = "";
/// <summary>
/// Sparkplug mode: claim the Primary Host Application role (Gitea #511) — a retained
/// Sparkplug mode: claim the Primary Host Application role — a retained
/// <c>ONLINE</c>, a matching <c>OFFLINE</c> armed as the MQTT Last Will, and an explicit
/// <c>OFFLINE</c> on clean shutdown.
/// </summary>
@@ -2,7 +2,7 @@ namespace ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers.Forms;
/// <summary>
/// The rule deciding which primary-host advisory <c>MqttDriverForm</c> shows when
/// <c>Act as Primary Host</c> is on (Gitea #511).
/// <c>Act as Primary Host</c> is on.
/// </summary>
/// <remarks>
/// <para>
@@ -20,7 +20,7 @@ public enum FocasManualAddressKind
Macro,
/// <summary>
/// A selector over the CNC's active alarm list (<c>ALARM:</c>, Gitea #647). Only useful on a tag that also
/// A selector over the CNC's active alarm list (<c>ALARM:</c>). Only useful on a tag that also
/// carries the native-alarm object — the pair is what becomes a Part 9 condition.
/// </summary>
Alarm,
@@ -40,7 +40,7 @@ public enum FocasManualAddressKind
/// <c>axis/spindle/program/status</c> — none of which is a FOCAS addressing space — so the
/// picker's own default value, <c>axis:5</c>, was an address the driver rejects. Together with
/// the browse-commit defect this meant every UI-assisted authoring path produced unusable tags,
/// and only hand-typed addresses worked at all (Gitea #540).
/// and only hand-typed addresses worked at all.
/// </para>
/// </remarks>
public static class FocasAddressBuilder
@@ -23,7 +23,7 @@ public sealed class ResilienceFormModel
public static readonly string[] Capabilities =
["Read", "Write", "Discover", "Subscribe", "Probe", "AlarmSubscribe", "AlarmAcknowledge", "Initialize"];
// RecycleIntervalSeconds is GONE (Gitea #522) — the scheduled-recycle machinery it authored was
// RecycleIntervalSeconds is GONE — the scheduled-recycle machinery it authored was
// deleted, so the field configured nothing. It is deliberately NOT explicitly stripped from stored
// JSON: the model's preserve-unknown-keys contract now covers it, so an existing blob's
// "recycleIntervalSeconds" survives an unrelated edit in _bag rather than being silently dropped,