feat(commons): ScriptTriggerAttribute — monitored attribute of a ValueChange/Conditional trigger (flow debugger script entry)

Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
Joseph Doherty
2026-09-08 01:07:38 -04:00
parent fefa3ffa77
commit 952b41f0f7
2 changed files with 95 additions and 0 deletions
@@ -0,0 +1,49 @@
using System.Text.Json;
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Scripts;
/// <summary>
/// Reads the single monitored attribute of a <c>ValueChange</c> or <c>Conditional</c> script
/// trigger (Flow Debugger script entry, design 2026-09-08 §2). The config keys are the ones the
/// Central UI's <c>ScriptTriggerConfigCodec</c> writes (<c>attributeName</c>) and SiteRuntime's
/// <c>TriggerRouting</c> also accepts (<c>attribute</c>). Pure; never throws on bad JSON.
/// </summary>
public static class ScriptTriggerAttribute
{
/// <summary>True for the trigger kinds the Flow Debugger fires by WRITING the monitored attribute.</summary>
public static bool IsWriteKind(string? triggerType) =>
string.Equals(triggerType, "ValueChange", StringComparison.OrdinalIgnoreCase)
|| string.Equals(triggerType, "Conditional", StringComparison.OrdinalIgnoreCase);
/// <summary>
/// Returns the monitored attribute for a write-kind trigger with a readable configuration;
/// false (and null) for every other kind, and for a write kind whose config is missing,
/// malformed, not an object, or names no attribute.
/// </summary>
public static bool TryRead(string? triggerType, string? triggerConfigurationJson, out string? attribute)
{
attribute = null;
if (!IsWriteKind(triggerType) || string.IsNullOrWhiteSpace(triggerConfigurationJson))
return false;
try
{
using var doc = JsonDocument.Parse(triggerConfigurationJson);
var root = doc.RootElement;
if (root.ValueKind != JsonValueKind.Object) return false;
foreach (var key in new[] { "attributeName", "attribute" })
{
if (root.TryGetProperty(key, out var v) && v.ValueKind == JsonValueKind.String
&& v.GetString() is { Length: > 0 } name)
{
attribute = name;
return true;
}
}
return false;
}
catch (JsonException)
{
return false;
}
}
}