fix(review): resolve deferred code-review findings; S7.Cli verdict, browser CP release, MemberLeft/Exited/Downed, Sql Detach hoist (#625)

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 06:59:53 -04:00
parent 3baa332d6b
commit 3fb6549209
22 changed files with 423 additions and 88 deletions
@@ -1,5 +1,6 @@
using CliFx.Attributes;
using CliFx.Infrastructure;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Driver.Cli.Common;
namespace ZB.MOM.WW.OtOpcUa.Driver.S7.Cli.Commands;
@@ -51,8 +52,14 @@ public sealed class ProbeCommand : S7CommandBase
var snapshot = await driver.ReadAsync(["__probe"], ct);
var health = driver.GetHealth();
// Derive the headline verdict from BOTH the driver state AND the probe-read
// StatusCode so the operator never sees `Health: Healthy` over a Bad snapshot
// line (Driver.S7.Cli-012; mirrors Modbus.Cli's ComputeVerdict).
var verdict = ComputeVerdict(health.State, snapshot[0].StatusCode);
await console.Output.WriteLineAsync($"Host: {Host}:{Port}");
await console.Output.WriteLineAsync($"CPU: {CpuType} rack={Rack} slot={Slot}");
await console.Output.WriteLineAsync($"Verdict: {verdict}");
await console.Output.WriteLineAsync($"Health: {health.State}");
if (health.LastError is { } err)
await console.Output.WriteLineAsync($"Last error: {err}");
@@ -77,4 +84,28 @@ public sealed class ProbeCommand : S7CommandBase
await console.Output.WriteLineAsync($"Last error: {err}");
}
}
/// <summary>
/// Combine the driver-side <see cref="DriverState"/> with the probe snapshot's OPC UA
/// <c>StatusCode</c> into a single headline verdict: <c>FAIL</c> when the driver is not
/// Healthy or the snapshot is Bad, <c>DEGRADED</c> when Healthy but Uncertain, else <c>OK</c>.
/// </summary>
/// <param name="state">The driver's health state.</param>
/// <param name="statusCode">The OPC UA status code from the probe read.</param>
/// <returns>A string describing the verdict.</returns>
public static string ComputeVerdict(DriverState state, uint statusCode)
{
// Top 2 bits encode the quality class: 00 Good, 01 Uncertain, 10/11 Bad.
var qualityClass = statusCode & 0xC0000000u;
var snapshotGood = qualityClass == 0x00000000u;
var snapshotUncertain = qualityClass == 0x40000000u;
if (state != DriverState.Healthy || !snapshotGood && !snapshotUncertain)
return $"FAIL (driver={state}, probe={SnapshotFormatter.FormatStatus(statusCode)})";
if (snapshotUncertain)
return $"DEGRADED (driver={state}, probe={SnapshotFormatter.FormatStatus(statusCode)})";
return $"OK (driver={state}, probe={SnapshotFormatter.FormatStatus(statusCode)})";
}
}