From 261419870ae49daf58c753edb859a48d83492877 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 9 Jun 2026 08:29:47 -0400 Subject: [PATCH] fix(docker-dev): make cluster-seed Galaxy Tag insert idempotent on UX_Tag_FolderPath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The three TestMachine_001 folder-path tag inserts were guarded by TagId, but the violated constraint is UX_Tag_FolderPath — a unique filtered index on (DriverInstanceId, FolderPath, Name) WHERE EquipmentId IS NULL. The Galaxy driver auto-materialises these same folder-path tags at runtime under its own generated TagIds (nw-mirror-*), so on a re-run the TagId guard found nothing, the insert fired, and it collided on UX_Tag_FolderPath — cluster-seed exited 1. Guard each insert on the index's natural key instead, so the row is skipped whether it came from a prior seed or the driver's runtime mirror. Verified by re-running cluster-seed against the populated dev volume (which holds nw-mirror-testmachine_001-testalarm00{1,2,3}): exit 0, no UX_Tag_FolderPath violation. --- docker-dev/seed/seed-clusters.sql | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docker-dev/seed/seed-clusters.sql b/docker-dev/seed/seed-clusters.sql index ce15c214..a4ce9d7e 100644 --- a/docker-dev/seed/seed-clusters.sql +++ b/docker-dev/seed/seed-clusters.sql @@ -157,23 +157,35 @@ IF NOT EXISTS (SELECT 1 FROM dbo.DriverInstance WHERE DriverInstanceId = 'MAIN-g -- Name to address the MXAccess item. The Galaxy driver subscribes via the -- "FolderPath.Name" MXAccess reference form; OPC UA browse path is the -- equivalent "FolderPath/Name" under the SystemPlatform namespace. +-- +-- Idempotency: each insert is guarded on the UX_Tag_FolderPath key +-- (DriverInstanceId, FolderPath, Name WHERE EquipmentId IS NULL), NOT TagId. +-- The Galaxy driver auto-materialises these same folder-path tags at runtime +-- under its own generated TagIds, so a TagId-only guard would pass on a re-run +-- and then collide on UX_Tag_FolderPath, making cluster-seed exit 1. ------------------------------------------------------------------------------ -IF NOT EXISTS (SELECT 1 FROM dbo.Tag WHERE TagId = 'MAIN-galaxy-TestMachine_001-TestAlarm001') +IF NOT EXISTS (SELECT 1 FROM dbo.Tag + WHERE DriverInstanceId = 'MAIN-galaxy-mxgw' AND FolderPath = 'TestMachine_001' + AND Name = 'TestAlarm001' AND EquipmentId IS NULL) INSERT INTO dbo.Tag (TagRowId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig) VALUES (NEWID(), 'MAIN-galaxy-TestMachine_001-TestAlarm001', 'MAIN-galaxy-mxgw', NULL, NULL, 'TestAlarm001', 'TestMachine_001', 'Boolean', 0, 0, NULL, N'{}'); -IF NOT EXISTS (SELECT 1 FROM dbo.Tag WHERE TagId = 'MAIN-galaxy-TestMachine_001-TestAlarm002') +IF NOT EXISTS (SELECT 1 FROM dbo.Tag + WHERE DriverInstanceId = 'MAIN-galaxy-mxgw' AND FolderPath = 'TestMachine_001' + AND Name = 'TestAlarm002' AND EquipmentId IS NULL) INSERT INTO dbo.Tag (TagRowId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig) VALUES (NEWID(), 'MAIN-galaxy-TestMachine_001-TestAlarm002', 'MAIN-galaxy-mxgw', NULL, NULL, 'TestAlarm002', 'TestMachine_001', 'Boolean', 0, 0, NULL, N'{}'); -IF NOT EXISTS (SELECT 1 FROM dbo.Tag WHERE TagId = 'MAIN-galaxy-TestMachine_001-TestAlarm003') +IF NOT EXISTS (SELECT 1 FROM dbo.Tag + WHERE DriverInstanceId = 'MAIN-galaxy-mxgw' AND FolderPath = 'TestMachine_001' + AND Name = 'TestAlarm003' AND EquipmentId IS NULL) INSERT INTO dbo.Tag (TagRowId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig) VALUES