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
@@ -1,33 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="ScadaLink.CentralUI.Tests" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../ScadaLink.Commons/ScadaLink.Commons.csproj" />
<ProjectReference Include="../ScadaLink.Security/ScadaLink.Security.csproj" />
<ProjectReference Include="../ScadaLink.TemplateEngine/ScadaLink.TemplateEngine.csproj" />
<ProjectReference Include="../ScadaLink.DeploymentManager/ScadaLink.DeploymentManager.csproj" />
<ProjectReference Include="../ScadaLink.HealthMonitoring/ScadaLink.HealthMonitoring.csproj" />
<ProjectReference Include="../ScadaLink.Communication/ScadaLink.Communication.csproj" />
<ProjectReference Include="../ScadaLink.Transport/ScadaLink.Transport.csproj" />
</ItemGroup>
</Project>
@@ -1,3 +0,0 @@
namespace ScadaLink.Commons.Messages.Management;
public record DebugSnapshotCommand(int InstanceId);
@@ -1,7 +0,0 @@
namespace ScadaLink.Commons.Types.DataConnections;
public enum OpcUaDeadbandType
{
Absolute,
Percent
}
@@ -1,7 +0,0 @@
namespace ScadaLink.Commons.Types.Enums;
public enum AlarmState
{
Active,
Normal
}
-58
View File
@@ -1,58 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="ScadaLink.Host.Tests" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Akka.Cluster.Hosting" />
<PackageReference Include="Akka.Cluster.Tools" />
<PackageReference Include="Akka.Hosting" />
<PackageReference Include="Akka.Remote.Hosting" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Grpc.AspNetCore" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" />
<PackageReference Include="Serilog.AspNetCore" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog.Sinks.File" />
<!-- Transitive override: Akka.Hosting 1.5.62 pins OpenTelemetry.Api 1.9.0 which is flagged
(GHSA-g94r-2vxg-569j, GHSA-8785-wc3w-h8q6). Bumping directly clears both advisories. -->
<PackageReference Include="OpenTelemetry.Api" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../ScadaLink.Commons/ScadaLink.Commons.csproj" />
<ProjectReference Include="../ScadaLink.TemplateEngine/ScadaLink.TemplateEngine.csproj" />
<ProjectReference Include="../ScadaLink.DeploymentManager/ScadaLink.DeploymentManager.csproj" />
<ProjectReference Include="../ScadaLink.SiteRuntime/ScadaLink.SiteRuntime.csproj" />
<ProjectReference Include="../ScadaLink.DataConnectionLayer/ScadaLink.DataConnectionLayer.csproj" />
<ProjectReference Include="../ScadaLink.Communication/ScadaLink.Communication.csproj" />
<ProjectReference Include="../ScadaLink.StoreAndForward/ScadaLink.StoreAndForward.csproj" />
<ProjectReference Include="../ScadaLink.ExternalSystemGateway/ScadaLink.ExternalSystemGateway.csproj" />
<ProjectReference Include="../ScadaLink.NotificationService/ScadaLink.NotificationService.csproj" />
<ProjectReference Include="../ScadaLink.NotificationOutbox/ScadaLink.NotificationOutbox.csproj" />
<ProjectReference Include="../ScadaLink.Transport/ScadaLink.Transport.csproj" />
<ProjectReference Include="../ScadaLink.AuditLog/ScadaLink.AuditLog.csproj" />
<ProjectReference Include="../ScadaLink.SiteCallAudit/ScadaLink.SiteCallAudit.csproj" />
<ProjectReference Include="../ScadaLink.CentralUI/ScadaLink.CentralUI.csproj" />
<ProjectReference Include="../ScadaLink.Security/ScadaLink.Security.csproj" />
<ProjectReference Include="../ScadaLink.HealthMonitoring/ScadaLink.HealthMonitoring.csproj" />
<ProjectReference Include="../ScadaLink.SiteEventLogging/ScadaLink.SiteEventLogging.csproj" />
<ProjectReference Include="../ScadaLink.ClusterInfrastructure/ScadaLink.ClusterInfrastructure.csproj" />
<ProjectReference Include="../ScadaLink.InboundAPI/ScadaLink.InboundAPI.csproj" />
<ProjectReference Include="../ScadaLink.ConfigurationDatabase/ScadaLink.ConfigurationDatabase.csproj" />
<ProjectReference Include="../ScadaLink.ManagementService/ScadaLink.ManagementService.csproj" />
</ItemGroup>
</Project>
@@ -1,24 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Akka" />
<PackageReference Include="Akka.Cluster.Tools" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../ScadaLink.Commons/ScadaLink.Commons.csproj" />
<ProjectReference Include="../ScadaLink.TemplateEngine/ScadaLink.TemplateEngine.csproj" />
<ProjectReference Include="../ScadaLink.DeploymentManager/ScadaLink.DeploymentManager.csproj" />
<ProjectReference Include="../ScadaLink.Communication/ScadaLink.Communication.csproj" />
<ProjectReference Include="../ScadaLink.Security/ScadaLink.Security.csproj" />
<ProjectReference Include="../ScadaLink.HealthMonitoring/ScadaLink.HealthMonitoring.csproj" />
<ProjectReference Include="..\ScadaLink.InboundAPI\ScadaLink.InboundAPI.csproj" />
</ItemGroup>
</Project>
@@ -1,7 +1,7 @@
using System.Collections.Concurrent;
using ScadaLink.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Audit Log (#23) M6 Bundle E (T8, T9) — central singleton implementation of
@@ -22,7 +22,7 @@ namespace ScadaLink.AuditLog.Central;
/// counters anyway — having a single class own both means the
/// <c>Interlocked</c> field IS the snapshot value, no extra plumbing needed.
/// Mirrors the
/// <see cref="ScadaLink.HealthMonitoring.SiteHealthCollector"/> pattern where
/// <see cref="ZB.MOM.WW.ScadaBridge.HealthMonitoring.SiteHealthCollector"/> pattern where
/// the collector both receives and exposes the metric.
/// </para>
/// <para>
@@ -1,13 +1,13 @@
using Akka.Actor;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ScadaLink.AuditLog.Payload;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces.Repositories;
using ScadaLink.Commons.Messages.Audit;
using ScadaLink.ConfigurationDatabase;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Audit;
using ZB.MOM.WW.ScadaBridge.ConfigurationDatabase;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Central-side singleton (per Bundle E wiring) that ingests batches of
@@ -215,7 +215,7 @@ public class AuditLogIngestActor : ReceiveActor
await using var scope = _serviceProvider!.CreateAsyncScope();
var auditRepo = scope.ServiceProvider.GetRequiredService<IAuditLogRepository>();
var siteCallRepo = scope.ServiceProvider.GetRequiredService<ISiteCallAuditRepository>();
var dbContext = scope.ServiceProvider.GetRequiredService<ScadaLinkDbContext>();
var dbContext = scope.ServiceProvider.GetRequiredService<ScadaBridgeDbContext>();
// Bundle C (M5-T6): resolve the filter for the whole batch from
// the scope; null = pass-through for test composition roots that
// skip the filter registration. The filter is contract-bound to
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Tuning knobs for the central
@@ -2,9 +2,9 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.Commons.Interfaces;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Central <see cref="IHostedService"/> (M6-T5, Bundle D) that rolls
@@ -47,7 +47,7 @@ namespace ScadaLink.AuditLog.Central;
/// <para>
/// <b>DI scope per tick.</b> <see cref="IPartitionMaintenance"/> is scoped
/// (alongside the rest of the EF repositories) because the implementation
/// reuses the per-scope <c>ScadaLinkDbContext</c>. A hosted service is a
/// reuses the per-scope <c>ScadaBridgeDbContext</c>. A hosted service is a
/// singleton, so it must open and dispose a scope around each tick — the
/// same pattern <see cref="AuditLogPurgeActor"/> uses.
/// </para>
@@ -3,10 +3,10 @@ using Akka.Actor;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.AuditLog.Configuration;
using ScadaLink.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.AuditLog.Configuration;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Central singleton (M6 Bundle C) that drives the daily AuditLog partition
@@ -1,9 +1,9 @@
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Tuning knobs for the central <see cref="AuditLogPurgeActor"/> singleton.
/// Default cadence is 24 hours per the M6 plan; the retention window itself
/// is sourced from <see cref="ScadaLink.AuditLog.Configuration.AuditLogOptions.RetentionDays"/>
/// is sourced from <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Configuration.AuditLogOptions.RetentionDays"/>
/// (default 365) so operators tune retention from a single section.
/// </summary>
/// <remarks>
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Published on the actor-system EventStream by <see cref="AuditLogPurgeActor"/>
@@ -1,6 +1,6 @@
using ScadaLink.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Audit Log (#23) M6 Bundle E (T9) — bridges
@@ -14,7 +14,7 @@ namespace ScadaLink.AuditLog.Central;
/// <remarks>
/// <para>
/// <b>Site vs central.</b> M5 Bundle C wired the SITE-side bridge
/// (<see cref="ScadaLink.AuditLog.Site.HealthMetricsAuditRedactionFailureCounter"/>),
/// (<see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Site.HealthMetricsAuditRedactionFailureCounter"/>),
/// which routes increments into the site health report payload's
/// <c>AuditRedactionFailure</c> field. That handles redactor failures on the
/// site SQLite hot-path (FallbackAuditWriter). M6 Bundle E (T9) adds the
@@ -39,7 +39,7 @@ namespace ScadaLink.AuditLog.Central;
/// the central-vs-site asymmetry explicit at the DI boundary — readers of
/// <see cref="ServiceCollectionExtensions.AddAuditLogCentralMaintenance"/>
/// see "site → site bridge, central → central bridge", matching the
/// <see cref="ScadaLink.AuditLog.Site.HealthMetricsAuditRedactionFailureCounter"/>
/// <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Site.HealthMetricsAuditRedactionFailureCounter"/>
/// shape one-for-one.
/// </para>
/// </remarks>
@@ -1,11 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ScadaLink.AuditLog.Payload;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces.Repositories;
using ScadaLink.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Central-only direct-write implementation of <see cref="ICentralAuditWriter"/>.
@@ -24,7 +24,7 @@ namespace ScadaLink.AuditLog.Central;
/// </para>
/// <para>
/// <b>Scope-per-call resolution.</b> <see cref="IAuditLogRepository"/> is a SCOPED
/// EF Core service (registered by <c>ScadaLink.ConfigurationDatabase</c>). The
/// EF Core service (registered by <c>ZB.MOM.WW.ScadaBridge.ConfigurationDatabase</c>). The
/// writer itself is registered as a singleton (so all callers share one instance),
/// so it cannot hold a scope across calls — it opens a fresh
/// <see cref="IServiceScope"/> per <see cref="WriteAsync"/> invocation, mirroring
@@ -1,6 +1,6 @@
using ScadaLink.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Audit Log (#23) M6 Bundle E read-side surface exposing the central-side
@@ -1,10 +1,10 @@
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Audit Log (#23) M6 Bundle E (T8) counter sink invoked by central-side audit
/// writers (<see cref="CentralAuditWriter"/>, <see cref="AuditLogIngestActor"/>)
/// every time a repository <c>InsertIfNotExistsAsync</c> throws. Mirrors the
/// site-side <see cref="ScadaLink.AuditLog.Site.IAuditWriteFailureCounter"/>
/// site-side <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Site.IAuditWriteFailureCounter"/>
/// shape one-for-one — same one-method contract, same NoOp default, same
/// must-never-abort-the-user-facing-action invariant.
/// </summary>
@@ -1,6 +1,6 @@
using ScadaLink.Commons.Messages.Integration;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Integration;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Mockable abstraction over the central-side <c>PullAuditEvents</c> gRPC
@@ -33,7 +33,7 @@ public interface IPullAuditEventsClient
/// <summary>
/// Issues a <c>PullAuditEvents</c> RPC against the site whose endpoint
/// is registered against <paramref name="siteId"/>. Returns the next
/// batch of <see cref="ScadaLink.Commons.Entities.Audit.AuditEvent"/>
/// batch of <see cref="ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit.AuditEvent"/>
/// rows ordered oldest-first AND a <c>MoreAvailable</c> flag the actor
/// uses to decide whether to fire another pull immediately.
/// </summary>
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Enumeration surface consumed by <see cref="SiteAuditReconciliationActor"/> to
@@ -1,11 +1,11 @@
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Default <see cref="ICentralAuditWriteFailureCounter"/> binding used when
/// the central health surface (<see cref="AuditCentralHealthSnapshot"/>) has
/// not been wired (test composition roots, site-only hosts that incidentally
/// resolve a <see cref="CentralAuditWriter"/>). Drops every increment on the
/// floor. Mirrors <see cref="ScadaLink.AuditLog.Site.NoOpAuditWriteFailureCounter"/>.
/// floor. Mirrors <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Site.NoOpAuditWriteFailureCounter"/>.
/// </summary>
public sealed class NoOpCentralAuditWriteFailureCounter : ICentralAuditWriteFailureCounter
{
@@ -2,10 +2,10 @@ using Akka.Actor;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Central singleton (M6 Bundle B) that drives the audit-log reconciliation
@@ -18,7 +18,7 @@ namespace ScadaLink.AuditLog.Central;
/// <remarks>
/// <para>
/// <b>Self-healing telemetry, not a dispatcher.</b> The push path
/// (<see cref="ScadaLink.AuditLog.Site.Telemetry.SiteAuditTelemetryActor"/> +
/// (<see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry.SiteAuditTelemetryActor"/> +
/// <c>IngestAuditEvents</c>) is the primary mechanism. This actor exists so a
/// missed push (gRPC blip, central restart, site offline) is eventually
/// repaired by central re-pulling whatever the site still has in
@@ -77,7 +77,7 @@ public class SiteAuditReconciliationActor : ReceiveActor
/// Per-site reconciliation watermark — the highest
/// <see cref="AuditEvent.OccurredAtUtc"/> seen for that site on a previous
/// tick. Asking for <c>OccurredAtUtc &gt;= cursor</c> rather than &gt;
/// is the site contract (<see cref="ScadaLink.Commons.Interfaces.Services.ISiteAuditQueue.ReadPendingSinceAsync"/>);
/// is the site contract (<see cref="ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services.ISiteAuditQueue.ReadPendingSinceAsync"/>);
/// duplicate-with-same-timestamp rows are filtered out by the idempotent
/// repository write.
/// </summary>
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Tuning knobs for the central <see cref="SiteAuditReconciliationActor"/> singleton.
@@ -45,7 +45,7 @@ public sealed class SiteAuditReconciliationOptions
ReconciliationIntervalOverride ?? TimeSpan.FromSeconds(ReconciliationIntervalSeconds);
/// <summary>
/// Maximum number of <see cref="ScadaLink.Commons.Entities.Audit.AuditEvent"/>
/// Maximum number of <see cref="ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit.AuditEvent"/>
/// rows requested in a single <c>PullAuditEvents</c> RPC call.
/// </summary>
public int BatchSize { get; set; } = 256;
@@ -2,7 +2,7 @@ using System.Collections.Concurrent;
using Akka.Actor;
using Akka.Event;
namespace ScadaLink.AuditLog.Central;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <summary>
/// Audit Log (#23) M6 Bundle E (T7) — central singleton that subscribes to the
@@ -1,7 +1,7 @@
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.AuditLog.Configuration;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Configuration;
/// <summary>
/// Configuration for Audit Log (#23). Bound from the <c>AuditLog</c> section of
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Options;
namespace ScadaLink.AuditLog.Configuration;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Configuration;
/// <summary>
/// Validates <see cref="AuditLogOptions"/> on startup. The caps drive payload
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Configuration;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Configuration;
/// <summary>
/// Per-target redaction override applied additively on top of
@@ -21,7 +21,7 @@ public sealed class PerTargetRedactionOverride
/// JSON (<c>{"sql":"...","parameters":{"@name":"value", ...}}</c>); values
/// whose name matches are replaced with <c>&lt;redacted&gt;</c>. Null (the
/// default) means parameter values are captured verbatim. Only applied to
/// <see cref="ScadaLink.Commons.Types.Enums.AuditChannel.DbOutbound"/>
/// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Types.Enums.AuditChannel.DbOutbound"/>
/// rows.
/// </summary>
public string? RedactSqlParamsMatching { get; set; }
@@ -6,11 +6,11 @@ using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.AuditLog.Configuration;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.AuditLog.Configuration;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.AuditLog.Payload;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
/// <summary>
/// Default <see cref="IAuditPayloadFilter"/>. Bundle A established the
@@ -27,7 +27,7 @@ namespace ScadaLink.AuditLog.Payload;
/// added via a live config change compile on first use of the next event;
/// patterns removed simply stop being looked up. No <c>OnChange</c> subscription
/// or explicit cache invalidation is required (the
/// <c>AuditLogOptionsBindingTests</c> fixture in <c>ScadaLink.AuditLog.Tests</c>
/// <c>AuditLogOptionsBindingTests</c> fixture in <c>ZB.MOM.WW.ScadaBridge.AuditLog.Tests</c>
/// pins this behaviour).
/// </para>
/// <para>
@@ -1,6 +1,6 @@
using ScadaLink.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
namespace ScadaLink.AuditLog.Payload;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
/// <summary>
/// Filters an <see cref="AuditEvent"/> between construction and persistence —
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Payload;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
/// <summary>
/// Counter sink invoked by <see cref="DefaultAuditPayloadFilter"/> every time
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Payload;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
/// <summary>
/// Default <see cref="IAuditRedactionFailureCounter"/> binding used when the
@@ -1,7 +1,7 @@
using System.Text.RegularExpressions;
using ScadaLink.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
namespace ScadaLink.AuditLog.Payload;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
/// <summary>
/// AuditLog-008: minimal always-safe fallback filter used by the writer chain
@@ -4,14 +4,14 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.AuditLog.Central;
using ScadaLink.AuditLog.Configuration;
using ScadaLink.AuditLog.Payload;
using ScadaLink.AuditLog.Site;
using ScadaLink.AuditLog.Site.Telemetry;
using ScadaLink.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.AuditLog.Central;
using ZB.MOM.WW.ScadaBridge.AuditLog.Configuration;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.AuditLog.Site;
using ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
namespace ScadaLink.AuditLog;
namespace ZB.MOM.WW.ScadaBridge.AuditLog;
/// <summary>
/// Composition root for the Audit Log (#23) component.
@@ -29,7 +29,7 @@ namespace ScadaLink.AuditLog;
/// <para>
/// Audit Log (#23) sits alongside Notification Outbox (#21) and Site Call
/// Audit (#22). <c>IAuditLogRepository</c> is registered by
/// <c>ScadaLink.ConfigurationDatabase.ServiceCollectionExtensions.AddConfigurationDatabase</c>,
/// <c>ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.ServiceCollectionExtensions.AddConfigurationDatabase</c>,
/// so the caller (the Host on the central node) must also call that.
/// </para>
/// </remarks>
@@ -141,14 +141,14 @@ public static class ServiceCollectionExtensions
// through IAuditWriter and the operational half through the
// IOperationTrackingStore. The audit writer is always wired (the M2
// chain above); the operational tracking store is SITE-ONLY (registered
// by ScadaLink.SiteRuntime). On a Central composition root the tracking
// by ZB.MOM.WW.ScadaBridge.SiteRuntime). On a Central composition root the tracking
// store has no registration, so the factory resolves it with GetService
// (returning null) — the forwarder degrades to "audit-only" emission,
// mirroring the lazy IAuditWriter chain established in M2.
services.AddSingleton<ICachedCallTelemetryForwarder>(sp =>
new CachedCallTelemetryForwarder(
sp.GetRequiredService<IAuditWriter>(),
sp.GetService<ScadaLink.Commons.Interfaces.IOperationTrackingStore>(),
sp.GetService<ZB.MOM.WW.ScadaBridge.Commons.Interfaces.IOperationTrackingStore>(),
sp.GetRequiredService<ILogger<CachedCallTelemetryForwarder>>(),
// AuditLog-007: INodeIdentityProvider is now required across
// every consumer in AddAuditLog. The Host's
@@ -196,7 +196,7 @@ public static class ServiceCollectionExtensions
// emit AuditLog rows that originate ON central, not via site telemetry.
// Singleton — the writer is stateless; its per-call scope opens a fresh
// IAuditLogRepository (a SCOPED EF Core service registered by
// ScadaLink.ConfigurationDatabase). The interface (ICentralAuditWriter)
// ZB.MOM.WW.ScadaBridge.ConfigurationDatabase). The interface (ICentralAuditWriter)
// is intentionally distinct from IAuditWriter so site composition roots
// do not accidentally bind it; central composition roots that include
// AddConfigurationDatabase get a working implementation transparently.
@@ -237,7 +237,7 @@ public static class ServiceCollectionExtensions
/// <para>
/// Must be called AFTER both <see cref="AddAuditLog"/> (registers the
/// NoOp defaults this method replaces) and
/// <c>ScadaLink.HealthMonitoring.ServiceCollectionExtensions.AddHealthMonitoring</c>
/// <c>ZB.MOM.WW.ScadaBridge.HealthMonitoring.ServiceCollectionExtensions.AddHealthMonitoring</c>
/// or <c>AddSiteHealthMonitoring</c> (registers the
/// <see cref="ISiteHealthCollector"/> the bridges depend on). Resolving
/// <see cref="IAuditWriteFailureCounter"/> or
@@ -1,9 +1,9 @@
using Microsoft.Extensions.Logging;
using ScadaLink.AuditLog.Payload;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Composes the primary <see cref="SqliteAuditWriter"/> with a drop-oldest
@@ -1,7 +1,7 @@
using ScadaLink.AuditLog.Payload;
using ScadaLink.HealthMonitoring;
using ZB.MOM.WW.ScadaBridge.AuditLog.Payload;
using ZB.MOM.WW.ScadaBridge.HealthMonitoring;
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Audit Log (#23) M5 Bundle C — bridges
@@ -1,6 +1,6 @@
using ScadaLink.HealthMonitoring;
using ZB.MOM.WW.ScadaBridge.HealthMonitoring;
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Audit Log (#23) M2 Bundle G — bridges <see cref="IAuditWriteFailureCounter"/>
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Lightweight counter sink invoked by <see cref="FallbackAuditWriter"/> every
@@ -1,8 +1,8 @@
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Default <see cref="IAuditWriteFailureCounter"/> registered by
/// <see cref="ScadaLink.AuditLog.ServiceCollectionExtensions.AddAuditLog"/> on
/// <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.ServiceCollectionExtensions.AddAuditLog"/> on
/// every node. Bundle G replaces this binding with a real counter that bridges
/// into the Site Health Monitoring report payload as
/// <c>SiteAuditWriteFailures</c> — until then,
@@ -1,8 +1,8 @@
using System.Runtime.CompilerServices;
using System.Threading.Channels;
using ScadaLink.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Drop-oldest in-memory ring buffer used by <see cref="FallbackAuditWriter"/>
@@ -1,9 +1,9 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ScadaLink.Commons.Interfaces.Services;
using ScadaLink.HealthMonitoring;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.HealthMonitoring;
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Audit Log (#23) M6 Bundle E (T6) — site-side hosted service that
@@ -25,14 +25,14 @@ namespace ScadaLink.AuditLog.Site;
/// <b>Cadence.</b> 30 s by default — coarse enough to amortise the SQL probe
/// across many reports, fine enough that the central dashboard never lags by
/// more than one health-report interval. Tunable via
/// <see cref="ScadaLink.AuditLog.Site.SqliteAuditWriterOptions"/> in a follow-up
/// <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Site.SqliteAuditWriterOptions"/> in a follow-up
/// if ops needs a different cadence; for M6 we hard-code the value because the
/// brief calls it out explicitly.
/// </para>
/// <para>
/// <b>Failure containment.</b> The probe call is wrapped in a try/catch so a
/// transient SQLite error never tears down the hosted service — the next tick
/// retries. Mirrors <see cref="ScadaLink.AuditLog.Central.AuditLogPartitionMaintenanceService"/>'s
/// retries. Mirrors <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.Central.AuditLogPartitionMaintenanceService"/>'s
/// "exception logged, not propagated" contract.
/// </para>
/// </remarks>
@@ -2,16 +2,16 @@ using System.Threading.Channels;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces.Services;
using ScadaLink.Commons.Types;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Site-side SQLite hot-path writer for Audit Log (#23) events. Mirrors the
/// <see cref="ScadaLink.SiteEventLogging.SiteEventLogger"/> design — a single
/// <see cref="ZB.MOM.WW.ScadaBridge.SiteEventLogging.SiteEventLogger"/> design — a single
/// owned <see cref="SqliteConnection"/> serialised behind a write lock, fed by a
/// bounded <see cref="Channel{T}"/> drained on a dedicated background writer
/// task — so script-thread callers never block on disk I/O.
@@ -1,8 +1,8 @@
namespace ScadaLink.AuditLog.Site;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// <summary>
/// Options for the site-side SQLite hot-path audit writer.
/// Mirrors the ScadaLink.SiteEventLogging pattern: a single SQLite connection
/// Mirrors the ZB.MOM.WW.ScadaBridge.SiteEventLogging pattern: a single SQLite connection
/// fed by a background writer task draining a bounded
/// <see cref="System.Threading.Channels.Channel{T}"/> so script-thread enqueues
/// never block on disk I/O.
@@ -1,11 +1,11 @@
using Microsoft.Extensions.Logging;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces.Services;
using ScadaLink.Commons.Messages.Integration;
using ScadaLink.Commons.Types;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Integration;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.AuditLog.Site.Telemetry;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
/// <summary>
/// Audit Log #23 (M3 Bundle E — Tasks E4/E5): translates per-attempt
@@ -1,12 +1,12 @@
using Microsoft.Extensions.Logging;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces;
using ScadaLink.Commons.Interfaces.Services;
using ScadaLink.Commons.Messages.Integration;
using ScadaLink.Commons.Types;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Integration;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.AuditLog.Site.Telemetry;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
/// <summary>
/// Site-side dual emitter for cached-call lifecycle telemetry (Audit Log #23 /
@@ -1,9 +1,9 @@
using Akka.Actor;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Messages.Audit;
using ScadaLink.Communication.Grpc;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Audit;
using ZB.MOM.WW.ScadaBridge.Communication.Grpc;
namespace ScadaLink.AuditLog.Site.Telemetry;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
/// <summary>
/// Production <see cref="ISiteStreamAuditClient"/> binding for site composition
@@ -1,6 +1,6 @@
using ScadaLink.Communication.Grpc;
using ZB.MOM.WW.ScadaBridge.Communication.Grpc;
namespace ScadaLink.AuditLog.Site.Telemetry;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
/// <summary>
/// Mockable abstraction over the central site-audit push surface that
@@ -17,7 +17,7 @@ public interface ISiteStreamAuditClient
/// Forwards <paramref name="batch"/> to the central audit-ingest path. The
/// returned <see cref="IngestAck"/> carries the <c>accepted_event_ids</c>
/// the actor will flip to
/// <see cref="ScadaLink.Commons.Types.Enums.AuditForwardState.Forwarded"/>
/// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Types.Enums.AuditForwardState.Forwarded"/>
/// in the site SQLite queue.
/// </summary>
/// <param name="batch">The batch of audit events to forward.</param>
@@ -31,7 +31,7 @@ public interface ISiteStreamAuditClient
/// in a single MS SQL transaction. Returns the same <see cref="IngestAck"/>
/// shape as <see cref="IngestAuditEventsAsync"/> so the site-side forwarder
/// can flip the underlying audit rows to
/// <see cref="ScadaLink.Commons.Types.Enums.AuditForwardState.Forwarded"/>
/// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Types.Enums.AuditForwardState.Forwarded"/>
/// once central has acknowledged them.
/// </summary>
/// <remarks>
@@ -1,10 +1,10 @@
using ScadaLink.Communication.Grpc;
using ZB.MOM.WW.ScadaBridge.Communication.Grpc;
namespace ScadaLink.AuditLog.Site.Telemetry;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
/// <summary>
/// Default <see cref="ISiteStreamAuditClient"/> registered by
/// <see cref="ScadaLink.AuditLog.ServiceCollectionExtensions.AddAuditLog"/>.
/// <see cref="ZB.MOM.WW.ScadaBridge.AuditLog.ServiceCollectionExtensions.AddAuditLog"/>.
/// It is a no-op binding for composition roots that have no
/// <c>SiteCommunicationActor</c> — central and test roots. Site roles override
/// it in the Host with the ClusterClient-based
@@ -2,13 +2,13 @@ using Akka.Actor;
using Google.Protobuf.WellKnownTypes;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Interfaces;
using ScadaLink.Commons.Interfaces.Services;
using ScadaLink.Commons.Types;
using ScadaLink.Communication.Grpc;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Types;
using ZB.MOM.WW.ScadaBridge.Communication.Grpc;
namespace ScadaLink.AuditLog.Site.Telemetry;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
/// <summary>
/// Site-side actor that drains the local SQLite audit queue and pushes Pending
@@ -1,4 +1,4 @@
namespace ScadaLink.AuditLog.Site.Telemetry;
namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site.Telemetry;
/// <summary>
/// Tuning knobs for the site-side <see cref="SiteAuditTelemetryActor"/> drain
@@ -8,7 +8,7 @@ namespace ScadaLink.AuditLog.Site.Telemetry;
public sealed class SiteAuditTelemetryOptions
{
/// <summary>
/// Maximum number of <see cref="ScadaLink.Commons.Entities.Audit.AuditEvent"/>
/// Maximum number of <see cref="ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit.AuditEvent"/>
/// rows read from the site SQLite queue and pushed in a single gRPC batch.
/// </summary>
public int BatchSize { get; set; } = 256;
@@ -19,17 +19,17 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../ScadaLink.Commons/ScadaLink.Commons.csproj" />
<ProjectReference Include="../ZB.MOM.WW.ScadaBridge.Commons/ZB.MOM.WW.ScadaBridge.Commons.csproj" />
<!-- Audit Log (#23) sits alongside Notification Outbox (#21) and Site Call Audit (#22).
IAuditLogRepository is registered by ScadaLink.ConfigurationDatabase; the project
IAuditLogRepository is registered by ZB.MOM.WW.ScadaBridge.ConfigurationDatabase; the project
reference is documented here so M2 writers + telemetry actors can depend on it. -->
<ProjectReference Include="../ScadaLink.ConfigurationDatabase/ScadaLink.ConfigurationDatabase.csproj" />
<ProjectReference Include="../ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.csproj" />
<!-- Communication carries the IngestAuditEvents proto + DTOs (#23 M2 site sync). -->
<ProjectReference Include="../ScadaLink.Communication/ScadaLink.Communication.csproj" />
<ProjectReference Include="../ZB.MOM.WW.ScadaBridge.Communication/ZB.MOM.WW.ScadaBridge.Communication.csproj" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="ScadaLink.AuditLog.Tests" />
<InternalsVisibleTo Include="ZB.MOM.WW.ScadaBridge.AuditLog.Tests" />
</ItemGroup>
</Project>
@@ -1,13 +1,13 @@
using System.Text.Json;
namespace ScadaLink.CLI;
namespace ZB.MOM.WW.ScadaBridge.CLI;
/// <summary>
/// Resolved CLI configuration combining config file values, environment variable overrides, and per-invocation credentials.
/// </summary>
public class CliConfig
{
/// <summary>Base URL of the ScadaLink Management API (e.g. http://localhost:9000).</summary>
/// <summary>Base URL of the ScadaBridge Management API (e.g. http://localhost:9000).</summary>
public string? ManagementUrl { get; set; }
/// <summary>Default output format for CLI commands; defaults to "json".</summary>
public string DefaultFormat { get; set; } = "json";
@@ -37,7 +37,7 @@ public class CliConfig
// Load from config file
var configPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".scadalink", "config.json");
".scadabridge", "config.json");
if (File.Exists(configPath))
{
// CLI-021: a malformed (`JsonException`), unreadable
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class ApiMethodCommands
{
@@ -1,7 +1,7 @@
using System.CommandLine;
using System.CommandLine.Parsing;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Resolved Management API connection details for an <c>audit</c> subcommand, or an
@@ -76,7 +76,7 @@ public static class AuditCommandHelpers
if (string.IsNullOrWhiteSpace(url))
{
return AuditConnection.Fail(
"No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadalink/config.json.",
"No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.",
"NO_URL");
}
@@ -1,10 +1,10 @@
using System.CommandLine;
using System.CommandLine.Parsing;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// The <c>scadalink audit</c> command group (Audit Log #23 M8). Provides read access to
/// The <c>scadabridge audit</c> command group (Audit Log #23 M8). Provides read access to
/// the centralized append-only Audit Log via the Bundle B REST endpoints
/// (<c>GET /api/audit/query</c>, <c>GET /api/audit/export</c>), plus a v1 no-op
/// <c>verify-chain</c> placeholder for the deferred hash-chain tamper-evidence feature.
@@ -2,7 +2,7 @@ using System.Globalization;
using System.Net;
using System.Text.Json;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Filter + destination arguments for an <c>audit export</c> invocation. Mirrors the
@@ -1,6 +1,6 @@
using System.Text.Json;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Renders a page of audit-log events to a writer. The <c>audit query</c> command picks
@@ -1,17 +1,17 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// The <c>scadalink audit-config</c> command group: views the configuration-change
/// The <c>scadabridge audit-config</c> command group: views the configuration-change
/// audit log (the <c>IAuditService</c> trail of admin edits — distinct from the
/// centralized append-only Audit Log served by <see cref="AuditCommands"/>).
/// </summary>
/// <remarks>
/// Renamed from <c>audit-log</c> in #23 M8-T7 to avoid confusion with the new
/// <c>scadalink audit</c> group. The old <c>audit-log</c> name is retained as a
/// <c>scadabridge audit</c> group. The old <c>audit-log</c> name is retained as a
/// deprecated alias; <see cref="DeprecatedAlias"/> still resolves the full subcommand
/// tree, and <c>Program.cs</c> prints a deprecation warning when it is used.
/// </remarks>
@@ -3,7 +3,7 @@ using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Filter arguments for an <c>audit query</c> invocation. Mirrors the Bundle B
@@ -1,6 +1,6 @@
using System.Globalization;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Helpers for the <c>audit verify-chain</c> subcommand. v1 is a no-op: hash-chain
@@ -1,9 +1,9 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using System.Text.Json;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Transport (#24) bundle export / preview / import. The bundle bytes travel
@@ -1,6 +1,6 @@
using System.CommandLine;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Factory methods for the global CLI options. Centralising option construction keeps
@@ -1,9 +1,9 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using System.Text.Json;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
internal static class CommandHelpers
{
@@ -51,7 +51,7 @@ internal static class CommandHelpers
if (string.IsNullOrWhiteSpace(url))
{
OutputFormatter.WriteError(
"No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadalink/config.json.",
"No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.",
"NO_URL");
return 1;
}
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class DataConnectionCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// CLI commands for managing database connection definitions.
@@ -4,9 +4,9 @@ using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Microsoft.AspNetCore.SignalR.Client;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class DebugCommands
{
@@ -57,7 +57,7 @@ public static class DebugCommands
if (string.IsNullOrWhiteSpace(url))
{
OutputFormatter.WriteError(
"No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadalink/config.json.",
"No management URL specified. Use --url, set SCADALINK_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.",
"NO_URL");
return 1;
}
@@ -1,4 +1,4 @@
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Pure, testable helpers for the <c>debug stream</c> command. The SignalR-driven
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class DeployCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class ExternalSystemCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class HealthCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class InstanceCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class NotificationCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class SecurityCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class SharedScriptCommands
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class SiteCommands
{
@@ -1,6 +1,6 @@
using System.Text.Json;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Human-readable table formatter for <c>audit query --format table</c> (Audit Log
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.Commons.Messages.Management;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ScadaLink.CLI.Commands;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
public static class TemplateCommands
{
@@ -2,7 +2,7 @@ using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
namespace ScadaLink.CLI;
namespace ZB.MOM.WW.ScadaBridge.CLI;
public class ManagementHttpClient : IDisposable
{
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ScadaLink.CLI;
namespace ZB.MOM.WW.ScadaBridge.CLI;
public static class OutputFormatter
{
@@ -1,8 +1,8 @@
using System.CommandLine;
using System.CommandLine.Parsing;
using ScadaLink.CLI.Commands;
using ZB.MOM.WW.ScadaBridge.CLI.Commands;
var rootCommand = new RootCommand("ScadaLink CLI — manage the ScadaLink SCADA system");
var rootCommand = new RootCommand("ScadaBridge CLI — manage the ScadaBridge SCADA system");
var urlOption = new Option<string>("--url") { Description = "Management API URL", Recursive = true };
var usernameOption = new Option<string>("--username") { Description = "LDAP username", Recursive = true };
@@ -1,14 +1,14 @@
# ScadaLink CLI
# ScadaBridge CLI
Command-line tool for managing the ScadaLink SCADA system. Connects to a Central node via HTTP and routes commands through the Management API endpoint (`POST /management`), which dispatches to the ManagementActor. Authentication is handled server-side via LDAP.
Command-line tool for managing the ScadaBridge SCADA system. Connects to a Central node via HTTP and routes commands through the Management API endpoint (`POST /management`), which dispatches to the ManagementActor. Authentication is handled server-side via LDAP.
## Installation
```sh
dotnet build src/ScadaLink.CLI
dotnet build src/ZB.MOM.WW.ScadaBridge.CLI
```
The output binary is `scadalink` (or `scadalink.exe` on Windows).
The output binary is `scadabridge` (or `scadabridge.exe` on Windows).
## Connection
@@ -16,16 +16,16 @@ Every command requires a connection to a running Central node. The management UR
1. `--url` flag on the command line
2. `SCADALINK_MANAGEMENT_URL` environment variable
3. `managementUrl` field in `~/.scadalink/config.json`
3. `managementUrl` field in `~/.scadabridge/config.json`
```sh
scadalink --url http://central-host:5000 <command>
scadabridge --url http://central-host:5000 <command>
```
**Docker:** With the Docker setup, the Central UI (and management API) is available at `http://localhost:9001`:
```sh
scadalink --url http://localhost:9001 <command>
scadabridge --url http://localhost:9001 <command>
```
For HA failover, use a load balancer URL. The management API is stateless (Basic Auth per request), so any central node can handle any request without sticky sessions.
@@ -43,7 +43,7 @@ These options are accepted by the root command and inherited by all subcommands.
## Configuration File
`~/.scadalink/config.json` is loaded at startup. All fields are optional.
`~/.scadabridge/config.json` is loaded at startup. All fields are optional.
```json
{
@@ -89,7 +89,7 @@ Exit codes:
List all templates with their full attribute, alarm, script, and composition definitions.
```sh
scadalink --url <url> template list
scadabridge --url <url> template list
```
#### `template get`
@@ -97,7 +97,7 @@ scadalink --url <url> template list
Get a single template by ID.
```sh
scadalink --url <url> template get --id <int>
scadabridge --url <url> template get --id <int>
```
| Option | Required | Description |
@@ -109,7 +109,7 @@ scadalink --url <url> template get --id <int>
Create a new template, optionally inheriting from a parent.
```sh
scadalink --url <url> template create --name <string> [--description <string>] [--parent-id <int>]
scadabridge --url <url> template create --name <string> [--description <string>] [--parent-id <int>]
```
| Option | Required | Description |
@@ -125,7 +125,7 @@ field below must be supplied with the value it should have after the update, eve
it is unchanged.
```sh
scadalink --url <url> template update --id <int> --name <string> [--description <string>] [--parent-id <int>]
scadabridge --url <url> template update --id <int> --name <string> [--description <string>] [--parent-id <int>]
```
| Option | Required | Description |
@@ -140,7 +140,7 @@ scadalink --url <url> template update --id <int> --name <string> [--description
Delete a template by ID.
```sh
scadalink --url <url> template delete --id <int>
scadabridge --url <url> template delete --id <int>
```
| Option | Required | Description |
@@ -152,7 +152,7 @@ scadalink --url <url> template delete --id <int>
Run pre-deployment validation on a template (flattening, naming collisions, script compilation).
```sh
scadalink --url <url> template validate --id <int>
scadabridge --url <url> template validate --id <int>
```
| Option | Required | Description |
@@ -164,7 +164,7 @@ scadalink --url <url> template validate --id <int>
Add an attribute to a template.
```sh
scadalink --url <url> template attribute add --template-id <int> --name <string> --data-type <string> [--default-value <string>] [--tag-path <string>]
scadabridge --url <url> template attribute add --template-id <int> --name <string> --data-type <string> [--default-value <string>] [--tag-path <string>]
```
| Option | Required | Description |
@@ -180,7 +180,7 @@ scadalink --url <url> template attribute add --template-id <int> --name <string>
Update an attribute on a template.
```sh
scadalink --url <url> template attribute update --template-id <int> --name <string> [--data-type <string>] [--default-value <string>] [--tag-path <string>]
scadabridge --url <url> template attribute update --template-id <int> --name <string> [--data-type <string>] [--default-value <string>] [--tag-path <string>]
```
| Option | Required | Description |
@@ -196,7 +196,7 @@ scadalink --url <url> template attribute update --template-id <int> --name <stri
Remove an attribute from a template.
```sh
scadalink --url <url> template attribute delete --template-id <int> --name <string>
scadabridge --url <url> template attribute delete --template-id <int> --name <string>
```
| Option | Required | Description |
@@ -209,7 +209,7 @@ scadalink --url <url> template attribute delete --template-id <int> --name <stri
Add an alarm definition to a template.
```sh
scadalink --url <url> template alarm add --template-id <int> --name <string> --trigger-attribute <string> --condition <string> --setpoint <string> [--severity <string>] [--notification-list <string>]
scadabridge --url <url> template alarm add --template-id <int> --name <string> --trigger-attribute <string> --condition <string> --setpoint <string> [--severity <string>] [--notification-list <string>]
```
| Option | Required | Description |
@@ -227,7 +227,7 @@ scadalink --url <url> template alarm add --template-id <int> --name <string> --t
Update an alarm definition on a template.
```sh
scadalink --url <url> template alarm update --template-id <int> --name <string> [--condition <string>] [--setpoint <string>] [--severity <string>] [--notification-list <string>]
scadabridge --url <url> template alarm update --template-id <int> --name <string> [--condition <string>] [--setpoint <string>] [--severity <string>] [--notification-list <string>]
```
| Option | Required | Description |
@@ -244,7 +244,7 @@ scadalink --url <url> template alarm update --template-id <int> --name <string>
Remove an alarm definition from a template.
```sh
scadalink --url <url> template alarm delete --template-id <int> --name <string>
scadabridge --url <url> template alarm delete --template-id <int> --name <string>
```
| Option | Required | Description |
@@ -257,7 +257,7 @@ scadalink --url <url> template alarm delete --template-id <int> --name <string>
Add a script to a template.
```sh
scadalink --url <url> template script add --template-id <int> --name <string> --trigger-type <string> [--trigger-attribute <string>] [--interval <int>] --code <string>
scadabridge --url <url> template script add --template-id <int> --name <string> --trigger-type <string> [--trigger-attribute <string>] [--interval <int>] --code <string>
```
| Option | Required | Description |
@@ -274,7 +274,7 @@ scadalink --url <url> template script add --template-id <int> --name <string> --
Update a script on a template.
```sh
scadalink --url <url> template script update --template-id <int> --name <string> [--trigger-type <string>] [--trigger-attribute <string>] [--interval <int>] [--code <string>]
scadabridge --url <url> template script update --template-id <int> --name <string> [--trigger-type <string>] [--trigger-attribute <string>] [--interval <int>] [--code <string>]
```
| Option | Required | Description |
@@ -291,7 +291,7 @@ scadalink --url <url> template script update --template-id <int> --name <string>
Remove a script from a template.
```sh
scadalink --url <url> template script delete --template-id <int> --name <string>
scadabridge --url <url> template script delete --template-id <int> --name <string>
```
| Option | Required | Description |
@@ -304,7 +304,7 @@ scadalink --url <url> template script delete --template-id <int> --name <string>
Add a feature module composition to a template.
```sh
scadalink --url <url> template composition add --template-id <int> --module-template-id <int> --instance-name <string>
scadabridge --url <url> template composition add --template-id <int> --module-template-id <int> --instance-name <string>
```
| Option | Required | Description |
@@ -318,7 +318,7 @@ scadalink --url <url> template composition add --template-id <int> --module-temp
Remove a feature module composition from a template, identified by its own composition ID.
```sh
scadalink --url <url> template composition delete --id <int>
scadabridge --url <url> template composition delete --id <int>
```
| Option | Required | Description |
@@ -334,7 +334,7 @@ scadalink --url <url> template composition delete --id <int>
Get a single instance by ID.
```sh
scadalink --url <url> instance get --id <int>
scadabridge --url <url> instance get --id <int>
```
| Option | Required | Description |
@@ -346,7 +346,7 @@ scadalink --url <url> instance get --id <int>
List instances, with optional filters.
```sh
scadalink --url <url> instance list [--site-id <int>] [--template-id <int>] [--search <string>]
scadabridge --url <url> instance list [--site-id <int>] [--template-id <int>] [--search <string>]
```
| Option | Required | Description |
@@ -360,7 +360,7 @@ scadalink --url <url> instance list [--site-id <int>] [--template-id <int>] [--s
Create a new instance of a template at a site.
```sh
scadalink --url <url> instance create --name <string> --template-id <int> --site-id <int> [--area-id <int>]
scadabridge --url <url> instance create --name <string> --template-id <int> --site-id <int> [--area-id <int>]
```
| Option | Required | Description |
@@ -375,7 +375,7 @@ scadalink --url <url> instance create --name <string> --template-id <int> --site
Deploy an instance to its site. Acquires the per-instance operation lock.
```sh
scadalink --url <url> instance deploy --id <int>
scadabridge --url <url> instance deploy --id <int>
```
| Option | Required | Description |
@@ -387,7 +387,7 @@ scadalink --url <url> instance deploy --id <int>
Enable a previously disabled instance.
```sh
scadalink --url <url> instance enable --id <int>
scadabridge --url <url> instance enable --id <int>
```
| Option | Required | Description |
@@ -399,7 +399,7 @@ scadalink --url <url> instance enable --id <int>
Disable a running instance without deleting it.
```sh
scadalink --url <url> instance disable --id <int>
scadabridge --url <url> instance disable --id <int>
```
| Option | Required | Description |
@@ -411,7 +411,7 @@ scadalink --url <url> instance disable --id <int>
Delete an instance. The instance must be disabled first.
```sh
scadalink --url <url> instance delete --id <int>
scadabridge --url <url> instance delete --id <int>
```
| Option | Required | Description |
@@ -423,7 +423,7 @@ scadalink --url <url> instance delete --id <int>
Set data connection bindings for an instance's attributes.
```sh
scadalink --url <url> instance set-bindings --id <int> --bindings <json>
scadabridge --url <url> instance set-bindings --id <int> --bindings <json>
```
| Option | Required | Description |
@@ -440,7 +440,7 @@ scadalink --url <url> instance set-bindings --id <int> --bindings <json>
Get a single site by ID.
```sh
scadalink --url <url> site get --id <int>
scadabridge --url <url> site get --id <int>
```
| Option | Required | Description |
@@ -452,7 +452,7 @@ scadalink --url <url> site get --id <int>
List all registered sites.
```sh
scadalink --url <url> site list
scadabridge --url <url> site list
```
#### `site create`
@@ -460,7 +460,7 @@ scadalink --url <url> site list
Register a new site.
```sh
scadalink --url <url> site create --name <string> --identifier <string> [--description <string>]
scadabridge --url <url> site create --name <string> --identifier <string> [--description <string>]
```
| Option | Required | Description |
@@ -474,7 +474,7 @@ scadalink --url <url> site create --name <string> --identifier <string> [--descr
Delete a site. Fails if any instances are assigned to it.
```sh
scadalink --url <url> site delete --id <int>
scadabridge --url <url> site delete --id <int>
```
| Option | Required | Description |
@@ -486,7 +486,7 @@ scadalink --url <url> site delete --id <int>
Push compiled artifacts to one or all sites.
```sh
scadalink --url <url> site deploy-artifacts [--site-id <int>]
scadabridge --url <url> site deploy-artifacts [--site-id <int>]
```
| Option | Required | Description |
@@ -498,7 +498,7 @@ scadalink --url <url> site deploy-artifacts [--site-id <int>]
List all areas for a site.
```sh
scadalink --url <url> site area list --site-id <int>
scadabridge --url <url> site area list --site-id <int>
```
| Option | Required | Description |
@@ -510,7 +510,7 @@ scadalink --url <url> site area list --site-id <int>
Create an area within a site.
```sh
scadalink --url <url> site area create --site-id <int> --name <string> [--parent-area-id <int>]
scadabridge --url <url> site area create --site-id <int> --name <string> [--parent-area-id <int>]
```
| Option | Required | Description |
@@ -525,7 +525,7 @@ Update an area's name. An update **replaces** the whole entity — the required
below must be supplied, even if unchanged.
```sh
scadalink --url <url> site area update --id <int> --name <string>
scadabridge --url <url> site area update --id <int> --name <string>
```
| Option | Required | Description |
@@ -538,7 +538,7 @@ scadalink --url <url> site area update --id <int> --name <string>
Delete an area. Fails if any instances are assigned to it.
```sh
scadalink --url <url> site area delete --id <int>
scadabridge --url <url> site area delete --id <int>
```
| Option | Required | Description |
@@ -554,7 +554,7 @@ scadalink --url <url> site area delete --id <int>
Deploy a single instance (same as `instance deploy`).
```sh
scadalink --url <url> deploy instance --id <int>
scadabridge --url <url> deploy instance --id <int>
```
| Option | Required | Description |
@@ -566,7 +566,7 @@ scadalink --url <url> deploy instance --id <int>
Deploy compiled artifacts to one or all sites (same as `site deploy-artifacts`).
```sh
scadalink --url <url> deploy artifacts [--site-id <int>]
scadabridge --url <url> deploy artifacts [--site-id <int>]
```
| Option | Required | Description |
@@ -578,7 +578,7 @@ scadalink --url <url> deploy artifacts [--site-id <int>]
Query deployment records, with optional filters and pagination.
```sh
scadalink --url <url> deploy status [--instance-id <int>] [--status <string>] [--page <int>] [--page-size <int>]
scadabridge --url <url> deploy status [--instance-id <int>] [--status <string>] [--page <int>] [--page-size <int>]
```
| Option | Required | Default | Description |
@@ -597,7 +597,7 @@ scadalink --url <url> deploy status [--instance-id <int>] [--status <string>] [-
Get a single data connection by ID.
```sh
scadalink --url <url> data-connection get --id <int>
scadabridge --url <url> data-connection get --id <int>
```
| Option | Required | Description |
@@ -609,7 +609,7 @@ scadalink --url <url> data-connection get --id <int>
List data connections, optionally filtered by site.
```sh
scadalink --url <url> data-connection list [--site-id <int>]
scadabridge --url <url> data-connection list [--site-id <int>]
```
| Option | Required | Description |
@@ -621,7 +621,7 @@ scadalink --url <url> data-connection list [--site-id <int>]
Create a new data connection belonging to a specific site.
```sh
scadalink --url <url> data-connection create --site-id <int> --name <string> --protocol <string> [--primary-config <json>] [--backup-config <json>] [--failover-retry-count <int>]
scadabridge --url <url> data-connection create --site-id <int> --name <string> --protocol <string> [--primary-config <json>] [--backup-config <json>] [--failover-retry-count <int>]
```
| Option | Required | Description |
@@ -639,7 +639,7 @@ Update a data connection definition. An update **replaces** the whole entity —
required field below must be supplied, even if unchanged.
```sh
scadalink --url <url> data-connection update --id <int> --name <string> --protocol <string> [--primary-config <json>] [--backup-config <json>] [--failover-retry-count <int>]
scadabridge --url <url> data-connection update --id <int> --name <string> --protocol <string> [--primary-config <json>] [--backup-config <json>] [--failover-retry-count <int>]
```
| Option | Required | Description |
@@ -656,7 +656,7 @@ scadalink --url <url> data-connection update --id <int> --name <string> --protoc
Delete a data connection.
```sh
scadalink --url <url> data-connection delete --id <int>
scadabridge --url <url> data-connection delete --id <int>
```
| Option | Required | Description |
@@ -672,7 +672,7 @@ scadalink --url <url> data-connection delete --id <int>
Get a single external system definition by ID.
```sh
scadalink --url <url> external-system get --id <int>
scadabridge --url <url> external-system get --id <int>
```
| Option | Required | Description |
@@ -684,7 +684,7 @@ scadalink --url <url> external-system get --id <int>
List all external system definitions.
```sh
scadalink --url <url> external-system list
scadabridge --url <url> external-system list
```
#### `external-system create`
@@ -692,7 +692,7 @@ scadalink --url <url> external-system list
Register an external HTTP system that scripts can call.
```sh
scadalink --url <url> external-system create --name <string> --endpoint-url <url> --auth-type <string> [--auth-config <json>]
scadabridge --url <url> external-system create --name <string> --endpoint-url <url> --auth-type <string> [--auth-config <json>]
```
| Option | Required | Description |
@@ -708,7 +708,7 @@ Update an external system definition. An update **replaces** the whole entity
required field below must be supplied, even if unchanged.
```sh
scadalink --url <url> external-system update --id <int> --name <string> --endpoint-url <url> --auth-type <string> [--auth-config <json>]
scadabridge --url <url> external-system update --id <int> --name <string> --endpoint-url <url> --auth-type <string> [--auth-config <json>]
```
| Option | Required | Description |
@@ -724,7 +724,7 @@ scadalink --url <url> external-system update --id <int> --name <string> --endpoi
Delete an external system definition.
```sh
scadalink --url <url> external-system delete --id <int>
scadabridge --url <url> external-system delete --id <int>
```
| Option | Required | Description |
@@ -740,7 +740,7 @@ scadalink --url <url> external-system delete --id <int>
Get a single notification list by ID.
```sh
scadalink --url <url> notification get --id <int>
scadabridge --url <url> notification get --id <int>
```
| Option | Required | Description |
@@ -752,7 +752,7 @@ scadalink --url <url> notification get --id <int>
List all notification lists.
```sh
scadalink --url <url> notification list
scadabridge --url <url> notification list
```
#### `notification create`
@@ -760,7 +760,7 @@ scadalink --url <url> notification list
Create a notification list with one or more recipients.
```sh
scadalink --url <url> notification create --name <string> --emails <email1,email2,...>
scadabridge --url <url> notification create --name <string> --emails <email1,email2,...>
```
| Option | Required | Description |
@@ -774,7 +774,7 @@ Update a notification list. An update **replaces** the whole entity — every re
field below must be supplied, even if unchanged.
```sh
scadalink --url <url> notification update --id <int> --name <string> --emails <email1,email2,...>
scadabridge --url <url> notification update --id <int> --name <string> --emails <email1,email2,...>
```
| Option | Required | Description |
@@ -788,7 +788,7 @@ scadalink --url <url> notification update --id <int> --name <string> --emails <e
Delete a notification list.
```sh
scadalink --url <url> notification delete --id <int>
scadabridge --url <url> notification delete --id <int>
```
| Option | Required | Description |
@@ -800,7 +800,7 @@ scadalink --url <url> notification delete --id <int>
Show the current SMTP configuration.
```sh
scadalink --url <url> notification smtp list
scadabridge --url <url> notification smtp list
```
#### `notification smtp update`
@@ -808,7 +808,7 @@ scadalink --url <url> notification smtp list
Update the SMTP configuration.
```sh
scadalink --url <url> notification smtp update --host <string> --port <int> --auth-type <string> [--username <string>] [--password <string>] [--from-address <string>]
scadabridge --url <url> notification smtp update --host <string> --port <int> --auth-type <string> [--username <string>] [--password <string>] [--from-address <string>]
```
| Option | Required | Description |
@@ -829,7 +829,7 @@ scadalink --url <url> notification smtp update --host <string> --port <int> --au
List all inbound API keys.
```sh
scadalink --url <url> security api-key list
scadabridge --url <url> security api-key list
```
#### `security api-key create`
@@ -837,7 +837,7 @@ scadalink --url <url> security api-key list
Create a new inbound API key. The generated key value is returned in the response and not stored in plaintext — save it immediately.
```sh
scadalink --url <url> security api-key create --name <string>
scadabridge --url <url> security api-key create --name <string>
```
| Option | Required | Description |
@@ -849,7 +849,7 @@ scadalink --url <url> security api-key create --name <string>
Update an API key's name or enabled status.
```sh
scadalink --url <url> security api-key update --id <int> [--name <string>] [--enabled <bool>]
scadabridge --url <url> security api-key update --id <int> [--name <string>] [--enabled <bool>]
```
| Option | Required | Description |
@@ -863,7 +863,7 @@ scadalink --url <url> security api-key update --id <int> [--name <string>] [--en
Revoke and delete an API key.
```sh
scadalink --url <url> security api-key delete --id <int>
scadabridge --url <url> security api-key delete --id <int>
```
| Option | Required | Description |
@@ -875,21 +875,21 @@ scadalink --url <url> security api-key delete --id <int>
List all LDAP group → role mappings.
```sh
scadalink --url <url> security role-mapping list
scadabridge --url <url> security role-mapping list
```
#### `security role-mapping create`
Map an LDAP group to a ScadaLink role.
Map an LDAP group to a ScadaBridge role.
```sh
scadalink --url <url> security role-mapping create --ldap-group <string> --role <string>
scadabridge --url <url> security role-mapping create --ldap-group <string> --role <string>
```
| Option | Required | Description |
|--------|----------|-------------|
| `--ldap-group` | yes | LDAP group distinguished name or CN |
| `--role` | yes | ScadaLink role: `Admin`, `Design`, or `Deployment` |
| `--role` | yes | ScadaBridge role: `Admin`, `Design`, or `Deployment` |
#### `security role-mapping update`
@@ -897,21 +897,21 @@ Update an LDAP role mapping. An update **replaces** the whole entity — every r
field below must be supplied, even if unchanged.
```sh
scadalink --url <url> security role-mapping update --id <int> --ldap-group <string> --role <string>
scadabridge --url <url> security role-mapping update --id <int> --ldap-group <string> --role <string>
```
| Option | Required | Description |
|--------|----------|-------------|
| `--id` | yes | Mapping ID |
| `--ldap-group` | yes | LDAP group distinguished name or CN |
| `--role` | yes | ScadaLink role |
| `--role` | yes | ScadaBridge role |
#### `security role-mapping delete`
Remove an LDAP role mapping.
```sh
scadalink --url <url> security role-mapping delete --id <int>
scadabridge --url <url> security role-mapping delete --id <int>
```
| Option | Required | Description |
@@ -923,7 +923,7 @@ scadalink --url <url> security role-mapping delete --id <int>
List all site scope rules for role mappings.
```sh
scadalink --url <url> security scope-rule list [--role-mapping-id <int>]
scadabridge --url <url> security scope-rule list [--role-mapping-id <int>]
```
| Option | Required | Description |
@@ -935,7 +935,7 @@ scadalink --url <url> security scope-rule list [--role-mapping-id <int>]
Add a site scope rule to a role mapping, restricting it to a specific site.
```sh
scadalink --url <url> security scope-rule add --role-mapping-id <int> --site-id <int>
scadabridge --url <url> security scope-rule add --role-mapping-id <int> --site-id <int>
```
| Option | Required | Description |
@@ -948,7 +948,7 @@ scadalink --url <url> security scope-rule add --role-mapping-id <int> --site-id
Remove a site scope rule from a role mapping.
```sh
scadalink --url <url> security scope-rule delete --id <int>
scadabridge --url <url> security scope-rule delete --id <int>
```
| Option | Required | Description |
@@ -964,7 +964,7 @@ scadalink --url <url> security scope-rule delete --id <int>
Return the current health state for all known sites as a JSON object keyed by site identifier.
```sh
scadalink --url <url> health summary
scadabridge --url <url> health summary
```
#### `health site`
@@ -972,7 +972,7 @@ scadalink --url <url> health summary
Return the health state for a single site.
```sh
scadalink --url <url> health site --identifier <string>
scadabridge --url <url> health site --identifier <string>
```
| Option | Required | Description |
@@ -984,7 +984,7 @@ scadalink --url <url> health site --identifier <string>
Query the site event log for a specific site. Events are fetched remotely from the site's local SQLite store.
```sh
scadalink --url <url> health event-log --site-identifier <string> [--from <datetime>] [--to <datetime>] [--search <string>] [--page <int>] [--page-size <int>]
scadabridge --url <url> health event-log --site-identifier <string> [--from <datetime>] [--to <datetime>] [--search <string>] [--page <int>] [--page-size <int>]
```
| Option | Required | Default | Description |
@@ -1001,7 +1001,7 @@ scadalink --url <url> health event-log --site-identifier <string> [--from <datet
Query parked (dead-letter) messages at a specific site.
```sh
scadalink --url <url> health parked-messages --site-identifier <string> [--page <int>] [--page-size <int>]
scadabridge --url <url> health parked-messages --site-identifier <string> [--page <int>] [--page-size <int>]
```
| Option | Required | Default | Description |
@@ -1019,7 +1019,7 @@ scadalink --url <url> health parked-messages --site-identifier <string> [--page
Request a point-in-time snapshot of a running instance's current attribute values and alarm states from the site. The instance must be deployed and enabled.
```sh
scadalink --url <url> debug snapshot --id <int>
scadabridge --url <url> debug snapshot --id <int>
```
| Option | Required | Description |
@@ -1033,7 +1033,7 @@ The command resolves the instance's site internally and routes the request to th
Stream live attribute values and alarm state changes in real-time using a SignalR WebSocket connection to the central server's `/hubs/debug-stream` hub. Events are printed as they arrive. Press Ctrl+C to disconnect.
```sh
scadalink --url <url> debug stream --id <int>
scadabridge --url <url> debug stream --id <int>
```
| Option | Required | Description |
@@ -1071,7 +1071,7 @@ without the required role returns exit code `2`.
Query audit log events with optional filters and keyset pagination.
```sh
scadalink --url <url> audit query [options]
scadabridge --url <url> audit query [options]
```
| Option | Required | Default | Description |
@@ -1107,7 +1107,7 @@ Export audit log events to a file. The export streams from the server, so it is
bounded by the query page size.
```sh
scadalink --url <url> audit export --since <time> --until <time> --format <fmt> --output <path> [filters]
scadabridge --url <url> audit export --since <time> --until <time> --format <fmt> --output <path> [filters]
```
| Option | Required | Default | Description |
@@ -1132,7 +1132,7 @@ scadalink --url <url> audit export --since <time> --until <time> --format <fmt>
Verify the audit log hash chain for a given month.
```sh
scadalink --url <url> audit verify-chain --month <YYYY-MM>
scadabridge --url <url> audit verify-chain --month <YYYY-MM>
```
| Option | Required | Default | Description |
@@ -1154,7 +1154,7 @@ edits to templates, instances, sites, etc.). This is **separate** from the
centralized [`audit`](#audit--centralized-audit-log) group above.
> **Renamed.** This group was named `audit-log` before #23 M8. The old name still
> works as a deprecated alias — `scadalink audit-log query ...` resolves the full
> works as a deprecated alias — `scadabridge audit-log query ...` resolves the full
> subcommand tree unchanged — but prints a deprecation warning to stderr:
> `Warning: 'audit-log' is deprecated and will be removed in a future release. Use 'audit-config' instead.`
> Migrate scripts to `audit-config`; the `audit-log` alias will be removed in a
@@ -1165,7 +1165,7 @@ centralized [`audit`](#audit--centralized-audit-log) group above.
Query the configuration-change audit log with optional filters and pagination.
```sh
scadalink --url <url> audit-config query [options]
scadabridge --url <url> audit-config query [options]
```
| Option | Required | Default | Description |
@@ -1187,7 +1187,7 @@ scadalink --url <url> audit-config query [options]
List all shared script definitions.
```sh
scadalink --url <url> shared-script list
scadabridge --url <url> shared-script list
```
#### `shared-script get`
@@ -1195,7 +1195,7 @@ scadalink --url <url> shared-script list
Get a single shared script by ID.
```sh
scadalink --url <url> shared-script get --id <int>
scadabridge --url <url> shared-script get --id <int>
```
| Option | Required | Description |
@@ -1207,7 +1207,7 @@ scadalink --url <url> shared-script get --id <int>
Create a new shared script.
```sh
scadalink --url <url> shared-script create --name <string> --code <string>
scadabridge --url <url> shared-script create --name <string> --code <string>
```
| Option | Required | Description |
@@ -1221,7 +1221,7 @@ Update a shared script. An update **replaces** the whole entity — every requir
below must be supplied, even if unchanged.
```sh
scadalink --url <url> shared-script update --id <int> --name <string> --code <string> [--parameters <json>] [--return-def <json>]
scadabridge --url <url> shared-script update --id <int> --name <string> --code <string> [--parameters <json>] [--return-def <json>]
```
| Option | Required | Description |
@@ -1237,7 +1237,7 @@ scadalink --url <url> shared-script update --id <int> --name <string> --code <st
Delete a shared script.
```sh
scadalink --url <url> shared-script delete --id <int>
scadabridge --url <url> shared-script delete --id <int>
```
| Option | Required | Description |
@@ -1253,7 +1253,7 @@ scadalink --url <url> shared-script delete --id <int>
List all database connection definitions.
```sh
scadalink --url <url> db-connection list
scadabridge --url <url> db-connection list
```
#### `db-connection get`
@@ -1261,7 +1261,7 @@ scadalink --url <url> db-connection list
Get a single database connection by ID.
```sh
scadalink --url <url> db-connection get --id <int>
scadabridge --url <url> db-connection get --id <int>
```
| Option | Required | Description |
@@ -1273,7 +1273,7 @@ scadalink --url <url> db-connection get --id <int>
Create a new database connection definition.
```sh
scadalink --url <url> db-connection create --name <string> --connection-string <string> [--provider <string>]
scadabridge --url <url> db-connection create --name <string> --connection-string <string> [--provider <string>]
```
| Option | Required | Description |
@@ -1288,7 +1288,7 @@ Update a database connection definition. An update **replaces** the whole entity
every required field below must be supplied, even if unchanged.
```sh
scadalink --url <url> db-connection update --id <int> --name <string> --connection-string <string>
scadabridge --url <url> db-connection update --id <int> --name <string> --connection-string <string>
```
| Option | Required | Description |
@@ -1302,7 +1302,7 @@ scadalink --url <url> db-connection update --id <int> --name <string> --connecti
Delete a database connection definition.
```sh
scadalink --url <url> db-connection delete --id <int>
scadabridge --url <url> db-connection delete --id <int>
```
| Option | Required | Description |
@@ -1318,7 +1318,7 @@ scadalink --url <url> db-connection delete --id <int>
List all inbound API method definitions.
```sh
scadalink --url <url> api-method list
scadabridge --url <url> api-method list
```
#### `api-method get`
@@ -1326,7 +1326,7 @@ scadalink --url <url> api-method list
Get a single inbound API method by ID.
```sh
scadalink --url <url> api-method get --id <int>
scadabridge --url <url> api-method get --id <int>
```
| Option | Required | Description |
@@ -1338,7 +1338,7 @@ scadalink --url <url> api-method get --id <int>
Create a new inbound API method.
```sh
scadalink --url <url> api-method create --name <string> --code <string> [--description <string>]
scadabridge --url <url> api-method create --name <string> --code <string> [--description <string>]
```
| Option | Required | Description |
@@ -1353,7 +1353,7 @@ Update an inbound API method. An update **replaces** the whole entity — every
field below must be supplied, even if unchanged.
```sh
scadalink --url <url> api-method update --id <int> --script <string> [--timeout <int>] [--parameters <json>] [--return-def <json>]
scadabridge --url <url> api-method update --id <int> --script <string> [--timeout <int>] [--parameters <json>] [--return-def <json>]
```
| Option | Required | Default | Description |
@@ -1371,7 +1371,7 @@ Script changes take effect immediately — the updated code is recompiled in-mem
Delete an inbound API method.
```sh
scadalink --url <url> api-method delete --id <int>
scadabridge --url <url> api-method delete --id <int>
```
| Option | Required | Description |
@@ -1386,7 +1386,7 @@ The CLI connects to the Central cluster using Akka.NET's `ClusterClient`. It doe
The connection is established per-command invocation and torn down cleanly via `CoordinatedShutdown` when the command completes.
Role enforcement is applied by the ManagementActor on the server side. The CLI authenticates against LDAP using `--username` / `--password`, resolves LDAP group memberships, then maps groups to ScadaLink roles (Admin, Design, Deployment) via role mappings configured in the security settings. Operations require the appropriate role — for example, creating templates requires `Design`, deploying requires `Deployment`. In the test environment, use the `multi-role` user (password: `password`) which has all three roles.
Role enforcement is applied by the ManagementActor on the server side. The CLI authenticates against LDAP using `--username` / `--password`, resolves LDAP group memberships, then maps groups to ScadaBridge roles (Admin, Design, Deployment) via role mappings configured in the security settings. Operations require the appropriate role — for example, creating templates requires `Design`, deploying requires `Deployment`. In the test environment, use the `multi-role` user (password: `password`) which has all three roles.
## Issues & Missing Features
@@ -5,16 +5,16 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AssemblyName>scadalink</AssemblyName>
<AssemblyName>scadabridge</AssemblyName>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="ScadaLink.CLI.Tests" />
<InternalsVisibleTo Include="ZB.MOM.WW.ScadaBridge.CLI.Tests" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" />
<PackageReference Include="System.CommandLine" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../ScadaLink.Commons/ScadaLink.Commons.csproj" />
<ProjectReference Include="../ZB.MOM.WW.ScadaBridge.Commons/ZB.MOM.WW.ScadaBridge.Commons.csproj" />
</ItemGroup>
</Project>
@@ -3,19 +3,19 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using ScadaLink.CentralUI.Services;
using ScadaLink.Commons.Types.Audit;
using ScadaLink.Commons.Types.Enums;
using ScadaLink.Security;
using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Security;
namespace ScadaLink.CentralUI.Audit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Audit;
/// <summary>
/// Minimal-API endpoint hosting the Audit Log CSV export (#23 M7-T14 / Bundle F).
///
/// <para>
/// CentralUI ships no MVC controllers (see <see cref="ScadaLink.CentralUI.Auth.AuthEndpoints"/>
/// and <see cref="ScadaLink.CentralUI.ScriptAnalysis.ScriptAnalysisEndpoints"/>),
/// CentralUI ships no MVC controllers (see <see cref="ZB.MOM.WW.ScadaBridge.CentralUI.Auth.AuthEndpoints"/>
/// and <see cref="ZB.MOM.WW.ScadaBridge.CentralUI.ScriptAnalysis.ScriptAnalysisEndpoints"/>),
/// so the brief's "controller" is implemented as a minimal-API endpoint instead.
/// The endpoint streams to <c>Response.Body</c> directly so the export does NOT
/// buffer the full result set in memory — see
@@ -5,9 +5,9 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using ScadaLink.Security;
using ZB.MOM.WW.ScadaBridge.Security;
namespace ScadaLink.CentralUI.Auth;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
/// <summary>
/// Minimal API endpoints for login/logout. These run outside Blazor Server (standard HTTP POST).
@@ -49,7 +49,7 @@ public static class AuthEndpoints
// Build claims from LDAP auth + role mapping.
// CentralUI-005: no fixed "expires_at" absolute-cap claim is stamped
// — session expiry is owned by the cookie middleware's sliding window
// (ScadaLink.Security AddCookie: ExpireTimeSpan = idle timeout,
// (ZB.MOM.WW.ScadaBridge.Security AddCookie: ExpireTimeSpan = idle timeout,
// SlidingExpiration = true). A frozen absolute claim would contradict
// the documented sliding-refresh policy.
var claims = new List<Claim>
@@ -170,7 +170,7 @@ public static class AuthEndpoints
/// Builds the <see cref="AuthenticationProperties"/> for the login sign-in.
/// CentralUI-005: deliberately does <b>not</b> set <see cref="AuthenticationProperties.ExpiresUtc"/>.
/// Session expiry is owned by the cookie authentication middleware's sliding
/// window (configured in <c>ScadaLink.Security</c>'s <c>AddCookie</c>:
/// window (configured in <c>ZB.MOM.WW.ScadaBridge.Security</c>'s <c>AddCookie</c>:
/// <c>ExpireTimeSpan</c> = the idle timeout, <c>SlidingExpiration = true</c>).
/// Setting a fixed <c>ExpiresUtc</c> here would re-impose a hard absolute cap
/// that overrides the sliding window and contradicts the documented
@@ -1,8 +1,8 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;
using ScadaLink.Security;
using ZB.MOM.WW.ScadaBridge.Security;
namespace ScadaLink.CentralUI.Auth;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
/// <summary>
/// Claim-lookup helpers for the Central UI. CentralUI-024: claim types are owned
@@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
using Microsoft.AspNetCore.Http;
namespace ScadaLink.CentralUI.Auth;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
/// <summary>
/// Bridges ASP.NET Core cookie authentication with Blazor Server's auth state.
@@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Components.Authorization;
using ScadaLink.Commons.Entities.Sites;
using ScadaLink.Security;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites;
using ZB.MOM.WW.ScadaBridge.Security;
namespace ScadaLink.CentralUI.Auth;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
/// <summary>
/// Resolves the set of sites the current user is permitted to operate on, from
@@ -1,5 +1,5 @@
@using ScadaLink.Commons.Entities.Audit
@using ScadaLink.Commons.Types.Enums
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums
@* Audit Log drilldown drawer (#23 M7 Bundle C / M7-T4..T8).
Right-side Bootstrap offcanvas-style drawer hosted by the Audit Log page.
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Components;
using ScadaLink.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
namespace ScadaLink.CentralUI.Components.Audit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Audit;
/// <summary>
/// Child component for the central Audit Log page (#23 M7 Bundle C / M7-T4..T8).
@@ -1,5 +1,5 @@
@using ScadaLink.Commons.Entities.Audit
@using ScadaLink.Commons.Types.Enums
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums
@* Reusable single-AuditEvent detail body (#23 M7 Bundle C / M7-T4..T8).
Extracted from AuditDrilldownDrawer so the drawer and the execution-tree
@@ -3,10 +3,10 @@ using System.Text;
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.CentralUI.Components.Audit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Audit;
/// <summary>
/// Reusable single-<see cref="AuditEvent"/> detail body (#23 M7 Bundle C /
@@ -1,8 +1,8 @@
@using ScadaLink.CentralUI.Services
@using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories
@using ScadaLink.Commons.Types.Audit
@using ScadaLink.Commons.Types.Enums
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums
@inject ISiteRepository SiteRepository
@inject IAuditLogQueryService AuditLogQueryService
@@ -1,16 +1,16 @@
using Microsoft.AspNetCore.Components;
using ScadaLink.Commons.Entities.Sites;
using ScadaLink.Commons.Types.Audit;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.CentralUI.Components.Audit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Audit;
/// <summary>
/// Filter bar for the central Audit Log page (#23 M7-T2). Owns the
/// <see cref="AuditQueryModel"/> binding state and renders the filter controls
/// — Channel as a single-select (one channel at a time, so the Kind options
/// narrow to it cleanly); Kind / Status / Site as compact
/// <see cref="ScadaLink.CentralUI.Components.Shared.MultiSelectDropdown{TValue}"/>
/// <see cref="ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared.MultiSelectDropdown{TValue}"/>
/// controls; plus the time range, free-text searches and the Errors-only
/// toggle — and publishes an <see cref="AuditLogQueryFilter"/> via
/// <see cref="OnFilterChanged"/> when the user clicks Apply. The selected
@@ -34,7 +34,7 @@ public partial class AuditFilterBar
/// <summary>
/// Distinct <c>SourceNode</c> identifiers in display order; populated once
/// when the filter bar initialises from the cached
/// <see cref="ScadaLink.CentralUI.Services.IAuditLogQueryService.GetDistinctSourceNodesAsync"/>
/// <see cref="ZB.MOM.WW.ScadaBridge.CentralUI.Services.IAuditLogQueryService.GetDistinctSourceNodesAsync"/>
/// snapshot (60s TTL). Failure is non-fatal — the dropdown falls back to
/// "No nodes available", mirroring the site loader.
/// </summary>
@@ -43,7 +43,7 @@ public partial class AuditFilterBar
/// <summary>
/// Raised when the user clicks Apply. Carries the
/// <see cref="AuditLogQueryFilter"/> the parent page hands to
/// <see cref="ScadaLink.CentralUI.Services.IAuditLogQueryService"/>.
/// <see cref="ZB.MOM.WW.ScadaBridge.CentralUI.Services.IAuditLogQueryService"/>.
/// </summary>
[Parameter] public EventCallback<AuditLogQueryFilter> OnFilterChanged { get; set; }
@@ -1,8 +1,8 @@
using System.Collections.Immutable;
using ScadaLink.Commons.Types.Audit;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.CentralUI.Components.Audit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Audit;
/// <summary>
/// UI-side binding model for <see cref="AuditFilterBar"/> (#23 M7-T2).
@@ -1,8 +1,8 @@
@using ScadaLink.CentralUI.Components.Shared
@using ScadaLink.CentralUI.Services
@using ScadaLink.Commons.Entities.Audit
@using ScadaLink.Commons.Types.Audit
@using ScadaLink.Commons.Types.Enums
@using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums
@inject IAuditLogQueryService QueryService
<div data-test="audit-results-grid">
@@ -1,11 +1,11 @@
using System.Text.Json;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Types.Audit;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.CentralUI.Components.Audit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Audit;
/// <summary>
/// Keyset-paged results grid for the central Audit Log page (#23 M7-T3).
@@ -1,4 +1,4 @@
@using ScadaLink.Commons.Entities.Audit
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit
@* Execution-Tree Node Detail Modal (Task 3).
Opened from an execution-tree node double-click. Given an ExecutionId it
@@ -1,12 +1,12 @@
using System.Globalization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using ScadaLink.CentralUI.Services;
using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Types.Audit;
using ScadaLink.Commons.Types.Enums;
using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ScadaLink.CentralUI.Components.Audit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Audit;
/// <summary>
/// Execution-Tree Node Detail Modal (Execution-Tree Node Detail Modal feature,

Some files were not shown because too many files have changed in this diff Show More