refactor(historian-gateway): retire Wonderware historian projects (gateway is sole backend)

The HistorianGateway driver is now the sole historian read/write+alarm backend, so the
Wonderware sidecar projects are dead code. Removes the 5 Wonderware projects (driver,
.Client, .Client.Contracts, + their 2 test projects) from the solution and tree, and fully
retires the vestigial 'Historian.Wonderware' driver type (UI/probe-only; it had no driver
factory): the Host probe registration, the AdminUI driver-config surface (driver page,
tag-config editor/model/validator entry, address picker/builder, driver-type catalog +
dropdown + edit-router entries), and their tests. Prunes the now-unused Wonderware
connection fields (Host/Port/UseTls/ServerCertThumbprint/SharedSecret) from
AlarmHistorianOptions (keeping Enabled + the SQLite store-and-forward knobs) and refreshes
the stale XML docs that named Wonderware as the production backend.

Claude-Session: https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii
This commit is contained in:
Joseph Doherty
2026-06-26 19:25:21 -04:00
parent 245db98f5e
commit 0b4b2e4cfd
84 changed files with 37 additions and 9345 deletions
@@ -1,29 +0,0 @@
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers.Pickers;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Pickers;
public sealed class HistorianWonderwareAddressBuilderTests
{
[Theory]
[InlineData("SysTimeHour", "Cyclic", 60, "SysTimeHour?mode=Cyclic&interval=60")]
[InlineData("ReactorTemp", "Last", 1, "ReactorTemp?mode=Last&interval=1")]
[InlineData("FlowRate", "Delta", 30, "FlowRate?mode=Delta&interval=30")]
public void Build_Canonical(string tag, string mode, int interval, string expected)
=> HistorianWonderwareAddressBuilder.Build(tag, mode, interval).ShouldBe(expected);
/// <summary>A tag name carrying query-reserved characters is percent-encoded so the produced
/// address stays a well-formed query string (AdminUI-005). With "A&amp;B?C" the '&amp;' and '?'
/// must not be read as a query separator / start, so they are escaped.</summary>
[Fact]
public void Build_escapes_reserved_characters_in_tag_name()
{
var result = HistorianWonderwareAddressBuilder.Build("A&B?C", "Cyclic", 60);
// The only literal '?' is the query separator the builder inserts; the only literal '&'
// is the one between mode and interval. The reserved characters in the name are escaped.
result.ShouldBe("A%26B%3FC?mode=Cyclic&interval=60");
result.IndexOf('?').ShouldBe(result.IndexOf("?mode=", System.StringComparison.Ordinal));
}
}