feat(template-engine): flatten IsMesReportable with null-inherits override semantics
Claude-Session: https://claude.ai/code/session_01Y5ef34iUUMjmwnMpL9xgmB
This commit is contained in:
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user