From fce66d104a0038457c5cc10b4e0fa7a1b1a93cc4 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 7 Jun 2026 10:37:22 -0400 Subject: [PATCH] refactor(config): materialise collision groups once; note VirtualTag folder coupling --- .../Validation/DraftValidator.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs index 6447f831..16dc5f21 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Validation/DraftValidator.cs @@ -47,14 +47,17 @@ public static class DraftValidator var signals = draft.Tags .Where(t => t.EquipmentId is not null) .Select(t => (Key: Key(t.EquipmentId!, t.FolderPath, t.Name), Eq: t.EquipmentId!, t.Name)) + // VirtualTag has no FolderPath column today — null is correct here; update if it ever gains one. .Concat(draft.VirtualTags .Select(v => (Key: Key(v.EquipmentId, null, v.Name), Eq: v.EquipmentId, v.Name))); - foreach (var g in signals.GroupBy(s => s.Key, StringComparer.Ordinal).Where(g => g.Count() > 1)) + foreach (var g in signals.GroupBy(s => s.Key, StringComparer.Ordinal)) { - var f = g.First(); + var items = g.ToList(); + if (items.Count <= 1) continue; + var f = items[0]; errors.Add(new("EquipmentSignalNameCollision", - $"{g.Count()} signals collide on OPC UA NodeId '{g.Key}' (equipment '{f.Eq}', name '{f.Name}'); " + + $"{items.Count} signals collide on OPC UA NodeId '{g.Key}' (equipment '{f.Eq}', name '{f.Name}'); " + "a Name must be unique across Tag and VirtualTag within an equipment+folder", f.Eq)); }