diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260722122301_AddClusterNodeTransportPorts.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260722122301_AddClusterNodeTransportPorts.Designer.cs
new file mode 100644
index 00000000..4ddceca4
--- /dev/null
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260722122301_AddClusterNodeTransportPorts.Designer.cs
@@ -0,0 +1,1704 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using ZB.MOM.WW.OtOpcUa.Configuration;
+
+#nullable disable
+
+namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations
+{
+ [DbContext(typeof(OtOpcUaConfigDbContext))]
+ [Migration("20260722122301_AddClusterNodeTransportPorts")]
+ partial class AddClusterNodeTransportPorts
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "10.0.7")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("FriendlyName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Xml")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("DataProtectionKeys", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b =>
+ {
+ b.Property("NodeId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("AkkaPort")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasDefaultValue(4053);
+
+ b.Property("ApplicationUri")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ClusterId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("CreatedAt")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("DashboardPort")
+ .HasColumnType("int");
+
+ b.Property("DriverConfigOverridesJson")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("GrpcPort")
+ .HasColumnType("int");
+
+ b.Property("Host")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("LastSeenAt")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("OpcUaPort")
+ .HasColumnType("int");
+
+ b.Property("ServiceLevelBase")
+ .HasColumnType("tinyint");
+
+ b.HasKey("NodeId");
+
+ b.HasIndex("ApplicationUri")
+ .IsUnique()
+ .HasDatabaseName("UX_ClusterNode_ApplicationUri");
+
+ b.HasIndex("ClusterId")
+ .HasDatabaseName("IX_ClusterNode_ClusterId");
+
+ b.ToTable("ClusterNode", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeCredential", b =>
+ {
+ b.Property("CredentialId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("CreatedAt")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("Kind")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("NodeId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RotatedAt")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.HasKey("CredentialId");
+
+ b.HasIndex("Kind", "Value")
+ .IsUnique()
+ .HasDatabaseName("UX_ClusterNodeCredential_Value")
+ .HasFilter("[Enabled] = 1");
+
+ b.HasIndex("NodeId", "Enabled")
+ .HasDatabaseName("IX_ClusterNodeCredential_NodeId");
+
+ b.ToTable("ClusterNodeCredential", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigAuditLog", b =>
+ {
+ b.Property("AuditId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("AuditId"));
+
+ b.Property("ClusterId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("CorrelationId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DetailsJson")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("EventId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EventType")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("GenerationId")
+ .HasColumnType("bigint");
+
+ b.Property("NodeId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Outcome")
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("Principal")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Timestamp")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.HasKey("AuditId");
+
+ b.HasIndex("EventId")
+ .IsUnique()
+ .HasDatabaseName("UX_ConfigAuditLog_EventId")
+ .HasFilter("[EventId] IS NOT NULL");
+
+ b.HasIndex("GenerationId")
+ .HasDatabaseName("IX_ConfigAuditLog_Generation")
+ .HasFilter("[GenerationId] IS NOT NULL");
+
+ b.HasIndex("ClusterId", "Timestamp")
+ .IsDescending(false, true)
+ .HasDatabaseName("IX_ConfigAuditLog_Cluster_Time");
+
+ b.ToTable("ConfigAuditLog", null, t =>
+ {
+ t.HasCheckConstraint("CK_ConfigAuditLog_DetailsJson_IsJson", "DetailsJson IS NULL OR ISJSON(DetailsJson) = 1");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigEdit", b =>
+ {
+ b.Property("EditId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("EditedAtUtc")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("EditedBy")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("EntityId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EntityType")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ExecutionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("FieldsJson")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SourceNode")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("EditId");
+
+ b.HasIndex("EditedAtUtc")
+ .HasDatabaseName("IX_ConfigEdit_EditedAt");
+
+ b.HasIndex("ExecutionId")
+ .HasDatabaseName("IX_ConfigEdit_Execution")
+ .HasFilter("[ExecutionId] IS NOT NULL");
+
+ b.HasIndex("EntityType", "EntityId")
+ .HasDatabaseName("IX_ConfigEdit_Entity");
+
+ b.ToTable("ConfigEdit", null, t =>
+ {
+ t.HasCheckConstraint("CK_ConfigEdit_FieldsJson_IsJson", "ISJSON(FieldsJson) = 1");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Deployment", b =>
+ {
+ b.Property("DeploymentId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("ArtifactBlob")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b.Property("CreatedAtUtc")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("FailureReason")
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.Property("RevisionHash")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("SealedAtUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.HasKey("DeploymentId");
+
+ b.HasIndex("CreatedAtUtc")
+ .HasDatabaseName("IX_Deployment_CreatedAt");
+
+ b.HasIndex("Status")
+ .HasDatabaseName("IX_Deployment_Status");
+
+ b.ToTable("Deployment", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b =>
+ {
+ b.Property("DeviceRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("DeviceConfig")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DeviceId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DriverInstanceId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.HasKey("DeviceRowId");
+
+ b.HasIndex("DeviceId")
+ .IsUnique()
+ .HasDatabaseName("UX_Device_LogicalId")
+ .HasFilter("[DeviceId] IS NOT NULL");
+
+ b.HasIndex("DriverInstanceId")
+ .HasDatabaseName("IX_Device_Driver");
+
+ b.HasIndex("DriverInstanceId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_Device_Driver_Name");
+
+ b.ToTable("Device", null, t =>
+ {
+ t.HasCheckConstraint("CK_Device_DeviceConfig_IsJson", "ISJSON(DeviceConfig) = 1");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.DriverHostStatus", b =>
+ {
+ b.Property("NodeId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DriverInstanceId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("HostName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("Detail")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("LastSeenUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("State")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("StateChangedUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.HasKey("NodeId", "DriverInstanceId", "HostName");
+
+ b.HasIndex("LastSeenUtc")
+ .HasDatabaseName("IX_DriverHostStatus_LastSeen");
+
+ b.HasIndex("NodeId")
+ .HasDatabaseName("IX_DriverHostStatus_Node");
+
+ b.ToTable("DriverHostStatus", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.DriverInstance", b =>
+ {
+ b.Property("DriverInstanceRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("ClusterId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DriverConfig")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DriverInstanceId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DriverType")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("RawFolderId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ResilienceConfig")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.HasKey("DriverInstanceRowId");
+
+ b.HasIndex("ClusterId")
+ .HasDatabaseName("IX_DriverInstance_Cluster");
+
+ b.HasIndex("DriverInstanceId")
+ .IsUnique()
+ .HasDatabaseName("UX_DriverInstance_LogicalId")
+ .HasFilter("[DriverInstanceId] IS NOT NULL");
+
+ b.HasIndex("RawFolderId")
+ .HasDatabaseName("IX_DriverInstance_RawFolder");
+
+ b.HasIndex("ClusterId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_DriverInstance_ClusterRoot_Name")
+ .HasFilter("[RawFolderId] IS NULL");
+
+ b.HasIndex("ClusterId", "RawFolderId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_DriverInstance_Folder_Name")
+ .HasFilter("[RawFolderId] IS NOT NULL");
+
+ b.ToTable("DriverInstance", null, t =>
+ {
+ t.HasCheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 1");
+
+ t.HasCheckConstraint("CK_DriverInstance_ResilienceConfig_IsJson", "ResilienceConfig IS NULL OR ISJSON(ResilienceConfig) = 1");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.DriverInstanceResilienceStatus", b =>
+ {
+ b.Property("DriverInstanceId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("HostName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("BaselineFootprintBytes")
+ .HasColumnType("bigint");
+
+ b.Property("ConsecutiveFailures")
+ .HasColumnType("int");
+
+ b.Property("CurrentBulkheadDepth")
+ .HasColumnType("int");
+
+ b.Property("CurrentFootprintBytes")
+ .HasColumnType("bigint");
+
+ b.Property("LastCircuitBreakerOpenUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("LastRecycleUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("LastSampledUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.HasKey("DriverInstanceId", "HostName");
+
+ b.HasIndex("LastSampledUtc")
+ .HasDatabaseName("IX_DriverResilience_LastSampled");
+
+ b.ToTable("DriverInstanceResilienceStatus", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b =>
+ {
+ b.Property("EquipmentRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("AssetLocation")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("DeviceManualUri")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("EquipmentClassRef")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("EquipmentId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("EquipmentUuid")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("HardwareRevision")
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("MachineCode")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Manufacturer")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ManufacturerUri")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("Model")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("SAPID")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("SerialNumber")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("SoftwareRevision")
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("UnsLineId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("YearOfConstruction")
+ .HasColumnType("smallint");
+
+ b.Property("ZTag")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("EquipmentRowId");
+
+ b.HasIndex("EquipmentId")
+ .IsUnique()
+ .HasDatabaseName("UX_Equipment_LogicalId")
+ .HasFilter("[EquipmentId] IS NOT NULL");
+
+ b.HasIndex("EquipmentUuid")
+ .IsUnique()
+ .HasDatabaseName("UX_Equipment_Uuid");
+
+ b.HasIndex("MachineCode")
+ .HasDatabaseName("IX_Equipment_MachineCode");
+
+ b.HasIndex("SAPID")
+ .HasDatabaseName("IX_Equipment_SAPID")
+ .HasFilter("[SAPID] IS NOT NULL");
+
+ b.HasIndex("UnsLineId")
+ .HasDatabaseName("IX_Equipment_Line");
+
+ b.HasIndex("ZTag")
+ .HasDatabaseName("IX_Equipment_ZTag")
+ .HasFilter("[ZTag] IS NOT NULL");
+
+ b.HasIndex("UnsLineId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_Equipment_LinePath");
+
+ b.ToTable("Equipment", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ExternalIdReservation", b =>
+ {
+ b.Property("ReservationId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("ClusterId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("EquipmentUuid")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("FirstPublishedAt")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("FirstPublishedBy")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Kind")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("LastPublishedAt")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("ReleaseReason")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("ReleasedAt")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("ReleasedBy")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("ReservationId");
+
+ b.HasIndex("EquipmentUuid")
+ .HasDatabaseName("IX_ExternalIdReservation_Equipment");
+
+ b.HasIndex("Kind", "Value")
+ .IsUnique()
+ .HasDatabaseName("UX_ExternalIdReservation_KindValue_Active")
+ .HasFilter("[ReleasedAt] IS NULL");
+
+ b.ToTable("ExternalIdReservation", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.LdapGroupRoleMapping", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClusterId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("CreatedAtUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("IsSystemWide")
+ .HasColumnType("bit");
+
+ b.Property("LdapGroup")
+ .IsRequired()
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("Notes")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("Role")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ClusterId");
+
+ b.HasIndex("LdapGroup")
+ .HasDatabaseName("IX_LdapGroupRoleMapping_Group");
+
+ b.HasIndex("LdapGroup", "ClusterId")
+ .IsUnique()
+ .HasDatabaseName("UX_LdapGroupRoleMapping_Group_Cluster")
+ .HasFilter("[ClusterId] IS NOT NULL");
+
+ b.ToTable("LdapGroupRoleMapping", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b =>
+ {
+ b.Property("NodeAclRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("ClusterId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("LdapGroup")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NodeAclId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Notes")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("PermissionFlags")
+ .HasColumnType("int");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("ScopeId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ScopeKind")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.HasKey("NodeAclRowId");
+
+ b.HasIndex("ClusterId")
+ .HasDatabaseName("IX_NodeAcl_Cluster");
+
+ b.HasIndex("LdapGroup")
+ .HasDatabaseName("IX_NodeAcl_Group");
+
+ b.HasIndex("NodeAclId")
+ .IsUnique()
+ .HasDatabaseName("UX_NodeAcl_LogicalId")
+ .HasFilter("[NodeAclId] IS NOT NULL");
+
+ b.HasIndex("ScopeKind", "ScopeId")
+ .HasDatabaseName("IX_NodeAcl_Scope")
+ .HasFilter("[ScopeId] IS NOT NULL");
+
+ b.HasIndex("ClusterId", "LdapGroup", "ScopeKind", "ScopeId")
+ .IsUnique()
+ .HasDatabaseName("UX_NodeAcl_GroupScope")
+ .HasFilter("[ScopeId] IS NOT NULL");
+
+ b.ToTable("NodeAcl", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeDeploymentState", b =>
+ {
+ b.Property("NodeId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeploymentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AppliedAtUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("FailureReason")
+ .HasMaxLength(2048)
+ .HasColumnType("nvarchar(2048)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("StartedAtUtc")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.HasKey("NodeId", "DeploymentId");
+
+ b.HasIndex("DeploymentId")
+ .HasDatabaseName("IX_NodeDeploymentState_Deployment");
+
+ b.HasIndex("Status")
+ .HasDatabaseName("IX_NodeDeploymentState_Status");
+
+ b.ToTable("NodeDeploymentState", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b =>
+ {
+ b.Property("PollGroupRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("DriverInstanceId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IntervalMs")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("PollGroupId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.HasKey("PollGroupRowId");
+
+ b.HasIndex("DriverInstanceId")
+ .HasDatabaseName("IX_PollGroup_Driver");
+
+ b.HasIndex("PollGroupId")
+ .IsUnique()
+ .HasDatabaseName("UX_PollGroup_LogicalId")
+ .HasFilter("[PollGroupId] IS NOT NULL");
+
+ b.ToTable("PollGroup", null, t =>
+ {
+ t.HasCheckConstraint("CK_PollGroup_IntervalMs_Min", "IntervalMs >= 50");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.RawFolder", b =>
+ {
+ b.Property("RawFolderRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("ClusterId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ParentRawFolderId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RawFolderId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("SortOrder")
+ .HasColumnType("int");
+
+ b.HasKey("RawFolderRowId");
+
+ b.HasIndex("ClusterId")
+ .HasDatabaseName("IX_RawFolder_Cluster");
+
+ b.HasIndex("RawFolderId")
+ .IsUnique()
+ .HasDatabaseName("UX_RawFolder_LogicalId")
+ .HasFilter("[RawFolderId] IS NOT NULL");
+
+ b.HasIndex("ClusterId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_RawFolder_ClusterRoot_Name")
+ .HasFilter("[ParentRawFolderId] IS NULL");
+
+ b.HasIndex("ClusterId", "ParentRawFolderId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_RawFolder_Parent_Name")
+ .HasFilter("[ParentRawFolderId] IS NOT NULL");
+
+ b.ToTable("RawFolder", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Script", b =>
+ {
+ b.Property("ScriptRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("Language")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("ScriptId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("SourceCode")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SourceHash")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("ScriptRowId");
+
+ b.HasIndex("ScriptId")
+ .IsUnique()
+ .HasDatabaseName("UX_Script_LogicalId")
+ .HasFilter("[ScriptId] IS NOT NULL");
+
+ b.HasIndex("SourceHash")
+ .HasDatabaseName("IX_Script_SourceHash");
+
+ b.ToTable("Script", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ScriptedAlarm", b =>
+ {
+ b.Property("ScriptedAlarmRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("AlarmType")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("EquipmentId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("HistorizeToAveva")
+ .HasColumnType("bit");
+
+ b.Property("MessageTemplate")
+ .IsRequired()
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("PredicateScriptId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Retain")
+ .HasColumnType("bit");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("ScriptedAlarmId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Severity")
+ .HasColumnType("int");
+
+ b.HasKey("ScriptedAlarmRowId");
+
+ b.HasIndex("PredicateScriptId")
+ .HasDatabaseName("IX_ScriptedAlarm_Script");
+
+ b.HasIndex("ScriptedAlarmId")
+ .IsUnique()
+ .HasDatabaseName("UX_ScriptedAlarm_LogicalId")
+ .HasFilter("[ScriptedAlarmId] IS NOT NULL");
+
+ b.HasIndex("EquipmentId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_ScriptedAlarm_EquipmentPath");
+
+ b.ToTable("ScriptedAlarm", null, t =>
+ {
+ t.HasCheckConstraint("CK_ScriptedAlarm_AlarmType", "AlarmType IN ('AlarmCondition','LimitAlarm','OffNormalAlarm','DiscreteAlarm')");
+
+ t.HasCheckConstraint("CK_ScriptedAlarm_Severity_Range", "Severity BETWEEN 1 AND 1000");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ScriptedAlarmState", b =>
+ {
+ b.Property("ScriptedAlarmId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("AckedState")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("CommentsJson")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ConfirmedState")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("EnabledState")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("LastAckComment")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("LastAckUser")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastAckUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("LastConfirmComment")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("LastConfirmUser")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastConfirmUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("ShelvingExpiresUtc")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("ShelvingState")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("UpdatedAtUtc")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.HasKey("ScriptedAlarmId");
+
+ b.ToTable("ScriptedAlarmState", null, t =>
+ {
+ t.HasCheckConstraint("CK_ScriptedAlarmState_CommentsJson_IsJson", "ISJSON(CommentsJson) = 1");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b =>
+ {
+ b.Property("ClusterId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("CreatedAt")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime2(3)")
+ .HasDefaultValueSql("SYSUTCDATETIME()");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("Enterprise")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("ModifiedAt")
+ .HasColumnType("datetime2(3)");
+
+ b.Property("ModifiedBy")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("NodeCount")
+ .HasColumnType("tinyint");
+
+ b.Property("Notes")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("RedundancyMode")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("Site")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.HasKey("ClusterId");
+
+ b.HasIndex("Name")
+ .IsUnique()
+ .HasDatabaseName("UX_ServerCluster_Name");
+
+ b.HasIndex("Site")
+ .HasDatabaseName("IX_ServerCluster_Site");
+
+ b.ToTable("ServerCluster", null, t =>
+ {
+ t.HasCheckConstraint("CK_ServerCluster_RedundancyMode_NodeCount", "((NodeCount = 1 AND RedundancyMode = 'None') OR (NodeCount = 2 AND RedundancyMode IN ('Warm', 'Hot')))");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b =>
+ {
+ b.Property("TagRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("AccessLevel")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)");
+
+ b.Property("DataType")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("DeviceId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("PollGroupId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("TagConfig")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TagGroupId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("TagId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("WriteIdempotent")
+ .HasColumnType("bit");
+
+ b.HasKey("TagRowId");
+
+ b.HasIndex("TagId")
+ .IsUnique()
+ .HasDatabaseName("UX_Tag_LogicalId")
+ .HasFilter("[TagId] IS NOT NULL");
+
+ b.HasIndex("DeviceId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_Tag_Device_Name")
+ .HasFilter("[TagGroupId] IS NULL");
+
+ b.HasIndex("DeviceId", "TagGroupId")
+ .HasDatabaseName("IX_Tag_Device");
+
+ b.HasIndex("DeviceId", "TagGroupId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_Tag_Group_Name")
+ .HasFilter("[TagGroupId] IS NOT NULL");
+
+ b.ToTable("Tag", null, t =>
+ {
+ t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.TagGroup", b =>
+ {
+ b.Property("TagGroupRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("DeviceId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ParentTagGroupId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("SortOrder")
+ .HasColumnType("int");
+
+ b.Property("TagGroupId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("TagGroupRowId");
+
+ b.HasIndex("DeviceId")
+ .HasDatabaseName("IX_TagGroup_Device");
+
+ b.HasIndex("TagGroupId")
+ .IsUnique()
+ .HasDatabaseName("UX_TagGroup_LogicalId")
+ .HasFilter("[TagGroupId] IS NOT NULL");
+
+ b.HasIndex("DeviceId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_TagGroup_DeviceRoot_Name")
+ .HasFilter("[ParentTagGroupId] IS NULL");
+
+ b.HasIndex("DeviceId", "ParentTagGroupId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_TagGroup_Parent_Name")
+ .HasFilter("[ParentTagGroupId] IS NOT NULL");
+
+ b.ToTable("TagGroup", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsArea", b =>
+ {
+ b.Property("UnsAreaRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("ClusterId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("Notes")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("UnsAreaId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("UnsAreaRowId");
+
+ b.HasIndex("ClusterId")
+ .HasDatabaseName("IX_UnsArea_Cluster");
+
+ b.HasIndex("UnsAreaId")
+ .IsUnique()
+ .HasDatabaseName("UX_UnsArea_LogicalId")
+ .HasFilter("[UnsAreaId] IS NOT NULL");
+
+ b.HasIndex("ClusterId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_UnsArea_ClusterName");
+
+ b.ToTable("UnsArea", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b =>
+ {
+ b.Property("UnsLineRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("Notes")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("UnsAreaId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("UnsLineId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("UnsLineRowId");
+
+ b.HasIndex("UnsAreaId")
+ .HasDatabaseName("IX_UnsLine_Area");
+
+ b.HasIndex("UnsLineId")
+ .IsUnique()
+ .HasDatabaseName("UX_UnsLine_LogicalId")
+ .HasFilter("[UnsLineId] IS NOT NULL");
+
+ b.HasIndex("UnsAreaId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_UnsLine_AreaName");
+
+ b.ToTable("UnsLine", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsTagReference", b =>
+ {
+ b.Property("UnsTagReferenceRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("DisplayNameOverride")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("EquipmentId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("SortOrder")
+ .HasColumnType("int");
+
+ b.Property("TagId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("UnsTagReferenceId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("UnsTagReferenceRowId");
+
+ b.HasIndex("EquipmentId")
+ .HasDatabaseName("IX_UnsTagReference_Equipment");
+
+ b.HasIndex("TagId")
+ .HasDatabaseName("IX_UnsTagReference_Tag");
+
+ b.HasIndex("UnsTagReferenceId")
+ .IsUnique()
+ .HasDatabaseName("UX_UnsTagReference_LogicalId")
+ .HasFilter("[UnsTagReferenceId] IS NOT NULL");
+
+ b.HasIndex("EquipmentId", "TagId")
+ .IsUnique()
+ .HasDatabaseName("UX_UnsTagReference_Equip_Tag");
+
+ b.ToTable("UnsTagReference", (string)null);
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.VirtualTag", b =>
+ {
+ b.Property("VirtualTagRowId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier")
+ .HasDefaultValueSql("NEWSEQUENTIALID()");
+
+ b.Property("ChangeTriggered")
+ .HasColumnType("bit");
+
+ b.Property("DataType")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("EquipmentId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Historize")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("RowVersion")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("rowversion");
+
+ b.Property("ScriptId")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("TimerIntervalMs")
+ .HasColumnType("int");
+
+ b.Property("VirtualTagId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.HasKey("VirtualTagRowId");
+
+ b.HasIndex("ScriptId")
+ .HasDatabaseName("IX_VirtualTag_Script");
+
+ b.HasIndex("VirtualTagId")
+ .IsUnique()
+ .HasDatabaseName("UX_VirtualTag_LogicalId")
+ .HasFilter("[VirtualTagId] IS NOT NULL");
+
+ b.HasIndex("EquipmentId", "Name")
+ .IsUnique()
+ .HasDatabaseName("UX_VirtualTag_EquipmentPath");
+
+ b.ToTable("VirtualTag", null, t =>
+ {
+ t.HasCheckConstraint("CK_VirtualTag_TimerInterval_Min", "TimerIntervalMs IS NULL OR TimerIntervalMs >= 50");
+
+ t.HasCheckConstraint("CK_VirtualTag_Trigger_AtLeastOne", "ChangeTriggered = 1 OR TimerIntervalMs IS NOT NULL");
+ });
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b =>
+ {
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster")
+ .WithMany("Nodes")
+ .HasForeignKey("ClusterId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Cluster");
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeCredential", b =>
+ {
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node")
+ .WithMany("Credentials")
+ .HasForeignKey("NodeId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Node");
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.DriverInstance", b =>
+ {
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster")
+ .WithMany()
+ .HasForeignKey("ClusterId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Cluster");
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.LdapGroupRoleMapping", b =>
+ {
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster")
+ .WithMany()
+ .HasForeignKey("ClusterId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.Navigation("Cluster");
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeDeploymentState", b =>
+ {
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Deployment", "Deployment")
+ .WithMany()
+ .HasForeignKey("DeploymentId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node")
+ .WithMany()
+ .HasForeignKey("NodeId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Deployment");
+
+ b.Navigation("Node");
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.RawFolder", b =>
+ {
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", null)
+ .WithMany("RawFolders")
+ .HasForeignKey("ClusterId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsArea", b =>
+ {
+ b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster")
+ .WithMany()
+ .HasForeignKey("ClusterId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Cluster");
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b =>
+ {
+ b.Navigation("Credentials");
+ });
+
+ modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b =>
+ {
+ b.Navigation("Nodes");
+
+ b.Navigation("RawFolders");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260722122301_AddClusterNodeTransportPorts.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260722122301_AddClusterNodeTransportPorts.cs
new file mode 100644
index 00000000..24fac11e
--- /dev/null
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260722122301_AddClusterNodeTransportPorts.cs
@@ -0,0 +1,39 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations
+{
+ ///
+ public partial class AddClusterNodeTransportPorts : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "AkkaPort",
+ table: "ClusterNode",
+ type: "int",
+ nullable: false,
+ defaultValue: 4053);
+
+ migrationBuilder.AddColumn(
+ name: "GrpcPort",
+ table: "ClusterNode",
+ type: "int",
+ nullable: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "AkkaPort",
+ table: "ClusterNode");
+
+ migrationBuilder.DropColumn(
+ name: "GrpcPort",
+ table: "ClusterNode");
+ }
+ }
+}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/OtOpcUaConfigDbContextModelSnapshot.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/OtOpcUaConfigDbContextModelSnapshot.cs
index b5522bd5..289ae370 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/OtOpcUaConfigDbContextModelSnapshot.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/OtOpcUaConfigDbContextModelSnapshot.cs
@@ -47,6 +47,11 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
+ b.Property("AkkaPort")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasDefaultValue(4053);
+
b.Property("ApplicationUri")
.IsRequired()
.HasMaxLength(256)
@@ -76,6 +81,9 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations
b.Property("Enabled")
.HasColumnType("bit");
+ b.Property("GrpcPort")
+ .HasColumnType("int");
+
b.Property