feat(template-engine): flatten IsMesReportable with null-inherits override semantics

Claude-Session: https://claude.ai/code/session_01Y5ef34iUUMjmwnMpL9xgmB
This commit is contained in:
Joseph Doherty
2026-09-11 09:55:11 -04:00
parent b07394447f
commit 54e21a8107
2 changed files with 97 additions and 0 deletions
@@ -359,6 +359,7 @@ public class FlatteningService
{
TriggerConfiguration = newConfig,
PriorityLevel = ovr.PriorityLevelOverride ?? existing.PriorityLevel,
IsMesReportable = ovr.IsMesReportableOverride ?? existing.IsMesReportable,
Source = "Override"
};
}
@@ -453,6 +454,7 @@ public class FlatteningService
Description = alarm.Description,
PriorityLevel = alarm.PriorityLevel,
IsLocked = alarm.IsLocked,
IsMesReportable = alarm.IsMesReportable,
TriggerType = alarm.TriggerType.ToString(),
TriggerConfiguration = triggerConfig,
OnTriggerScriptCanonicalName = null, // Resolved later
@@ -563,6 +563,101 @@ public class FlatteningServiceTests
Assert.Contains("HighTemp", result.Error);
}
// ── MES reportable flag: template value + instance override ────────────
[Fact]
public void Flatten_MesReportable_TemplateValueCarried()
{
var template = CreateTemplate(1, "Base");
template.Alarms.Add(new TemplateAlarm("HighTemp")
{
TriggerType = AlarmTriggerType.RangeViolation,
TriggerConfiguration = "{\"attributeName\":\"Temp\",\"high\":100}",
PriorityLevel = 1,
IsMesReportable = true
});
template.Alarms.Add(new TemplateAlarm("LowTemp")
{
TriggerType = AlarmTriggerType.RangeViolation,
TriggerConfiguration = "{\"attributeName\":\"Temp\",\"low\":10}",
PriorityLevel = 2
});
var instance = CreateInstance();
var result = _sut.Flatten(
instance,
[template],
new Dictionary<int, IReadOnlyList<TemplateComposition>>(),
new Dictionary<int, IReadOnlyList<Template>>(),
new Dictionary<int, DataConnection>());
Assert.True(result.IsSuccess);
Assert.True(result.Value.Alarms.First(a => a.CanonicalName == "HighTemp").IsMesReportable);
Assert.False(result.Value.Alarms.First(a => a.CanonicalName == "LowTemp").IsMesReportable);
}
[Fact]
public void Flatten_MesReportable_OverrideFalseWins()
{
var template = CreateTemplate(1, "Base");
template.Alarms.Add(new TemplateAlarm("HighTemp")
{
TriggerType = AlarmTriggerType.RangeViolation,
TriggerConfiguration = "{\"attributeName\":\"Temp\",\"high\":100}",
PriorityLevel = 1,
IsMesReportable = true
});
var instance = CreateInstance();
instance.AlarmOverrides.Add(new InstanceAlarmOverride("HighTemp")
{
IsMesReportableOverride = false
});
var result = _sut.Flatten(
instance,
[template],
new Dictionary<int, IReadOnlyList<TemplateComposition>>(),
new Dictionary<int, IReadOnlyList<Template>>(),
new Dictionary<int, DataConnection>());
Assert.True(result.IsSuccess);
var alarm = result.Value.Alarms.First(a => a.CanonicalName == "HighTemp");
Assert.False(alarm.IsMesReportable);
Assert.Equal("Override", alarm.Source);
}
[Fact]
public void Flatten_MesReportable_OverrideNullInherits()
{
var template = CreateTemplate(1, "Base");
template.Alarms.Add(new TemplateAlarm("HighTemp")
{
TriggerType = AlarmTriggerType.RangeViolation,
TriggerConfiguration = "{\"attributeName\":\"Temp\",\"high\":100}",
PriorityLevel = 1,
IsMesReportable = true
});
var instance = CreateInstance();
instance.AlarmOverrides.Add(new InstanceAlarmOverride("HighTemp")
{
PriorityLevelOverride = 7
});
var result = _sut.Flatten(
instance,
[template],
new Dictionary<int, IReadOnlyList<TemplateComposition>>(),
new Dictionary<int, IReadOnlyList<Template>>(),
new Dictionary<int, DataConnection>());
Assert.True(result.IsSuccess);
var alarm = result.Value.Alarms.First(a => a.CanonicalName == "HighTemp");
Assert.Equal(7, alarm.PriorityLevel);
Assert.True(alarm.IsMesReportable);
}
// ── TemplateEngine-001: deep composition nesting ───────────────────────
[Fact]