refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)

Solution + 23 src projects + 26 test projects renamed; folders, csproj,
namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated.
ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated.
SQL roles/logins, LDAP domains, CLI command name, and CLI config dir
(~/.scadalink → ~/.scadabridge) also renamed.

Build green; 5 Host.Tests fail awaiting SQL login rename in next commit.
Pre-existing StaleTagMonitor timing flakes unchanged.

Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
Joseph Doherty
2026-05-28 09:37:45 -04:00
parent 6d87ee3c3b
commit 7b0b9c7365
1531 changed files with 11180 additions and 11054 deletions
+88 -88
View File
@@ -4,7 +4,7 @@
**Goal:** Extract OPC UA endpoint configuration from free-form JSON strings into a strongly-typed `OpcUaEndpointConfig` POCO with a validator and serializer in Commons; consume the model from both the site-side runtime (`OpcUaDataConnection`) and the central UI (`/admin/connections` create/edit), rendering typed Bootstrap controls instead of a JSON textarea.
**Architecture:** New POCO/validator/serializer in `ScadaLink.Commons` are the single schema. Typed nested JSON (`System.Text.Json`, camelCase) is the storage shape; a legacy flat string-dict fallback in the serializer keeps existing rows readable. `IDataConnection.ConnectAsync` keeps its `IDictionary<string,string>` contract (protocol-agnostic), and `OpcUaDataConnection` uses `OpcUaEndpointConfigSerializer.FromFlatDict` internally to get the typed model. A shared `<OpcUaEndpointEditor>` Blazor component renders the form, used twice (primary + backup).
**Architecture:** New POCO/validator/serializer in `ZB.MOM.WW.ScadaBridge.Commons` are the single schema. Typed nested JSON (`System.Text.Json`, camelCase) is the storage shape; a legacy flat string-dict fallback in the serializer keeps existing rows readable. `IDataConnection.ConnectAsync` keeps its `IDictionary<string,string>` contract (protocol-agnostic), and `OpcUaDataConnection` uses `OpcUaEndpointConfigSerializer.FromFlatDict` internally to get the typed model. A shared `<OpcUaEndpointEditor>` Blazor component renders the form, used twice (primary + backup).
**Tech Stack:** C# 12 / .NET 10, System.Text.Json, Blazor Server, Bootstrap 5, xUnit + bUnit + NSubstitute.
@@ -34,15 +34,15 @@
## Task 1: Create POCOs and add ValidationCategory value
**Files:**
- Create: `src/ScadaLink.Commons/Types/DataConnections/OpcUaSecurityMode.cs`
- Create: `src/ScadaLink.Commons/Types/DataConnections/OpcUaHeartbeatConfig.cs`
- Create: `src/ScadaLink.Commons/Types/DataConnections/OpcUaEndpointConfig.cs`
- Modify: `src/ScadaLink.Commons/Types/Flattening/ValidationResult.cs` (add `ConnectionConfig` enum value)
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/OpcUaSecurityMode.cs`
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/OpcUaHeartbeatConfig.cs`
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/OpcUaEndpointConfig.cs`
- Modify: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/Flattening/ValidationResult.cs` (add `ConnectionConfig` enum value)
**Step 1: Create `OpcUaSecurityMode.cs`**
```csharp
namespace ScadaLink.Commons.Types.DataConnections;
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
public enum OpcUaSecurityMode
{
@@ -55,7 +55,7 @@ public enum OpcUaSecurityMode
**Step 2: Create `OpcUaHeartbeatConfig.cs`**
```csharp
namespace ScadaLink.Commons.Types.DataConnections;
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
public sealed class OpcUaHeartbeatConfig
{
@@ -67,7 +67,7 @@ public sealed class OpcUaHeartbeatConfig
**Step 3: Create `OpcUaEndpointConfig.cs`**
```csharp
namespace ScadaLink.Commons.Types.DataConnections;
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
public sealed class OpcUaEndpointConfig
{
@@ -95,7 +95,7 @@ public sealed class OpcUaEndpointConfig
**Step 4: Add `ConnectionConfig` to `ValidationCategory`**
In `src/ScadaLink.Commons/Types/Flattening/ValidationResult.cs:50-65`, append `ConnectionConfig` to the enum:
In `src/ZB.MOM.WW.ScadaBridge.Commons/Types/Flattening/ValidationResult.cs:50-65`, append `ConnectionConfig` to the enum:
```csharp
public enum ValidationCategory
@@ -119,13 +119,13 @@ public enum ValidationCategory
**Step 5: Build to confirm everything compiles**
Run: `dotnet build src/ScadaLink.Commons/ScadaLink.Commons.csproj`
Run: `dotnet build src/ZB.MOM.WW.ScadaBridge.Commons/ZB.MOM.WW.ScadaBridge.Commons.csproj`
Expected: build succeeded, 0 errors.
**Step 6: Commit**
```bash
git add src/ScadaLink.Commons/Types/DataConnections/ src/ScadaLink.Commons/Types/Flattening/ValidationResult.cs
git add src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/ src/ZB.MOM.WW.ScadaBridge.Commons/Types/Flattening/ValidationResult.cs
git commit -m "feat(commons): OpcUaEndpointConfig POCOs + ConnectionConfig ValidationCategory"
```
@@ -134,15 +134,15 @@ git commit -m "feat(commons): OpcUaEndpointConfig POCOs + ConnectionConfig Valid
## Task 2: TDD — `OpcUaEndpointConfigSerializer` tests (failing)
**Files:**
- Create: `tests/ScadaLink.Commons.Tests/Types/DataConnections/OpcUaEndpointConfigSerializerTests.cs`
- Create: `tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Types/DataConnections/OpcUaEndpointConfigSerializerTests.cs`
**Step 1: Write the failing test file**
```csharp
using ScadaLink.Commons.Serialization;
using ScadaLink.Commons.Types.DataConnections;
using ZB.MOM.WW.ScadaBridge.Commons.Serialization;
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
namespace ScadaLink.Commons.Tests.Types.DataConnections;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Types.DataConnections;
public class OpcUaEndpointConfigSerializerTests
{
@@ -308,13 +308,13 @@ public class OpcUaEndpointConfigSerializerTests
**Step 2: Run the tests to verify failure**
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
Expected: build error — type `OpcUaEndpointConfigSerializer` does not exist.
**Step 3: Commit the failing tests**
```bash
git add tests/ScadaLink.Commons.Tests/Types/DataConnections/
git add tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Types/DataConnections/
git commit -m "test(commons): failing tests for OpcUaEndpointConfigSerializer"
```
@@ -323,16 +323,16 @@ git commit -m "test(commons): failing tests for OpcUaEndpointConfigSerializer"
## Task 3: Implement `OpcUaEndpointConfigSerializer`
**Files:**
- Create: `src/ScadaLink.Commons/Serialization/OpcUaEndpointConfigSerializer.cs`
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Serialization/OpcUaEndpointConfigSerializer.cs`
**Step 1: Implement the serializer**
```csharp
using System.Text.Json;
using System.Text.Json.Serialization;
using ScadaLink.Commons.Types.DataConnections;
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
namespace ScadaLink.Commons.Serialization;
namespace ZB.MOM.WW.ScadaBridge.Commons.Serialization;
/// <summary>
/// Serializes <see cref="OpcUaEndpointConfig"/> to/from the typed nested JSON
@@ -450,13 +450,13 @@ public static class OpcUaEndpointConfigSerializer
**Step 2: Run tests, verify they pass**
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
Expected: all 8 tests pass.
**Step 3: Commit**
```bash
git add src/ScadaLink.Commons/Serialization/
git add src/ZB.MOM.WW.ScadaBridge.Commons/Serialization/
git commit -m "feat(commons): OpcUaEndpointConfigSerializer with legacy fallback + flat-dict interop"
```
@@ -465,16 +465,16 @@ git commit -m "feat(commons): OpcUaEndpointConfigSerializer with legacy fallback
## Task 4: TDD — `OpcUaEndpointConfigValidator` tests (failing)
**Files:**
- Create: `tests/ScadaLink.Commons.Tests/Validators/OpcUaEndpointConfigValidatorTests.cs`
- Create: `tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Validators/OpcUaEndpointConfigValidatorTests.cs`
**Step 1: Write the failing test file**
```csharp
using ScadaLink.Commons.Types.DataConnections;
using ScadaLink.Commons.Types.Flattening;
using ScadaLink.Commons.Validators;
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
using ZB.MOM.WW.ScadaBridge.Commons.Validators;
namespace ScadaLink.Commons.Tests.Validators;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Validators;
public class OpcUaEndpointConfigValidatorTests
{
@@ -586,13 +586,13 @@ public class OpcUaEndpointConfigValidatorTests
**Step 2: Run, verify failure**
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
Expected: build error — `OpcUaEndpointConfigValidator` not defined.
**Step 3: Commit**
```bash
git add tests/ScadaLink.Commons.Tests/Validators/
git add tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Validators/
git commit -m "test(commons): failing tests for OpcUaEndpointConfigValidator"
```
@@ -601,15 +601,15 @@ git commit -m "test(commons): failing tests for OpcUaEndpointConfigValidator"
## Task 5: Implement `OpcUaEndpointConfigValidator`
**Files:**
- Create: `src/ScadaLink.Commons/Validators/OpcUaEndpointConfigValidator.cs`
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Validators/OpcUaEndpointConfigValidator.cs`
**Step 1: Implement**
```csharp
using ScadaLink.Commons.Types.DataConnections;
using ScadaLink.Commons.Types.Flattening;
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
namespace ScadaLink.Commons.Validators;
namespace ZB.MOM.WW.ScadaBridge.Commons.Validators;
/// <summary>
/// Pure-function validator for <see cref="OpcUaEndpointConfig"/>. Errors carry
@@ -672,13 +672,13 @@ public static class OpcUaEndpointConfigValidator
**Step 2: Run tests, verify pass**
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
Expected: all 11 tests pass.
**Step 3: Commit**
```bash
git add src/ScadaLink.Commons/Validators/
git add src/ZB.MOM.WW.ScadaBridge.Commons/Validators/
git commit -m "feat(commons): OpcUaEndpointConfigValidator"
```
@@ -687,8 +687,8 @@ git commit -m "feat(commons): OpcUaEndpointConfigValidator"
## Task 6: Refactor `OpcUaDataConnection.ConnectAsync`
**Files:**
- Modify: `src/ScadaLink.DataConnectionLayer/Adapters/OpcUaDataConnection.cs:44-115`
- Verify: `tests/ScadaLink.DataConnectionLayer.Tests/` — any existing test that constructs a `Dictionary<string,string>` and passes it to `ConnectAsync` should keep working unchanged.
- Modify: `src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/OpcUaDataConnection.cs:44-115`
- Verify: `tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/` — any existing test that constructs a `Dictionary<string,string>` and passes it to `ConnectAsync` should keep working unchanged.
**Step 1: Replace `ConnectAsync`, `StartHeartbeatMonitorAsync`, and remove `ParseInt`/`ParseBool` helpers**
@@ -760,22 +760,22 @@ private async Task StartHeartbeatMonitorAsync(OpcUaHeartbeatConfig? heartbeat, C
}
```
Delete the two `internal static` helpers at lines 107-115 (`ParseInt`, `ParseBool`). Add `using ScadaLink.Commons.Serialization;` and `using ScadaLink.Commons.Types.DataConnections;` at the top.
Delete the two `internal static` helpers at lines 107-115 (`ParseInt`, `ParseBool`). Add `using ZB.MOM.WW.ScadaBridge.Commons.Serialization;` and `using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;` at the top.
**Step 2: Run DCL test suite — confirm nothing broke**
Run: `dotnet test tests/ScadaLink.DataConnectionLayer.Tests/ScadaLink.DataConnectionLayer.Tests.csproj`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests.csproj`
Expected: all green. Existing tests pass `Dictionary<string,string>` to `ConnectAsync`; `FromFlatDict` accepts the same keys (including `endpoint` and `EndpointUrl` casing variants).
**Step 3: If a test was directly verifying `ParseInt`/`ParseBool` behavior, delete it**
`grep -n "ParseInt\|ParseBool" tests/ScadaLink.DataConnectionLayer.Tests/ -r` — if it returns hits, delete those test cases. They were testing internals that no longer exist; the same behavior is now covered by `OpcUaEndpointConfigSerializerTests.FromFlatDict_*`.
`grep -n "ParseInt\|ParseBool" tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/ -r` — if it returns hits, delete those test cases. They were testing internals that no longer exist; the same behavior is now covered by `OpcUaEndpointConfigSerializerTests.FromFlatDict_*`.
**Step 4: Commit**
```bash
git add src/ScadaLink.DataConnectionLayer/Adapters/OpcUaDataConnection.cs
git add tests/ScadaLink.DataConnectionLayer.Tests/ # if any test edits
git add src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/OpcUaDataConnection.cs
git add tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/ # if any test edits
git commit -m "refactor(dcl): OpcUaDataConnection uses OpcUaEndpointConfig via FromFlatDict"
```
@@ -784,8 +784,8 @@ git commit -m "refactor(dcl): OpcUaDataConnection uses OpcUaEndpointConfig via F
## Task 7: Refactor `DeploymentManagerActor.EnsureDclConnections`
**Files:**
- Modify: `src/ScadaLink.SiteRuntime/Actors/DeploymentManagerActor.cs:411-468`
- Verify: `tests/ScadaLink.SiteRuntime.Tests/` — particularly any test that hands a sample `FlattenedConfiguration` with a connection JSON.
- Modify: `src/ZB.MOM.WW.ScadaBridge.SiteRuntime/Actors/DeploymentManagerActor.cs:411-468`
- Verify: `tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/` — particularly any test that hands a sample `FlattenedConfiguration` with a connection JSON.
**Why this changes:** The current code does dumb `JsonDocument.EnumerateObject` + `prop.Value.ToString()` to flatten the connection JSON into a `Dictionary<string,string>`. With the new typed nested JSON shape (containing a nested `heartbeat` object), that flattener produces `"heartbeat" → "{\"tagPath\":\"...\"}"` — broken. The serializer's `Deserialize` + `ToFlatDict` does it correctly and also handles the legacy shape.
@@ -860,13 +860,13 @@ private static IDictionary<string, string> FlattenConnectionConfig(string protoc
**Step 2: Run SiteRuntime tests**
Run: `dotnet test tests/ScadaLink.SiteRuntime.Tests/ScadaLink.SiteRuntime.Tests.csproj`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests.csproj`
Expected: green. Any existing test passing legacy-style JSON for an OPC UA connection still works because `Deserialize` handles both shapes.
**Step 3: Commit**
```bash
git add src/ScadaLink.SiteRuntime/Actors/DeploymentManagerActor.cs
git add src/ZB.MOM.WW.ScadaBridge.SiteRuntime/Actors/DeploymentManagerActor.cs
git commit -m "refactor(site-runtime): route OPC UA connection JSON through serializer"
```
@@ -875,18 +875,18 @@ git commit -m "refactor(site-runtime): route OPC UA connection JSON through seri
## Task 8: TDD — `<OpcUaEndpointEditor>` Blazor component tests (failing)
**Files:**
- Create: `tests/ScadaLink.CentralUI.Tests/Forms/OpcUaEndpointEditorTests.cs`
- Create: `tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Forms/OpcUaEndpointEditorTests.cs`
**Step 1: Write the failing tests**
```csharp
using Bunit;
using ScadaLink.Commons.Types.DataConnections;
using ScadaLink.Commons.Types.Flattening;
using ScadaLink.Commons.Validators;
using OpcUaEndpointEditor = ScadaLink.CentralUI.Components.Forms.OpcUaEndpointEditor;
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
using ZB.MOM.WW.ScadaBridge.Commons.Validators;
using OpcUaEndpointEditor = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Forms.OpcUaEndpointEditor;
namespace ScadaLink.CentralUI.Tests.Forms;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Forms;
public class OpcUaEndpointEditorTests : BunitContext
{
@@ -969,13 +969,13 @@ public class OpcUaEndpointEditorTests : BunitContext
**Step 2: Run, verify failure**
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
Expected: build error — `OpcUaEndpointEditor` does not exist.
**Step 3: Commit**
```bash
git add tests/ScadaLink.CentralUI.Tests/Forms/
git add tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Forms/
git commit -m "test(ui): failing bUnit tests for OpcUaEndpointEditor"
```
@@ -984,14 +984,14 @@ git commit -m "test(ui): failing bUnit tests for OpcUaEndpointEditor"
## Task 9: Implement `<OpcUaEndpointEditor>` Blazor component
**Files:**
- Create: `src/ScadaLink.CentralUI/Components/Forms/OpcUaEndpointEditor.razor`
- Create: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Forms/OpcUaEndpointEditor.razor`
**Step 1: Implement the component**
```razor
@namespace ScadaLink.CentralUI.Components.Forms
@using ScadaLink.Commons.Types.DataConnections
@using ScadaLink.Commons.Types.Flattening
@namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Forms
@using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening
<div class="opcua-endpoint-editor">
<h6 class="text-muted border-bottom pb-1">@Title</h6>
@@ -1143,13 +1143,13 @@ git commit -m "test(ui): failing bUnit tests for OpcUaEndpointEditor"
**Step 2: Run the editor tests, verify pass**
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
Expected: all 6 tests pass.
**Step 3: Commit**
```bash
git add src/ScadaLink.CentralUI/Components/Forms/
git add src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Forms/
git commit -m "feat(ui): OpcUaEndpointEditor Blazor component"
```
@@ -1158,9 +1158,9 @@ git commit -m "feat(ui): OpcUaEndpointEditor Blazor component"
## Task 10: TDD — `DataConnectionForm` refactor tests (failing/updating)
**Files:**
- Create or modify: `tests/ScadaLink.CentralUI.Tests/DataConnectionFormTests.cs`
- Create or modify: `tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/DataConnectionFormTests.cs`
Before writing, run: `ls tests/ScadaLink.CentralUI.Tests/ | grep -i "DataConnection"`. If a test file already exists, **modify** it; otherwise create new.
Before writing, run: `ls tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ | grep -i "DataConnection"`. If a test file already exists, **modify** it; otherwise create new.
**Step 1: Write the failing tests**
@@ -1171,11 +1171,11 @@ using Bunit;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using ScadaLink.Commons.Entities.Sites;
using ScadaLink.Commons.Interfaces.Repositories;
using DataConnectionForm = ScadaLink.CentralUI.Components.Pages.Admin.DataConnectionForm;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
using DataConnectionForm = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Admin.DataConnectionForm;
namespace ScadaLink.CentralUI.Tests;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests;
public class DataConnectionFormTests : BunitContext
{
@@ -1271,13 +1271,13 @@ public class DataConnectionFormTests : BunitContext
**Step 2: Run, verify failure**
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
Expected: at least one test fails — current form still has the Protocol dropdown and stores raw textarea JSON, not typed-camelCase JSON.
**Step 3: Commit**
```bash
git add tests/ScadaLink.CentralUI.Tests/DataConnectionFormTests.cs
git add tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/DataConnectionFormTests.cs
git commit -m "test(ui): failing tests for DataConnectionForm refactor"
```
@@ -1286,7 +1286,7 @@ git commit -m "test(ui): failing tests for DataConnectionForm refactor"
## Task 11: Refactor `DataConnectionForm.razor`
**Files:**
- Modify: `src/ScadaLink.CentralUI/Components/Pages/Admin/DataConnectionForm.razor` (whole file)
- Modify: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Admin/DataConnectionForm.razor` (whole file)
**Step 1: Rewrite the form**
@@ -1297,14 +1297,14 @@ Replace the entire file with:
@page "/admin/connections/{Id:int}/edit"
@page "/admin/data-connections/create"
@page "/admin/data-connections/{Id:int}/edit"
@using ScadaLink.Security
@using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories
@using ScadaLink.Commons.Types.DataConnections
@using ScadaLink.Commons.Types.Flattening
@using ScadaLink.Commons.Serialization
@using ScadaLink.Commons.Validators
@using ScadaLink.CentralUI.Components.Forms
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
@using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening
@using ZB.MOM.WW.ScadaBridge.Commons.Serialization
@using ZB.MOM.WW.ScadaBridge.Commons.Validators
@using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Forms
@attribute [Authorize(Policy = AuthorizationPolicies.RequireAdmin)]
@inject ISiteRepository SiteRepository
@inject NavigationManager NavigationManager
@@ -1525,18 +1525,18 @@ Replace the entire file with:
**Step 2: Run the form tests, verify pass**
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
Expected: all tests pass.
**Step 3: Run the full CentralUI suite**
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj`
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj`
Expected: all tests pass (the pre-existing `DataConnectionsPageTests` is unaffected; it tests the list page, not the form).
**Step 4: Commit**
```bash
git add src/ScadaLink.CentralUI/Components/Pages/Admin/DataConnectionForm.razor
git add src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Admin/DataConnectionForm.razor
git commit -m "refactor(ui/admin): DataConnectionForm uses OpcUaEndpointEditor and typed model"
```
@@ -1553,10 +1553,10 @@ Expected: build succeeded, 0 errors. Warnings acceptable.
Run: `dotnet test`
Expected: all test projects green. Likely-affected suites:
- `ScadaLink.Commons.Tests` (+ new serializer & validator tests, ~19 new total)
- `ScadaLink.DataConnectionLayer.Tests` (existing tests must still pass)
- `ScadaLink.SiteRuntime.Tests` (existing tests must still pass)
- `ScadaLink.CentralUI.Tests` (+ new editor tests, + new/updated form tests)
- `ZB.MOM.WW.ScadaBridge.Commons.Tests` (+ new serializer & validator tests, ~19 new total)
- `ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests` (existing tests must still pass)
- `ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests` (existing tests must still pass)
- `ZB.MOM.WW.ScadaBridge.CentralUI.Tests` (+ new editor tests, + new/updated form tests)
**Step 3: If anything fails**, do NOT proceed to Docker. Diagnose and fix in a new commit before moving on.
@@ -1569,7 +1569,7 @@ There is no commit in this task — it's a checkpoint.
**Step 1: Rebuild and start the cluster**
Run: `bash docker/deploy.sh`
Expected: `scadalink:latest` rebuilt, 5 cluster containers up (central-a, central-b, site-a, site-b, site-c per `docker/README.md`).
Expected: `scadabridge:latest` rebuilt, 5 cluster containers up (central-a, central-b, site-a, site-b, site-c per `docker/README.md`).
**Step 2: Open the connections page**
@@ -1603,13 +1603,13 @@ From the list page, click a site row to select it, then click `+ Connection`.
**Step 6: Verify DB JSON shape**
Run: `docker exec scadalink-central-a sqlite3 /var/lib/scadalink/scadalink.db "SELECT PrimaryConfiguration FROM DataConnections ORDER BY Id DESC LIMIT 1;"`
Run: `docker exec scadabridge-central-a sqlite3 /var/lib/scadabridge/scadabridge.db "SELECT PrimaryConfiguration FROM DataConnections ORDER BY Id DESC LIMIT 1;"`
Expected: typed nested JSON containing `"endpointUrl"`, `"securityMode"`, `"heartbeat":{"tagPath":...}`.
**Step 7: Deploy a template that uses the connection**
Optional but a strong smoke. Use any pre-existing template that has a connection binding. Navigate to `/deployment/topology`, deploy to the site that owns the new connection.
Expected: site logs (`docker logs scadalink-site-a`) show "OPC UA connected to opc.tcp://..." — the runtime parsed the new JSON shape correctly.
Expected: site logs (`docker logs scadabridge-site-a`) show "OPC UA connected to opc.tcp://..." — the runtime parsed the new JSON shape correctly.
**Step 8: If anything's off**, capture screenshots / logs, fix, and re-deploy before committing.
@@ -1631,7 +1631,7 @@ Expected: branch advances on origin; existing PR #1 picks up the new commits.
**Step 3: Verify the PR**
Open `https://gitea.dohertylan.com/dohertj2/scadalink-design/pulls/1` and confirm the new commits are listed.
Open `https://gitea.dohertylan.com/dohertj2/scadabridge-design/pulls/1` and confirm the new commits are listed.
---