feat(native-alarms): per-binding IsMesReportable on native alarm source bindings (ScadaBridge#59)

TemplateNativeAlarmSource.IsMesReportable + tri-state InstanceNativeAlarmSourceOverride
.IsMesReportableOverride flatten onto ResolvedNativeAlarmSource; NativeAlarmActor stamps every
mirrored condition and InstanceActor the quiet-binding placeholder, so ScriptAlarm,
Alarms.MesReportableAsync() and the #60 wire fields carry it. Additive to the 900-999 severity band.
Migration AddNativeAlarmSourceMesReportable. Management commands, CLI --mes-reportable, Central UI
(template dialog checkbox, instance override select), Transport DTOs/importer/diff and the revision
hash (true-only, so existing hashes are unchanged) carry it.

Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
Joseph Doherty
2026-11-09 15:09:54 -05:00
parent 69a2017000
commit f98369a786
38 changed files with 2579 additions and 43 deletions
@@ -651,9 +651,10 @@ public static class InstanceCommands
var setConnectionOption = new Option<string?>("--connection") { Description = "Connection name override (blank = inherited)" };
var setSourceRefOption = new Option<string?>("--source-ref") { Description = "Source reference override (blank = inherited)" };
var setFilterOption = new Option<string?>("--filter") { Description = "Condition filter override (blank = inherited)" };
var setMesOption = new Option<bool?>("--mes-reportable") { Description = "MES-reportable override for the binding: true or false; omit to inherit" };
var setCmd = new Command("set") { Description = "Set (upsert) a native alarm source override on an instance" };
setCmd.Add(setIdOption); setCmd.Add(setSourceOption); setCmd.Add(setConnectionOption);
setCmd.Add(setSourceRefOption); setCmd.Add(setFilterOption);
setCmd.Add(setSourceRefOption); setCmd.Add(setFilterOption); setCmd.Add(setMesOption);
setCmd.SetAction(async (ParseResult result) =>
{
return await CommandHelpers.ExecuteCommandAsync(
@@ -663,7 +664,8 @@ public static class InstanceCommands
result.GetValue(setSourceOption)!,
result.GetValue(setConnectionOption),
result.GetValue(setSourceRefOption),
result.GetValue(setFilterOption)));
result.GetValue(setFilterOption),
result.GetValue(setMesOption)));
});
group.Add(setCmd);
@@ -180,6 +180,7 @@ public static class TemplateCommands
var filterOption = new Option<string?>("--filter") { Description = "Condition filter; omit to clear and mirror all conditions" };
var descriptionOption = new Option<string?>("--description") { Description = "Description; omit to clear" };
var lockedOption = new Option<bool>("--locked") { Description = "Lock status; omit for unlocked" };
var mesOption = new Option<bool>("--mes-reportable") { Description = "Every condition under this binding is MES-reportable (additive to the 900-999 severity band); omit for false" };
var cmd = new Command("update") { Description = "Replace the fields of a native alarm source binding" };
cmd.Add(idOption);
cmd.Add(nameOption);
@@ -188,6 +189,7 @@ public static class TemplateCommands
cmd.Add(filterOption);
cmd.Add(descriptionOption);
cmd.Add(lockedOption);
cmd.Add(mesOption);
cmd.SetAction(async (ParseResult result) =>
{
return await CommandHelpers.ExecuteCommandAsync(
@@ -195,7 +197,8 @@ public static class TemplateCommands
new UpdateTemplateNativeAlarmSourceCommand(
result.GetValue(idOption), result.GetValue(nameOption)!,
result.GetValue(connectionOption)!, result.GetValue(sourceOption)!,
result.GetValue(filterOption), result.GetValue(descriptionOption), result.GetValue(lockedOption)));
result.GetValue(filterOption), result.GetValue(descriptionOption), result.GetValue(lockedOption),
result.GetValue(mesOption)));
});
return cmd;
}
@@ -838,6 +841,8 @@ public static class TemplateCommands
var descOption = new Option<string?>("--description") { Description = "Description" };
var lockedOption = new Option<bool>("--locked") { Description = "Lock status" };
lockedOption.DefaultValueFactory = _ => false;
var mesOption = new Option<bool>("--mes-reportable") { Description = "Every condition under this binding is MES-reportable (additive to the 900-999 severity band)" };
mesOption.DefaultValueFactory = _ => false;
var addCmd = new Command("add") { Description = "Add a native alarm source binding to a template" };
addCmd.Add(templateIdOption);
@@ -847,6 +852,7 @@ public static class TemplateCommands
addCmd.Add(filterOption);
addCmd.Add(descOption);
addCmd.Add(lockedOption);
addCmd.Add(mesOption);
addCmd.SetAction(async (ParseResult result) =>
{
return await CommandHelpers.ExecuteCommandAsync(
@@ -858,7 +864,8 @@ public static class TemplateCommands
result.GetValue(sourceRefOption)!,
result.GetValue(filterOption),
result.GetValue(descOption),
result.GetValue(lockedOption)));
result.GetValue(lockedOption),
result.GetValue(mesOption)));
});
group.Add(addCmd);