diff --git a/docker-dev/seed/seed-clusters.sql b/docker-dev/seed/seed-clusters.sql index 0e12f0a8..37c687ec 100644 --- a/docker-dev/seed/seed-clusters.sql +++ b/docker-dev/seed/seed-clusters.sql @@ -123,13 +123,13 @@ COMMIT TRANSACTION; -- Summary (logged by sqlcmd output) ------------------------------------------------------------------------------ +-- v3: the Namespace table is retired; DriverInstance is folder-scoped (RawFolderId) and Tags +-- are device-scoped (DeviceId + optional TagGroupId). This seed only creates clusters + nodes + +-- LDAP role mappings, so the summary reflects just those. Raw-tree config (RawFolder/DriverInstance/ +-- Device/TagGroup/Tag) is authored via the AdminUI /raw page in later batches. SELECT ClusterId, Name, NodeCount, RedundancyMode FROM dbo.ServerCluster ORDER BY ClusterId; SELECT NodeId, ClusterId, Host, OpcUaPort, ApplicationUri, ServiceLevelBase FROM dbo.ClusterNode ORDER BY ClusterId, NodeId; -SELECT NamespaceId, ClusterId, Kind, NamespaceUri FROM dbo.Namespace ORDER BY ClusterId, NamespaceId; -SELECT DriverInstanceId, ClusterId, DriverType, NamespaceId, Name - FROM dbo.DriverInstance ORDER BY ClusterId, DriverInstanceId; -SELECT TagId, DriverInstanceId, FolderPath, Name, DataType FROM dbo.Tag ORDER BY DriverInstanceId, FolderPath, Name; ------------------------------------------------------------------------------ -- LDAP group -> AdminUI role mappings (shared dev GLAuth, 10.100.0.35) @@ -152,3 +152,24 @@ IF NOT EXISTS (SELECT 1 FROM dbo.LdapGroupRoleMapping WHERE LdapGroup = 'OtOpcUa VALUES (NEWID(), 'OtOpcUa-Viewers', 'Viewer', NULL, 1, SYSUTCDATETIME(), N'shared-glauth dev seed'); SELECT LdapGroup, Role, IsSystemWide FROM dbo.LdapGroupRoleMapping ORDER BY LdapGroup; + +------------------------------------------------------------------------------ +-- v3 Batch 1 gate: a Modbus driver in cluster MAIN so the docker-dev boot has a +-- driver to show Connected against the modbus fixture (10.100.0.35:5020). Raw tree: +-- DriverInstance(RawFolderId NULL) -> Device(endpoint in DeviceConfig) -> Tag(raw). +-- Idempotent. Address space stays DARK this batch (no variable nodes materialize). +------------------------------------------------------------------------------ +SET QUOTED_IDENTIFIER ON; +SET ANSI_NULLS ON; +IF NOT EXISTS (SELECT 1 FROM dbo.DriverInstance WHERE DriverInstanceId = 'MAIN-modbus') + INSERT dbo.DriverInstance(DriverInstanceId, ClusterId, RawFolderId, Name, DriverType, DriverConfig, Enabled) + VALUES ('MAIN-modbus', 'MAIN', NULL, 'pymodbus', 'Modbus', + N'{ "TimeoutMs": 2000, "AutoReconnect": true, "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000, "ProbeAddress": 0 } }', 1); +IF NOT EXISTS (SELECT 1 FROM dbo.Device WHERE DeviceId = 'MAIN-modbus-dev') + INSERT dbo.Device(DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig) + VALUES ('MAIN-modbus-dev', 'MAIN-modbus', 'plc', 1, N'{ "Host": "10.100.0.35", "Port": 5020, "UnitId": 1 }'); +IF NOT EXISTS (SELECT 1 FROM dbo.Tag WHERE TagId = 'MAIN-modbus-hr200') + INSERT dbo.Tag(TagId, DeviceId, TagGroupId, Name, DataType, AccessLevel, WriteIdempotent, TagConfig) + VALUES ('MAIN-modbus-hr200', 'MAIN-modbus-dev', NULL, 'HR200', 'UInt16', 'ReadWrite', 1, + N'{ "region": "HoldingRegisters", "address": 200, "dataType": "UInt16", "writable": true }'); +SELECT DriverInstanceId, ClusterId, DriverType, Enabled FROM dbo.DriverInstance WHERE ClusterId='MAIN'; diff --git a/docs/Configuration.md b/docs/Configuration.md index e1fdd181..fdcac78c 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1,5 +1,16 @@ # Configuration Reference +> **v3 in progress (Batch 1 landed — schema + RawPath identity).** The config **DB schema** was +> replaced by the greenfield v3 model: a driver-centric **Raw tree** +> (`Cluster → RawFolder → DriverInstance → Device → TagGroup → Tag`) plus a reference-only **UNS** +> projection (`UnsTagReference`). A tag's identity is now its **RawPath** +> (`////`), not a `TagConfig.FullName` blob; the +> `Namespace`/`NamespaceKind`/`EquipmentImportBatch` entities are retired, and connection endpoints +> moved from `DriverConfig` into each `Device`'s `DeviceConfig`. The two OPC UA namespaces (`ns=Raw` / +> `ns=UNS`) and the `/raw` authoring UI arrive in later v3 batches; **Batch 1 leaves the address space +> deliberately dark** (drivers connect, but no tag variables materialize yet). The `appsettings*.json` +> surface below is unchanged. Full design: `docs/plans/2026-07-15-raw-uns-two-subtree-v3-design.md`. + This is the live configuration reference for the OtOpcUa Host (`src/Server/ZB.MOM.WW.OtOpcUa.Host/`). It enumerates the `appsettings*.json` sections, the bound Options classes, and the `OTOPCUA_*` / sim-endpoint environment variables — every entry grounded in source. Two related concerns get their own dedicated pages and are **only summarised + linked** here, not duplicated: diff --git a/docs/plans/2026-07-15-v3-batch1-PR.md b/docs/plans/2026-07-15-v3-batch1-PR.md new file mode 100644 index 00000000..89d6e7ac --- /dev/null +++ b/docs/plans/2026-07-15-v3-batch1-PR.md @@ -0,0 +1,68 @@ +# v3 Batch 1 — greenfield schema + RawPath identity rewiring + +**Branch:** `v3/batch1-schema-identity` → `master` +**Plan:** `docs/plans/2026-07-15-v3-batch1-schema-identity-plan.md` · **Design:** `docs/plans/2026-07-15-raw-uns-two-subtree-v3-design.md` + +Greenfield, compatibility-breaking. The config schema and every identity seam now speak **RawPath** +(`////`). The full solution builds and all macOS-safe +tests pass; the OPC UA address space is **deliberately dark** (drivers connect, no tag variables +materialize) until Batch 4. + +## What changed + +- **Schema (greenfield):** new `RawFolder` / `TagGroup` / `UnsTagReference`; reshaped `DriverInstance` + (−`NamespaceId`, +`RawFolderId?`), `Tag` (raw-only: req `DeviceId`, +`TagGroupId?`, + −`DriverInstanceId`/`EquipmentId`/`FolderPath`, kept `WriteIdempotent`), `Equipment` (−driver/device + binding); `Namespace` / `NamespaceKind` / `EquipmentImportBatch` retired. Single squashed `V3Initial` + migration (stored procs audited — the vestigial generation-model procs were rewritten to v3-valid + stubs; `sp_ComputeGenerationDiff` diffs the new tables). +- **Identity:** new `Commons/Types/RawPaths.cs` helper; `TagConfigIntent` sheds `FullName`; + `EquipmentTagRefResolver` is byName(RawPath)-only (blob-fallback deleted); new + `RawTagEntry(RawPath, TagConfig, WriteIdempotent, DeviceName)` delivery record. All 8 drivers + re-keyed: the per-driver `*EquipmentTagParser` became `*TagDefinitionFactory.FromTagConfig`, options + `Tags` → `RawTags`, `TagConfig` key normalization (`nodeId` / `attributeRef`; `deviceHostAddress` + dropped). +- **Endpoint → DeviceConfig:** new `DriverDeviceConfigMerger` (Commons) merges DriverConfig + per-device + DeviceConfig; multi-device drivers reconstruct their `Devices[]` from Device rows; the artifact injects + the merged config + `rawTags` at spawn. +- **Pipeline:** `ConfigComposer` snapshots the new tables; `DeploymentArtifact` flattens per-driver + `RawTagEntry` lists keyed by RawPath (via `RawPathResolver`) + emits an empty (dark) equipment-tag + plan set; `AddressSpaceComposer`/walker compose folders + VirtualTags + ScriptedAlarms only; + `DriverHostActor` maps re-keyed to RawPath; `DraftValidator` gains `RawNameInvalid` / + `HistorianTagnameTooLong` / `UnsEffectiveNameCollision`. +- **AdminUI (compile-only stubs):** Namespace pages → retired banners; driver pages dropped the + pre-declared Tags editor + NamespaceId; `UnsTreeService` tag-authoring returns "moved to the Raw tree + (/raw) in v3 Batch 2". (Batch 2/3 build the real `/raw` + reference UI.) + +## Verification gate (all four items) + +1. **Build + test green.** Full solution builds (0 errors). macOS-safe unit suites: Commons 196, + Core 260, Core.Abstractions 134, **Configuration 107**, Runtime 355 (42 dark-Batch-4 skips), + ControlPlane 78, OpcUaServer 335 (4 skips), AdminUI 507 (3 skips), + all 8 driver unit suites + (Modbus 315, S7 264, AbCip 342, AbLegacy 213, TwinCAT 192, FOCAS 272, OpcUaClient 138, Galaxy 313) + and the 6 driver IntegrationTests projects compile. Enum-serialization round-trip coverage preserved. +2. **Fresh-DB migration.** `V3Initial` applies clean to a scratch DB; `SchemaComplianceTests` 8/8. +3. **docker-dev boot (live).** Volume wiped → `V3Initial` applied → both central nodes reached Akka + Up → a seeded Modbus driver **spawned and connected** to the `10.100.0.35:5020` fixture + (`DriverInstance MAIN-modbus: connected`), deployment **sealed (acks=2)**; AdminUI HTTP 200 on + `/`, `/clusters`, `/uns` with 0 unhandled exceptions. +4. **Dark address space (Client.CLI browse).** Recursive browse of `opc.tcp://localhost:4840`: the raw + tag `HR200` and the driver have **0 occurrences**; the custom namespace `ns=2` holds only the empty + `OtOpcUa` root — no authored variables materialize (Batch 4 lights them up). + +## AdminUI Batch-1 stubs (Batch 2/3 replace) + +Namespace pages (`NamespaceEdit`, `ClusterNamespaces`) → banners; the 8 driver pages' pre-declared Tags +editors + Namespace bindings removed; `DriverIdentitySection` Namespace dropdown removed; +`UnsTreeService.CreateTagAsync`/`UpdateTagAsync` return the "moved to /raw" failure; per-equipment tag +lists empty. + +## Deferred (owned by later batches, not regressions) + +- `/raw` project tree + reference-picker UI, dual `ns=Raw`/`ns=UNS` namespaces + tag-variable + materialization, `{{equip}}` reference-relative resolution — Batches 2–4 (address space intentionally + dark now). +- User-facing docs beyond the `Configuration.md` v3 note (they describe the not-yet-built UI/address + space) — updated as Batches 2–4 land. +- Live driver IntegrationTests + one pre-existing `AbCip_Green_AgainstSim` fixture-probe failure + (AB CIP sim handshake — environment/fixture gate, untouched). diff --git a/scripts/smoke/seed-abcip-smoke.sql b/scripts/smoke/seed-abcip-smoke.sql index e5526af9..a45c644d 100644 --- a/scripts/smoke/seed-abcip-smoke.sql +++ b/scripts/smoke/seed-abcip-smoke.sql @@ -1,128 +1,74 @@ --- AB CIP e2e smoke seed — closes #211 (umbrella #209). +-- AB CIP (Logix) e2e smoke seed — v3 schema (Raw tree: DriverInstance → Device → Tag; UNS by ref). -- --- One-cluster seed pointing at the ab_server ControlLogix fixture --- (`docker compose -f tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests/Docker/docker-compose.yml --profile controllogix up -d`). --- Publishes a single `TestDINT:DInt` tag under NodeId `ns=;s=TestDINT` --- (ab_server seeds this tag by default). --- --- Usage: --- sqlcmd -S "localhost,14330" -d OtOpcUaConfig -U sa -P "OtOpcUaDev_2026!" \ --- -i scripts/smoke/seed-abcip-smoke.sql --- --- After seeding, point appsettings at this cluster: --- Node:NodeId = "abcip-smoke-node" --- Node:ClusterId = "abcip-smoke" --- Then start server + run `./scripts/e2e/test-abcip.ps1 -BridgeNodeId "ns=2;s=TestDINT"`. +-- Idempotent DELETE-and-recreate pointing at the CIP fixture (ab://127.0.0.1:44818/1,0). v3: the +-- ConfigGeneration/Namespace model + sp_PublishGeneration are gone; the per-device HostAddress moved +-- from DriverConfig.Devices[] into the Device's DeviceConfig (the deviceHostAddress tag key is dropped +-- — the tag's DeviceId FK owns placement now). SET NOCOUNT ON; SET XACT_ABORT ON; SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON; -SET ANSI_PADDING ON; -SET ANSI_WARNINGS ON; -SET ARITHABORT ON; -SET CONCAT_NULL_YIELDS_NULL ON; DECLARE @ClusterId nvarchar(64) = 'abcip-smoke'; DECLARE @NodeId nvarchar(64) = 'abcip-smoke-node'; DECLARE @DrvId nvarchar(64) = 'abcip-smoke-drv'; -DECLARE @NsId nvarchar(64) = 'abcip-smoke-ns'; +DECLARE @DevId nvarchar(64) = 'abcip-smoke-dev'; DECLARE @AreaId nvarchar(64) = 'abcip-smoke-area'; DECLARE @LineId nvarchar(64) = 'abcip-smoke-line'; DECLARE @EqId nvarchar(64) = 'abcip-smoke-eq'; -DECLARE @EqUuid uniqueidentifier = '41BC12E0-41BC-412E-841B-C12E041BC12E'; -DECLARE @TagId nvarchar(64) = 'abcip-smoke-tag-testdint'; +DECLARE @EqUuid uniqueidentifier = 'ABC17000-ABC1-45E0-9ABC-17000ABC1700'; +DECLARE @Tag nvarchar(64) = 'abcip-smoke-tag-dint'; +DECLARE @RefId nvarchar(64) = 'abcip-smoke-ref-dint'; BEGIN TRAN; -DELETE FROM dbo.Tag WHERE TagId IN (@TagId); -DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; -DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; -DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; -DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; -DELETE FROM dbo.Namespace WHERE NamespaceId = @NsId; -DELETE FROM dbo.ConfigGeneration WHERE ClusterId = @ClusterId; -DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNodeGenerationState WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; -DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; - +DELETE FROM dbo.UnsTagReference WHERE UnsTagReferenceId = @RefId; +DELETE FROM dbo.Tag WHERE TagId = @Tag; +DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; +DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; +DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; +DELETE FROM dbo.Device WHERE DeviceId = @DevId; +DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; +DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; +DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; +DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; DELETE FROM dbo.ClusterNodeCredential WHERE Kind = 'SqlLogin' AND Value = 'sa'; INSERT dbo.ServerCluster(ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, CreatedBy) -VALUES (@ClusterId, 'AB CIP Smoke', 'zb', 'lab', 1, 'None', 1, 'abcip-smoke'); +VALUES (@ClusterId, 'AbCip Smoke', 'zb', 'lab', 1, 'None', 1, 'abcip-smoke'); -INSERT dbo.ClusterNode(NodeId, ClusterId, RedundancyRole, Host, OpcUaPort, DashboardPort, +INSERT dbo.ClusterNode(NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) -VALUES (@NodeId, @ClusterId, 'Primary', 'localhost', 4840, 15050, - 'urn:OtOpcUa:abcip-smoke-node', 200, 1, 'abcip-smoke'); +VALUES (@NodeId, @ClusterId, 'localhost', 4840, 15050, 'urn:OtOpcUa:abcip-smoke-node', 200, 1, 'abcip-smoke'); INSERT dbo.ClusterNodeCredential(NodeId, Kind, Value, Enabled, CreatedBy) VALUES (@NodeId, 'SqlLogin', 'sa', 1, 'abcip-smoke'); -DECLARE @Gen bigint; -INSERT dbo.ConfigGeneration(ClusterId, Status, CreatedBy) -VALUES (@ClusterId, 'Draft', 'abcip-smoke'); -SET @Gen = SCOPE_IDENTITY(); - -INSERT dbo.Namespace(GenerationId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled) -VALUES (@Gen, @NsId, @ClusterId, 'Equipment', 'urn:abcip-smoke:eq', 1); - -INSERT dbo.UnsArea(GenerationId, UnsAreaId, ClusterId, Name) -VALUES (@Gen, @AreaId, @ClusterId, 'lab-floor'); - -INSERT dbo.UnsLine(GenerationId, UnsLineId, UnsAreaId, Name) -VALUES (@Gen, @LineId, @AreaId, 'abcip-line'); - -INSERT dbo.Equipment(GenerationId, EquipmentId, EquipmentUuid, DriverInstanceId, UnsLineId, - Name, MachineCode, Enabled) -VALUES (@Gen, @EqId, @EqUuid, @DrvId, @LineId, 'ab-sim', 'abcip-001', 1); - --- AB CIP DriverInstance — single ControlLogix device at the ab_server fixture --- gateway. DriverConfig shape mirrors AbCipDriverConfigDto. -INSERT dbo.DriverInstance(GenerationId, DriverInstanceId, ClusterId, NamespaceId, - Name, DriverType, DriverConfig, Enabled) -VALUES (@Gen, @DrvId, @ClusterId, @NsId, 'ab-server-smoke', 'AbCip', N'{ - "TimeoutMs": 2000, - "Devices": [ - { - "HostAddress": "ab://127.0.0.1:44818/1,0", - "PlcFamily": "ControlLogix", - "DeviceName": "ab-server" - } - ], - "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000 }, - "Tags": [ - { - "Name": "TestDINT", - "DeviceHostAddress": "ab://127.0.0.1:44818/1,0", - "TagPath": "TestDINT", - "DataType": "DInt", - "Writable": true, - "WriteIdempotent": true - } - ] +-- DriverConfig keeps protocol/channel settings; the per-device Devices[] list is retired in favor +-- of Device rows carrying HostAddress in DeviceConfig. +INSERT dbo.DriverInstance(DriverInstanceId, ClusterId, RawFolderId, Name, DriverType, DriverConfig, Enabled) +VALUES (@DrvId, @ClusterId, NULL, 'logix-smoke', 'AbCip', N'{ + "EnableControllerBrowse": false, + "ProbeTimeoutSeconds": 5 }', 1); -INSERT dbo.Tag(GenerationId, TagId, DriverInstanceId, EquipmentId, Name, DataType, - AccessLevel, TagConfig, WriteIdempotent) -VALUES (@Gen, @TagId, @DrvId, @EqId, 'TestDINT', 'Int32', 'ReadWrite', - N'{"FullName":"TestDINT","DataType":"DInt"}', 1); +-- DeviceConfig shape finalized against reworked options in Wave B (WP5). +INSERT dbo.Device(DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig) +VALUES (@DevId, @DrvId, 'plc', 1, N'{ "HostAddress": "ab://127.0.0.1:44818/1,0" }'); -EXEC dbo.sp_PublishGeneration @ClusterId = @ClusterId, @DraftGenerationId = @Gen, - @Notes = N'AB CIP smoke — task #211'; +INSERT dbo.Tag(TagId, DeviceId, TagGroupId, Name, DataType, AccessLevel, WriteIdempotent, TagConfig) +VALUES (@Tag, @DevId, NULL, 'TestDINT', 'DInt', 'ReadWrite', 1, + N'{ "address": "TestDINT", "dataType": "DInt" }'); + +INSERT dbo.UnsArea(UnsAreaId, ClusterId, Name) VALUES (@AreaId, @ClusterId, 'lab-floor'); +INSERT dbo.UnsLine(UnsLineId, UnsAreaId, Name) VALUES (@LineId, @AreaId, 'abcip-line'); +INSERT dbo.Equipment(EquipmentId, EquipmentUuid, UnsLineId, Name, MachineCode, Enabled) +VALUES (@EqId, @EqUuid, @LineId, 'logix-sim', 'abcip-001', 1); + +INSERT dbo.UnsTagReference(UnsTagReferenceId, EquipmentId, TagId, SortOrder) +VALUES (@RefId, @EqId, @Tag, 0); COMMIT; -PRINT ''; -PRINT 'AB CIP smoke seed complete.'; -PRINT ' Cluster: ' + @ClusterId; -PRINT ' Node: ' + @NodeId; -PRINT ' Generation: ' + CONVERT(nvarchar(20), @Gen); -PRINT ''; -PRINT 'Next steps:'; -PRINT ' 1. Set src/.../Server/appsettings.json Node:NodeId = "abcip-smoke-node"'; -PRINT ' Node:ClusterId = "abcip-smoke"'; -PRINT ' 2. docker compose -f tests/.../AbCip.IntegrationTests/Docker/docker-compose.yml --profile controllogix up -d'; -PRINT ' 3. dotnet run --project src/Server/ZB.MOM.WW.OtOpcUa.Server'; -PRINT ' 4. ./scripts/e2e/test-abcip.ps1 -BridgeNodeId "ns=2;s=TestDINT"'; +PRINT 'AbCip smoke seed complete (v3 schema). Cluster: ' + @ClusterId + ' Node: ' + @NodeId; diff --git a/scripts/smoke/seed-ablegacy-smoke.sql b/scripts/smoke/seed-ablegacy-smoke.sql index 30867c2a..71395ef8 100644 --- a/scripts/smoke/seed-ablegacy-smoke.sql +++ b/scripts/smoke/seed-ablegacy-smoke.sql @@ -1,125 +1,74 @@ --- AB Legacy e2e smoke seed — closes #213 (umbrella #209). +-- AB Legacy (PCCC / SLC-500, MicroLogix) e2e smoke seed — v3 schema (DriverInstance → Device → Tag). -- --- Works against the ab_server PCCC Docker fixture (one of the slc500 / --- micrologix / plc5 compose profiles) or real SLC 500 / MicroLogix / PLC-5 --- hardware. Default HostAddress below points at the Docker fixture with a --- `/1,0` cip-path; libplctag's ab_server rejects empty paths before routing --- to the PCCC dispatcher. Real hardware uses an empty path — change the --- HostAddress to `ab://:44818/` (note the trailing slash with nothing --- after) before running the seed for that setup. --- --- Usage: --- docker compose -f tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.IntegrationTests/Docker/docker-compose.yml --profile slc500 up -d --- sqlcmd -S "localhost,14330" -d OtOpcUaConfig -U sa -P "OtOpcUaDev_2026!" \ --- -i scripts/smoke/seed-ablegacy-smoke.sql +-- Idempotent DELETE-and-recreate pointing at the fixture (ab://127.0.0.1:44818/1,0). To target real +-- hardware, edit the Device's DeviceConfig HostAddress to end with / (trailing slash, no path). +-- v3: the ConfigGeneration/Namespace model + sp_PublishGeneration are gone; the per-device HostAddress +-- moved from DriverConfig.Devices[] into the Device's DeviceConfig (the deviceHostAddress tag key is +-- dropped — the tag's DeviceId FK owns placement now). SET NOCOUNT ON; SET XACT_ABORT ON; SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON; -SET ANSI_PADDING ON; -SET ANSI_WARNINGS ON; -SET ARITHABORT ON; -SET CONCAT_NULL_YIELDS_NULL ON; DECLARE @ClusterId nvarchar(64) = 'ablegacy-smoke'; DECLARE @NodeId nvarchar(64) = 'ablegacy-smoke-node'; DECLARE @DrvId nvarchar(64) = 'ablegacy-smoke-drv'; -DECLARE @NsId nvarchar(64) = 'ablegacy-smoke-ns'; +DECLARE @DevId nvarchar(64) = 'ablegacy-smoke-dev'; DECLARE @AreaId nvarchar(64) = 'ablegacy-smoke-area'; DECLARE @LineId nvarchar(64) = 'ablegacy-smoke-line'; DECLARE @EqId nvarchar(64) = 'ablegacy-smoke-eq'; -DECLARE @EqUuid uniqueidentifier = '5A1D2030-5A1D-4203-A5A1-D20305A1D203'; -DECLARE @TagId nvarchar(64) = 'ablegacy-smoke-tag-n7_5'; +DECLARE @EqUuid uniqueidentifier = 'AB1E9AC0-AB1E-45E0-9AB1-E9AC0AB1E9AC'; +DECLARE @Tag nvarchar(64) = 'ablegacy-smoke-tag-n7-5'; +DECLARE @RefId nvarchar(64) = 'ablegacy-smoke-ref-n7-5'; BEGIN TRAN; -DELETE FROM dbo.Tag WHERE TagId IN (@TagId); -DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; -DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; -DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; -DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; -DELETE FROM dbo.Namespace WHERE NamespaceId = @NsId; -DELETE FROM dbo.ConfigGeneration WHERE ClusterId = @ClusterId; -DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNodeGenerationState WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; -DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; - +DELETE FROM dbo.UnsTagReference WHERE UnsTagReferenceId = @RefId; +DELETE FROM dbo.Tag WHERE TagId = @Tag; +DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; +DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; +DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; +DELETE FROM dbo.Device WHERE DeviceId = @DevId; +DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; +DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; +DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; +DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; DELETE FROM dbo.ClusterNodeCredential WHERE Kind = 'SqlLogin' AND Value = 'sa'; INSERT dbo.ServerCluster(ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, CreatedBy) -VALUES (@ClusterId, 'AB Legacy Smoke', 'zb', 'lab', 1, 'None', 1, 'ablegacy-smoke'); +VALUES (@ClusterId, 'AbLegacy Smoke', 'zb', 'lab', 1, 'None', 1, 'ablegacy-smoke'); -INSERT dbo.ClusterNode(NodeId, ClusterId, RedundancyRole, Host, OpcUaPort, DashboardPort, +INSERT dbo.ClusterNode(NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) -VALUES (@NodeId, @ClusterId, 'Primary', 'localhost', 4840, 15050, - 'urn:OtOpcUa:ablegacy-smoke-node', 200, 1, 'ablegacy-smoke'); +VALUES (@NodeId, @ClusterId, 'localhost', 4840, 15050, 'urn:OtOpcUa:ablegacy-smoke-node', 200, 1, 'ablegacy-smoke'); INSERT dbo.ClusterNodeCredential(NodeId, Kind, Value, Enabled, CreatedBy) VALUES (@NodeId, 'SqlLogin', 'sa', 1, 'ablegacy-smoke'); -DECLARE @Gen bigint; -INSERT dbo.ConfigGeneration(ClusterId, Status, CreatedBy) -VALUES (@ClusterId, 'Draft', 'ablegacy-smoke'); -SET @Gen = SCOPE_IDENTITY(); - -INSERT dbo.Namespace(GenerationId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled) -VALUES (@Gen, @NsId, @ClusterId, 'Equipment', 'urn:ablegacy-smoke:eq', 1); - -INSERT dbo.UnsArea(GenerationId, UnsAreaId, ClusterId, Name) -VALUES (@Gen, @AreaId, @ClusterId, 'lab-floor'); - -INSERT dbo.UnsLine(GenerationId, UnsLineId, UnsAreaId, Name) -VALUES (@Gen, @LineId, @AreaId, 'ablegacy-line'); - -INSERT dbo.Equipment(GenerationId, EquipmentId, EquipmentUuid, DriverInstanceId, UnsLineId, - Name, MachineCode, Enabled) -VALUES (@Gen, @EqId, @EqUuid, @DrvId, @LineId, 'slc-sim', 'ablegacy-001', 1); - --- AB Legacy DriverInstance — SLC 500 target. Replace the placeholder gateway --- `192.168.1.10` with the real PLC / RSEmulate host before running. -INSERT dbo.DriverInstance(GenerationId, DriverInstanceId, ClusterId, NamespaceId, - Name, DriverType, DriverConfig, Enabled) -VALUES (@Gen, @DrvId, @ClusterId, @NsId, 'ablegacy-smoke', 'AbLegacy', N'{ - "TimeoutMs": 2000, - "Devices": [ - { - "HostAddress": "ab://127.0.0.1:44818/1,0", - "PlcFamily": "Slc500", - "DeviceName": "slc-500" - } - ], - "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000, "ProbeAddress": "S:0" }, - "Tags": [ - { - "Name": "N7_5", - "DeviceHostAddress": "ab://127.0.0.1:44818/1,0", - "Address": "N7:5", - "DataType": "Int", - "Writable": true, - "WriteIdempotent": true - } - ] +-- DriverConfig keeps protocol/channel settings; per-device HostAddress moves to DeviceConfig. +INSERT dbo.DriverInstance(DriverInstanceId, ClusterId, RawFolderId, Name, DriverType, DriverConfig, Enabled) +VALUES (@DrvId, @ClusterId, NULL, 'slc-smoke', 'AbLegacy', N'{ + "ProbeTimeoutSeconds": 5, + "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000, "ProbeAddress": "S:0" } }', 1); -INSERT dbo.Tag(GenerationId, TagId, DriverInstanceId, EquipmentId, Name, DataType, - AccessLevel, TagConfig, WriteIdempotent) -VALUES (@Gen, @TagId, @DrvId, @EqId, 'N7_5', 'Int16', 'ReadWrite', - N'{"FullName":"N7_5","Address":"N7:5","DataType":"Int"}', 1); +-- DeviceConfig shape finalized against reworked options in Wave B (WP5). +INSERT dbo.Device(DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig) +VALUES (@DevId, @DrvId, 'plc', 1, N'{ "HostAddress": "ab://127.0.0.1:44818/1,0" }'); -EXEC dbo.sp_PublishGeneration @ClusterId = @ClusterId, @DraftGenerationId = @Gen, - @Notes = N'AB Legacy smoke — task #213'; +INSERT dbo.Tag(TagId, DeviceId, TagGroupId, Name, DataType, AccessLevel, WriteIdempotent, TagConfig) +VALUES (@Tag, @DevId, NULL, 'N7_5', 'Int', 'ReadWrite', 1, + N'{ "address": "N7:5", "dataType": "Int" }'); + +INSERT dbo.UnsArea(UnsAreaId, ClusterId, Name) VALUES (@AreaId, @ClusterId, 'lab-floor'); +INSERT dbo.UnsLine(UnsLineId, UnsAreaId, Name) VALUES (@LineId, @AreaId, 'ablegacy-line'); +INSERT dbo.Equipment(EquipmentId, EquipmentUuid, UnsLineId, Name, MachineCode, Enabled) +VALUES (@EqId, @EqUuid, @LineId, 'slc-sim', 'ablegacy-001', 1); + +INSERT dbo.UnsTagReference(UnsTagReferenceId, EquipmentId, TagId, SortOrder) +VALUES (@RefId, @EqId, @Tag, 0); COMMIT; -PRINT ''; -PRINT 'AB Legacy smoke seed complete.'; -PRINT ' Cluster: ' + @ClusterId; -PRINT ' Node: ' + @NodeId; -PRINT ' Generation: ' + CONVERT(nvarchar(20), @Gen); -PRINT ''; -PRINT 'NOTE: default points at the ab_server slc500 Docker fixture with a /1,0'; -PRINT ' cip-path (required by ab_server). For real SLC/MicroLogix/PLC-5'; -PRINT ' hardware, edit the DriverConfig HostAddress to end with /'; -PRINT ' e.g. "ab://:44818/" and re-run this seed.'; +PRINT 'AbLegacy smoke seed complete (v3 schema). Cluster: ' + @ClusterId + ' Node: ' + @NodeId; diff --git a/scripts/smoke/seed-modbus-smoke.sql b/scripts/smoke/seed-modbus-smoke.sql index 3ebb4c3f..2eeb3841 100644 --- a/scripts/smoke/seed-modbus-smoke.sql +++ b/scripts/smoke/seed-modbus-smoke.sql @@ -1,156 +1,101 @@ --- Modbus e2e smoke seed — closes #210 (umbrella #209). +-- Modbus e2e smoke seed — v3 schema (Raw tree: DriverInstance → Device → Tag; UNS by reference). -- --- Idempotent — DROP-and-recreate of one cluster's worth of Modbus test config: --- * 1 ServerCluster ('modbus-smoke') + ClusterNode ('modbus-smoke-node') --- * 1 ConfigGeneration (Draft → Published at the end) --- * 1 Namespace + UnsArea + UnsLine + Equipment --- * 1 Modbus DriverInstance pointing at the pymodbus standard fixture --- (127.0.0.1:5020 per tests/.../Modbus.IntegrationTests/Docker) --- * 1 Tag at HR[200]:UInt16 (HR[100] is auto-increment in standard.json, +-- Idempotent — DELETE-and-recreate of one cluster's worth of Modbus test config: +-- * 1 ServerCluster ('modbus-smoke') + ClusterNode ('modbus-smoke-node') + SqlLogin credential +-- * 1 Modbus DriverInstance at the cluster root (RawFolderId NULL) +-- * 1 Device carrying the pymodbus endpoint in DeviceConfig +-- * 1 Tag at HR[200]:UInt16 under the device (HR[100] is auto-increment in standard.json, -- unusable as a write target — the e2e script uses HR[200] for that reason) +-- * 1 UnsArea/UnsLine/Equipment + a UnsTagReference projecting the raw tag into UNS +-- +-- v3 changes vs. the pre-v2 original: the ConfigGeneration/GenerationId/Namespace model and the +-- sp_PublishGeneration publish step are gone (deploy is a C# ControlPlane operation now); the +-- connection endpoint moved from DriverConfig into the Device's DeviceConfig. -- -- Usage: --- sqlcmd -S "localhost,14330" -d OtOpcUaConfig -U sa -P "OtOpcUaDev_2026!" \ --- -i scripts/smoke/seed-modbus-smoke.sql --- --- After seeding, update src/.../Server/appsettings.json: --- Node:NodeId = "modbus-smoke-node" --- Node:ClusterId = "modbus-smoke" --- --- Then start the simulator + server + run the e2e script: --- docker compose -f tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Docker/docker-compose.yml --profile standard up -d --- dotnet run --project src/Server/ZB.MOM.WW.OtOpcUa.Server --- ./scripts/e2e/test-modbus.ps1 -BridgeNodeId "ns=2;s=HR200" +-- sqlcmd -S "10.100.0.35,14330" -d -U sa -P "" -i scripts/smoke/seed-modbus-smoke.sql SET NOCOUNT ON; SET XACT_ABORT ON; SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON; -SET ANSI_PADDING ON; -SET ANSI_WARNINGS ON; -SET ARITHABORT ON; -SET CONCAT_NULL_YIELDS_NULL ON; DECLARE @ClusterId nvarchar(64) = 'modbus-smoke'; DECLARE @NodeId nvarchar(64) = 'modbus-smoke-node'; DECLARE @DrvId nvarchar(64) = 'modbus-smoke-drv'; -DECLARE @NsId nvarchar(64) = 'modbus-smoke-ns'; +DECLARE @DevId nvarchar(64) = 'modbus-smoke-dev'; DECLARE @AreaId nvarchar(64) = 'modbus-smoke-area'; DECLARE @LineId nvarchar(64) = 'modbus-smoke-line'; DECLARE @EqId nvarchar(64) = 'modbus-smoke-eq'; DECLARE @EqUuid uniqueidentifier = '72BD5A10-72BD-45A1-B72B-D5A1072BD5A1'; DECLARE @TagHr200 nvarchar(64) = 'modbus-smoke-tag-hr200'; +DECLARE @RefId nvarchar(64) = 'modbus-smoke-ref-hr200'; BEGIN TRAN; -- Clean prior smoke state (child rows first). -DELETE FROM dbo.Tag WHERE TagId IN (@TagHr200); -DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; -DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; -DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; -DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; -DELETE FROM dbo.Namespace WHERE NamespaceId = @NsId; -DELETE FROM dbo.ConfigGeneration WHERE ClusterId = @ClusterId; -DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNodeGenerationState WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; -DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; +DELETE FROM dbo.UnsTagReference WHERE UnsTagReferenceId = @RefId; +DELETE FROM dbo.Tag WHERE TagId = @TagHr200; +DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; +DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; +DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; +DELETE FROM dbo.Device WHERE DeviceId = @DevId; +DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; +DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; +DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; +DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; --- `UX_ClusterNodeCredential_Value` is a unique index on (Kind, Value) WHERE --- Enabled=1, so a `sa` login can only bind to one node at a time. Drop any --- prior smoke cluster's binding before we claim the login for this one. +-- `UX_ClusterNodeCredential_Value` is a unique index on (Kind, Value) WHERE Enabled=1, so the +-- `sa` login can only bind to one node at a time. Drop any prior smoke binding first. DELETE FROM dbo.ClusterNodeCredential WHERE Kind = 'SqlLogin' AND Value = 'sa'; --- 1. Cluster + Node. +-- 1. Cluster + Node + credential binding. INSERT dbo.ServerCluster(ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, CreatedBy) VALUES (@ClusterId, 'Modbus Smoke', 'zb', 'lab', 1, 'None', 1, 'modbus-smoke'); --- DashboardPort 15050 rather than 5000 — HttpListener on :5000 requires --- URL-ACL reservation or admin rights on Windows (HttpListenerException 32). --- 15000+ ports are unreserved by default. Safe to change back when deploying --- with a netsh urlacl grant or reverse-proxy fronting :5000. -INSERT dbo.ClusterNode(NodeId, ClusterId, RedundancyRole, Host, OpcUaPort, DashboardPort, +INSERT dbo.ClusterNode(NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) -VALUES (@NodeId, @ClusterId, 'Primary', 'localhost', 4840, 15050, +VALUES (@NodeId, @ClusterId, 'localhost', 4840, 15050, 'urn:OtOpcUa:modbus-smoke-node', 200, 1, 'modbus-smoke'); --- Bind the SQL login this smoke test connects as to the node identity. The --- sp_GetCurrentGenerationForCluster + sp_UpdateClusterNodeGenerationState --- sprocs raise RAISERROR('Unauthorized: caller %s is not bound to NodeId %s') --- when this row is missing. `Kind='SqlLogin'` / `Value='sa'` matches the --- container's SA user; rotate Value for real deployments using a non-SA login. INSERT dbo.ClusterNodeCredential(NodeId, Kind, Value, Enabled, CreatedBy) VALUES (@NodeId, 'SqlLogin', 'sa', 1, 'modbus-smoke'); --- 2. Draft generation. -DECLARE @Gen bigint; -INSERT dbo.ConfigGeneration(ClusterId, Status, CreatedBy) -VALUES (@ClusterId, 'Draft', 'modbus-smoke'); -SET @Gen = SCOPE_IDENTITY(); - --- 3. Namespace. -INSERT dbo.Namespace(GenerationId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled) -VALUES (@Gen, @NsId, @ClusterId, 'Equipment', 'urn:modbus-smoke:eq', 1); - --- 4. UNS hierarchy. -INSERT dbo.UnsArea(GenerationId, UnsAreaId, ClusterId, Name) -VALUES (@Gen, @AreaId, @ClusterId, 'lab-floor'); - -INSERT dbo.UnsLine(GenerationId, UnsLineId, UnsAreaId, Name) -VALUES (@Gen, @LineId, @AreaId, 'modbus-line'); - -INSERT dbo.Equipment(GenerationId, EquipmentId, EquipmentUuid, DriverInstanceId, UnsLineId, - Name, MachineCode, Enabled) -VALUES (@Gen, @EqId, @EqUuid, @DrvId, @LineId, 'modbus-sim', 'modbus-001', 1); - --- 5. Modbus DriverInstance. DriverConfig mirrors ModbusDriverConfigDto --- (mapped to ModbusDriverOptions by ModbusDriverFactoryExtensions). -INSERT dbo.DriverInstance(GenerationId, DriverInstanceId, ClusterId, NamespaceId, - Name, DriverType, DriverConfig, Enabled) -VALUES (@Gen, @DrvId, @ClusterId, @NsId, 'pymodbus-smoke', 'Modbus', N'{ - "Host": "127.0.0.1", - "Port": 5020, - "UnitId": 1, +-- 2. Modbus DriverInstance at the cluster root (RawFolderId NULL). DriverConfig keeps protocol/ +-- channel settings only — the endpoint (Host/Port/UnitId) now lives in the Device's DeviceConfig. +INSERT dbo.DriverInstance(DriverInstanceId, ClusterId, RawFolderId, Name, DriverType, DriverConfig, Enabled) +VALUES (@DrvId, @ClusterId, NULL, 'pymodbus-smoke', 'Modbus', N'{ "TimeoutMs": 2000, "AutoReconnect": true, - "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000, "ProbeAddress": 0 }, - "Tags": [ - { - "Name": "HR200", - "Region": "HoldingRegisters", - "Address": 200, - "DataType": "UInt16", - "Writable": true, - "WriteIdempotent": true - } - ] + "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000, "ProbeAddress": 0 } }', 1); --- 6. Tag row bound to the Equipment. Driver reports the same tag via --- DiscoverAsync + the walker maps the UnsArea/Line/Equipment/Tag path to the --- driver's folder/variable (NodeId ends up ns=;s=HR200 per --- ModbusDriver.DiscoverAsync using FullName = tag.Name). -INSERT dbo.Tag(GenerationId, TagId, DriverInstanceId, EquipmentId, Name, DataType, - AccessLevel, TagConfig, WriteIdempotent) -VALUES (@Gen, @TagHr200, @DrvId, @EqId, 'HR200', 'UInt16', 'ReadWrite', - N'{"FullName":"HR200","DataType":"UInt16"}', 1); +-- 3. Device — endpoint. DeviceConfig shape finalized against reworked options in Wave B (WP5). +INSERT dbo.Device(DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig) +VALUES (@DevId, @DrvId, 'plc', 1, N'{ "Host": "127.0.0.1", "Port": 5020, "UnitId": 1 }'); --- 7. Publish the generation — flips Status Draft → Published, merges --- ExternalIdReservation, claims cluster write lock. -EXEC dbo.sp_PublishGeneration @ClusterId = @ClusterId, @DraftGenerationId = @Gen, - @Notes = N'Modbus smoke — task #210'; +-- 4. Raw tag under the device (identity = RawPath; TagConfig carries the driver address only). +INSERT dbo.Tag(TagId, DeviceId, TagGroupId, Name, DataType, AccessLevel, WriteIdempotent, TagConfig) +VALUES (@TagHr200, @DevId, NULL, 'HR200', 'UInt16', 'ReadWrite', 1, + N'{ "region": "HoldingRegisters", "address": 200, "dataType": "UInt16", "writable": true }'); + +-- 5. UNS hierarchy + a reference projecting the raw tag into the equipment. +INSERT dbo.UnsArea(UnsAreaId, ClusterId, Name) VALUES (@AreaId, @ClusterId, 'lab-floor'); +INSERT dbo.UnsLine(UnsLineId, UnsAreaId, Name) VALUES (@LineId, @AreaId, 'modbus-line'); +INSERT dbo.Equipment(EquipmentId, EquipmentUuid, UnsLineId, Name, MachineCode, Enabled) +VALUES (@EqId, @EqUuid, @LineId, 'modbus-sim', 'modbus-001', 1); + +INSERT dbo.UnsTagReference(UnsTagReferenceId, EquipmentId, TagId, SortOrder) +VALUES (@RefId, @EqId, @TagHr200, 0); COMMIT; PRINT ''; -PRINT 'Modbus smoke seed complete.'; -PRINT ' Cluster: ' + @ClusterId; -PRINT ' Node: ' + @NodeId; -PRINT ' Generation: ' + CONVERT(nvarchar(20), @Gen); +PRINT 'Modbus smoke seed complete (v3 schema).'; +PRINT ' Cluster: ' + @ClusterId + ' Node: ' + @NodeId; PRINT ''; PRINT 'Next steps:'; -PRINT ' 1. Set src/.../Server/appsettings.json Node:NodeId = "modbus-smoke-node"'; -PRINT ' Node:ClusterId = "modbus-smoke"'; +PRINT ' 1. Set Server appsettings Node:NodeId = "modbus-smoke-node" / Node:ClusterId = "modbus-smoke"'; PRINT ' 2. docker compose -f tests/.../Modbus.IntegrationTests/Docker/docker-compose.yml --profile standard up -d'; PRINT ' 3. dotnet run --project src/Server/ZB.MOM.WW.OtOpcUa.Server'; -PRINT ' 4. ./scripts/e2e/test-modbus.ps1 -BridgeNodeId "ns=2;s=HR200"'; +PRINT ' 4. Deploy the config via the AdminUI/ControlPlane, then ./scripts/e2e/test-modbus.ps1'; diff --git a/scripts/smoke/seed-phase-7-smoke.sql b/scripts/smoke/seed-phase-7-smoke.sql index 707531d6..960d5a89 100644 --- a/scripts/smoke/seed-phase-7-smoke.sql +++ b/scripts/smoke/seed-phase-7-smoke.sql @@ -1,186 +1,120 @@ --- Phase 7 live OPC UA E2E smoke seed (task #240). +-- Phase 7 live OPC UA E2E smoke seed — v3 schema (Raw tree + UNS-by-reference + scripting). -- --- Idempotent — DROP-and-recreate of one cluster's worth of test config: --- * 1 ServerCluster ('p7-smoke') --- * 1 ClusterNode ('p7-smoke-node') --- * 1 ConfigGeneration (created Draft, then flipped to Published at the end) --- * 1 Namespace (Equipment kind) --- * 1 UnsArea / UnsLine / Equipment / Tag — Tag bound to a real Galaxy attribute --- * 1 DriverInstance (Galaxy) --- * 1 Script + 1 VirtualTag using it --- * 1 Script + 1 ScriptedAlarm using it +-- Idempotent DELETE-and-recreate of one cluster's worth of test config: +-- * 1 ServerCluster ('p7-smoke') + ClusterNode + SqlLogin credential +-- * 1 Galaxy (GalaxyMxGateway) DriverInstance at the cluster root + 1 Device (gateway endpoint) +-- * 1 raw Tag bound to a Galaxy attribute (identity = RawPath; address in TagConfig.attributeRef) +-- * 1 UnsArea / UnsLine / Equipment + a UnsTagReference projecting the raw tag into UNS +-- * 1 Script + 1 VirtualTag using it; 1 Script + 1 ScriptedAlarm using it -- --- Drop & re-create deletes ALL rows scoped to the cluster (in dependency order) --- so re-running this script after a code change starts from a clean state. --- Table-level CHECK constraints are validated on insert; if a constraint is --- violated this script aborts with the offending row's column. --- --- Usage: --- sqlcmd -S "localhost,14330" -d OtOpcUaConfig -U sa -P "OtOpcUaDev_2026!" \ --- -i scripts/smoke/seed-phase-7-smoke.sql +-- v3 changes: ConfigGeneration/GenerationId/Namespace model + sp_PublishGeneration are gone (deploy +-- is a C# ControlPlane operation); Galaxy driver type is 'GalaxyMxGateway'; the gateway endpoint +-- lives in the Device's DeviceConfig; ctx.GetTag / alarm-message tokens take a RawPath. The exact +-- Galaxy TagConfig key ('attributeRef') + scripting RawPath contract are finalized in WP2/WP3/WP4. SET NOCOUNT ON; SET XACT_ABORT ON; SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON; -SET ANSI_PADDING ON; -SET ANSI_WARNINGS ON; -SET ARITHABORT ON; -SET CONCAT_NULL_YIELDS_NULL ON; DECLARE @ClusterId nvarchar(64) = 'p7-smoke'; DECLARE @NodeId nvarchar(64) = 'p7-smoke-node'; DECLARE @DrvId nvarchar(64) = 'p7-smoke-galaxy'; -DECLARE @NsId nvarchar(64) = 'p7-smoke-ns'; +DECLARE @DevId nvarchar(64) = 'p7-smoke-dev'; DECLARE @AreaId nvarchar(64) = 'p7-smoke-area'; DECLARE @LineId nvarchar(64) = 'p7-smoke-line'; DECLARE @EqId nvarchar(64) = 'p7-smoke-eq'; DECLARE @EqUuid uniqueidentifier = '5B2CF10D-5B2C-4F10-B5B2-CF10D5B2CF10'; DECLARE @TagId nvarchar(64) = 'p7-smoke-tag-source'; +DECLARE @RefId nvarchar(64) = 'p7-smoke-ref-source'; DECLARE @VtScript nvarchar(64) = 'p7-smoke-script-vt'; DECLARE @AlScript nvarchar(64) = 'p7-smoke-script-al'; DECLARE @VtId nvarchar(64) = 'p7-smoke-vt-derived'; DECLARE @AlId nvarchar(64) = 'p7-smoke-al-overtemp'; +-- RawPath of the source tag: // (cluster root, no folder/group). +DECLARE @RawPath nvarchar(256) = N'galaxy-smoke/plc/Source'; + BEGIN TRAN; --- Wipe any prior smoke state. Order matters: child rows first. -DELETE s FROM dbo.ScriptedAlarmState s - WHERE s.ScriptedAlarmId = @AlId; -DELETE FROM dbo.ScriptedAlarm WHERE ScriptedAlarmId = @AlId; -DELETE FROM dbo.VirtualTag WHERE VirtualTagId = @VtId; -DELETE FROM dbo.Script WHERE ScriptId IN (@VtScript, @AlScript); -DELETE FROM dbo.Tag WHERE TagId = @TagId; -DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; -DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; -DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; -DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; -DELETE FROM dbo.Namespace WHERE NamespaceId = @NsId; -DELETE FROM dbo.ConfigGeneration WHERE ClusterId = @ClusterId; +-- Wipe prior smoke state. Order matters: child rows first. +DELETE FROM dbo.ScriptedAlarmState WHERE ScriptedAlarmId = @AlId; +DELETE FROM dbo.ScriptedAlarm WHERE ScriptedAlarmId = @AlId; +DELETE FROM dbo.VirtualTag WHERE VirtualTagId = @VtId; +DELETE FROM dbo.Script WHERE ScriptId IN (@VtScript, @AlScript); +DELETE FROM dbo.UnsTagReference WHERE UnsTagReferenceId = @RefId; +DELETE FROM dbo.Tag WHERE TagId = @TagId; +DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; +DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; +DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; +DELETE FROM dbo.Device WHERE DeviceId = @DevId; +DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNodeGenerationState WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; -DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; +DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; +DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; +DELETE FROM dbo.ClusterNodeCredential WHERE Kind = 'SqlLogin' AND Value = 'sa'; --- 1. Cluster + Node +-- 1. Cluster + Node + credential binding. INSERT dbo.ServerCluster(ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, CreatedBy) VALUES (@ClusterId, 'P7 Smoke', 'zb', 'lab', 1, 'None', 1, 'p7-smoke'); -INSERT dbo.ClusterNode(NodeId, ClusterId, RedundancyRole, Host, OpcUaPort, DashboardPort, +INSERT dbo.ClusterNode(NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) -VALUES (@NodeId, @ClusterId, 'Primary', 'localhost', 4840, 5000, - 'urn:OtOpcUa:p7-smoke-node', 200, 1, 'p7-smoke'); +VALUES (@NodeId, @ClusterId, 'localhost', 4840, 5000, 'urn:OtOpcUa:p7-smoke-node', 200, 1, 'p7-smoke'); --- sp_GetCurrentGenerationForCluster gates access by SUSER_SNAME() against --- ClusterNodeCredential; without this binding the Server bootstrap fails with --- `Unauthorized: caller sa is not bound to NodeId p7-smoke-node`. Dev Docker --- SQL runs with `sa`; production deploys would rotate to a per-node login. INSERT dbo.ClusterNodeCredential(NodeId, Kind, Value, Enabled, CreatedBy) VALUES (@NodeId, N'SqlLogin', N'sa', 1, N'p7-smoke'); --- 2. Generation (created Draft, flipped to Published at the end so insert order --- constraints (one Draft per cluster, etc.) don't fight us). -DECLARE @Gen bigint; -INSERT dbo.ConfigGeneration(ClusterId, Status, CreatedBy) -VALUES (@ClusterId, 'Draft', 'p7-smoke'); -SET @Gen = SCOPE_IDENTITY(); - --- 3. Namespace -INSERT dbo.Namespace(GenerationId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled) -VALUES (@Gen, @NsId, @ClusterId, 'Equipment', 'urn:p7-smoke:eq', 1); - --- 4. UNS hierarchy -INSERT dbo.UnsArea(GenerationId, UnsAreaId, ClusterId, Name) -VALUES (@Gen, @AreaId, @ClusterId, 'lab-floor'); - -INSERT dbo.UnsLine(GenerationId, UnsLineId, UnsAreaId, Name) -VALUES (@Gen, @LineId, @AreaId, 'galaxy-line'); - -INSERT dbo.Equipment(GenerationId, EquipmentId, EquipmentUuid, DriverInstanceId, UnsLineId, - Name, MachineCode, Enabled) -VALUES (@Gen, @EqId, @EqUuid, @DrvId, @LineId, 'reactor-1', 'p7-rx-001', 1); - --- 5. Driver — Galaxy proxy. DriverConfig JSON tells the proxy how to reach the --- already-running OtOpcUaGalaxyHost. Secret + pipe name match --- .local/galaxy-host-secret.txt + the OtOpcUaGalaxyHost service env. -INSERT dbo.DriverInstance(GenerationId, DriverInstanceId, ClusterId, NamespaceId, - Name, DriverType, DriverConfig, Enabled) -VALUES (@Gen, @DrvId, @ClusterId, @NsId, 'galaxy-smoke', 'Galaxy', N'{ - "DriverInstanceId": "p7-smoke-galaxy", - "PipeName": "OtOpcUaGalaxy", - "SharedSecret": "4hgDJ4jLcKXmOmD1Ara8xtE8N3R47Q2y1Xf/Eama/Fk=", +-- 2. Galaxy driver at the cluster root. DriverConfig keeps non-endpoint settings; the mxaccessgw +-- gateway endpoint lives in the Device's DeviceConfig (shape finalized in Wave B / WP5). +INSERT dbo.DriverInstance(DriverInstanceId, ClusterId, RawFolderId, Name, DriverType, DriverConfig, Enabled) +VALUES (@DrvId, @ClusterId, NULL, 'galaxy-smoke', 'GalaxyMxGateway', N'{ "ConnectTimeoutMs": 10000 }', 1); --- 6. One driver-sourced Tag bound to the Equipment. TagConfig is the Galaxy --- fullRef; the EquipmentNodeWalker reads the JSON's FullName field and --- hands that string to the Galaxy driver as the MXAccess reference. --- Default points at TestMachine_001.TestHistoryValue — the live dev-box --- Galaxy ships it as Int32 + writable (security_classification=Operate) --- + historized (HistoryExtension primitive), so the E2E script can --- exercise read + write + subscribe + alarm + history against the --- same attribute. Swap to any other writable historized attribute on --- this Galaxy by re-running `gr/queries/attributes_extended.sql` with --- `WHERE is_historized=1 AND security_classification > 0`. -INSERT dbo.Tag(GenerationId, TagId, DriverInstanceId, EquipmentId, Name, DataType, - AccessLevel, TagConfig, WriteIdempotent) -VALUES (@Gen, @TagId, @DrvId, @EqId, 'Source', 'Int32', 'ReadWrite', - N'{"FullName":"TestMachine_001.TestHistoryValue","DataType":"Int32"}', 0); +INSERT dbo.Device(DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig) +VALUES (@DevId, @DrvId, 'plc', 1, N'{ "GatewayAddress": "http://127.0.0.1:5001", "ClientName": "p7-smoke" }'); --- 7. Scripts (SourceHash is SHA-256 of SourceCode, computed externally — using --- a placeholder here; the engine recomputes on first use anyway). --- --- MachineStatus predicate — the dynamic "is the machine running?" status --- derived from the raw Source value. Boolean: true when Source > 0. Matches --- the shape Aveva operators typically want on a machine-status tile (green --- when above zero, otherwise grey) without needing a separate threshold --- attribute. Rename + re-threshold here to mirror site semantics. -INSERT dbo.Script(GenerationId, ScriptId, Name, SourceCode, SourceHash, Language) +-- 3. Raw tag bound to a Galaxy attribute. Identity is its RawPath; the MXAccess reference lives in +-- TagConfig.attributeRef (v3 Galaxy address key; finalized in WP2/WP3). +INSERT dbo.Tag(TagId, DeviceId, TagGroupId, Name, DataType, AccessLevel, WriteIdempotent, TagConfig) +VALUES (@TagId, @DevId, NULL, 'Source', 'Int32', 'ReadWrite', 0, + N'{ "attributeRef": "TestMachine_001.TestHistoryValue", "dataType": "Int32" }'); + +-- 4. UNS hierarchy + reference into the equipment. +INSERT dbo.UnsArea(UnsAreaId, ClusterId, Name) VALUES (@AreaId, @ClusterId, 'lab-floor'); +INSERT dbo.UnsLine(UnsLineId, UnsAreaId, Name) VALUES (@LineId, @AreaId, 'galaxy-line'); +INSERT dbo.Equipment(EquipmentId, EquipmentUuid, UnsLineId, Name, MachineCode, Enabled) +VALUES (@EqId, @EqUuid, @LineId, 'reactor-1', 'p7-rx-001', 1); + +INSERT dbo.UnsTagReference(UnsTagReferenceId, EquipmentId, TagId, SortOrder) +VALUES (@RefId, @EqId, @TagId, 0); + +-- 5. Scripts. ctx.GetTag takes a RawPath in v3 (SourceHash placeholder; the engine recomputes). +INSERT dbo.Script(ScriptId, Name, SourceCode, SourceHash, Language) VALUES - (@Gen, @VtScript, 'machine-status-predicate', - N'return System.Convert.ToInt32(ctx.GetTag("/lab-floor/galaxy-line/reactor-1/Source").Value) > 0;', + (@VtScript, 'machine-status-predicate', + N'return System.Convert.ToInt32(ctx.GetTag("' + @RawPath + N'").Value) > 0;', '0000000000000000000000000000000000000000000000000000000000000000', 'CSharp'), - (@Gen, @AlScript, 'overtemp-predicate', - N'return System.Convert.ToInt32(ctx.GetTag("/lab-floor/galaxy-line/reactor-1/Source").Value) > 50;', + (@AlScript, 'overtemp-predicate', + N'return System.Convert.ToInt32(ctx.GetTag("' + @RawPath + N'").Value) > 50;', '0000000000000000000000000000000000000000000000000000000000000000', 'CSharp'); --- 8. VirtualTag — MachineStatus boolean computed by Roslyn each time Source --- changes. Historized so the dashboard can plot a running/idle timeline --- next to the raw TestHistoryValue trend from Aveva Historian. -INSERT dbo.VirtualTag(GenerationId, VirtualTagId, EquipmentId, Name, DataType, +-- 6. VirtualTag — MachineStatus boolean computed on each Source change. +INSERT dbo.VirtualTag(VirtualTagId, EquipmentId, Name, DataType, ScriptId, ChangeTriggered, TimerIntervalMs, Historize, Enabled) -VALUES (@Gen, @VtId, @EqId, 'MachineStatus', 'Boolean', @VtScript, 1, NULL, 1, 1); +VALUES (@VtId, @EqId, 'MachineStatus', 'Boolean', @VtScript, 1, NULL, 1, 1); --- 9. ScriptedAlarm — Active when Source > 50. -INSERT dbo.ScriptedAlarm(GenerationId, ScriptedAlarmId, EquipmentId, Name, AlarmType, +-- 7. ScriptedAlarm — Active when Source > 50. {token} is a RawPath in v3. +INSERT dbo.ScriptedAlarm(ScriptedAlarmId, EquipmentId, Name, AlarmType, Severity, MessageTemplate, PredicateScriptId, HistorizeToAveva, Retain, Enabled) -VALUES (@Gen, @AlId, @EqId, 'OverTemp', 'LimitAlarm', 800, - N'Reactor source value {/lab-floor/galaxy-line/reactor-1/Source} exceeded 50', +VALUES (@AlId, @EqId, 'OverTemp', 'LimitAlarm', 800, + N'Reactor source value {' + @RawPath + N'} exceeded 50', @AlScript, 1, 1, 1); --- 10. Publish — flip the generation Status. sp_PublishGeneration takes --- concurrency locks + does ExternalIdReservation merging; we drive it via --- EXEC rather than UPDATE so the rest of the publish workflow runs. -EXEC dbo.sp_PublishGeneration @ClusterId = @ClusterId, @DraftGenerationId = @Gen, - @Notes = N'Phase 7 live smoke — task #240'; - COMMIT; PRINT ''; -PRINT 'Phase 7 smoke seed complete.'; -PRINT ' Cluster: ' + @ClusterId; -PRINT ' Node: ' + @NodeId + ' (set Node:NodeId in appsettings.json)'; -PRINT ' Generation: ' + CONVERT(nvarchar(20), @Gen); -PRINT ''; -PRINT 'Next steps:'; -PRINT ' 1. Edit src/Server/ZB.MOM.WW.OtOpcUa.Server/appsettings.json:'; -PRINT ' Node:NodeId = "p7-smoke-node"'; -PRINT ' Node:ClusterId = "p7-smoke"'; -PRINT ' 2. Edit the placeholder Galaxy attribute in dbo.Tag.TagConfig above'; -PRINT ' so it points at a real attribute on this Galaxy — replace'; -PRINT ' REPLACE_WITH_REAL_GALAXY_ATTRIBUTE with e.g. "Plant1.Reactor1.Temp".'; -PRINT ' 3. Start the Server in a non-elevated shell so the Galaxy.Host pipe ACL'; -PRINT ' accepts the connection:'; -PRINT ' dotnet run --project src/Server/ZB.MOM.WW.OtOpcUa.Server'; -PRINT ' 4. Validate via Client.CLI per docs/v2/implementation/phase-7-e2e-smoke.md'; +PRINT 'Phase 7 smoke seed complete (v3 schema). Cluster: ' + @ClusterId + ' Node: ' + @NodeId; +PRINT 'Next: set Server Node:NodeId/ClusterId, deploy via the ControlPlane, then run the Client.CLI checks.'; diff --git a/scripts/smoke/seed-s7-smoke.sql b/scripts/smoke/seed-s7-smoke.sql index 8b5c2f31..911a573a 100644 --- a/scripts/smoke/seed-s7-smoke.sql +++ b/scripts/smoke/seed-s7-smoke.sql @@ -1,127 +1,74 @@ --- S7 e2e smoke seed — closes #212 (umbrella #209). +-- S7 e2e smoke seed — v3 schema (Raw tree: DriverInstance → Device → Tag; UNS by reference). -- --- One-cluster seed pointing at the python-snap7 fixture --- (`docker compose -f tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/Docker/docker-compose.yml --profile s7_1500 up -d`). --- python-snap7 listens on port 1102 (non-priv); real S7 CPUs listen on 102. --- Publishes one Int16 tag at DB1.DBW0 under `ns=;s=DB1_DBW0` (driver --- sanitises the dot for browse names — see S7Driver.DiscoverAsync). +-- Idempotent DELETE-and-recreate of one cluster's worth of S7 test config pointing at the snap7 +-- fixture (127.0.0.1:1102). v3: the ConfigGeneration/Namespace model + sp_PublishGeneration are +-- gone; the endpoint (Host/Port/Rack/Slot) moved from DriverConfig into the Device's DeviceConfig. -- --- Usage: --- sqlcmd -S "localhost,14330" -d OtOpcUaConfig -U sa -P "OtOpcUaDev_2026!" \ --- -i scripts/smoke/seed-s7-smoke.sql --- --- After seeding: --- Node:NodeId = "s7-smoke-node" --- Node:ClusterId = "s7-smoke" --- Then start server + run `./scripts/e2e/test-s7.ps1 -BridgeNodeId "ns=2;s=DB1_DBW0" -S7Host "127.0.0.1:1102"`. +-- After seeding: set Server appsettings Node:NodeId/ClusterId, deploy via the ControlPlane, then +-- `./scripts/e2e/test-s7.ps1 -BridgeNodeId "ns=2;s=DB1_DBW0" -S7Host "127.0.0.1:1102"`. SET NOCOUNT ON; SET XACT_ABORT ON; SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON; -SET ANSI_PADDING ON; -SET ANSI_WARNINGS ON; -SET ARITHABORT ON; -SET CONCAT_NULL_YIELDS_NULL ON; DECLARE @ClusterId nvarchar(64) = 's7-smoke'; DECLARE @NodeId nvarchar(64) = 's7-smoke-node'; DECLARE @DrvId nvarchar(64) = 's7-smoke-drv'; -DECLARE @NsId nvarchar(64) = 's7-smoke-ns'; +DECLARE @DevId nvarchar(64) = 's7-smoke-dev'; DECLARE @AreaId nvarchar(64) = 's7-smoke-area'; DECLARE @LineId nvarchar(64) = 's7-smoke-line'; DECLARE @EqId nvarchar(64) = 's7-smoke-eq'; -DECLARE @EqUuid uniqueidentifier = '17BD5A10-17BD-417B-917B-D5A1017BD5A1'; -DECLARE @TagId nvarchar(64) = 's7-smoke-tag-db1dbw0'; +DECLARE @EqUuid uniqueidentifier = '5717A5E0-5717-45E0-9571-7A5E05717A5E'; +DECLARE @Tag nvarchar(64) = 's7-smoke-tag-db1dbw0'; +DECLARE @RefId nvarchar(64) = 's7-smoke-ref-db1dbw0'; BEGIN TRAN; -DELETE FROM dbo.Tag WHERE TagId IN (@TagId); -DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; -DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; -DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; -DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; -DELETE FROM dbo.Namespace WHERE NamespaceId = @NsId; -DELETE FROM dbo.ConfigGeneration WHERE ClusterId = @ClusterId; -DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNodeGenerationState WHERE NodeId = @NodeId; -DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; -DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; - +DELETE FROM dbo.UnsTagReference WHERE UnsTagReferenceId = @RefId; +DELETE FROM dbo.Tag WHERE TagId = @Tag; +DELETE FROM dbo.Equipment WHERE EquipmentId = @EqId; +DELETE FROM dbo.UnsLine WHERE UnsLineId = @LineId; +DELETE FROM dbo.UnsArea WHERE UnsAreaId = @AreaId; +DELETE FROM dbo.Device WHERE DeviceId = @DevId; +DELETE FROM dbo.DriverInstance WHERE DriverInstanceId = @DrvId; +DELETE FROM dbo.ClusterNodeCredential WHERE NodeId = @NodeId; +DELETE FROM dbo.ClusterNode WHERE NodeId = @NodeId; +DELETE FROM dbo.ServerCluster WHERE ClusterId = @ClusterId; DELETE FROM dbo.ClusterNodeCredential WHERE Kind = 'SqlLogin' AND Value = 'sa'; INSERT dbo.ServerCluster(ClusterId, Name, Enterprise, Site, NodeCount, RedundancyMode, Enabled, CreatedBy) VALUES (@ClusterId, 'S7 Smoke', 'zb', 'lab', 1, 'None', 1, 's7-smoke'); -INSERT dbo.ClusterNode(NodeId, ClusterId, RedundancyRole, Host, OpcUaPort, DashboardPort, +INSERT dbo.ClusterNode(NodeId, ClusterId, Host, OpcUaPort, DashboardPort, ApplicationUri, ServiceLevelBase, Enabled, CreatedBy) -VALUES (@NodeId, @ClusterId, 'Primary', 'localhost', 4840, 15050, - 'urn:OtOpcUa:s7-smoke-node', 200, 1, 's7-smoke'); --- Dashboard moved off :5000 (Windows URL-ACL). +VALUES (@NodeId, @ClusterId, 'localhost', 4840, 15050, 'urn:OtOpcUa:s7-smoke-node', 200, 1, 's7-smoke'); INSERT dbo.ClusterNodeCredential(NodeId, Kind, Value, Enabled, CreatedBy) VALUES (@NodeId, 'SqlLogin', 'sa', 1, 's7-smoke'); -DECLARE @Gen bigint; -INSERT dbo.ConfigGeneration(ClusterId, Status, CreatedBy) -VALUES (@ClusterId, 'Draft', 's7-smoke'); -SET @Gen = SCOPE_IDENTITY(); - -INSERT dbo.Namespace(GenerationId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled) -VALUES (@Gen, @NsId, @ClusterId, 'Equipment', 'urn:s7-smoke:eq', 1); - -INSERT dbo.UnsArea(GenerationId, UnsAreaId, ClusterId, Name) -VALUES (@Gen, @AreaId, @ClusterId, 'lab-floor'); - -INSERT dbo.UnsLine(GenerationId, UnsLineId, UnsAreaId, Name) -VALUES (@Gen, @LineId, @AreaId, 's7-line'); - -INSERT dbo.Equipment(GenerationId, EquipmentId, EquipmentUuid, DriverInstanceId, UnsLineId, - Name, MachineCode, Enabled) -VALUES (@Gen, @EqId, @EqUuid, @DrvId, @LineId, 's7-sim', 's7-001', 1); - --- S7 DriverInstance — python-snap7 S7-1500 profile, slot 0, port 1102. --- DriverConfig shape mirrors S7DriverConfigDto. -INSERT dbo.DriverInstance(GenerationId, DriverInstanceId, ClusterId, NamespaceId, - Name, DriverType, DriverConfig, Enabled) -VALUES (@Gen, @DrvId, @ClusterId, @NsId, 'snap7-smoke', 'S7', N'{ - "Host": "127.0.0.1", - "Port": 1102, - "CpuType": "S71500", - "Rack": 0, - "Slot": 0, - "TimeoutMs": 5000, - "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000, "ProbeAddress": "MW0" }, - "Tags": [ - { - "Name": "DB1_DBW0", - "Address": "DB1.DBW0", - "DataType": "Int16", - "Writable": true, - "WriteIdempotent": true - } - ] +-- DriverConfig keeps protocol/channel settings; endpoint moves to DeviceConfig. +INSERT dbo.DriverInstance(DriverInstanceId, ClusterId, RawFolderId, Name, DriverType, DriverConfig, Enabled) +VALUES (@DrvId, @ClusterId, NULL, 'snap7-smoke', 'S7', N'{ + "Probe": { "Enabled": true, "IntervalMs": 5000, "TimeoutMs": 2000, "ProbeAddress": "MW0" } }', 1); -INSERT dbo.Tag(GenerationId, TagId, DriverInstanceId, EquipmentId, Name, DataType, - AccessLevel, TagConfig, WriteIdempotent) -VALUES (@Gen, @TagId, @DrvId, @EqId, 'DB1_DBW0', 'Int16', 'ReadWrite', - N'{"FullName":"DB1_DBW0","Address":"DB1.DBW0","DataType":"Int16"}', 1); +-- DeviceConfig shape finalized against reworked options in Wave B (WP5). +INSERT dbo.Device(DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig) +VALUES (@DevId, @DrvId, 'plc', 1, N'{ "Host": "127.0.0.1", "Port": 1102, "Rack": 0, "Slot": 0 }'); -EXEC dbo.sp_PublishGeneration @ClusterId = @ClusterId, @DraftGenerationId = @Gen, - @Notes = N'S7 smoke — task #212'; +INSERT dbo.Tag(TagId, DeviceId, TagGroupId, Name, DataType, AccessLevel, WriteIdempotent, TagConfig) +VALUES (@Tag, @DevId, NULL, 'DB1_DBW0', 'Int16', 'ReadWrite', 1, + N'{ "address": "DB1.DBW0", "dataType": "Int16" }'); + +INSERT dbo.UnsArea(UnsAreaId, ClusterId, Name) VALUES (@AreaId, @ClusterId, 'lab-floor'); +INSERT dbo.UnsLine(UnsLineId, UnsAreaId, Name) VALUES (@LineId, @AreaId, 's7-line'); +INSERT dbo.Equipment(EquipmentId, EquipmentUuid, UnsLineId, Name, MachineCode, Enabled) +VALUES (@EqId, @EqUuid, @LineId, 's7-sim', 's7-001', 1); + +INSERT dbo.UnsTagReference(UnsTagReferenceId, EquipmentId, TagId, SortOrder) +VALUES (@RefId, @EqId, @Tag, 0); COMMIT; -PRINT ''; -PRINT 'S7 smoke seed complete.'; -PRINT ' Cluster: ' + @ClusterId; -PRINT ' Node: ' + @NodeId; -PRINT ' Generation: ' + CONVERT(nvarchar(20), @Gen); -PRINT ''; -PRINT 'Next steps:'; -PRINT ' 1. Set src/.../Server/appsettings.json Node:NodeId = "s7-smoke-node"'; -PRINT ' Node:ClusterId = "s7-smoke"'; -PRINT ' 2. docker compose -f tests/.../S7.IntegrationTests/Docker/docker-compose.yml --profile s7_1500 up -d'; -PRINT ' 3. dotnet run --project src/Server/ZB.MOM.WW.OtOpcUa.Server'; -PRINT ' 4. ./scripts/e2e/test-s7.ps1 -BridgeNodeId "ns=2;s=DB1_DBW0" -S7Host "127.0.0.1:1102"'; +PRINT 'S7 smoke seed complete (v3 schema). Cluster: ' + @ClusterId + ' Node: ' + @NodeId; diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DriverDeviceConfigMerger.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DriverDeviceConfigMerger.cs new file mode 100644 index 00000000..b97756cf --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DriverDeviceConfigMerger.cs @@ -0,0 +1,99 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using ZB.MOM.WW.OtOpcUa.Core.Abstractions; + +namespace ZB.MOM.WW.OtOpcUa.Commons.Types; + +/// +/// v3 endpoint→DeviceConfig merge authority. Folds a driver's DriverConfig JSON +/// (protocol/channel-level settings) together with its per-Device DeviceConfig JSON +/// (host/endpoint + per-device settings — the Kepware channel/device split) plus the driver's authored +/// raw tags into the SINGLE config blob every driver factory binds from. Shared by the deploy-decode +/// seam (DeploymentArtifact, which builds each DriverInstanceSpec.DriverConfig) and — in +/// Batch 2 — the browse modal (which needs the same merged shape as the browser's configJson), +/// so the merge lives in exactly one place. +/// Contract. Output = the parsed DriverConfig object with, in order: +/// +/// When there is EXACTLY ONE device, its DeviceConfig keys shallow-merged up to the top +/// level (DeviceConfig wins) — so a single-endpoint driver's endpoint (Host/Port, +/// EndpointUrl, gateway address, …) lands where its options bind. Multiple devices do NOT +/// merge up (their endpoints are per-device, read from the array below). +/// A reconstructed Devices array — one object per device = its DeviceConfig keys +/// plus DeviceName = the device's entity Name (the RawPath device segment / +/// routing key). Multi-device drivers read this; single-endpoint +/// drivers ignore the unknown key. +/// A RawTags array = the driver's authored list, so +/// options.RawTags binds. +/// +/// Existing top-level protocol/channel keys survive (single-device DeviceConfig keys override on a name +/// clash — the documented Kepware precedence). Never throws on malformed member JSON: a blank/invalid +/// DriverConfig or DeviceConfig degrades to an empty object for that member. +/// +public static class DriverDeviceConfigMerger +{ + private static readonly JsonSerializerOptions SerializeOptions = new() + { + WriteIndented = false, + DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.Never, + }; + + /// The device rows feeding the merge: the entity Name (routing key) + schemaless DeviceConfig JSON. + /// The device's entity Name — the RawPath device segment and multi-device routing key. + /// The device's schemaless DeviceConfig JSON (endpoint + per-device settings). + public readonly record struct DeviceRow(string Name, string? DeviceConfig); + + /// Merge a driver's config + its devices' configs + its authored raw tags into one config blob. + /// The driver-level DriverConfig JSON (protocol/channel settings). + /// The driver's device rows, in deterministic order (the sole device merges up). + /// The driver's authored raw tags to inject as the RawTags array. + /// The single merged config JSON string the driver factory binds from. + public static string Merge( + string? driverConfigJson, + IReadOnlyList devices, + IReadOnlyList rawTags) + { + ArgumentNullException.ThrowIfNull(devices); + ArgumentNullException.ThrowIfNull(rawTags); + + var root = ParseObject(driverConfigJson); + + // (1) Exactly one device ⇒ shallow-merge its DeviceConfig up to the top level (DeviceConfig wins), + // so a single-endpoint driver's endpoint lands where its options bind. Multiple devices are + // per-device only (read from the Devices array below), so no merge-up. + if (devices.Count == 1) + { + var only = ParseObject(devices[0].DeviceConfig); + foreach (var (key, value) in only) + root[key] = value?.DeepClone(); + } + + // (2) Reconstruct the Devices array from ALL device rows: DeviceConfig keys + DeviceName = entity Name. + var devicesArray = new JsonArray(); + foreach (var device in devices) + { + var obj = ParseObject(device.DeviceConfig); + obj["DeviceName"] = device.Name; // entity Name is the RawPath device segment + routing key + devicesArray.Add(obj); + } + root["Devices"] = devicesArray; + + // (3) Inject the authored raw tags so options.RawTags binds. + root["RawTags"] = JsonSerializer.SerializeToNode(rawTags, SerializeOptions); + + return root.ToJsonString(SerializeOptions); + } + + /// Parse JSON into a mutable ; blank / non-object / malformed ⇒ a fresh empty object. + private static JsonObject ParseObject(string? json) + { + if (string.IsNullOrWhiteSpace(json)) return new JsonObject(); + try + { + return JsonNode.Parse(json) as JsonObject ?? new JsonObject(); + } + catch (JsonException) + { + return new JsonObject(); + } + } +} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RawPathResolver.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RawPathResolver.cs new file mode 100644 index 00000000..47feedfd --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RawPathResolver.cs @@ -0,0 +1,132 @@ +namespace ZB.MOM.WW.OtOpcUa.Commons.Types; + +/// +/// Resolves a raw Tag's v3 RawPath — the single identity string +/// <Folder/…>/<Driver>/<Device>/<TagGroup/…>/<Tag> — from the raw +/// topology's ancestry maps, and a driver's RawPath prefix (folders + driver name). Pure + input-shape +/// agnostic: callers build the four id→ancestry maps from whatever they have (EF entities on the +/// authoring/validation side, artifact JSON on the deploy-decode side) and both sides then agree +/// byte-for-byte because the segment order + join live ONLY here (over ). +/// Every path is built through , so segment charset (no +/// /, no lead/trail whitespace) is enforced in one place. A broken link (missing device / driver +/// lookup, or an invalid segment) yields — never a throw — so a malformed +/// artifact degrades to "this tag has no RawPath" (dropped) rather than faulting a whole deploy decode. +/// Ancestry walks are depth-bounded to survive a corrupt parent cycle. +/// +public sealed class RawPathResolver +{ + private const int MaxAncestryDepth = 256; + + private readonly IReadOnlyDictionary _folders; + private readonly IReadOnlyDictionary _drivers; + private readonly IReadOnlyDictionary _devices; + private readonly IReadOnlyDictionary _groups; + + /// Initializes a new over the raw topology's ancestry maps. + /// RawFolderId → (ParentRawFolderId?, Name). parent = cluster root. + /// DriverInstanceId → (RawFolderId?, Name). folder = cluster root. + /// DeviceId → (DriverInstanceId, Name). + /// TagGroupId → (ParentTagGroupId?, Name). parent = directly under the device. + public RawPathResolver( + IReadOnlyDictionary folders, + IReadOnlyDictionary drivers, + IReadOnlyDictionary devices, + IReadOnlyDictionary groups) + { + ArgumentNullException.ThrowIfNull(folders); + ArgumentNullException.ThrowIfNull(drivers); + ArgumentNullException.ThrowIfNull(devices); + ArgumentNullException.ThrowIfNull(groups); + _folders = folders; + _drivers = drivers; + _devices = devices; + _groups = groups; + } + + /// + /// Build the RawPath prefix a driver contributes to every child tag: its folder ancestry + /// (root → leaf) followed by the driver name. Returns when the driver id is + /// unknown or any segment/link is invalid. + /// + /// The driver instance id. + /// The driver RawPath prefix, or on a broken/unknown chain. + public string? TryBuildDriverPrefix(string driverInstanceId) + { + if (driverInstanceId is null || !_drivers.TryGetValue(driverInstanceId, out var driver)) return null; + try + { + var path = BuildFolderChain(driver.RawFolderId); + return RawPaths.Combine(path, driver.Name); + } + catch (ArgumentException) + { + return null; + } + } + + /// + /// Build a raw tag's full RawPath: + /// <driver-prefix>/<Device>/<TagGroup ancestry root→leaf>/<Tag>. + /// Returns when the device / driver lookup is missing or any segment/link is + /// invalid. + /// + /// The tag's owning device id. + /// The tag's owning tag-group id, or when directly under the device. + /// The tag's leaf name. + /// The tag's RawPath, or on a broken/unknown chain. + public string? TryBuildTagPath(string deviceId, string? tagGroupId, string tagName) + { + if (deviceId is null || !_devices.TryGetValue(deviceId, out var device)) return null; + var driverPrefix = TryBuildDriverPrefix(device.DriverInstanceId); + if (driverPrefix is null) return null; + try + { + var path = RawPaths.Combine(driverPrefix, device.Name); + path = AppendGroupChain(path, tagGroupId); + return RawPaths.Combine(path, tagName); + } + catch (ArgumentException) + { + return null; + } + } + + /// Build a folder ancestry path (root → leaf) for the given leaf folder id (null = cluster root ⇒ blank). + private string? BuildFolderChain(string? leafFolderId) + { + if (leafFolderId is null) return null; + var names = new List(); + var current = leafFolderId; + var depth = 0; + while (current is not null && depth++ < MaxAncestryDepth) + { + if (!_folders.TryGetValue(current, out var folder)) + throw new ArgumentException($"Unknown RawFolder '{current}'."); + names.Add(folder.Name); + current = folder.ParentId; + } + names.Reverse(); + return names.Count == 0 ? null : RawPaths.Build(names); + } + + /// Append a tag-group ancestry path (root → leaf) onto (null group ⇒ unchanged). + private string AppendGroupChain(string parentPath, string? leafGroupId) + { + if (leafGroupId is null) return parentPath; + var names = new List(); + var current = leafGroupId; + var depth = 0; + while (current is not null && depth++ < MaxAncestryDepth) + { + if (!_groups.TryGetValue(current, out var group)) + throw new ArgumentException($"Unknown TagGroup '{current}'."); + names.Add(group.Name); + current = group.ParentId; + } + names.Reverse(); + var path = parentPath; + foreach (var name in names) + path = RawPaths.Combine(path, name); + return path; + } +} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RawPaths.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RawPaths.cs new file mode 100644 index 00000000..1b38957f --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RawPaths.cs @@ -0,0 +1,135 @@ +namespace ZB.MOM.WW.OtOpcUa.Commons.Types; + +/// +/// The v3 identity authority. A RawPath is the cluster-scoped, slash-separated raw device +/// path — <Folder/…>/<Driver>/<Device>/<TagGroup/…>/<Tag> — and is +/// the single string used at every identity seam: ns=Raw NodeIds, the driver wire-reference +/// (EquipmentTagRefResolver key), the value fan-out / write-routing maps +/// (DriverHostActor), the historian default tagname + mux interest key, the native-alarm +/// ConditionId, and ctx.GetTag script paths. +/// +/// RawPaths are ALWAYS built through this helper — never string-concatenated ad hoc — so the +/// separator and the segment charset are enforced in exactly one place. Comparison is +/// case-sensitive ordinal everywhere (see ). +/// +/// +public static class RawPaths +{ + /// The single path separator character. Forbidden inside any segment. + public const char Separator = '/'; + + /// The path separator as a string (join/split convenience). + public const string SeparatorString = "/"; + + /// The one comparer for RawPaths and their segments: case-sensitive ordinal. + public static StringComparer Comparer => StringComparer.Ordinal; + + /// + /// Validate a single path segment. A segment must be non-empty, contain no + /// , and carry no leading/trailing whitespace (the separator and + /// surrounding whitespace would corrupt the NodeId / round-trip). + /// + /// The candidate segment (a folder / driver / device / group / tag name). + /// A human-readable error when invalid, or when the segment is valid. + public static string? ValidateSegment(string? segment) + { + if (string.IsNullOrEmpty(segment)) + return "Name must not be empty."; + if (segment.IndexOf(Separator) >= 0) + return $"Name must not contain '{Separator}'."; + if (char.IsWhiteSpace(segment[0]) || char.IsWhiteSpace(segment[^1])) + return "Name must not have leading or trailing whitespace."; + return null; + } + + /// True when passes . + /// The candidate segment. + /// when the segment is a legal RawPath segment. + public static bool IsValidSegment(string? segment) => ValidateSegment(segment) is null; + + /// + /// Build a RawPath from ordered segments (root-first). Every segment is validated via + /// ; an invalid or empty segment list throws. + /// + /// The ordered, non-empty segments (root → leaf). + /// The slash-joined RawPath. + /// A segment is invalid, or the sequence is empty. + public static string Build(IEnumerable segments) + { + ArgumentNullException.ThrowIfNull(segments); + var list = segments as IReadOnlyList ?? segments.ToList(); + if (list.Count == 0) + throw new ArgumentException("A RawPath must have at least one segment.", nameof(segments)); + + for (var i = 0; i < list.Count; i++) + { + var error = ValidateSegment(list[i]); + if (error is not null) + throw new ArgumentException($"Invalid RawPath segment at index {i} ('{list[i]}'): {error}", nameof(segments)); + } + + return string.Join(Separator, list); + } + + /// Build a RawPath from ordered segments (root-first). See . + /// The ordered, non-empty segments (root → leaf). + /// The slash-joined RawPath. + public static string Build(params string[] segments) => Build((IEnumerable)segments); + + /// + /// Append a child segment to an existing (already-built) parent RawPath. The child is + /// validated; a blank parent yields the (validated) child alone. + /// + /// The parent RawPath (assumed already valid), or blank for a root segment. + /// The child segment to append. + /// The combined RawPath. + /// The child segment is invalid. + public static string Combine(string? parentPath, string childSegment) + { + var error = ValidateSegment(childSegment); + if (error is not null) + throw new ArgumentException($"Invalid RawPath segment ('{childSegment}'): {error}", nameof(childSegment)); + + return string.IsNullOrEmpty(parentPath) ? childSegment : parentPath + Separator + childSegment; + } + + /// Split a RawPath into its ordered segments (root → leaf). + /// The RawPath to split. + /// The ordered segments; a single-element array for a one-segment path. + public static IReadOnlyList Split(string rawPath) + { + ArgumentNullException.ThrowIfNull(rawPath); + return rawPath.Split(Separator); + } + + /// The leaf (last) segment of a RawPath. + /// The RawPath. + /// The final segment. + public static string Leaf(string rawPath) + { + ArgumentNullException.ThrowIfNull(rawPath); + var idx = rawPath.LastIndexOf(Separator); + return idx < 0 ? rawPath : rawPath[(idx + 1)..]; + } + + /// + /// Get the parent RawPath (everything up to, not including, the leaf). Returns + /// for a single-segment path (no parent). + /// + /// The RawPath. + /// The parent RawPath when this returns . + /// when a parent exists. + public static bool TryParent(string rawPath, out string parent) + { + ArgumentNullException.ThrowIfNull(rawPath); + var idx = rawPath.LastIndexOf(Separator); + if (idx < 0) + { + parent = string.Empty; + return false; + } + + parent = rawPath[..idx]; + return true; + } +} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/TagConfigIntent.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/TagConfigIntent.cs index ba81fcf2..97c5b5dc 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/TagConfigIntent.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/TagConfigIntent.cs @@ -8,28 +8,17 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types; /// (AddressSpaceComposer), the artifact-decode seam (DeploymentArtifact), the draft /// gate (DraftValidator), and the walker (EquipmentNodeWalker). One /// per blob. Never throws. -/// Two deliberate variations are carried on the record so every seam can be served from one -/// parse: -/// -/// is the driver-side wire reference: the top-level -/// FullName string when present, else the RAW blob (an equipment tag's TagConfig JSON -/// is its wire reference for the six protocol drivers). Parse(null) ⇒ -/// FullName == "". -/// is the FullName property ONLY when -/// present-and-string, else — the DraftValidator Galaxy-rule semantics -/// (it wants the explicit reference, not the raw-blob fallback). -/// +/// Under the v3 identity contract, TagConfig no longer carries identity — the +/// RawPath (computed elsewhere) is the single identity string at every seam. This type parses +/// only the cross-driver PLATFORM intents (alarm / historize / array); the driver-specific +/// address fields stay opaque inside the blob and are read by the per-driver resolvers. /// -/// Top-level FullName string, else the raw blob (wire-reference fallback). -/// The FullName property when present-and-string, else . /// The optional native-alarm intent parsed from the alarm object; ⇒ plain value variable. /// isHistorized — true only when the value is a bool true. /// Non-whitespace historianTagname string override, else (not trimmed). /// isArray bool. /// arrayLength honoured ONLY when and a JSON number fitting ; else . public sealed record TagConfigIntent( - string FullName, - string? ExplicitFullName, TagAlarmIntent? Alarm, bool IsHistorized, string? HistorianTagname, @@ -38,40 +27,33 @@ public sealed record TagConfigIntent( { /// /// Parse a Tag's schemaless TagConfig JSON into the cross-driver platform intents. - /// Never throws: malformed JSON / non-object root / blank / null ⇒ all intents default with - /// = the raw blob (or "" for null). Semantics are ported verbatim from the - /// historical AddressSpaceComposer.Extract* statics (the canonical copy). + /// Never throws: malformed JSON / non-object root / blank / null ⇒ all intents default. + /// Semantics are ported verbatim from the historical AddressSpaceComposer.Extract* + /// statics (the canonical copy). /// /// The tag's raw TagConfig JSON (nullable/blank tolerated). /// The parsed intents; never . public static TagConfigIntent Parse(string? tagConfig) { if (string.IsNullOrWhiteSpace(tagConfig)) - return new TagConfigIntent(tagConfig ?? string.Empty, null, null, false, null, false, null); + return new TagConfigIntent(null, false, null, false, null); try { using var doc = JsonDocument.Parse(tagConfig); var root = doc.RootElement; if (root.ValueKind != JsonValueKind.Object) - return new TagConfigIntent(tagConfig, null, null, false, null, false, null); - - var explicitFullName = - root.TryGetProperty("FullName", out var fn) && fn.ValueKind == JsonValueKind.String - ? fn.GetString() - : null; - var fullName = explicitFullName ?? tagConfig; + return new TagConfigIntent(null, false, null, false, null); var (isHistorized, historianTagname) = ParseHistorize(root); var (isArray, arrayLength) = ParseArray(root); return new TagConfigIntent( - fullName, explicitFullName, ParseAlarm(root), - isHistorized, historianTagname, isArray, arrayLength); + ParseAlarm(root), isHistorized, historianTagname, isArray, arrayLength); } catch (JsonException) { - return new TagConfigIntent(tagConfig, null, null, false, null, false, null); + return new TagConfigIntent(null, false, null, false, null); } } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs index 0fca1d16..58b52274 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs @@ -1,6 +1,12 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; -/// Per-device row for multi-device drivers (Modbus, AB CIP). Optional for single-device drivers. +/// +/// v3: a device under a . Now UNIVERSAL — every driver has ≥1 device +/// (single-endpoint drivers get an auto-created default device). Endpoint/connection settings live +/// in (the Kepware channel/device split: DriverConfig keeps +/// protocol/channel-level settings; DeviceConfig carries host/endpoint + per-device +/// settings). The device name is a RawPath segment. +/// public sealed class Device { /// diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs index 6bc962a2..a63cf0e8 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs @@ -13,12 +13,13 @@ public sealed class DriverInstance public required string ClusterId { get; set; } /// - /// Logical FK to . Same-cluster binding enforced by - /// sp_ValidateDraft: Namespace.ClusterId must equal DriverInstance.ClusterId. + /// v3: logical FK to a containing ; + /// = the driver sits at the cluster root of the Raw tree. Contributes the leading segments of + /// every child tag's RawPath. /// - public required string NamespaceId { get; set; } + public string? RawFolderId { get; set; } - /// Gets or sets the friendly name of this driver instance. + /// Gets or sets the friendly name of this driver instance. A RawPath segment. public required string Name { get; set; } /// Galaxy | Modbus | AbCip | AbLegacy | S7 | TwinCat | Focas | OpcUaClient diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs index e6eef1c8..ce537148 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs @@ -17,14 +17,9 @@ public sealed class Equipment /// UUIDv4, IMMUTABLE across all generations of the same EquipmentId. Downstream-consumer join key. public Guid EquipmentUuid { get; set; } - /// - /// Optional logical FK to the driver providing data for this equipment. - /// null = VirtualTag-only / driver-less equipment (no field driver). - /// - public string? DriverInstanceId { get; set; } - - /// Optional logical FK to a multi-device driver's device. - public string? DeviceId { get; set; } + // v3: equipment no longer binds a driver or device. It references existing raw tags via + // UnsTagReference and hosts VirtualTags + ScriptedAlarms. The old DriverInstanceId / DeviceId + // binding columns are retired. /// Logical FK to . public required string UnsLineId { get; set; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs deleted file mode 100644 index 35c58cf2..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs +++ /dev/null @@ -1,124 +0,0 @@ -namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; - -/// -/// Staged equipment-import batch per Phase 6.4 Stream B.2. Rows land in the child -/// table under a batch header; operator reviews + either -/// drops (via DropImportBatch) or finalises (via FinaliseImportBatch) in one -/// bounded transaction. The live Equipment table never sees partial state. -/// -/// -/// User-scoped visibility: the preview modal only shows batches where -/// equals the current operator. Prevents accidental -/// cross-operator finalise during concurrent imports. An admin finalise / drop surface -/// can override this — tracked alongside the UI follow-up. -/// -/// stamps the moment the batch promoted from staging -/// into Equipment. Null = still in staging; non-null = archived / finalised. -/// -public sealed class EquipmentImportBatch -{ - /// Gets or sets the unique identifier for this batch. - public Guid Id { get; set; } - - /// Gets or sets the cluster identifier. - public required string ClusterId { get; set; } - - /// Gets or sets the user name who created this batch. - public required string CreatedBy { get; set; } - - /// Gets or sets the UTC timestamp when this batch was created. - public DateTime CreatedAtUtc { get; set; } - - /// Gets or sets the total number of rows staged in this batch. - public int RowsStaged { get; set; } - - /// Gets or sets the number of rows accepted in this batch. - public int RowsAccepted { get; set; } - - /// Gets or sets the number of rows rejected in this batch. - public int RowsRejected { get; set; } - - /// Gets or sets the UTC timestamp when this batch was finalised, or null if still in staging. - public DateTime? FinalisedAtUtc { get; set; } - - /// Gets or sets the collection of staged rows in this batch. - public ICollection Rows { get; set; } = []; -} - -/// -/// One staged row under an . Mirrors the required -/// + optional columns from the CSV importer's output + an -/// flag + a string the preview modal -/// renders. -/// -public sealed class EquipmentImportRow -{ - /// Gets or sets the unique identifier for this row. - public Guid Id { get; set; } - - /// Gets or sets the parent batch identifier. - public Guid BatchId { get; set; } - - /// Gets or sets the line number in the source file. - public int LineNumberInFile { get; set; } - - /// Gets or sets a value indicating whether this row was accepted. - public bool IsAccepted { get; set; } - - /// Gets or sets the reason this row was rejected, if applicable. - public string? RejectReason { get; set; } - - /// Gets or sets the Z tag identifier. - public required string ZTag { get; set; } - - /// Gets or sets the machine code. - public required string MachineCode { get; set; } - - /// Gets or sets the SAP identifier. - public required string SAPID { get; set; } - - /// Gets or sets the equipment identifier. - public required string EquipmentId { get; set; } - - /// Gets or sets the equipment UUID. - public required string EquipmentUuid { get; set; } - - /// Gets or sets the equipment name. - public required string Name { get; set; } - - /// Gets or sets the UNS area name. - public required string UnsAreaName { get; set; } - - /// Gets or sets the UNS line name. - public required string UnsLineName { get; set; } - - /// Gets or sets the manufacturer name. - public string? Manufacturer { get; set; } - - /// Gets or sets the equipment model. - public string? Model { get; set; } - - /// Gets or sets the serial number. - public string? SerialNumber { get; set; } - - /// Gets or sets the hardware revision. - public string? HardwareRevision { get; set; } - - /// Gets or sets the software revision. - public string? SoftwareRevision { get; set; } - - /// Gets or sets the year of construction. - public string? YearOfConstruction { get; set; } - - /// Gets or sets the asset location. - public string? AssetLocation { get; set; } - - /// Gets or sets the manufacturer URI. - public string? ManufacturerUri { get; set; } - - /// Gets or sets the device manual URI. - public string? DeviceManualUri { get; set; } - - /// Gets or sets the parent batch. - public EquipmentImportBatch? Batch { get; set; } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs deleted file mode 100644 index f7324fb2..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs +++ /dev/null @@ -1,37 +0,0 @@ -using ZB.MOM.WW.OtOpcUa.Configuration.Enums; - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; - -/// -/// OPC UA namespace served by a cluster. Generation-versioned — -/// namespaces are content (affect what consumers see at the endpoint), not topology. -/// -public sealed class Namespace -{ - /// Gets or sets the row identifier for this namespace. - public Guid NamespaceRowId { get; set; } - - /// Stable logical ID, e.g. "LINE3-OPCUA-equipment". Globally unique in v2. - public required string NamespaceId { get; set; } - - /// Gets or sets the cluster identifier. - public required string ClusterId { get; set; } - - /// Gets or sets the namespace kind. - public required NamespaceKind Kind { get; set; } - - /// E.g. "urn:zb:warsaw-west:equipment". Unique fleet-wide per generation. - public required string NamespaceUri { get; set; } - - /// Gets or sets a value indicating whether the namespace is enabled. - public bool Enabled { get; set; } = true; - - /// Gets or sets optional notes about the namespace. - public string? Notes { get; set; } - - /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. - public byte[] RowVersion { get; set; } = Array.Empty(); - - /// Gets or sets the associated server cluster. - public ServerCluster? Cluster { get; set; } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/RawFolder.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/RawFolder.cs new file mode 100644 index 00000000..c3947912 --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/RawFolder.cs @@ -0,0 +1,30 @@ +namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; + +/// +/// v3 Raw-tree driver-organizing folder. Nestable (Kepware-style) directly under a cluster or +/// under another . Folders group rows; they +/// contribute the leading segments of a driver's RawPath. +/// +public sealed class RawFolder +{ + /// Gets or sets the database row identifier (PK). + public Guid RawFolderRowId { get; set; } + + /// Stable logical ID, unique fleet-wide. + public required string RawFolderId { get; set; } + + /// Logical FK to — the folder is cluster-rooted. + public required string ClusterId { get; set; } + + /// Logical FK to a parent ; = root under the cluster. + public string? ParentRawFolderId { get; set; } + + /// Sibling-unique folder name. A RawPath segment: no /, no lead/trail whitespace. + public required string Name { get; set; } + + /// Sibling display ordering. + public int SortOrder { get; set; } + + /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. + public byte[] RowVersion { get; set; } = Array.Empty(); +} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs index 192964f4..ffcc94b2 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs @@ -47,6 +47,6 @@ public sealed class ServerCluster // Navigation /// Gets or sets the collection of cluster nodes. public ICollection Nodes { get; set; } = []; - /// Gets or sets the collection of namespaces in the cluster. - public ICollection Namespaces { get; set; } = []; + /// Gets or sets the collection of root-level Raw-tree folders in the cluster. + public ICollection RawFolders { get; set; } = []; } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs index 32fefab5..0bc1e25f 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs @@ -3,46 +3,34 @@ using ZB.MOM.WW.OtOpcUa.Configuration.Enums; namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; /// -/// One canonical tag (signal) in a cluster's generation. set ⟺ the -/// tag participates in the Equipment tree. A GalaxyMxGateway-bound equipment tag is an -/// ordinary equipment tag (GalaxyMxGateway is a standard Equipment-kind driver) that carries its -/// Galaxy attribute reference in TagConfig.FullName — there is no separate alias concept. +/// v3 raw-only tag (signal). A tag is authored ONCE, under a in the Raw +/// tree; its identity is its RawPath +/// (<Folder/…>/<Driver>/<Device>/<TagGroup/…>/<Name>). UNS +/// surfaces it by reference (), never by re-authoring. The tag's +/// driver-specific address lives inside as an ordinary field (what the +/// driver dials), not as system identity. /// public sealed class Tag { - /// - /// Gets or sets the unique database row identifier for the tag. - /// + /// Gets or sets the unique database row identifier for the tag (PK). public Guid TagRowId { get; set; } - /// - /// Gets or sets the tag identifier. - /// + /// Gets or sets the stable logical tag identifier (unique fleet-wide). public required string TagId { get; set; } - /// - /// Gets or sets the driver instance identifier for this tag. - /// - public required string DriverInstanceId { get; set; } + /// v3: required logical FK to . Every tag lives under a device. + public required string DeviceId { get; set; } /// - /// Gets or sets the device identifier. + /// Optional logical FK to a containing ; + /// = the tag sits directly under its device. Contributes the middle + /// segments of the tag's RawPath. /// - public string? DeviceId { get; set; } + public string? TagGroupId { get; set; } - /// - /// Set when the tag belongs to an Equipment; NULL for FolderPath-scoped (namespace-root) tags. - /// - public string? EquipmentId { get; set; } - - /// - /// Gets or sets the tag name. - /// + /// Gets or sets the tag name. A RawPath segment: no /, no lead/trail whitespace. public required string Name { get; set; } - /// Only used when is NULL (FolderPath-scoped namespace tag). - public string? FolderPath { get; set; } - /// OPC UA built-in type name (Boolean / Int32 / Float / etc.). public required string DataType { get; set; } @@ -51,7 +39,7 @@ public sealed class Tag /// public required TagAccessLevel AccessLevel { get; set; } - /// Opt-in for write retry eligibility. + /// Opt-in for write retry eligibility (R2 resilience contract — retained in v3). public bool WriteIdempotent { get; set; } /// diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/TagGroup.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/TagGroup.cs new file mode 100644 index 00000000..cd0a32b4 --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/TagGroup.cs @@ -0,0 +1,30 @@ +namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; + +/// +/// v3 Raw-tree tag-organizing group. Nestable (Kepware-style) directly under a +/// or under another . Groups contribute the middle +/// segments of a tag's RawPath (between the device and the tag name). +/// +public sealed class TagGroup +{ + /// Gets or sets the database row identifier (PK). + public Guid TagGroupRowId { get; set; } + + /// Stable logical ID, unique fleet-wide. + public required string TagGroupId { get; set; } + + /// Logical FK to — the group lives under a device. + public required string DeviceId { get; set; } + + /// Logical FK to a parent ; = root under the device. + public string? ParentTagGroupId { get; set; } + + /// Sibling-unique group name. A RawPath segment: no /, no lead/trail whitespace. + public required string Name { get; set; } + + /// Sibling display ordering. + public int SortOrder { get; set; } + + /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. + public byte[] RowVersion { get; set; } = Array.Empty(); +} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsTagReference.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsTagReference.cs new file mode 100644 index 00000000..1b8e4fab --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsTagReference.cs @@ -0,0 +1,35 @@ +namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities; + +/// +/// v3 UNS projection row: a reference from an to an existing raw +/// . UNS authoring is reference-only — equipment no longer authors +/// TagConfig or binds a driver; it points at raw tags (optionally under a display-name +/// override). The backing raw tag is the single value source; the UNS node fans out from it. +/// +public sealed class UnsTagReference +{ + /// Gets or sets the database row identifier (PK). + public Guid UnsTagReferenceRowId { get; set; } + + /// Stable logical ID, unique fleet-wide. + public required string UnsTagReferenceId { get; set; } + + /// Logical FK to — the referencing equipment. + public required string EquipmentId { get; set; } + + /// Logical FK to — the backing raw tag (same cluster as the equipment). + public required string TagId { get; set; } + + /// + /// Optional UNS display-name override; = use the raw tag's Name. + /// The effective name must be unique within the equipment across references, VirtualTags, and + /// ScriptedAlarms (enforced at authoring and at the deploy gate). + /// + public string? DisplayNameOverride { get; set; } + + /// Sibling display ordering within the equipment's Tags list. + public int SortOrder { get; set; } + + /// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model. + public byte[] RowVersion { get; set; } = Array.Empty(); +} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Enums/NamespaceKind.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Enums/NamespaceKind.cs deleted file mode 100644 index 41969599..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Enums/NamespaceKind.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace ZB.MOM.WW.OtOpcUa.Configuration.Enums; - -/// OPC UA namespace kind. One of each kind per cluster per generation. -public enum NamespaceKind -{ - /// - /// Equipment namespace — raw signals from native-protocol drivers (Modbus, AB CIP, AB Legacy, - /// S7, TwinCAT, FOCAS, and OpcUaClient when gatewaying raw equipment). UNS 5-level hierarchy - /// applies. - /// - Equipment, - - /// - /// Reserved for future replay driver per handoff §"Digital Twin Touchpoints" — not populated - /// in v2.0 but enum value reserved so the schema does not need to change when the replay - /// driver lands. - /// - Simulated, -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417212220_InitialSchema.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417212220_InitialSchema.Designer.cs deleted file mode 100644 index 02f69a71..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417212220_InitialSchema.Designer.cs +++ /dev/null @@ -1,1208 +0,0 @@ -// -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("20260417212220_InitialSchema")] - partial class InitialSchema - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - b.ToTable("Device", null, t => - { - t.HasCheckConstraint("CK_Device_DeviceConfig_IsJson", "ISJSON(DeviceConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - b.ToTable("DriverInstance", null, t => - { - t.HasCheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 1"); - }); - }); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417212220_InitialSchema.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417212220_InitialSchema.cs deleted file mode 100644 index 571d3b93..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417212220_InitialSchema.cs +++ /dev/null @@ -1,811 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class InitialSchema : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "ConfigAuditLog", - columns: table => new - { - AuditId = table.Column(type: "bigint", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - Timestamp = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - Principal = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - EventType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - GenerationId = table.Column(type: "bigint", nullable: true), - DetailsJson = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ConfigAuditLog", x => x.AuditId); - table.CheckConstraint("CK_ConfigAuditLog_DetailsJson_IsJson", "DetailsJson IS NULL OR ISJSON(DetailsJson) = 1"); - }); - - migrationBuilder.CreateTable( - name: "ExternalIdReservation", - columns: table => new - { - ReservationId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - Kind = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - Value = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - EquipmentUuid = table.Column(type: "uniqueidentifier", nullable: false), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - FirstPublishedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - FirstPublishedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - LastPublishedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - ReleasedAt = table.Column(type: "datetime2(3)", nullable: true), - ReleasedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), - ReleaseReason = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ExternalIdReservation", x => x.ReservationId); - }); - - migrationBuilder.CreateTable( - name: "ServerCluster", - columns: table => new - { - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - Enterprise = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - Site = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - NodeCount = table.Column(type: "tinyint", nullable: false), - RedundancyMode = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - Enabled = table.Column(type: "bit", nullable: false), - Notes = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), - CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - ModifiedAt = table.Column(type: "datetime2(3)", nullable: true), - ModifiedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ServerCluster", x => x.ClusterId); - table.CheckConstraint("CK_ServerCluster_RedundancyMode_NodeCount", "((NodeCount = 1 AND RedundancyMode = 'None') OR (NodeCount = 2 AND RedundancyMode IN ('Warm', 'Hot')))"); - }); - - migrationBuilder.CreateTable( - name: "ClusterNode", - columns: table => new - { - NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - RedundancyRole = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - Host = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false), - OpcUaPort = table.Column(type: "int", nullable: false), - DashboardPort = table.Column(type: "int", nullable: false), - ApplicationUri = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - ServiceLevelBase = table.Column(type: "tinyint", nullable: false), - DriverConfigOverridesJson = table.Column(type: "nvarchar(max)", nullable: true), - Enabled = table.Column(type: "bit", nullable: false), - LastSeenAt = table.Column(type: "datetime2(3)", nullable: true), - CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ClusterNode", x => x.NodeId); - table.ForeignKey( - name: "FK_ClusterNode_ServerCluster_ClusterId", - column: x => x.ClusterId, - principalTable: "ServerCluster", - principalColumn: "ClusterId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "ConfigGeneration", - columns: table => new - { - GenerationId = table.Column(type: "bigint", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Status = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - ParentGenerationId = table.Column(type: "bigint", nullable: true), - PublishedAt = table.Column(type: "datetime2(3)", nullable: true), - PublishedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), - Notes = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), - CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ConfigGeneration", x => x.GenerationId); - table.ForeignKey( - name: "FK_ConfigGeneration_ConfigGeneration_ParentGenerationId", - column: x => x.ParentGenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_ConfigGeneration_ServerCluster_ClusterId", - column: x => x.ClusterId, - principalTable: "ServerCluster", - principalColumn: "ClusterId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "ClusterNodeCredential", - columns: table => new - { - CredentialId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Kind = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - Value = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), - Enabled = table.Column(type: "bit", nullable: false), - RotatedAt = table.Column(type: "datetime2(3)", nullable: true), - CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ClusterNodeCredential", x => x.CredentialId); - table.ForeignKey( - name: "FK_ClusterNodeCredential_ClusterNode_NodeId", - column: x => x.NodeId, - principalTable: "ClusterNode", - principalColumn: "NodeId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "ClusterNodeGenerationState", - columns: table => new - { - NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - CurrentGenerationId = table.Column(type: "bigint", nullable: true), - LastAppliedAt = table.Column(type: "datetime2(3)", nullable: true), - LastAppliedStatus = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: true), - LastAppliedError = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), - LastSeenAt = table.Column(type: "datetime2(3)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ClusterNodeGenerationState", x => x.NodeId); - table.ForeignKey( - name: "FK_ClusterNodeGenerationState_ClusterNode_NodeId", - column: x => x.NodeId, - principalTable: "ClusterNode", - principalColumn: "NodeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_ClusterNodeGenerationState_ConfigGeneration_CurrentGenerationId", - column: x => x.CurrentGenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "Device", - columns: table => new - { - DeviceRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - DeviceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - Enabled = table.Column(type: "bit", nullable: false), - DeviceConfig = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Device", x => x.DeviceRowId); - table.CheckConstraint("CK_Device_DeviceConfig_IsJson", "ISJSON(DeviceConfig) = 1"); - table.ForeignKey( - name: "FK_Device_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "DriverInstance", - columns: table => new - { - DriverInstanceRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - NamespaceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - DriverType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - Enabled = table.Column(type: "bit", nullable: false), - DriverConfig = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_DriverInstance", x => x.DriverInstanceRowId); - table.CheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 1"); - table.ForeignKey( - name: "FK_DriverInstance_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_DriverInstance_ServerCluster_ClusterId", - column: x => x.ClusterId, - principalTable: "ServerCluster", - principalColumn: "ClusterId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "Equipment", - columns: table => new - { - EquipmentRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - EquipmentUuid = table.Column(type: "uniqueidentifier", nullable: false), - DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - DeviceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - UnsLineId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - MachineCode = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - ZTag = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - SAPID = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - Manufacturer = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - Model = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - SerialNumber = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - HardwareRevision = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), - SoftwareRevision = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), - YearOfConstruction = table.Column(type: "smallint", nullable: true), - AssetLocation = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - ManufacturerUri = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - DeviceManualUri = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - EquipmentClassRef = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), - Enabled = table.Column(type: "bit", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Equipment", x => x.EquipmentRowId); - table.ForeignKey( - name: "FK_Equipment_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "Namespace", - columns: table => new - { - NamespaceRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - NamespaceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Kind = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - NamespaceUri = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Enabled = table.Column(type: "bit", nullable: false), - Notes = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Namespace", x => x.NamespaceRowId); - table.ForeignKey( - name: "FK_Namespace_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_Namespace_ServerCluster_ClusterId", - column: x => x.ClusterId, - principalTable: "ServerCluster", - principalColumn: "ClusterId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "NodeAcl", - columns: table => new - { - NodeAclRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - NodeAclId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - LdapGroup = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - ScopeKind = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - ScopeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - PermissionFlags = table.Column(type: "int", nullable: false), - Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_NodeAcl", x => x.NodeAclRowId); - table.ForeignKey( - name: "FK_NodeAcl_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "PollGroup", - columns: table => new - { - PollGroupRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - PollGroupId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - IntervalMs = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PollGroup", x => x.PollGroupRowId); - table.CheckConstraint("CK_PollGroup_IntervalMs_Min", "IntervalMs >= 50"); - table.ForeignKey( - name: "FK_PollGroup_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "Tag", - columns: table => new - { - TagRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - TagId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - DeviceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - FolderPath = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - DataType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - AccessLevel = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - WriteIdempotent = table.Column(type: "bit", nullable: false), - PollGroupId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - TagConfig = table.Column(type: "nvarchar(max)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Tag", x => x.TagRowId); - table.CheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - table.ForeignKey( - name: "FK_Tag_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "UnsArea", - columns: table => new - { - UnsAreaRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - UnsAreaId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_UnsArea", x => x.UnsAreaRowId); - table.ForeignKey( - name: "FK_UnsArea_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_UnsArea_ServerCluster_ClusterId", - column: x => x.ClusterId, - principalTable: "ServerCluster", - principalColumn: "ClusterId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "UnsLine", - columns: table => new - { - UnsLineRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - UnsLineId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - UnsAreaId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_UnsLine", x => x.UnsLineRowId); - table.ForeignKey( - name: "FK_UnsLine_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateIndex( - name: "UX_ClusterNode_ApplicationUri", - table: "ClusterNode", - column: "ApplicationUri", - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_ClusterNode_Primary_Per_Cluster", - table: "ClusterNode", - column: "ClusterId", - unique: true, - filter: "[RedundancyRole] = 'Primary'"); - - migrationBuilder.CreateIndex( - name: "IX_ClusterNodeCredential_NodeId", - table: "ClusterNodeCredential", - columns: new[] { "NodeId", "Enabled" }); - - migrationBuilder.CreateIndex( - name: "UX_ClusterNodeCredential_Value", - table: "ClusterNodeCredential", - columns: new[] { "Kind", "Value" }, - unique: true, - filter: "[Enabled] = 1"); - - migrationBuilder.CreateIndex( - name: "IX_ClusterNodeGenerationState_Generation", - table: "ClusterNodeGenerationState", - column: "CurrentGenerationId"); - - migrationBuilder.CreateIndex( - name: "IX_ConfigAuditLog_Cluster_Time", - table: "ConfigAuditLog", - columns: new[] { "ClusterId", "Timestamp" }, - descending: new[] { false, true }); - - migrationBuilder.CreateIndex( - name: "IX_ConfigAuditLog_Generation", - table: "ConfigAuditLog", - column: "GenerationId", - filter: "[GenerationId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_ConfigGeneration_Cluster_Published", - table: "ConfigGeneration", - columns: new[] { "ClusterId", "Status", "GenerationId" }, - descending: new[] { false, false, true }) - .Annotation("SqlServer:Include", new[] { "PublishedAt" }); - - migrationBuilder.CreateIndex( - name: "IX_ConfigGeneration_ParentGenerationId", - table: "ConfigGeneration", - column: "ParentGenerationId"); - - migrationBuilder.CreateIndex( - name: "UX_ConfigGeneration_Draft_Per_Cluster", - table: "ConfigGeneration", - column: "ClusterId", - unique: true, - filter: "[Status] = 'Draft'"); - - migrationBuilder.CreateIndex( - name: "IX_Device_Generation_Driver", - table: "Device", - columns: new[] { "GenerationId", "DriverInstanceId" }); - - migrationBuilder.CreateIndex( - name: "UX_Device_Generation_LogicalId", - table: "Device", - columns: new[] { "GenerationId", "DeviceId" }, - unique: true, - filter: "[DeviceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_DriverInstance_ClusterId", - table: "DriverInstance", - column: "ClusterId"); - - migrationBuilder.CreateIndex( - name: "IX_DriverInstance_Generation_Cluster", - table: "DriverInstance", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "IX_DriverInstance_Generation_Namespace", - table: "DriverInstance", - columns: new[] { "GenerationId", "NamespaceId" }); - - migrationBuilder.CreateIndex( - name: "UX_DriverInstance_Generation_LogicalId", - table: "DriverInstance", - columns: new[] { "GenerationId", "DriverInstanceId" }, - unique: true, - filter: "[DriverInstanceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_Driver", - table: "Equipment", - columns: new[] { "GenerationId", "DriverInstanceId" }); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_Line", - table: "Equipment", - columns: new[] { "GenerationId", "UnsLineId" }); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_MachineCode", - table: "Equipment", - columns: new[] { "GenerationId", "MachineCode" }); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_SAPID", - table: "Equipment", - columns: new[] { "GenerationId", "SAPID" }, - filter: "[SAPID] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_ZTag", - table: "Equipment", - columns: new[] { "GenerationId", "ZTag" }, - filter: "[ZTag] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_Generation_LinePath", - table: "Equipment", - columns: new[] { "GenerationId", "UnsLineId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_Generation_LogicalId", - table: "Equipment", - columns: new[] { "GenerationId", "EquipmentId" }, - unique: true, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_Generation_Uuid", - table: "Equipment", - columns: new[] { "GenerationId", "EquipmentUuid" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_ExternalIdReservation_Equipment", - table: "ExternalIdReservation", - column: "EquipmentUuid"); - - migrationBuilder.CreateIndex( - name: "UX_ExternalIdReservation_KindValue_Active", - table: "ExternalIdReservation", - columns: new[] { "Kind", "Value" }, - unique: true, - filter: "[ReleasedAt] IS NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Namespace_ClusterId", - table: "Namespace", - column: "ClusterId"); - - migrationBuilder.CreateIndex( - name: "IX_Namespace_Generation_Cluster", - table: "Namespace", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_Cluster_Kind", - table: "Namespace", - columns: new[] { "GenerationId", "ClusterId", "Kind" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_LogicalId", - table: "Namespace", - columns: new[] { "GenerationId", "NamespaceId" }, - unique: true, - filter: "[NamespaceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_LogicalId_Cluster", - table: "Namespace", - columns: new[] { "GenerationId", "NamespaceId", "ClusterId" }, - unique: true, - filter: "[NamespaceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_NamespaceUri", - table: "Namespace", - columns: new[] { "GenerationId", "NamespaceUri" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Generation_Cluster", - table: "NodeAcl", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Generation_Group", - table: "NodeAcl", - columns: new[] { "GenerationId", "LdapGroup" }); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Generation_Scope", - table: "NodeAcl", - columns: new[] { "GenerationId", "ScopeKind", "ScopeId" }, - filter: "[ScopeId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_NodeAcl_Generation_GroupScope", - table: "NodeAcl", - columns: new[] { "GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId" }, - unique: true, - filter: "[ScopeId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_NodeAcl_Generation_LogicalId", - table: "NodeAcl", - columns: new[] { "GenerationId", "NodeAclId" }, - unique: true, - filter: "[NodeAclId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_PollGroup_Generation_Driver", - table: "PollGroup", - columns: new[] { "GenerationId", "DriverInstanceId" }); - - migrationBuilder.CreateIndex( - name: "UX_PollGroup_Generation_LogicalId", - table: "PollGroup", - columns: new[] { "GenerationId", "PollGroupId" }, - unique: true, - filter: "[PollGroupId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_ServerCluster_Site", - table: "ServerCluster", - column: "Site"); - - migrationBuilder.CreateIndex( - name: "UX_ServerCluster_Name", - table: "ServerCluster", - column: "Name", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Tag_Generation_Driver_Device", - table: "Tag", - columns: new[] { "GenerationId", "DriverInstanceId", "DeviceId" }); - - migrationBuilder.CreateIndex( - name: "IX_Tag_Generation_Equipment", - table: "Tag", - columns: new[] { "GenerationId", "EquipmentId" }, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_Generation_EquipmentPath", - table: "Tag", - columns: new[] { "GenerationId", "EquipmentId", "Name" }, - unique: true, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_Generation_FolderPath", - table: "Tag", - columns: new[] { "GenerationId", "DriverInstanceId", "FolderPath", "Name" }, - unique: true, - filter: "[EquipmentId] IS NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_Generation_LogicalId", - table: "Tag", - columns: new[] { "GenerationId", "TagId" }, - unique: true, - filter: "[TagId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_UnsArea_ClusterId", - table: "UnsArea", - column: "ClusterId"); - - migrationBuilder.CreateIndex( - name: "IX_UnsArea_Generation_Cluster", - table: "UnsArea", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "UX_UnsArea_Generation_ClusterName", - table: "UnsArea", - columns: new[] { "GenerationId", "ClusterId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_UnsArea_Generation_LogicalId", - table: "UnsArea", - columns: new[] { "GenerationId", "UnsAreaId" }, - unique: true, - filter: "[UnsAreaId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_UnsLine_Generation_Area", - table: "UnsLine", - columns: new[] { "GenerationId", "UnsAreaId" }); - - migrationBuilder.CreateIndex( - name: "UX_UnsLine_Generation_AreaName", - table: "UnsLine", - columns: new[] { "GenerationId", "UnsAreaId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_UnsLine_Generation_LogicalId", - table: "UnsLine", - columns: new[] { "GenerationId", "UnsLineId" }, - unique: true, - filter: "[UnsLineId] IS NOT NULL"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "ClusterNodeCredential"); - - migrationBuilder.DropTable( - name: "ClusterNodeGenerationState"); - - migrationBuilder.DropTable( - name: "ConfigAuditLog"); - - migrationBuilder.DropTable( - name: "Device"); - - migrationBuilder.DropTable( - name: "DriverInstance"); - - migrationBuilder.DropTable( - name: "Equipment"); - - migrationBuilder.DropTable( - name: "ExternalIdReservation"); - - migrationBuilder.DropTable( - name: "Namespace"); - - migrationBuilder.DropTable( - name: "NodeAcl"); - - migrationBuilder.DropTable( - name: "PollGroup"); - - migrationBuilder.DropTable( - name: "Tag"); - - migrationBuilder.DropTable( - name: "UnsArea"); - - migrationBuilder.DropTable( - name: "UnsLine"); - - migrationBuilder.DropTable( - name: "ClusterNode"); - - migrationBuilder.DropTable( - name: "ConfigGeneration"); - - migrationBuilder.DropTable( - name: "ServerCluster"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417215224_StoredProcedures.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417215224_StoredProcedures.Designer.cs deleted file mode 100644 index 7943c0ec..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417215224_StoredProcedures.Designer.cs +++ /dev/null @@ -1,1208 +0,0 @@ -// -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("20260417215224_StoredProcedures")] - partial class StoredProcedures - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - b.ToTable("Device", null, t => - { - t.HasCheckConstraint("CK_Device_DeviceConfig_IsJson", "ISJSON(DeviceConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - b.ToTable("DriverInstance", null, t => - { - t.HasCheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 1"); - }); - }); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417215224_StoredProcedures.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417215224_StoredProcedures.cs deleted file mode 100644 index 66c5bc90..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417215224_StoredProcedures.cs +++ /dev/null @@ -1,510 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations; - -/// -/// Stored procedures per config-db-schema.md §"Stored Procedures". All node + admin DB -/// access funnels through these — direct table writes are revoked in the AuthorizationGrants -/// migration that follows. CREATE OR ALTER style so procs version with the schema. -/// -public partial class StoredProcedures : Migration -{ - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(Procs.GetCurrentGenerationForCluster); - migrationBuilder.Sql(Procs.GetGenerationContent); - migrationBuilder.Sql(Procs.RegisterNodeGenerationApplied); - migrationBuilder.Sql(Procs.ValidateDraft); - migrationBuilder.Sql(Procs.PublishGeneration); - migrationBuilder.Sql(Procs.RollbackToGeneration); - migrationBuilder.Sql(Procs.ComputeGenerationDiff); - migrationBuilder.Sql(Procs.ReleaseExternalIdReservation); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - foreach (var name in new[] - { - "sp_ReleaseExternalIdReservation", "sp_ComputeGenerationDiff", "sp_RollbackToGeneration", - "sp_PublishGeneration", "sp_ValidateDraft", "sp_RegisterNodeGenerationApplied", - "sp_GetGenerationContent", "sp_GetCurrentGenerationForCluster", - }) - { - migrationBuilder.Sql($"IF OBJECT_ID(N'dbo.{name}', N'P') IS NOT NULL DROP PROCEDURE dbo.{name};"); - } - } - - private static class Procs - { - public const string GetCurrentGenerationForCluster = @" -CREATE OR ALTER PROCEDURE dbo.sp_GetCurrentGenerationForCluster - @NodeId nvarchar(64), - @ClusterId nvarchar(64) -AS -BEGIN - SET NOCOUNT ON; - - DECLARE @Caller nvarchar(128) = SUSER_SNAME(); - - IF NOT EXISTS ( - SELECT 1 FROM dbo.ClusterNodeCredential - WHERE NodeId = @NodeId AND Value = @Caller AND Enabled = 1) - BEGIN - RAISERROR('Unauthorized: caller %s is not bound to NodeId %s', 16, 1, @Caller, @NodeId); - RETURN; - END - - IF NOT EXISTS ( - SELECT 1 FROM dbo.ClusterNode - WHERE NodeId = @NodeId AND ClusterId = @ClusterId AND Enabled = 1) - BEGIN - RAISERROR('Forbidden: NodeId %s does not belong to ClusterId %s', 16, 1, @NodeId, @ClusterId); - RETURN; - END - - SELECT TOP 1 GenerationId, ClusterId, Status, PublishedAt, PublishedBy, Notes - FROM dbo.ConfigGeneration - WHERE ClusterId = @ClusterId AND Status = 'Published' - ORDER BY GenerationId DESC; -END -"; - - public const string GetGenerationContent = @" -CREATE OR ALTER PROCEDURE dbo.sp_GetGenerationContent - @NodeId nvarchar(64), - @GenerationId bigint -AS -BEGIN - SET NOCOUNT ON; - - DECLARE @Caller nvarchar(128) = SUSER_SNAME(); - DECLARE @ClusterId nvarchar(64); - - SELECT @ClusterId = ClusterId FROM dbo.ConfigGeneration WHERE GenerationId = @GenerationId; - - IF @ClusterId IS NULL - BEGIN - RAISERROR('GenerationId %I64d not found', 16, 1, @GenerationId); - RETURN; - END - - IF NOT EXISTS ( - SELECT 1 - FROM dbo.ClusterNodeCredential c - JOIN dbo.ClusterNode n ON n.NodeId = c.NodeId - WHERE c.NodeId = @NodeId AND c.Value = @Caller AND c.Enabled = 1 - AND n.ClusterId = @ClusterId AND n.Enabled = 1) - BEGIN - RAISERROR('Forbidden: caller %s not bound to a node in ClusterId %s', 16, 1, @Caller, @ClusterId); - RETURN; - END - - SELECT * FROM dbo.Namespace WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.UnsArea WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.UnsLine WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.DriverInstance WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.Device WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.Equipment WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.PollGroup WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.Tag WHERE GenerationId = @GenerationId; - SELECT * FROM dbo.NodeAcl WHERE GenerationId = @GenerationId; -END -"; - - public const string RegisterNodeGenerationApplied = @" -CREATE OR ALTER PROCEDURE dbo.sp_RegisterNodeGenerationApplied - @NodeId nvarchar(64), - @GenerationId bigint, - @Status nvarchar(16), - @Error nvarchar(max) = NULL -AS -BEGIN - SET NOCOUNT ON; - - DECLARE @Caller nvarchar(128) = SUSER_SNAME(); - - IF NOT EXISTS ( - SELECT 1 FROM dbo.ClusterNodeCredential - WHERE NodeId = @NodeId AND Value = @Caller AND Enabled = 1) - BEGIN - RAISERROR('Unauthorized: caller %s is not bound to NodeId %s', 16, 1, @Caller, @NodeId); - RETURN; - END - - MERGE dbo.ClusterNodeGenerationState AS tgt - USING (SELECT @NodeId AS NodeId) AS src ON tgt.NodeId = src.NodeId - WHEN MATCHED THEN UPDATE SET - CurrentGenerationId = @GenerationId, - LastAppliedAt = SYSUTCDATETIME(), - LastAppliedStatus = @Status, - LastAppliedError = @Error, - LastSeenAt = SYSUTCDATETIME() - WHEN NOT MATCHED THEN INSERT - (NodeId, CurrentGenerationId, LastAppliedAt, LastAppliedStatus, LastAppliedError, LastSeenAt) - VALUES (@NodeId, @GenerationId, SYSUTCDATETIME(), @Status, @Error, SYSUTCDATETIME()); - - -- Build DetailsJson via STRING_ESCAPE so a @Status containing a double-quote/backslash cannot - -- produce malformed JSON (which would fail CK_ConfigAuditLog_DetailsJson_IsJson and abort the - -- transaction) or inject extra JSON structure into the audit record. - INSERT dbo.ConfigAuditLog (Principal, EventType, NodeId, GenerationId, DetailsJson) - VALUES (@Caller, 'NodeApplied', @NodeId, @GenerationId, - CONCAT('{""status"":""', STRING_ESCAPE(@Status, 'json'), '""}')); -END -"; - - public const string ValidateDraft = @" -CREATE OR ALTER PROCEDURE dbo.sp_ValidateDraft - @DraftGenerationId bigint -AS -BEGIN - SET NOCOUNT ON; - - DECLARE @ClusterId nvarchar(64); - DECLARE @Status nvarchar(16); - - SELECT @ClusterId = ClusterId, @Status = Status - FROM dbo.ConfigGeneration WHERE GenerationId = @DraftGenerationId; - - IF @ClusterId IS NULL - BEGIN - RAISERROR('GenerationId %I64d not found', 16, 1, @DraftGenerationId); - RETURN; - END - - IF @Status <> 'Draft' - BEGIN - RAISERROR('GenerationId %I64d is not in Draft status (current=%s)', 16, 1, @DraftGenerationId, @Status); - RETURN; - END - - IF EXISTS ( - SELECT 1 FROM dbo.Tag t - LEFT JOIN dbo.DriverInstance d ON d.GenerationId = t.GenerationId AND d.DriverInstanceId = t.DriverInstanceId - WHERE t.GenerationId = @DraftGenerationId AND d.DriverInstanceId IS NULL) - BEGIN - RAISERROR('Draft has tags with unresolved DriverInstanceId', 16, 1); - RETURN; - END - - IF EXISTS ( - SELECT 1 FROM dbo.Tag t - LEFT JOIN dbo.Device dv ON dv.GenerationId = t.GenerationId AND dv.DeviceId = t.DeviceId - WHERE t.GenerationId = @DraftGenerationId AND t.DeviceId IS NOT NULL AND dv.DeviceId IS NULL) - BEGIN - RAISERROR('Draft has tags with unresolved DeviceId', 16, 1); - RETURN; - END - - IF EXISTS ( - SELECT 1 FROM dbo.Tag t - LEFT JOIN dbo.PollGroup pg ON pg.GenerationId = t.GenerationId AND pg.PollGroupId = t.PollGroupId - WHERE t.GenerationId = @DraftGenerationId AND t.PollGroupId IS NOT NULL AND pg.PollGroupId IS NULL) - BEGIN - RAISERROR('Draft has tags with unresolved PollGroupId', 16, 1); - RETURN; - END - - IF EXISTS ( - SELECT 1 - FROM dbo.DriverInstance di - JOIN dbo.Namespace ns ON ns.GenerationId = di.GenerationId AND ns.NamespaceId = di.NamespaceId - WHERE di.GenerationId = @DraftGenerationId - AND ns.ClusterId <> di.ClusterId) - BEGIN - INSERT dbo.ConfigAuditLog (Principal, EventType, ClusterId, GenerationId) - VALUES (SUSER_SNAME(), 'CrossClusterNamespaceAttempt', @ClusterId, @DraftGenerationId); - RAISERROR('BadCrossClusterNamespaceBinding: namespace and driver must belong to the same cluster', 16, 1); - RETURN; - END - - IF EXISTS ( - SELECT 1 - FROM dbo.Equipment draft - JOIN dbo.Equipment prior - ON prior.EquipmentId = draft.EquipmentId - AND prior.EquipmentUuid <> draft.EquipmentUuid - AND prior.GenerationId <> draft.GenerationId - JOIN dbo.ConfigGeneration pg ON pg.GenerationId = prior.GenerationId - WHERE draft.GenerationId = @DraftGenerationId - AND pg.ClusterId = @ClusterId) - BEGIN - RAISERROR('EquipmentUuid immutability violated for an EquipmentId that existed in a prior generation', 16, 1); - RETURN; - END - - IF EXISTS ( - SELECT 1 - FROM dbo.Equipment draft - JOIN dbo.ExternalIdReservation r - ON r.Kind = 'ZTag' AND r.Value = draft.ZTag AND r.ReleasedAt IS NULL - AND r.EquipmentUuid <> draft.EquipmentUuid - WHERE draft.GenerationId = @DraftGenerationId AND draft.ZTag IS NOT NULL) - BEGIN - RAISERROR('BadDuplicateExternalIdentifier: a ZTag in the draft is reserved by a different EquipmentUuid', 16, 1); - RETURN; - END - - IF EXISTS ( - SELECT 1 - FROM dbo.Equipment draft - JOIN dbo.ExternalIdReservation r - ON r.Kind = 'SAPID' AND r.Value = draft.SAPID AND r.ReleasedAt IS NULL - AND r.EquipmentUuid <> draft.EquipmentUuid - WHERE draft.GenerationId = @DraftGenerationId AND draft.SAPID IS NOT NULL) - BEGIN - RAISERROR('BadDuplicateExternalIdentifier: a SAPID in the draft is reserved by a different EquipmentUuid', 16, 1); - RETURN; - END -END -"; - - public const string PublishGeneration = @" -CREATE OR ALTER PROCEDURE dbo.sp_PublishGeneration - @ClusterId nvarchar(64), - @DraftGenerationId bigint, - @Notes nvarchar(1024) = NULL -AS -BEGIN - SET NOCOUNT ON; - SET XACT_ABORT ON; - - -- Transaction-nesting awareness: if a caller (e.g. sp_RollbackToGeneration) already - -- holds a transaction, we use SAVE TRANSACTION so our failure path rolls back only to - -- the savepoint instead of issuing a bare ROLLBACK that wipes the caller's transaction - -- (which sets @@TRANCOUNT = 0 and causes error 3902 on the caller's subsequent COMMIT). - DECLARE @OwnsTxn bit = 0; - DECLARE @SaveName nvarchar(32) = N'sp_PublishGeneration'; - - IF @@TRANCOUNT = 0 - BEGIN - BEGIN TRANSACTION; - SET @OwnsTxn = 1; - END - ELSE - BEGIN - SAVE TRANSACTION sp_PublishGeneration; - END - - DECLARE @Lock nvarchar(255) = N'OtOpcUa_Publish_' + @ClusterId; - DECLARE @LockResult int; - EXEC @LockResult = sp_getapplock @Resource = @Lock, @LockMode = 'Exclusive', @LockTimeout = 0; - IF @LockResult < 0 - BEGIN - RAISERROR('PublishConflict: another publish is in progress for cluster %s', 16, 1, @ClusterId); - IF @OwnsTxn = 1 ROLLBACK; - ELSE ROLLBACK TRANSACTION sp_PublishGeneration; - RETURN; - END - - -- sp_ValidateDraft signals every rejection with RAISERROR(..., 16, 1) — a severity-16 error is - -- NOT batch-aborting and SET XACT_ABORT ON does not abort the transaction for it, so without a - -- TRY/CATCH control would return here and the draft would publish despite failed validation. - -- Catch the validation error, roll back the publish transaction (only to our savepoint when a - -- caller owns the outer transaction), and re-raise so the caller sees the real validation failure. - BEGIN TRY - EXEC dbo.sp_ValidateDraft @DraftGenerationId = @DraftGenerationId; - END TRY - BEGIN CATCH - IF @OwnsTxn = 1 ROLLBACK; - ELSE ROLLBACK TRANSACTION sp_PublishGeneration; - THROW; - END CATCH - - MERGE dbo.ExternalIdReservation AS tgt - USING ( - SELECT 'ZTag' AS Kind, ZTag AS Value, EquipmentUuid - FROM dbo.Equipment - WHERE GenerationId = @DraftGenerationId AND ZTag IS NOT NULL - UNION ALL - SELECT 'SAPID', SAPID, EquipmentUuid - FROM dbo.Equipment - WHERE GenerationId = @DraftGenerationId AND SAPID IS NOT NULL - ) AS src - ON tgt.Kind = src.Kind AND tgt.Value = src.Value AND tgt.EquipmentUuid = src.EquipmentUuid - WHEN MATCHED THEN UPDATE SET LastPublishedAt = SYSUTCDATETIME() - WHEN NOT MATCHED BY TARGET THEN - INSERT (Kind, Value, EquipmentUuid, ClusterId, FirstPublishedBy, LastPublishedAt) - VALUES (src.Kind, src.Value, src.EquipmentUuid, @ClusterId, SUSER_SNAME(), SYSUTCDATETIME()); - - UPDATE dbo.ConfigGeneration - SET Status = 'Superseded' - WHERE ClusterId = @ClusterId AND Status = 'Published'; - - UPDATE dbo.ConfigGeneration - SET Status = 'Published', - PublishedAt = SYSUTCDATETIME(), - PublishedBy = SUSER_SNAME(), - Notes = ISNULL(@Notes, Notes) - WHERE GenerationId = @DraftGenerationId AND ClusterId = @ClusterId AND Status = 'Draft'; - - IF @@ROWCOUNT = 0 - BEGIN - RAISERROR('Draft %I64d for cluster %s not in Draft status (was it already published?)', 16, 1, @DraftGenerationId, @ClusterId); - IF @OwnsTxn = 1 ROLLBACK; - ELSE ROLLBACK TRANSACTION sp_PublishGeneration; - RETURN; - END - - INSERT dbo.ConfigAuditLog (Principal, EventType, ClusterId, GenerationId) - VALUES (SUSER_SNAME(), 'Published', @ClusterId, @DraftGenerationId); - - IF @OwnsTxn = 1 COMMIT; -END -"; - - public const string RollbackToGeneration = @" -CREATE OR ALTER PROCEDURE dbo.sp_RollbackToGeneration - @ClusterId nvarchar(64), - @TargetGenerationId bigint, - @Notes nvarchar(1024) = NULL -AS -BEGIN - SET NOCOUNT ON; - SET XACT_ABORT ON; - BEGIN TRANSACTION; - - IF NOT EXISTS ( - SELECT 1 FROM dbo.ConfigGeneration - WHERE GenerationId = @TargetGenerationId AND ClusterId = @ClusterId - AND Status IN ('Published', 'Superseded')) - BEGIN - RAISERROR('Target generation %I64d not found or not rollback-eligible', 16, 1, @TargetGenerationId); - ROLLBACK; RETURN; - END - - DECLARE @NewGenId bigint; - INSERT dbo.ConfigGeneration (ClusterId, Status, CreatedAt, CreatedBy, PublishedAt, PublishedBy, Notes) - VALUES (@ClusterId, 'Draft', SYSUTCDATETIME(), SUSER_SNAME(), NULL, NULL, - ISNULL(@Notes, CONCAT('Rollback clone of generation ', @TargetGenerationId))); - SET @NewGenId = SCOPE_IDENTITY(); - - INSERT dbo.Namespace (GenerationId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled, Notes) - SELECT @NewGenId, NamespaceId, ClusterId, Kind, NamespaceUri, Enabled, Notes FROM dbo.Namespace WHERE GenerationId = @TargetGenerationId; - INSERT dbo.UnsArea (GenerationId, UnsAreaId, ClusterId, Name, Notes) - SELECT @NewGenId, UnsAreaId, ClusterId, Name, Notes FROM dbo.UnsArea WHERE GenerationId = @TargetGenerationId; - INSERT dbo.UnsLine (GenerationId, UnsLineId, UnsAreaId, Name, Notes) - SELECT @NewGenId, UnsLineId, UnsAreaId, Name, Notes FROM dbo.UnsLine WHERE GenerationId = @TargetGenerationId; - INSERT dbo.DriverInstance (GenerationId, DriverInstanceId, ClusterId, NamespaceId, Name, DriverType, Enabled, DriverConfig) - SELECT @NewGenId, DriverInstanceId, ClusterId, NamespaceId, Name, DriverType, Enabled, DriverConfig FROM dbo.DriverInstance WHERE GenerationId = @TargetGenerationId; - INSERT dbo.Device (GenerationId, DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig) - SELECT @NewGenId, DeviceId, DriverInstanceId, Name, Enabled, DeviceConfig FROM dbo.Device WHERE GenerationId = @TargetGenerationId; - INSERT dbo.Equipment (GenerationId, EquipmentId, EquipmentUuid, DriverInstanceId, DeviceId, UnsLineId, Name, MachineCode, ZTag, SAPID, Manufacturer, Model, SerialNumber, HardwareRevision, SoftwareRevision, YearOfConstruction, AssetLocation, ManufacturerUri, DeviceManualUri, EquipmentClassRef, Enabled) - SELECT @NewGenId, EquipmentId, EquipmentUuid, DriverInstanceId, DeviceId, UnsLineId, Name, MachineCode, ZTag, SAPID, Manufacturer, Model, SerialNumber, HardwareRevision, SoftwareRevision, YearOfConstruction, AssetLocation, ManufacturerUri, DeviceManualUri, EquipmentClassRef, Enabled FROM dbo.Equipment WHERE GenerationId = @TargetGenerationId; - INSERT dbo.PollGroup (GenerationId, PollGroupId, DriverInstanceId, Name, IntervalMs) - SELECT @NewGenId, PollGroupId, DriverInstanceId, Name, IntervalMs FROM dbo.PollGroup WHERE GenerationId = @TargetGenerationId; - INSERT dbo.Tag (GenerationId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig) - SELECT @NewGenId, TagId, DriverInstanceId, DeviceId, EquipmentId, Name, FolderPath, DataType, AccessLevel, WriteIdempotent, PollGroupId, TagConfig FROM dbo.Tag WHERE GenerationId = @TargetGenerationId; - INSERT dbo.NodeAcl (GenerationId, NodeAclId, ClusterId, LdapGroup, ScopeKind, ScopeId, PermissionFlags, Notes) - SELECT @NewGenId, NodeAclId, ClusterId, LdapGroup, ScopeKind, ScopeId, PermissionFlags, Notes FROM dbo.NodeAcl WHERE GenerationId = @TargetGenerationId; - - EXEC dbo.sp_PublishGeneration @ClusterId = @ClusterId, @DraftGenerationId = @NewGenId, @Notes = @Notes; - - -- @TargetGenerationId is a bigint, but build the JSON value via an explicit numeric CONVERT so - -- the emitted token is always a bare JSON number — never reliant on implicit string coercion. - INSERT dbo.ConfigAuditLog (Principal, EventType, ClusterId, GenerationId, DetailsJson) - VALUES (SUSER_SNAME(), 'RolledBack', @ClusterId, @NewGenId, - CONCAT('{""rolledBackTo"":', CONVERT(nvarchar(20), CONVERT(bigint, @TargetGenerationId)), '}')); - - COMMIT; -END -"; - - public const string ComputeGenerationDiff = @" -CREATE OR ALTER PROCEDURE dbo.sp_ComputeGenerationDiff - @FromGenerationId bigint, - @ToGenerationId bigint -AS -BEGIN - SET NOCOUNT ON; - - CREATE TABLE #diff (TableName nvarchar(32), LogicalId nvarchar(64), ChangeKind nvarchar(16)); - - WITH f AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @FromGenerationId), - t AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Namespace', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @FromGenerationId), - t AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'DriverInstance', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @FromGenerationId), - t AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Equipment', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @FromGenerationId), - t AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Tag', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - SELECT TableName, LogicalId, ChangeKind FROM #diff; - DROP TABLE #diff; -END -"; - - public const string ReleaseExternalIdReservation = @" -CREATE OR ALTER PROCEDURE dbo.sp_ReleaseExternalIdReservation - @Kind nvarchar(16), - @Value nvarchar(64), - @ReleaseReason nvarchar(512) -AS -BEGIN - SET NOCOUNT ON; - SET XACT_ABORT ON; - - IF @ReleaseReason IS NULL OR LEN(@ReleaseReason) = 0 - BEGIN - RAISERROR('ReleaseReason is required', 16, 1); - RETURN; - END - - UPDATE dbo.ExternalIdReservation - SET ReleasedAt = SYSUTCDATETIME(), - ReleasedBy = SUSER_SNAME(), - ReleaseReason = @ReleaseReason - WHERE Kind = @Kind AND Value = @Value AND ReleasedAt IS NULL; - - IF @@ROWCOUNT = 0 - BEGIN - RAISERROR('No active reservation found for (%s, %s)', 16, 1, @Kind, @Value); - RETURN; - END - - -- Escape both caller-supplied values via STRING_ESCAPE so quotes/backslashes cannot break the - -- JSON document or inject additional structure into the audit record. - INSERT dbo.ConfigAuditLog (Principal, EventType, DetailsJson) - VALUES (SUSER_SNAME(), 'ExternalIdReleased', - CONCAT('{""kind"":""', STRING_ESCAPE(@Kind, 'json'), - '"",""value"":""', STRING_ESCAPE(@Value, 'json'), '""}')); -END -"; - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417220857_AuthorizationGrants.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417220857_AuthorizationGrants.Designer.cs deleted file mode 100644 index c5c24506..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417220857_AuthorizationGrants.Designer.cs +++ /dev/null @@ -1,1208 +0,0 @@ -// -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("20260417220857_AuthorizationGrants")] - partial class AuthorizationGrants - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - b.ToTable("Device", null, t => - { - t.HasCheckConstraint("CK_Device_DeviceConfig_IsJson", "ISJSON(DeviceConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - b.ToTable("DriverInstance", null, t => - { - t.HasCheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 1"); - }); - }); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417220857_AuthorizationGrants.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417220857_AuthorizationGrants.cs deleted file mode 100644 index 3bb0d387..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260417220857_AuthorizationGrants.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations; - -/// -/// Creates the two DB roles per config-db-schema.md §"Authorization Model" and grants -/// EXECUTE on the appropriate stored procedures. Deliberately grants no direct table DML — all -/// writes funnel through the procs, which authenticate via SUSER_SNAME(). -/// Principals (SQL logins, gMSA users, cert-mapped users) are provisioned by the DBA outside -/// this migration and then added to one of the two roles. -/// -public partial class AuthorizationGrants : Migration -{ - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(@" -IF DATABASE_PRINCIPAL_ID('OtOpcUaNode') IS NULL - CREATE ROLE OtOpcUaNode; -IF DATABASE_PRINCIPAL_ID('OtOpcUaAdmin') IS NULL - CREATE ROLE OtOpcUaAdmin; -"); - - migrationBuilder.Sql(@" -GRANT EXECUTE ON OBJECT::dbo.sp_GetCurrentGenerationForCluster TO OtOpcUaNode; -GRANT EXECUTE ON OBJECT::dbo.sp_GetGenerationContent TO OtOpcUaNode; -GRANT EXECUTE ON OBJECT::dbo.sp_RegisterNodeGenerationApplied TO OtOpcUaNode; - -GRANT EXECUTE ON OBJECT::dbo.sp_GetCurrentGenerationForCluster TO OtOpcUaAdmin; -GRANT EXECUTE ON OBJECT::dbo.sp_GetGenerationContent TO OtOpcUaAdmin; -GRANT EXECUTE ON OBJECT::dbo.sp_ValidateDraft TO OtOpcUaAdmin; -GRANT EXECUTE ON OBJECT::dbo.sp_PublishGeneration TO OtOpcUaAdmin; -GRANT EXECUTE ON OBJECT::dbo.sp_RollbackToGeneration TO OtOpcUaAdmin; -GRANT EXECUTE ON OBJECT::dbo.sp_ComputeGenerationDiff TO OtOpcUaAdmin; -GRANT EXECUTE ON OBJECT::dbo.sp_ReleaseExternalIdReservation TO OtOpcUaAdmin; - -DENY UPDATE, DELETE, INSERT ON SCHEMA::dbo TO OtOpcUaNode; -DENY UPDATE, DELETE, INSERT ON SCHEMA::dbo TO OtOpcUaAdmin; -DENY SELECT ON SCHEMA::dbo TO OtOpcUaNode; --- Admins may SELECT for reporting views in the future — grant views explicitly, not the schema. -DENY SELECT ON SCHEMA::dbo TO OtOpcUaAdmin; -"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(@" -IF DATABASE_PRINCIPAL_ID('OtOpcUaNode') IS NOT NULL - DROP ROLE OtOpcUaNode; -IF DATABASE_PRINCIPAL_ID('OtOpcUaAdmin') IS NOT NULL - DROP ROLE OtOpcUaAdmin; -"); - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260418193608_AddDriverHostStatus.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260418193608_AddDriverHostStatus.Designer.cs deleted file mode 100644 index e6111beb..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260418193608_AddDriverHostStatus.Designer.cs +++ /dev/null @@ -1,1248 +0,0 @@ -// -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("20260418193608_AddDriverHostStatus")] - partial class AddDriverHostStatus - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - b.ToTable("DriverInstance", null, t => - { - t.HasCheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 1"); - }); - }); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260418193608_AddDriverHostStatus.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260418193608_AddDriverHostStatus.cs deleted file mode 100644 index ab14c5dd..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260418193608_AddDriverHostStatus.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class AddDriverHostStatus : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "DriverHostStatus", - columns: table => new - { - NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - HostName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - State = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - StateChangedUtc = table.Column(type: "datetime2(3)", nullable: false), - LastSeenUtc = table.Column(type: "datetime2(3)", nullable: false), - Detail = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_DriverHostStatus", x => new { x.NodeId, x.DriverInstanceId, x.HostName }); - }); - - migrationBuilder.CreateIndex( - name: "IX_DriverHostStatus_LastSeen", - table: "DriverHostStatus", - column: "LastSeenUtc"); - - migrationBuilder.CreateIndex( - name: "IX_DriverHostStatus_Node", - table: "DriverHostStatus", - column: "NodeId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "DriverHostStatus"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419124034_AddDriverInstanceResilienceStatus.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419124034_AddDriverInstanceResilienceStatus.Designer.cs deleted file mode 100644 index 76a80ede..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419124034_AddDriverInstanceResilienceStatus.Designer.cs +++ /dev/null @@ -1,1287 +0,0 @@ -// -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("20260419124034_AddDriverInstanceResilienceStatus")] - partial class AddDriverInstanceResilienceStatus - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - b.ToTable("DriverInstance", null, t => - { - t.HasCheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419124034_AddDriverInstanceResilienceStatus.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419124034_AddDriverInstanceResilienceStatus.cs deleted file mode 100644 index 120866a5..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419124034_AddDriverInstanceResilienceStatus.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class AddDriverInstanceResilienceStatus : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "DriverInstanceResilienceStatus", - columns: table => new - { - DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - HostName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - LastCircuitBreakerOpenUtc = table.Column(type: "datetime2(3)", nullable: true), - ConsecutiveFailures = table.Column(type: "int", nullable: false), - CurrentBulkheadDepth = table.Column(type: "int", nullable: false), - LastRecycleUtc = table.Column(type: "datetime2(3)", nullable: true), - BaselineFootprintBytes = table.Column(type: "bigint", nullable: false), - CurrentFootprintBytes = table.Column(type: "bigint", nullable: false), - LastSampledUtc = table.Column(type: "datetime2(3)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_DriverInstanceResilienceStatus", x => new { x.DriverInstanceId, x.HostName }); - }); - - migrationBuilder.CreateIndex( - name: "IX_DriverResilience_LastSampled", - table: "DriverInstanceResilienceStatus", - column: "LastSampledUtc"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "DriverInstanceResilienceStatus"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419131444_AddLdapGroupRoleMapping.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419131444_AddLdapGroupRoleMapping.Designer.cs deleted file mode 100644 index a82dbdae..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419131444_AddLdapGroupRoleMapping.Designer.cs +++ /dev/null @@ -1,1342 +0,0 @@ -// -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("20260419131444_AddLdapGroupRoleMapping")] - partial class AddLdapGroupRoleMapping - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - b.ToTable("DriverInstance", null, t => - { - t.HasCheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419131444_AddLdapGroupRoleMapping.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419131444_AddLdapGroupRoleMapping.cs deleted file mode 100644 index 58eaa7f0..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419131444_AddLdapGroupRoleMapping.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class AddLdapGroupRoleMapping : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "LdapGroupRoleMapping", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - LdapGroup = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), - Role = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - IsSystemWide = table.Column(type: "bit", nullable: false), - CreatedAtUtc = table.Column(type: "datetime2(3)", nullable: false), - Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_LdapGroupRoleMapping", x => x.Id); - table.ForeignKey( - name: "FK_LdapGroupRoleMapping_ServerCluster_ClusterId", - column: x => x.ClusterId, - principalTable: "ServerCluster", - principalColumn: "ClusterId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_LdapGroupRoleMapping_ClusterId", - table: "LdapGroupRoleMapping", - column: "ClusterId"); - - migrationBuilder.CreateIndex( - name: "IX_LdapGroupRoleMapping_Group", - table: "LdapGroupRoleMapping", - column: "LdapGroup"); - - migrationBuilder.CreateIndex( - name: "UX_LdapGroupRoleMapping_Group_Cluster", - table: "LdapGroupRoleMapping", - columns: new[] { "LdapGroup", "ClusterId" }, - unique: true, - filter: "[ClusterId] IS NOT NULL"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "LdapGroupRoleMapping"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419161932_AddDriverInstanceResilienceConfig.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419161932_AddDriverInstanceResilienceConfig.Designer.cs deleted file mode 100644 index ea8ef07b..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419161932_AddDriverInstanceResilienceConfig.Designer.cs +++ /dev/null @@ -1,1347 +0,0 @@ -// -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("20260419161932_AddDriverInstanceResilienceConfig")] - partial class AddDriverInstanceResilienceConfig - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ResilienceConfig") - .HasColumnType("nvarchar(max)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419161932_AddDriverInstanceResilienceConfig.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419161932_AddDriverInstanceResilienceConfig.cs deleted file mode 100644 index 568944fd..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419161932_AddDriverInstanceResilienceConfig.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class AddDriverInstanceResilienceConfig : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "ResilienceConfig", - table: "DriverInstance", - type: "nvarchar(max)", - nullable: true); - - migrationBuilder.AddCheckConstraint( - name: "CK_DriverInstance_ResilienceConfig_IsJson", - table: "DriverInstance", - sql: "ResilienceConfig IS NULL OR ISJSON(ResilienceConfig) = 1"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropCheckConstraint( - name: "CK_DriverInstance_ResilienceConfig_IsJson", - table: "DriverInstance"); - - migrationBuilder.DropColumn( - name: "ResilienceConfig", - table: "DriverInstance"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419185124_AddEquipmentImportBatch.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419185124_AddEquipmentImportBatch.Designer.cs deleted file mode 100644 index a985f7d1..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419185124_AddEquipmentImportBatch.Designer.cs +++ /dev/null @@ -1,1505 +0,0 @@ -// -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("20260419185124_AddEquipmentImportBatch")] - partial class AddEquipmentImportBatch - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ResilienceConfig") - .HasColumnType("nvarchar(max)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LinePath"); - - b.ToTable("Equipment", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419185124_AddEquipmentImportBatch.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419185124_AddEquipmentImportBatch.cs deleted file mode 100644 index 0e76922c..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260419185124_AddEquipmentImportBatch.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class AddEquipmentImportBatch : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "EquipmentImportBatch", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - CreatedAtUtc = table.Column(type: "datetime2(3)", nullable: false), - RowsStaged = table.Column(type: "int", nullable: false), - RowsAccepted = table.Column(type: "int", nullable: false), - RowsRejected = table.Column(type: "int", nullable: false), - FinalisedAtUtc = table.Column(type: "datetime2(3)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_EquipmentImportBatch", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "EquipmentImportRow", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - BatchId = table.Column(type: "uniqueidentifier", nullable: false), - LineNumberInFile = table.Column(type: "int", nullable: false), - IsAccepted = table.Column(type: "bit", nullable: false), - RejectReason = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - ZTag = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - MachineCode = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - SAPID = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - EquipmentUuid = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - UnsAreaName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - UnsLineName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Manufacturer = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - Model = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - SerialNumber = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - HardwareRevision = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - SoftwareRevision = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - YearOfConstruction = table.Column(type: "nvarchar(8)", maxLength: 8, nullable: true), - AssetLocation = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - ManufacturerUri = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - DeviceManualUri = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_EquipmentImportRow", x => x.Id); - table.ForeignKey( - name: "FK_EquipmentImportRow_EquipmentImportBatch_BatchId", - column: x => x.BatchId, - principalTable: "EquipmentImportBatch", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_EquipmentImportBatch_Creator_Finalised", - table: "EquipmentImportBatch", - columns: new[] { "CreatedBy", "FinalisedAtUtc" }); - - migrationBuilder.CreateIndex( - name: "IX_EquipmentImportRow_Batch", - table: "EquipmentImportRow", - column: "BatchId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "EquipmentImportRow"); - - migrationBuilder.DropTable( - name: "EquipmentImportBatch"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420000001_ExtendComputeGenerationDiffWithNodeAcl.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420000001_ExtendComputeGenerationDiffWithNodeAcl.Designer.cs deleted file mode 100644 index e4ca8be6..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420000001_ExtendComputeGenerationDiffWithNodeAcl.Designer.cs +++ /dev/null @@ -1,1505 +0,0 @@ -// -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("20260420000001_ExtendComputeGenerationDiffWithNodeAcl")] - partial class ExtendComputeGenerationDiffWithNodeAcl - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ResilienceConfig") - .HasColumnType("nvarchar(max)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LinePath"); - - b.ToTable("Equipment", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (string)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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420000001_ExtendComputeGenerationDiffWithNodeAcl.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420000001_ExtendComputeGenerationDiffWithNodeAcl.cs deleted file mode 100644 index ade0576c..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420000001_ExtendComputeGenerationDiffWithNodeAcl.cs +++ /dev/null @@ -1,172 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - /// Extends dbo.sp_ComputeGenerationDiff to emit NodeAcl rows alongside the - /// existing Namespace/DriverInstance/Equipment/Tag output — closes the final slice of - /// task #196 (DiffViewer ACL section). Logical id for NodeAcl is a composite - /// LdapGroup|ScopeKind|ScopeId triple so a Change row surfaces whether the grant - /// shifted permissions, moved scope, or was added/removed outright. - /// - /// - public partial class ExtendComputeGenerationDiffWithNodeAcl : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(Procs.ComputeGenerationDiffV2); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(Procs.ComputeGenerationDiffV1); - } - - private static class Procs - { - /// V2 — adds the NodeAcl section to the diff output. - public const string ComputeGenerationDiffV2 = @" -CREATE OR ALTER PROCEDURE dbo.sp_ComputeGenerationDiff - @FromGenerationId bigint, - @ToGenerationId bigint -AS -BEGIN - SET NOCOUNT ON; - - CREATE TABLE #diff (TableName nvarchar(32), LogicalId nvarchar(128), ChangeKind nvarchar(16)); - - WITH f AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @FromGenerationId), - t AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Namespace', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @FromGenerationId), - t AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'DriverInstance', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @FromGenerationId), - t AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Equipment', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @FromGenerationId), - t AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Tag', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - -- NodeAcl section. Logical id is the (LdapGroup, ScopeKind, ScopeId) triple so the diff - -- distinguishes same row with new permissions (Modified via CHECKSUM on PermissionFlags + Notes) - -- from a scope move (which surfaces as Added + Removed of different logical ids). - WITH f AS ( - SELECT CONVERT(nvarchar(128), LdapGroup + '|' + CONVERT(nvarchar(16), ScopeKind) + '|' + ISNULL(ScopeId, '(cluster)')) AS LogicalId, - CHECKSUM(ClusterId, PermissionFlags, Notes) AS Sig - FROM dbo.NodeAcl WHERE GenerationId = @FromGenerationId), - t AS ( - SELECT CONVERT(nvarchar(128), LdapGroup + '|' + CONVERT(nvarchar(16), ScopeKind) + '|' + ISNULL(ScopeId, '(cluster)')) AS LogicalId, - CHECKSUM(ClusterId, PermissionFlags, Notes) AS Sig - FROM dbo.NodeAcl WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'NodeAcl', COALESCE(f.LogicalId, t.LogicalId), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - SELECT TableName, LogicalId, ChangeKind FROM #diff; - DROP TABLE #diff; -END -"; - - /// V1 — exact proc shipped in migration 20260417215224_StoredProcedures. Restored on Down(). - public const string ComputeGenerationDiffV1 = @" -CREATE OR ALTER PROCEDURE dbo.sp_ComputeGenerationDiff - @FromGenerationId bigint, - @ToGenerationId bigint -AS -BEGIN - SET NOCOUNT ON; - - CREATE TABLE #diff (TableName nvarchar(32), LogicalId nvarchar(64), ChangeKind nvarchar(16)); - - WITH f AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @FromGenerationId), - t AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Namespace', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @FromGenerationId), - t AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'DriverInstance', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @FromGenerationId), - t AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Equipment', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @FromGenerationId), - t AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Tag', CONVERT(nvarchar(64), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - SELECT TableName, LogicalId, ChangeKind FROM #diff; - DROP TABLE #diff; -END -"; - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420231641_AddPhase7ScriptingTables.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420231641_AddPhase7ScriptingTables.Designer.cs deleted file mode 100644 index 06319e69..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420231641_AddPhase7ScriptingTables.Designer.cs +++ /dev/null @@ -1,1793 +0,0 @@ -// -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("20260420231641_AddPhase7ScriptingTables")] - partial class AddPhase7ScriptingTables - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ResilienceConfig") - .HasColumnType("nvarchar(max)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LinePath"); - - b.ToTable("Equipment", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.Script", b => - { - b.Property("ScriptRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Language") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - 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("GenerationId", "ScriptId") - .IsUnique() - .HasDatabaseName("UX_Script_Generation_LogicalId") - .HasFilter("[ScriptId] IS NOT NULL"); - - b.HasIndex("GenerationId", "SourceHash") - .HasDatabaseName("IX_Script_Generation_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("GenerationId") - .HasColumnType("bigint"); - - 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("ScriptedAlarmId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Severity") - .HasColumnType("int"); - - b.HasKey("ScriptedAlarmRowId"); - - b.HasIndex("GenerationId", "PredicateScriptId") - .HasDatabaseName("IX_ScriptedAlarm_Generation_Script"); - - b.HasIndex("GenerationId", "ScriptedAlarmId") - .IsUnique() - .HasDatabaseName("UX_ScriptedAlarm_Generation_LogicalId") - .HasFilter("[ScriptedAlarmId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_ScriptedAlarm_Generation_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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Historize") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - 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("GenerationId", "ScriptId") - .HasDatabaseName("IX_VirtualTag_Generation_Script"); - - b.HasIndex("GenerationId", "VirtualTagId") - .IsUnique() - .HasDatabaseName("UX_VirtualTag_Generation_LogicalId") - .HasFilter("[VirtualTagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_VirtualTag_Generation_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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Script", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ScriptedAlarm", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.VirtualTag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420231641_AddPhase7ScriptingTables.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420231641_AddPhase7ScriptingTables.cs deleted file mode 100644 index 3730ecfe..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420231641_AddPhase7ScriptingTables.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class AddPhase7ScriptingTables : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Script", - columns: table => new - { - ScriptRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - ScriptId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - SourceCode = table.Column(type: "nvarchar(max)", nullable: false), - SourceHash = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Language = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Script", x => x.ScriptRowId); - table.ForeignKey( - name: "FK_Script_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "ScriptedAlarm", - columns: table => new - { - ScriptedAlarmRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - ScriptedAlarmId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - AlarmType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - Severity = table.Column(type: "int", nullable: false), - MessageTemplate = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), - PredicateScriptId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - HistorizeToAveva = table.Column(type: "bit", nullable: false), - Retain = table.Column(type: "bit", nullable: false), - Enabled = table.Column(type: "bit", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ScriptedAlarm", x => x.ScriptedAlarmRowId); - table.CheckConstraint("CK_ScriptedAlarm_AlarmType", "AlarmType IN ('AlarmCondition','LimitAlarm','OffNormalAlarm','DiscreteAlarm')"); - table.CheckConstraint("CK_ScriptedAlarm_Severity_Range", "Severity BETWEEN 1 AND 1000"); - table.ForeignKey( - name: "FK_ScriptedAlarm_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "ScriptedAlarmState", - columns: table => new - { - ScriptedAlarmId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - EnabledState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - AckedState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - ConfirmedState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - ShelvingState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), - ShelvingExpiresUtc = table.Column(type: "datetime2(3)", nullable: true), - LastAckUser = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), - LastAckComment = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), - LastAckUtc = table.Column(type: "datetime2(3)", nullable: true), - LastConfirmUser = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), - LastConfirmComment = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), - LastConfirmUtc = table.Column(type: "datetime2(3)", nullable: true), - CommentsJson = table.Column(type: "nvarchar(max)", nullable: false), - UpdatedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()") - }, - constraints: table => - { - table.PrimaryKey("PK_ScriptedAlarmState", x => x.ScriptedAlarmId); - table.CheckConstraint("CK_ScriptedAlarmState_CommentsJson_IsJson", "ISJSON(CommentsJson) = 1"); - }); - - migrationBuilder.CreateTable( - name: "VirtualTag", - columns: table => new - { - VirtualTagRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - GenerationId = table.Column(type: "bigint", nullable: false), - VirtualTagId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - DataType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), - ScriptId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - ChangeTriggered = table.Column(type: "bit", nullable: false), - TimerIntervalMs = table.Column(type: "int", nullable: true), - Historize = table.Column(type: "bit", nullable: false), - Enabled = table.Column(type: "bit", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_VirtualTag", x => x.VirtualTagRowId); - table.CheckConstraint("CK_VirtualTag_TimerInterval_Min", "TimerIntervalMs IS NULL OR TimerIntervalMs >= 50"); - table.CheckConstraint("CK_VirtualTag_Trigger_AtLeastOne", "ChangeTriggered = 1 OR TimerIntervalMs IS NOT NULL"); - table.ForeignKey( - name: "FK_VirtualTag_ConfigGeneration_GenerationId", - column: x => x.GenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateIndex( - name: "IX_Script_Generation_SourceHash", - table: "Script", - columns: new[] { "GenerationId", "SourceHash" }); - - migrationBuilder.CreateIndex( - name: "UX_Script_Generation_LogicalId", - table: "Script", - columns: new[] { "GenerationId", "ScriptId" }, - unique: true, - filter: "[ScriptId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_ScriptedAlarm_Generation_Script", - table: "ScriptedAlarm", - columns: new[] { "GenerationId", "PredicateScriptId" }); - - migrationBuilder.CreateIndex( - name: "UX_ScriptedAlarm_Generation_EquipmentPath", - table: "ScriptedAlarm", - columns: new[] { "GenerationId", "EquipmentId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_ScriptedAlarm_Generation_LogicalId", - table: "ScriptedAlarm", - columns: new[] { "GenerationId", "ScriptedAlarmId" }, - unique: true, - filter: "[ScriptedAlarmId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_VirtualTag_Generation_Script", - table: "VirtualTag", - columns: new[] { "GenerationId", "ScriptId" }); - - migrationBuilder.CreateIndex( - name: "UX_VirtualTag_Generation_EquipmentPath", - table: "VirtualTag", - columns: new[] { "GenerationId", "EquipmentId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_VirtualTag_Generation_LogicalId", - table: "VirtualTag", - columns: new[] { "GenerationId", "VirtualTagId" }, - unique: true, - filter: "[VirtualTagId] IS NOT NULL"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Script"); - - migrationBuilder.DropTable( - name: "ScriptedAlarm"); - - migrationBuilder.DropTable( - name: "ScriptedAlarmState"); - - migrationBuilder.DropTable( - name: "VirtualTag"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420232000_ExtendComputeGenerationDiffWithPhase7.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420232000_ExtendComputeGenerationDiffWithPhase7.Designer.cs deleted file mode 100644 index 69d9562d..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420232000_ExtendComputeGenerationDiffWithPhase7.Designer.cs +++ /dev/null @@ -1,1793 +0,0 @@ -// -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("20260420232000_ExtendComputeGenerationDiffWithPhase7")] - partial class ExtendComputeGenerationDiffWithPhase7 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.0") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("Host") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.Property("OpcUaPort") - .HasColumnType("int"); - - b.Property("RedundancyRole") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("ServiceLevelBase") - .HasColumnType("tinyint"); - - b.HasKey("NodeId"); - - b.HasIndex("ApplicationUri") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_ApplicationUri"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ClusterNode_Primary_Per_Cluster") - .HasFilter("[RedundancyRole] = 'Primary'"); - - 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.ClusterNodeGenerationState", b => - { - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CurrentGenerationId") - .HasColumnType("bigint"); - - b.Property("LastAppliedAt") - .HasColumnType("datetime2(3)"); - - b.Property("LastAppliedError") - .HasMaxLength(2048) - .HasColumnType("nvarchar(2048)"); - - b.Property("LastAppliedStatus") - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("LastSeenAt") - .HasColumnType("datetime2(3)"); - - b.HasKey("NodeId"); - - b.HasIndex("CurrentGenerationId") - .HasDatabaseName("IX_ClusterNodeGenerationState_Generation"); - - b.ToTable("ClusterNodeGenerationState", (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("DetailsJson") - .HasColumnType("nvarchar(max)"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("NodeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Principal") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Timestamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime2(3)") - .HasDefaultValueSql("SYSUTCDATETIME()"); - - b.HasKey("AuditId"); - - 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.ConfigGeneration", b => - { - b.Property("GenerationId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("GenerationId")); - - 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("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("ParentGenerationId") - .HasColumnType("bigint"); - - b.Property("PublishedAt") - .HasColumnType("datetime2(3)"); - - b.Property("PublishedBy") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("GenerationId"); - - b.HasIndex("ClusterId") - .IsUnique() - .HasDatabaseName("UX_ConfigGeneration_Draft_Per_Cluster") - .HasFilter("[Status] = 'Draft'"); - - b.HasIndex("ParentGenerationId"); - - b.HasIndex("ClusterId", "Status", "GenerationId") - .IsDescending(false, false, true) - .HasDatabaseName("IX_ConfigGeneration_Cluster_Published"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ClusterId", "Status", "GenerationId"), new[] { "PublishedAt" }); - - b.ToTable("ConfigGeneration", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("DeviceRowId"); - - b.HasIndex("GenerationId", "DeviceId") - .IsUnique() - .HasDatabaseName("UX_Device_Generation_LogicalId") - .HasFilter("[DeviceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Device_Generation_Driver"); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("NamespaceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ResilienceConfig") - .HasColumnType("nvarchar(max)"); - - b.HasKey("DriverInstanceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_DriverInstance_Generation_Cluster"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .IsUnique() - .HasDatabaseName("UX_DriverInstance_Generation_LogicalId") - .HasFilter("[DriverInstanceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceId") - .HasDatabaseName("IX_DriverInstance_Generation_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("GenerationId") - .HasColumnType("bigint"); - - 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("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("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_Equipment_Generation_Driver"); - - b.HasIndex("GenerationId", "EquipmentId") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LogicalId") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentUuid") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_Uuid"); - - b.HasIndex("GenerationId", "MachineCode") - .HasDatabaseName("IX_Equipment_Generation_MachineCode"); - - b.HasIndex("GenerationId", "SAPID") - .HasDatabaseName("IX_Equipment_Generation_SAPID") - .HasFilter("[SAPID] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId") - .HasDatabaseName("IX_Equipment_Generation_Line"); - - b.HasIndex("GenerationId", "ZTag") - .HasDatabaseName("IX_Equipment_Generation_ZTag") - .HasFilter("[ZTag] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsLineId", "Name") - .IsUnique() - .HasDatabaseName("UX_Equipment_Generation_LinePath"); - - b.ToTable("Equipment", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_Namespace_Generation_Cluster"); - - b.HasIndex("GenerationId", "NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("GenerationId", "NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_NamespaceUri"); - - b.HasIndex("GenerationId", "ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_Cluster_Kind"); - - b.HasIndex("GenerationId", "NamespaceId", "ClusterId") - .IsUnique() - .HasDatabaseName("UX_Namespace_Generation_LogicalId_Cluster") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.ToTable("Namespace", (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("GenerationId") - .HasColumnType("bigint"); - - 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("ScopeId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("ScopeKind") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.HasKey("NodeAclRowId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_NodeAcl_Generation_Cluster"); - - b.HasIndex("GenerationId", "LdapGroup") - .HasDatabaseName("IX_NodeAcl_Generation_Group"); - - b.HasIndex("GenerationId", "NodeAclId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_LogicalId") - .HasFilter("[NodeAclId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ScopeKind", "ScopeId") - .HasDatabaseName("IX_NodeAcl_Generation_Scope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId") - .IsUnique() - .HasDatabaseName("UX_NodeAcl_Generation_GroupScope") - .HasFilter("[ScopeId] IS NOT NULL"); - - b.ToTable("NodeAcl", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("IntervalMs") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("PollGroupRowId"); - - b.HasIndex("GenerationId", "DriverInstanceId") - .HasDatabaseName("IX_PollGroup_Generation_Driver"); - - b.HasIndex("GenerationId", "PollGroupId") - .IsUnique() - .HasDatabaseName("UX_PollGroup_Generation_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.Script", b => - { - b.Property("ScriptRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Language") - .IsRequired() - .HasMaxLength(16) - .HasColumnType("nvarchar(16)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - 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("GenerationId", "ScriptId") - .IsUnique() - .HasDatabaseName("UX_Script_Generation_LogicalId") - .HasFilter("[ScriptId] IS NOT NULL"); - - b.HasIndex("GenerationId", "SourceHash") - .HasDatabaseName("IX_Script_Generation_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("GenerationId") - .HasColumnType("bigint"); - - 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("ScriptedAlarmId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Severity") - .HasColumnType("int"); - - b.HasKey("ScriptedAlarmRowId"); - - b.HasIndex("GenerationId", "PredicateScriptId") - .HasDatabaseName("IX_ScriptedAlarm_Generation_Script"); - - b.HasIndex("GenerationId", "ScriptedAlarmId") - .IsUnique() - .HasDatabaseName("UX_ScriptedAlarm_Generation_LogicalId") - .HasFilter("[ScriptedAlarmId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_ScriptedAlarm_Generation_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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PollGroupId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TagConfig") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("GenerationId", "EquipmentId") - .HasDatabaseName("IX_Tag_Generation_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Generation_Driver_Device"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("GenerationId", "DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_Generation_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsAreaRowId"); - - b.HasIndex("ClusterId"); - - b.HasIndex("GenerationId", "ClusterId") - .HasDatabaseName("IX_UnsArea_Generation_Cluster"); - - b.HasIndex("GenerationId", "UnsAreaId") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_LogicalId") - .HasFilter("[UnsAreaId] IS NOT NULL"); - - b.HasIndex("GenerationId", "ClusterId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsArea_Generation_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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Notes") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UnsAreaId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("UnsLineRowId"); - - b.HasIndex("GenerationId", "UnsAreaId") - .HasDatabaseName("IX_UnsLine_Generation_Area"); - - b.HasIndex("GenerationId", "UnsLineId") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_LogicalId") - .HasFilter("[UnsLineId] IS NOT NULL"); - - b.HasIndex("GenerationId", "UnsAreaId", "Name") - .IsUnique() - .HasDatabaseName("UX_UnsLine_Generation_AreaName"); - - b.ToTable("UnsLine", (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("GenerationId") - .HasColumnType("bigint"); - - b.Property("Historize") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - 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("GenerationId", "ScriptId") - .HasDatabaseName("IX_VirtualTag_Generation_Script"); - - b.HasIndex("GenerationId", "VirtualTagId") - .IsUnique() - .HasDatabaseName("UX_VirtualTag_Generation_LogicalId") - .HasFilter("[VirtualTagId] IS NOT NULL"); - - b.HasIndex("GenerationId", "EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_VirtualTag_Generation_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.ClusterNodeGenerationState", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "CurrentGeneration") - .WithMany() - .HasForeignKey("CurrentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", "Node") - .WithOne("GenerationState") - .HasForeignKey("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNodeGenerationState", "NodeId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("CurrentGeneration"); - - b.Navigation("Node"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Generations") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Parent") - .WithMany() - .HasForeignKey("ParentGenerationId") - .OnDelete(DeleteBehavior.Restrict); - - b.Navigation("Cluster"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Device", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Equipment", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.PollGroup", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Script", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ScriptedAlarm", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Tag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - 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.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.UnsLine", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.VirtualTag", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ConfigGeneration", "Generation") - .WithMany() - .HasForeignKey("GenerationId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Generation"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ClusterNode", b => - { - b.Navigation("Credentials"); - - b.Navigation("GenerationState"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Generations"); - - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420232000_ExtendComputeGenerationDiffWithPhase7.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420232000_ExtendComputeGenerationDiffWithPhase7.cs deleted file mode 100644 index 2cd3cf7d..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420232000_ExtendComputeGenerationDiffWithPhase7.cs +++ /dev/null @@ -1,232 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - /// Phase 7 follow-up (task #241) — extends dbo.sp_ComputeGenerationDiff to emit - /// Script / VirtualTag / ScriptedAlarm rows alongside the existing Namespace / - /// DriverInstance / Equipment / Tag / NodeAcl output. Admin DiffViewer now shows - /// Phase 7 changes between generations. - /// - /// - /// Logical ids: ScriptId, VirtualTagId, ScriptedAlarmId — stable across generations - /// so a Script whose source changes surfaces as Modified (CHECKSUM picks up the - /// SourceHash delta) while a renamed script surfaces as Modified on Name alone. - /// ScriptedAlarmState is deliberately excluded — it's not generation-scoped, so - /// diffing it between generations is meaningless. - /// - /// - public partial class ExtendComputeGenerationDiffWithPhase7 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(Procs.ComputeGenerationDiffV3); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(Procs.ComputeGenerationDiffV2); - } - - private static class Procs - { - /// V3 — adds Script / VirtualTag / ScriptedAlarm sections. - public const string ComputeGenerationDiffV3 = @" -CREATE OR ALTER PROCEDURE dbo.sp_ComputeGenerationDiff - @FromGenerationId bigint, - @ToGenerationId bigint -AS -BEGIN - SET NOCOUNT ON; - - CREATE TABLE #diff (TableName nvarchar(32), LogicalId nvarchar(128), ChangeKind nvarchar(16)); - - WITH f AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @FromGenerationId), - t AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Namespace', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @FromGenerationId), - t AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'DriverInstance', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @FromGenerationId), - t AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Equipment', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @FromGenerationId), - t AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Tag', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS ( - SELECT CONVERT(nvarchar(128), LdapGroup + '|' + CONVERT(nvarchar(16), ScopeKind) + '|' + ISNULL(ScopeId, '(cluster)')) AS LogicalId, - CHECKSUM(ClusterId, PermissionFlags, Notes) AS Sig - FROM dbo.NodeAcl WHERE GenerationId = @FromGenerationId), - t AS ( - SELECT CONVERT(nvarchar(128), LdapGroup + '|' + CONVERT(nvarchar(16), ScopeKind) + '|' + ISNULL(ScopeId, '(cluster)')) AS LogicalId, - CHECKSUM(ClusterId, PermissionFlags, Notes) AS Sig - FROM dbo.NodeAcl WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'NodeAcl', COALESCE(f.LogicalId, t.LogicalId), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - -- Phase 7 — Script section. CHECKSUM picks up source changes via SourceHash + rename - -- via Name; Language future-proofs for non-C# engines. Same Name + same Source = - -- Unchanged (identical hash). - WITH f AS (SELECT ScriptId AS LogicalId, CHECKSUM(Name, SourceHash, Language) AS Sig FROM dbo.Script WHERE GenerationId = @FromGenerationId), - t AS (SELECT ScriptId AS LogicalId, CHECKSUM(Name, SourceHash, Language) AS Sig FROM dbo.Script WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Script', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - -- Phase 7 — VirtualTag section. - WITH f AS (SELECT VirtualTagId AS LogicalId, CHECKSUM(EquipmentId, Name, DataType, ScriptId, ChangeTriggered, TimerIntervalMs, Historize, Enabled) AS Sig FROM dbo.VirtualTag WHERE GenerationId = @FromGenerationId), - t AS (SELECT VirtualTagId AS LogicalId, CHECKSUM(EquipmentId, Name, DataType, ScriptId, ChangeTriggered, TimerIntervalMs, Historize, Enabled) AS Sig FROM dbo.VirtualTag WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'VirtualTag', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - -- Phase 7 — ScriptedAlarm section. ScriptedAlarmState (operator ack trail) is - -- logical-id keyed outside the generation scope + intentionally excluded here — - -- diffing ack state between generations is semantically meaningless. - WITH f AS (SELECT ScriptedAlarmId AS LogicalId, CHECKSUM(EquipmentId, Name, AlarmType, Severity, MessageTemplate, PredicateScriptId, HistorizeToAveva, Retain, Enabled) AS Sig FROM dbo.ScriptedAlarm WHERE GenerationId = @FromGenerationId), - t AS (SELECT ScriptedAlarmId AS LogicalId, CHECKSUM(EquipmentId, Name, AlarmType, Severity, MessageTemplate, PredicateScriptId, HistorizeToAveva, Retain, Enabled) AS Sig FROM dbo.ScriptedAlarm WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'ScriptedAlarm', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - SELECT TableName, LogicalId, ChangeKind FROM #diff; - DROP TABLE #diff; -END -"; - - /// V2 — restores the pre-Phase-7 proc on Down(). - public const string ComputeGenerationDiffV2 = @" -CREATE OR ALTER PROCEDURE dbo.sp_ComputeGenerationDiff - @FromGenerationId bigint, - @ToGenerationId bigint -AS -BEGIN - SET NOCOUNT ON; - - CREATE TABLE #diff (TableName nvarchar(32), LogicalId nvarchar(128), ChangeKind nvarchar(16)); - - WITH f AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @FromGenerationId), - t AS (SELECT NamespaceId AS LogicalId, CHECKSUM(NamespaceUri, Kind, Enabled, Notes) AS Sig FROM dbo.Namespace WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Namespace', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @FromGenerationId), - t AS (SELECT DriverInstanceId AS LogicalId, CHECKSUM(ClusterId, NamespaceId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) AS Sig FROM dbo.DriverInstance WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'DriverInstance', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @FromGenerationId), - t AS (SELECT EquipmentId AS LogicalId, CHECKSUM(EquipmentUuid, DriverInstanceId, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) AS Sig FROM dbo.Equipment WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Equipment', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @FromGenerationId), - t AS (SELECT TagId AS LogicalId, CHECKSUM(DriverInstanceId, DeviceId, EquipmentId, PollGroupId, FolderPath, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) AS Sig FROM dbo.Tag WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'Tag', CONVERT(nvarchar(128), COALESCE(f.LogicalId, t.LogicalId)), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - WITH f AS ( - SELECT CONVERT(nvarchar(128), LdapGroup + '|' + CONVERT(nvarchar(16), ScopeKind) + '|' + ISNULL(ScopeId, '(cluster)')) AS LogicalId, - CHECKSUM(ClusterId, PermissionFlags, Notes) AS Sig - FROM dbo.NodeAcl WHERE GenerationId = @FromGenerationId), - t AS ( - SELECT CONVERT(nvarchar(128), LdapGroup + '|' + CONVERT(nvarchar(16), ScopeKind) + '|' + ISNULL(ScopeId, '(cluster)')) AS LogicalId, - CHECKSUM(ClusterId, PermissionFlags, Notes) AS Sig - FROM dbo.NodeAcl WHERE GenerationId = @ToGenerationId) - INSERT #diff - SELECT 'NodeAcl', COALESCE(f.LogicalId, t.LogicalId), - CASE WHEN f.LogicalId IS NULL THEN 'Added' - WHEN t.LogicalId IS NULL THEN 'Removed' - WHEN f.Sig <> t.Sig THEN 'Modified' - ELSE 'Unchanged' END - FROM f FULL OUTER JOIN t ON f.LogicalId = t.LogicalId - WHERE f.LogicalId IS NULL OR t.LogicalId IS NULL OR f.Sig <> t.Sig; - - SELECT TableName, LogicalId, ChangeKind FROM #diff; - DROP TABLE #diff; -END -"; - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260522000001_AddReleasedByToReleaseExternalIdReservation.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260522000001_AddReleasedByToReleaseExternalIdReservation.cs deleted file mode 100644 index c337481b..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260522000001_AddReleasedByToReleaseExternalIdReservation.cs +++ /dev/null @@ -1,120 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - /// Admin-008: adds @ReleasedBy parameter to - /// dbo.sp_ReleaseExternalIdReservation so the operator principal name (the LDAP - /// sign-in) is recorded in ExternalIdReservation.ReleasedBy and the - /// ConfigAuditLog.Principal column. - /// - /// Prior to this migration the proc used SUSER_SNAME() for both columns, which - /// recorded the shared SQL service account rather than the Admin-UI operator who performed - /// the release — making the audit trail useless for attribution. The stored proc now - /// accepts @ReleasedBy nvarchar(128) and uses it for both columns; validation - /// rejects a null/empty value the same way @ReleaseReason is validated. - /// - /// - public partial class AddReleasedByToReleaseExternalIdReservation : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(Procs.ReleaseExternalIdReservationV2); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql(Procs.ReleaseExternalIdReservationV1); - } - - private static class Procs - { - /// V2 — accepts @ReleasedBy for proper operator attribution. - public const string ReleaseExternalIdReservationV2 = @" -CREATE OR ALTER PROCEDURE dbo.sp_ReleaseExternalIdReservation - @Kind nvarchar(16), - @Value nvarchar(64), - @ReleaseReason nvarchar(512), - @ReleasedBy nvarchar(128) -AS -BEGIN - SET NOCOUNT ON; - SET XACT_ABORT ON; - - IF @ReleaseReason IS NULL OR LEN(@ReleaseReason) = 0 - BEGIN - RAISERROR('ReleaseReason is required', 16, 1); - RETURN; - END - - IF @ReleasedBy IS NULL OR LEN(@ReleasedBy) = 0 - BEGIN - RAISERROR('ReleasedBy is required', 16, 1); - RETURN; - END - - UPDATE dbo.ExternalIdReservation - SET ReleasedAt = SYSUTCDATETIME(), - ReleasedBy = @ReleasedBy, - ReleaseReason = @ReleaseReason - WHERE Kind = @Kind AND Value = @Value AND ReleasedAt IS NULL; - - IF @@ROWCOUNT = 0 - BEGIN - RAISERROR('No active reservation found for (%s, %s)', 16, 1, @Kind, @Value); - RETURN; - END - - -- Escape all caller-supplied values via STRING_ESCAPE so quotes/backslashes cannot break the - -- JSON document or inject additional structure into the audit record. - INSERT dbo.ConfigAuditLog (Principal, EventType, DetailsJson) - VALUES (@ReleasedBy, 'ExternalIdReleased', - CONCAT('{""kind"":""', STRING_ESCAPE(@Kind, 'json'), - '"",""value"":""', STRING_ESCAPE(@Value, 'json'), '""}')); -END -"; - - /// V1 — original proc (uses SUSER_SNAME() for attribution). Restored on Down(). - public const string ReleaseExternalIdReservationV1 = @" -CREATE OR ALTER PROCEDURE dbo.sp_ReleaseExternalIdReservation - @Kind nvarchar(16), - @Value nvarchar(64), - @ReleaseReason nvarchar(512) -AS -BEGIN - SET NOCOUNT ON; - SET XACT_ABORT ON; - - IF @ReleaseReason IS NULL OR LEN(@ReleaseReason) = 0 - BEGIN - RAISERROR('ReleaseReason is required', 16, 1); - RETURN; - END - - UPDATE dbo.ExternalIdReservation - SET ReleasedAt = SYSUTCDATETIME(), - ReleasedBy = SUSER_SNAME(), - ReleaseReason = @ReleaseReason - WHERE Kind = @Kind AND Value = @Value AND ReleasedAt IS NULL; - - IF @@ROWCOUNT = 0 - BEGIN - RAISERROR('No active reservation found for (%s, %s)', 16, 1, @Kind, @Value); - RETURN; - END - - -- Escape both caller-supplied values via STRING_ESCAPE so quotes/backslashes cannot break the - -- JSON document or inject additional structure into the audit record. - INSERT dbo.ConfigAuditLog (Principal, EventType, DetailsJson) - VALUES (SUSER_SNAME(), 'ExternalIdReleased', - CONCAT('{""kind"":""', STRING_ESCAPE(@Kind, 'json'), - '"",""value"":""', STRING_ESCAPE(@Value, 'json'), '""}')); -END -"; - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526081556_V2HostingAlignment.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526081556_V2HostingAlignment.cs deleted file mode 100644 index bbbbbd6d..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526081556_V2HostingAlignment.cs +++ /dev/null @@ -1,1562 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class V2HostingAlignment : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Device_ConfigGeneration_GenerationId", - table: "Device"); - - migrationBuilder.DropForeignKey( - name: "FK_DriverInstance_ConfigGeneration_GenerationId", - table: "DriverInstance"); - - migrationBuilder.DropForeignKey( - name: "FK_Equipment_ConfigGeneration_GenerationId", - table: "Equipment"); - - migrationBuilder.DropForeignKey( - name: "FK_Namespace_ConfigGeneration_GenerationId", - table: "Namespace"); - - migrationBuilder.DropForeignKey( - name: "FK_NodeAcl_ConfigGeneration_GenerationId", - table: "NodeAcl"); - - migrationBuilder.DropForeignKey( - name: "FK_PollGroup_ConfigGeneration_GenerationId", - table: "PollGroup"); - - migrationBuilder.DropForeignKey( - name: "FK_Script_ConfigGeneration_GenerationId", - table: "Script"); - - migrationBuilder.DropForeignKey( - name: "FK_ScriptedAlarm_ConfigGeneration_GenerationId", - table: "ScriptedAlarm"); - - migrationBuilder.DropForeignKey( - name: "FK_Tag_ConfigGeneration_GenerationId", - table: "Tag"); - - migrationBuilder.DropForeignKey( - name: "FK_UnsArea_ConfigGeneration_GenerationId", - table: "UnsArea"); - - migrationBuilder.DropForeignKey( - name: "FK_UnsLine_ConfigGeneration_GenerationId", - table: "UnsLine"); - - migrationBuilder.DropForeignKey( - name: "FK_VirtualTag_ConfigGeneration_GenerationId", - table: "VirtualTag"); - - migrationBuilder.DropTable( - name: "ClusterNodeGenerationState"); - - migrationBuilder.DropTable( - name: "ConfigGeneration"); - - migrationBuilder.DropIndex( - name: "IX_VirtualTag_Generation_Script", - table: "VirtualTag"); - - migrationBuilder.DropIndex( - name: "UX_VirtualTag_Generation_EquipmentPath", - table: "VirtualTag"); - - migrationBuilder.DropIndex( - name: "UX_VirtualTag_Generation_LogicalId", - table: "VirtualTag"); - - migrationBuilder.DropIndex( - name: "IX_UnsLine_Generation_Area", - table: "UnsLine"); - - migrationBuilder.DropIndex( - name: "UX_UnsLine_Generation_AreaName", - table: "UnsLine"); - - migrationBuilder.DropIndex( - name: "UX_UnsLine_Generation_LogicalId", - table: "UnsLine"); - - migrationBuilder.DropIndex( - name: "IX_UnsArea_Generation_Cluster", - table: "UnsArea"); - - migrationBuilder.DropIndex( - name: "UX_UnsArea_Generation_ClusterName", - table: "UnsArea"); - - migrationBuilder.DropIndex( - name: "UX_UnsArea_Generation_LogicalId", - table: "UnsArea"); - - migrationBuilder.DropIndex( - name: "IX_Tag_Generation_Driver_Device", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "IX_Tag_Generation_Equipment", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "UX_Tag_Generation_EquipmentPath", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "UX_Tag_Generation_FolderPath", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "UX_Tag_Generation_LogicalId", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "IX_ScriptedAlarm_Generation_Script", - table: "ScriptedAlarm"); - - migrationBuilder.DropIndex( - name: "UX_ScriptedAlarm_Generation_EquipmentPath", - table: "ScriptedAlarm"); - - migrationBuilder.DropIndex( - name: "UX_ScriptedAlarm_Generation_LogicalId", - table: "ScriptedAlarm"); - - migrationBuilder.DropIndex( - name: "IX_Script_Generation_SourceHash", - table: "Script"); - - migrationBuilder.DropIndex( - name: "UX_Script_Generation_LogicalId", - table: "Script"); - - migrationBuilder.DropIndex( - name: "IX_PollGroup_Generation_Driver", - table: "PollGroup"); - - migrationBuilder.DropIndex( - name: "UX_PollGroup_Generation_LogicalId", - table: "PollGroup"); - - migrationBuilder.DropIndex( - name: "IX_NodeAcl_Generation_Cluster", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "IX_NodeAcl_Generation_Group", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "IX_NodeAcl_Generation_Scope", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "UX_NodeAcl_Generation_GroupScope", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "UX_NodeAcl_Generation_LogicalId", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "IX_Namespace_Generation_Cluster", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "UX_Namespace_Generation_Cluster_Kind", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "UX_Namespace_Generation_LogicalId", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "UX_Namespace_Generation_LogicalId_Cluster", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "UX_Namespace_Generation_NamespaceUri", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_Generation_Driver", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_Generation_Line", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_Generation_MachineCode", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_Generation_SAPID", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_Generation_ZTag", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "UX_Equipment_Generation_LinePath", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "UX_Equipment_Generation_LogicalId", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "UX_Equipment_Generation_Uuid", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_DriverInstance_Generation_Cluster", - table: "DriverInstance"); - - migrationBuilder.DropIndex( - name: "IX_DriverInstance_Generation_Namespace", - table: "DriverInstance"); - - migrationBuilder.DropIndex( - name: "UX_DriverInstance_Generation_LogicalId", - table: "DriverInstance"); - - migrationBuilder.DropIndex( - name: "IX_Device_Generation_Driver", - table: "Device"); - - migrationBuilder.DropIndex( - name: "UX_Device_Generation_LogicalId", - table: "Device"); - - migrationBuilder.DropIndex( - name: "UX_ClusterNode_Primary_Per_Cluster", - table: "ClusterNode"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "VirtualTag"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "UnsLine"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "UnsArea"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "Tag"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "ScriptedAlarm"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "Script"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "PollGroup"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "NodeAcl"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "Namespace"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "Equipment"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "DriverInstance"); - - migrationBuilder.DropColumn( - name: "GenerationId", - table: "Device"); - - migrationBuilder.DropColumn( - name: "RedundancyRole", - table: "ClusterNode"); - - migrationBuilder.RenameIndex( - name: "IX_UnsArea_ClusterId", - table: "UnsArea", - newName: "IX_UnsArea_Cluster"); - - migrationBuilder.RenameIndex( - name: "IX_Namespace_ClusterId", - table: "Namespace", - newName: "IX_Namespace_Cluster"); - - migrationBuilder.RenameIndex( - name: "IX_DriverInstance_ClusterId", - table: "DriverInstance", - newName: "IX_DriverInstance_Cluster"); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "VirtualTag", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "UnsLine", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "UnsArea", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "Tag", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "ScriptedAlarm", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "Script", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "PollGroup", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "NodeAcl", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "Namespace", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "Equipment", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "DriverInstance", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.AddColumn( - name: "RowVersion", - table: "Device", - type: "rowversion", - rowVersion: true, - nullable: false, - defaultValue: new byte[0]); - - migrationBuilder.CreateTable( - name: "ConfigEdit", - columns: table => new - { - EditId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - EntityType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - EntityId = table.Column(type: "uniqueidentifier", nullable: false), - FieldsJson = table.Column(type: "nvarchar(max)", nullable: false), - ExecutionId = table.Column(type: "uniqueidentifier", nullable: true), - EditedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - EditedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - SourceNode = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ConfigEdit", x => x.EditId); - table.CheckConstraint("CK_ConfigEdit_FieldsJson_IsJson", "ISJSON(FieldsJson) = 1"); - }); - - migrationBuilder.CreateTable( - name: "DataProtectionKeys", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - FriendlyName = table.Column(type: "nvarchar(max)", nullable: true), - Xml = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_DataProtectionKeys", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Deployment", - columns: table => new - { - DeploymentId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), - RevisionHash = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Status = table.Column(type: "int", nullable: false), - CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - CreatedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - ArtifactBlob = table.Column(type: "varbinary(max)", nullable: false), - RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false), - FailureReason = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), - SealedAtUtc = table.Column(type: "datetime2(3)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Deployment", x => x.DeploymentId); - }); - - migrationBuilder.CreateTable( - name: "NodeDeploymentState", - columns: table => new - { - NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - DeploymentId = table.Column(type: "uniqueidentifier", nullable: false), - Status = table.Column(type: "int", nullable: false), - StartedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - AppliedAtUtc = table.Column(type: "datetime2(3)", nullable: true), - FailureReason = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), - RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_NodeDeploymentState", x => new { x.NodeId, x.DeploymentId }); - table.ForeignKey( - name: "FK_NodeDeploymentState_ClusterNode_NodeId", - column: x => x.NodeId, - principalTable: "ClusterNode", - principalColumn: "NodeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_NodeDeploymentState_Deployment_DeploymentId", - column: x => x.DeploymentId, - principalTable: "Deployment", - principalColumn: "DeploymentId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_VirtualTag_Script", - table: "VirtualTag", - column: "ScriptId"); - - migrationBuilder.CreateIndex( - name: "UX_VirtualTag_EquipmentPath", - table: "VirtualTag", - columns: new[] { "EquipmentId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_VirtualTag_LogicalId", - table: "VirtualTag", - column: "VirtualTagId", - unique: true, - filter: "[VirtualTagId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_UnsLine_Area", - table: "UnsLine", - column: "UnsAreaId"); - - migrationBuilder.CreateIndex( - name: "UX_UnsLine_AreaName", - table: "UnsLine", - columns: new[] { "UnsAreaId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_UnsLine_LogicalId", - table: "UnsLine", - column: "UnsLineId", - unique: true, - filter: "[UnsLineId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_UnsArea_ClusterName", - table: "UnsArea", - columns: new[] { "ClusterId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_UnsArea_LogicalId", - table: "UnsArea", - column: "UnsAreaId", - unique: true, - filter: "[UnsAreaId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Tag_Driver_Device", - table: "Tag", - columns: new[] { "DriverInstanceId", "DeviceId" }); - - migrationBuilder.CreateIndex( - name: "IX_Tag_Equipment", - table: "Tag", - column: "EquipmentId", - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_EquipmentPath", - table: "Tag", - columns: new[] { "EquipmentId", "Name" }, - unique: true, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_FolderPath", - table: "Tag", - columns: new[] { "DriverInstanceId", "FolderPath", "Name" }, - unique: true, - filter: "[EquipmentId] IS NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_LogicalId", - table: "Tag", - column: "TagId", - unique: true, - filter: "[TagId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_ScriptedAlarm_Script", - table: "ScriptedAlarm", - column: "PredicateScriptId"); - - migrationBuilder.CreateIndex( - name: "UX_ScriptedAlarm_EquipmentPath", - table: "ScriptedAlarm", - columns: new[] { "EquipmentId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_ScriptedAlarm_LogicalId", - table: "ScriptedAlarm", - column: "ScriptedAlarmId", - unique: true, - filter: "[ScriptedAlarmId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Script_SourceHash", - table: "Script", - column: "SourceHash"); - - migrationBuilder.CreateIndex( - name: "UX_Script_LogicalId", - table: "Script", - column: "ScriptId", - unique: true, - filter: "[ScriptId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_PollGroup_Driver", - table: "PollGroup", - column: "DriverInstanceId"); - - migrationBuilder.CreateIndex( - name: "UX_PollGroup_LogicalId", - table: "PollGroup", - column: "PollGroupId", - unique: true, - filter: "[PollGroupId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Cluster", - table: "NodeAcl", - column: "ClusterId"); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Group", - table: "NodeAcl", - column: "LdapGroup"); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Scope", - table: "NodeAcl", - columns: new[] { "ScopeKind", "ScopeId" }, - filter: "[ScopeId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_NodeAcl_GroupScope", - table: "NodeAcl", - columns: new[] { "ClusterId", "LdapGroup", "ScopeKind", "ScopeId" }, - unique: true, - filter: "[ScopeId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_NodeAcl_LogicalId", - table: "NodeAcl", - column: "NodeAclId", - unique: true, - filter: "[NodeAclId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Cluster_Kind", - table: "Namespace", - columns: new[] { "ClusterId", "Kind" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_LogicalId", - table: "Namespace", - column: "NamespaceId", - unique: true, - filter: "[NamespaceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_NamespaceUri", - table: "Namespace", - column: "NamespaceUri", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Driver", - table: "Equipment", - column: "DriverInstanceId"); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Line", - table: "Equipment", - column: "UnsLineId"); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_MachineCode", - table: "Equipment", - column: "MachineCode"); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_SAPID", - table: "Equipment", - column: "SAPID", - filter: "[SAPID] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_ZTag", - table: "Equipment", - column: "ZTag", - filter: "[ZTag] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_LinePath", - table: "Equipment", - columns: new[] { "UnsLineId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_LogicalId", - table: "Equipment", - column: "EquipmentId", - unique: true, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_Uuid", - table: "Equipment", - column: "EquipmentUuid", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_DriverInstance_Namespace", - table: "DriverInstance", - column: "NamespaceId"); - - migrationBuilder.CreateIndex( - name: "UX_DriverInstance_LogicalId", - table: "DriverInstance", - column: "DriverInstanceId", - unique: true, - filter: "[DriverInstanceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Device_Driver", - table: "Device", - column: "DriverInstanceId"); - - migrationBuilder.CreateIndex( - name: "UX_Device_LogicalId", - table: "Device", - column: "DeviceId", - unique: true, - filter: "[DeviceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_ClusterNode_ClusterId", - table: "ClusterNode", - column: "ClusterId"); - - migrationBuilder.CreateIndex( - name: "IX_ConfigEdit_EditedAt", - table: "ConfigEdit", - column: "EditedAtUtc"); - - migrationBuilder.CreateIndex( - name: "IX_ConfigEdit_Entity", - table: "ConfigEdit", - columns: new[] { "EntityType", "EntityId" }); - - migrationBuilder.CreateIndex( - name: "IX_ConfigEdit_Execution", - table: "ConfigEdit", - column: "ExecutionId", - filter: "[ExecutionId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Deployment_CreatedAt", - table: "Deployment", - column: "CreatedAtUtc"); - - migrationBuilder.CreateIndex( - name: "IX_Deployment_Status", - table: "Deployment", - column: "Status"); - - migrationBuilder.CreateIndex( - name: "IX_NodeDeploymentState_Deployment", - table: "NodeDeploymentState", - column: "DeploymentId"); - - migrationBuilder.CreateIndex( - name: "IX_NodeDeploymentState_Status", - table: "NodeDeploymentState", - column: "Status"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "ConfigEdit"); - - migrationBuilder.DropTable( - name: "DataProtectionKeys"); - - migrationBuilder.DropTable( - name: "NodeDeploymentState"); - - migrationBuilder.DropTable( - name: "Deployment"); - - migrationBuilder.DropIndex( - name: "IX_VirtualTag_Script", - table: "VirtualTag"); - - migrationBuilder.DropIndex( - name: "UX_VirtualTag_EquipmentPath", - table: "VirtualTag"); - - migrationBuilder.DropIndex( - name: "UX_VirtualTag_LogicalId", - table: "VirtualTag"); - - migrationBuilder.DropIndex( - name: "IX_UnsLine_Area", - table: "UnsLine"); - - migrationBuilder.DropIndex( - name: "UX_UnsLine_AreaName", - table: "UnsLine"); - - migrationBuilder.DropIndex( - name: "UX_UnsLine_LogicalId", - table: "UnsLine"); - - migrationBuilder.DropIndex( - name: "UX_UnsArea_ClusterName", - table: "UnsArea"); - - migrationBuilder.DropIndex( - name: "UX_UnsArea_LogicalId", - table: "UnsArea"); - - migrationBuilder.DropIndex( - name: "IX_Tag_Driver_Device", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "IX_Tag_Equipment", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "UX_Tag_EquipmentPath", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "UX_Tag_FolderPath", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "UX_Tag_LogicalId", - table: "Tag"); - - migrationBuilder.DropIndex( - name: "IX_ScriptedAlarm_Script", - table: "ScriptedAlarm"); - - migrationBuilder.DropIndex( - name: "UX_ScriptedAlarm_EquipmentPath", - table: "ScriptedAlarm"); - - migrationBuilder.DropIndex( - name: "UX_ScriptedAlarm_LogicalId", - table: "ScriptedAlarm"); - - migrationBuilder.DropIndex( - name: "IX_Script_SourceHash", - table: "Script"); - - migrationBuilder.DropIndex( - name: "UX_Script_LogicalId", - table: "Script"); - - migrationBuilder.DropIndex( - name: "IX_PollGroup_Driver", - table: "PollGroup"); - - migrationBuilder.DropIndex( - name: "UX_PollGroup_LogicalId", - table: "PollGroup"); - - migrationBuilder.DropIndex( - name: "IX_NodeAcl_Cluster", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "IX_NodeAcl_Group", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "IX_NodeAcl_Scope", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "UX_NodeAcl_GroupScope", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "UX_NodeAcl_LogicalId", - table: "NodeAcl"); - - migrationBuilder.DropIndex( - name: "UX_Namespace_Cluster_Kind", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "UX_Namespace_LogicalId", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "UX_Namespace_NamespaceUri", - table: "Namespace"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_Driver", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_Line", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_MachineCode", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_SAPID", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_Equipment_ZTag", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "UX_Equipment_LinePath", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "UX_Equipment_LogicalId", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "UX_Equipment_Uuid", - table: "Equipment"); - - migrationBuilder.DropIndex( - name: "IX_DriverInstance_Namespace", - table: "DriverInstance"); - - migrationBuilder.DropIndex( - name: "UX_DriverInstance_LogicalId", - table: "DriverInstance"); - - migrationBuilder.DropIndex( - name: "IX_Device_Driver", - table: "Device"); - - migrationBuilder.DropIndex( - name: "UX_Device_LogicalId", - table: "Device"); - - migrationBuilder.DropIndex( - name: "IX_ClusterNode_ClusterId", - table: "ClusterNode"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "VirtualTag"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "UnsLine"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "UnsArea"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "Tag"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "ScriptedAlarm"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "Script"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "PollGroup"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "NodeAcl"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "Namespace"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "Equipment"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "DriverInstance"); - - migrationBuilder.DropColumn( - name: "RowVersion", - table: "Device"); - - migrationBuilder.RenameIndex( - name: "IX_UnsArea_Cluster", - table: "UnsArea", - newName: "IX_UnsArea_ClusterId"); - - migrationBuilder.RenameIndex( - name: "IX_Namespace_Cluster", - table: "Namespace", - newName: "IX_Namespace_ClusterId"); - - migrationBuilder.RenameIndex( - name: "IX_DriverInstance_Cluster", - table: "DriverInstance", - newName: "IX_DriverInstance_ClusterId"); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "VirtualTag", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "UnsLine", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "UnsArea", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "Tag", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "ScriptedAlarm", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "Script", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "PollGroup", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "NodeAcl", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "Namespace", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "Equipment", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "DriverInstance", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "GenerationId", - table: "Device", - type: "bigint", - nullable: false, - defaultValue: 0L); - - migrationBuilder.AddColumn( - name: "RedundancyRole", - table: "ClusterNode", - type: "nvarchar(16)", - maxLength: 16, - nullable: false, - defaultValue: ""); - - migrationBuilder.CreateTable( - name: "ConfigGeneration", - columns: table => new - { - GenerationId = table.Column(type: "bigint", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - ParentGenerationId = table.Column(type: "bigint", nullable: true), - CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), - CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - Notes = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), - PublishedAt = table.Column(type: "datetime2(3)", nullable: true), - PublishedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), - Status = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ConfigGeneration", x => x.GenerationId); - table.ForeignKey( - name: "FK_ConfigGeneration_ConfigGeneration_ParentGenerationId", - column: x => x.ParentGenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_ConfigGeneration_ServerCluster_ClusterId", - column: x => x.ClusterId, - principalTable: "ServerCluster", - principalColumn: "ClusterId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "ClusterNodeGenerationState", - columns: table => new - { - NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - CurrentGenerationId = table.Column(type: "bigint", nullable: true), - LastAppliedAt = table.Column(type: "datetime2(3)", nullable: true), - LastAppliedError = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), - LastAppliedStatus = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: true), - LastSeenAt = table.Column(type: "datetime2(3)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ClusterNodeGenerationState", x => x.NodeId); - table.ForeignKey( - name: "FK_ClusterNodeGenerationState_ClusterNode_NodeId", - column: x => x.NodeId, - principalTable: "ClusterNode", - principalColumn: "NodeId", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_ClusterNodeGenerationState_ConfigGeneration_CurrentGenerationId", - column: x => x.CurrentGenerationId, - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateIndex( - name: "IX_VirtualTag_Generation_Script", - table: "VirtualTag", - columns: new[] { "GenerationId", "ScriptId" }); - - migrationBuilder.CreateIndex( - name: "UX_VirtualTag_Generation_EquipmentPath", - table: "VirtualTag", - columns: new[] { "GenerationId", "EquipmentId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_VirtualTag_Generation_LogicalId", - table: "VirtualTag", - columns: new[] { "GenerationId", "VirtualTagId" }, - unique: true, - filter: "[VirtualTagId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_UnsLine_Generation_Area", - table: "UnsLine", - columns: new[] { "GenerationId", "UnsAreaId" }); - - migrationBuilder.CreateIndex( - name: "UX_UnsLine_Generation_AreaName", - table: "UnsLine", - columns: new[] { "GenerationId", "UnsAreaId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_UnsLine_Generation_LogicalId", - table: "UnsLine", - columns: new[] { "GenerationId", "UnsLineId" }, - unique: true, - filter: "[UnsLineId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_UnsArea_Generation_Cluster", - table: "UnsArea", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "UX_UnsArea_Generation_ClusterName", - table: "UnsArea", - columns: new[] { "GenerationId", "ClusterId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_UnsArea_Generation_LogicalId", - table: "UnsArea", - columns: new[] { "GenerationId", "UnsAreaId" }, - unique: true, - filter: "[UnsAreaId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Tag_Generation_Driver_Device", - table: "Tag", - columns: new[] { "GenerationId", "DriverInstanceId", "DeviceId" }); - - migrationBuilder.CreateIndex( - name: "IX_Tag_Generation_Equipment", - table: "Tag", - columns: new[] { "GenerationId", "EquipmentId" }, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_Generation_EquipmentPath", - table: "Tag", - columns: new[] { "GenerationId", "EquipmentId", "Name" }, - unique: true, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_Generation_FolderPath", - table: "Tag", - columns: new[] { "GenerationId", "DriverInstanceId", "FolderPath", "Name" }, - unique: true, - filter: "[EquipmentId] IS NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Tag_Generation_LogicalId", - table: "Tag", - columns: new[] { "GenerationId", "TagId" }, - unique: true, - filter: "[TagId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_ScriptedAlarm_Generation_Script", - table: "ScriptedAlarm", - columns: new[] { "GenerationId", "PredicateScriptId" }); - - migrationBuilder.CreateIndex( - name: "UX_ScriptedAlarm_Generation_EquipmentPath", - table: "ScriptedAlarm", - columns: new[] { "GenerationId", "EquipmentId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_ScriptedAlarm_Generation_LogicalId", - table: "ScriptedAlarm", - columns: new[] { "GenerationId", "ScriptedAlarmId" }, - unique: true, - filter: "[ScriptedAlarmId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Script_Generation_SourceHash", - table: "Script", - columns: new[] { "GenerationId", "SourceHash" }); - - migrationBuilder.CreateIndex( - name: "UX_Script_Generation_LogicalId", - table: "Script", - columns: new[] { "GenerationId", "ScriptId" }, - unique: true, - filter: "[ScriptId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_PollGroup_Generation_Driver", - table: "PollGroup", - columns: new[] { "GenerationId", "DriverInstanceId" }); - - migrationBuilder.CreateIndex( - name: "UX_PollGroup_Generation_LogicalId", - table: "PollGroup", - columns: new[] { "GenerationId", "PollGroupId" }, - unique: true, - filter: "[PollGroupId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Generation_Cluster", - table: "NodeAcl", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Generation_Group", - table: "NodeAcl", - columns: new[] { "GenerationId", "LdapGroup" }); - - migrationBuilder.CreateIndex( - name: "IX_NodeAcl_Generation_Scope", - table: "NodeAcl", - columns: new[] { "GenerationId", "ScopeKind", "ScopeId" }, - filter: "[ScopeId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_NodeAcl_Generation_GroupScope", - table: "NodeAcl", - columns: new[] { "GenerationId", "ClusterId", "LdapGroup", "ScopeKind", "ScopeId" }, - unique: true, - filter: "[ScopeId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_NodeAcl_Generation_LogicalId", - table: "NodeAcl", - columns: new[] { "GenerationId", "NodeAclId" }, - unique: true, - filter: "[NodeAclId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Namespace_Generation_Cluster", - table: "Namespace", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_Cluster_Kind", - table: "Namespace", - columns: new[] { "GenerationId", "ClusterId", "Kind" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_LogicalId", - table: "Namespace", - columns: new[] { "GenerationId", "NamespaceId" }, - unique: true, - filter: "[NamespaceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_LogicalId_Cluster", - table: "Namespace", - columns: new[] { "GenerationId", "NamespaceId", "ClusterId" }, - unique: true, - filter: "[NamespaceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Namespace_Generation_NamespaceUri", - table: "Namespace", - columns: new[] { "GenerationId", "NamespaceUri" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_Driver", - table: "Equipment", - columns: new[] { "GenerationId", "DriverInstanceId" }); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_Line", - table: "Equipment", - columns: new[] { "GenerationId", "UnsLineId" }); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_MachineCode", - table: "Equipment", - columns: new[] { "GenerationId", "MachineCode" }); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_SAPID", - table: "Equipment", - columns: new[] { "GenerationId", "SAPID" }, - filter: "[SAPID] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Equipment_Generation_ZTag", - table: "Equipment", - columns: new[] { "GenerationId", "ZTag" }, - filter: "[ZTag] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_Generation_LinePath", - table: "Equipment", - columns: new[] { "GenerationId", "UnsLineId", "Name" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_Generation_LogicalId", - table: "Equipment", - columns: new[] { "GenerationId", "EquipmentId" }, - unique: true, - filter: "[EquipmentId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_Equipment_Generation_Uuid", - table: "Equipment", - columns: new[] { "GenerationId", "EquipmentUuid" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_DriverInstance_Generation_Cluster", - table: "DriverInstance", - columns: new[] { "GenerationId", "ClusterId" }); - - migrationBuilder.CreateIndex( - name: "IX_DriverInstance_Generation_Namespace", - table: "DriverInstance", - columns: new[] { "GenerationId", "NamespaceId" }); - - migrationBuilder.CreateIndex( - name: "UX_DriverInstance_Generation_LogicalId", - table: "DriverInstance", - columns: new[] { "GenerationId", "DriverInstanceId" }, - unique: true, - filter: "[DriverInstanceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Device_Generation_Driver", - table: "Device", - columns: new[] { "GenerationId", "DriverInstanceId" }); - - migrationBuilder.CreateIndex( - name: "UX_Device_Generation_LogicalId", - table: "Device", - columns: new[] { "GenerationId", "DeviceId" }, - unique: true, - filter: "[DeviceId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "UX_ClusterNode_Primary_Per_Cluster", - table: "ClusterNode", - column: "ClusterId", - unique: true, - filter: "[RedundancyRole] = 'Primary'"); - - migrationBuilder.CreateIndex( - name: "IX_ClusterNodeGenerationState_Generation", - table: "ClusterNodeGenerationState", - column: "CurrentGenerationId"); - - migrationBuilder.CreateIndex( - name: "IX_ConfigGeneration_Cluster_Published", - table: "ConfigGeneration", - columns: new[] { "ClusterId", "Status", "GenerationId" }, - descending: new[] { false, false, true }) - .Annotation("SqlServer:Include", new[] { "PublishedAt" }); - - migrationBuilder.CreateIndex( - name: "IX_ConfigGeneration_ParentGenerationId", - table: "ConfigGeneration", - column: "ParentGenerationId"); - - migrationBuilder.CreateIndex( - name: "UX_ConfigGeneration_Draft_Per_Cluster", - table: "ConfigGeneration", - column: "ClusterId", - unique: true, - filter: "[Status] = 'Draft'"); - - migrationBuilder.AddForeignKey( - name: "FK_Device_ConfigGeneration_GenerationId", - table: "Device", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_DriverInstance_ConfigGeneration_GenerationId", - table: "DriverInstance", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_Equipment_ConfigGeneration_GenerationId", - table: "Equipment", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_Namespace_ConfigGeneration_GenerationId", - table: "Namespace", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_NodeAcl_ConfigGeneration_GenerationId", - table: "NodeAcl", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_PollGroup_ConfigGeneration_GenerationId", - table: "PollGroup", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_Script_ConfigGeneration_GenerationId", - table: "Script", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_ScriptedAlarm_ConfigGeneration_GenerationId", - table: "ScriptedAlarm", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_Tag_ConfigGeneration_GenerationId", - table: "Tag", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_UnsArea_ConfigGeneration_GenerationId", - table: "UnsArea", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_UnsLine_ConfigGeneration_GenerationId", - table: "UnsLine", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_VirtualTag_ConfigGeneration_GenerationId", - table: "VirtualTag", - column: "GenerationId", - principalTable: "ConfigGeneration", - principalColumn: "GenerationId", - onDelete: ReferentialAction.Restrict); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526105027_AddConfigAuditLogEventIdColumns.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526105027_AddConfigAuditLogEventIdColumns.Designer.cs deleted file mode 100644 index 96ba5ae2..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526105027_AddConfigAuditLogEventIdColumns.Designer.cs +++ /dev/null @@ -1,1755 +0,0 @@ -// -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("20260526105027_AddConfigAuditLogEventIdColumns")] - partial class AddConfigAuditLogEventIdColumns - { - /// - 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("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("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("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.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("NamespaceId") - .IsRequired() - .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("NamespaceId") - .HasDatabaseName("IX_DriverInstance_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("DriverInstanceId") - .HasDatabaseName("IX_Equipment_Driver"); - - 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.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId") - .HasDatabaseName("IX_Namespace_Cluster"); - - b.HasIndex("NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_NamespaceUri"); - - b.HasIndex("ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Cluster_Kind"); - - b.ToTable("Namespace", (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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - 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("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("EquipmentId") - .HasDatabaseName("IX_Tag_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Driver_Device"); - - b.HasIndex("EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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.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.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - 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.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.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526105027_AddConfigAuditLogEventIdColumns.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526105027_AddConfigAuditLogEventIdColumns.cs deleted file mode 100644 index 72bb343d..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526105027_AddConfigAuditLogEventIdColumns.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class AddConfigAuditLogEventIdColumns : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "CorrelationId", - table: "ConfigAuditLog", - type: "uniqueidentifier", - nullable: true); - - migrationBuilder.AddColumn( - name: "EventId", - table: "ConfigAuditLog", - type: "uniqueidentifier", - nullable: true); - - migrationBuilder.CreateIndex( - name: "UX_ConfigAuditLog_EventId", - table: "ConfigAuditLog", - column: "EventId", - unique: true, - filter: "[EventId] IS NOT NULL"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - name: "UX_ConfigAuditLog_EventId", - table: "ConfigAuditLog"); - - migrationBuilder.DropColumn( - name: "CorrelationId", - table: "ConfigAuditLog"); - - migrationBuilder.DropColumn( - name: "EventId", - table: "ConfigAuditLog"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602112419_CanonicalizeAdminRoles.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602112419_CanonicalizeAdminRoles.Designer.cs deleted file mode 100644 index 853f9386..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602112419_CanonicalizeAdminRoles.Designer.cs +++ /dev/null @@ -1,1755 +0,0 @@ -// -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("20260602112419_CanonicalizeAdminRoles")] - partial class CanonicalizeAdminRoles - { - /// - 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("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("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("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.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("NamespaceId") - .IsRequired() - .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("NamespaceId") - .HasDatabaseName("IX_DriverInstance_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("DriverInstanceId") - .HasDatabaseName("IX_Equipment_Driver"); - - 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.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId") - .HasDatabaseName("IX_Namespace_Cluster"); - - b.HasIndex("NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_NamespaceUri"); - - b.HasIndex("ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Cluster_Kind"); - - b.ToTable("Namespace", (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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - 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("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("EquipmentId") - .HasDatabaseName("IX_Tag_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Driver_Device"); - - b.HasIndex("EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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.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.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - 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.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.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602112419_CanonicalizeAdminRoles.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602112419_CanonicalizeAdminRoles.cs deleted file mode 100644 index 49ee6312..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602112419_CanonicalizeAdminRoles.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - /// Task 1.7 — canonicalizes the control-plane admin role VALUES persisted in the - /// LdapGroupRoleMapping.Role column. The column stores the AdminRole enum - /// member name as a string (EF HasConversion<string>, nvarchar(32)); - /// renaming the enum members (ConfigViewer → Viewer, ConfigEditor → Designer, - /// FleetAdmin → Administrator) therefore requires rewriting existing rows so the C# - /// enum and the stored strings stay in sync. - /// - /// - /// This is a pure DATA migration: the schema (column type, length, indexes) is unchanged, - /// so the model snapshot is byte-identical to the prior migration. The new canonical strings - /// ("Viewer" = 6, "Designer" = 8, "Administrator" = 13 chars) all fit the existing - /// nvarchar(32) column. Enforcement semantics are preserved — it is a rename only. - /// - public partial class CanonicalizeAdminRoles : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql("UPDATE [LdapGroupRoleMapping] SET [Role] = N'Viewer' WHERE [Role] = N'ConfigViewer';"); - migrationBuilder.Sql("UPDATE [LdapGroupRoleMapping] SET [Role] = N'Designer' WHERE [Role] = N'ConfigEditor';"); - migrationBuilder.Sql("UPDATE [LdapGroupRoleMapping] SET [Role] = N'Administrator' WHERE [Role] = N'FleetAdmin';"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.Sql("UPDATE [LdapGroupRoleMapping] SET [Role] = N'FleetAdmin' WHERE [Role] = N'Administrator';"); - migrationBuilder.Sql("UPDATE [LdapGroupRoleMapping] SET [Role] = N'ConfigEditor' WHERE [Role] = N'Designer';"); - migrationBuilder.Sql("UPDATE [LdapGroupRoleMapping] SET [Role] = N'ConfigViewer' WHERE [Role] = N'Viewer';"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602135350_AddConfigAuditLogOutcome.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602135350_AddConfigAuditLogOutcome.Designer.cs deleted file mode 100644 index 291b6673..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602135350_AddConfigAuditLogOutcome.Designer.cs +++ /dev/null @@ -1,1759 +0,0 @@ -// -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("20260602135350_AddConfigAuditLogOutcome")] - partial class AddConfigAuditLogOutcome - { - /// - 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("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("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.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("NamespaceId") - .IsRequired() - .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("NamespaceId") - .HasDatabaseName("IX_DriverInstance_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("DriverInstanceId") - .HasDatabaseName("IX_Equipment_Driver"); - - 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.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId") - .HasDatabaseName("IX_Namespace_Cluster"); - - b.HasIndex("NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_NamespaceUri"); - - b.HasIndex("ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Cluster_Kind"); - - b.ToTable("Namespace", (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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - 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("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("EquipmentId") - .HasDatabaseName("IX_Tag_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Driver_Device"); - - b.HasIndex("EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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.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.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - 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.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.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602135350_AddConfigAuditLogOutcome.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602135350_AddConfigAuditLogOutcome.cs deleted file mode 100644 index c43068d6..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260602135350_AddConfigAuditLogOutcome.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - /// Task 2.2 — adds the nullable Outcome column to ConfigAuditLog for the - /// canonical ZB.MOM.WW.Audit.AuditOutcome (stored as its enum member name, - /// nvarchar(16), mirroring how AdminRole is persisted). Purely additive: - /// nullable with no backfill, so existing rows and the bespoke stored-procedure audit - /// path (which does not derive an outcome) keep writing NULL. - /// - public partial class AddConfigAuditLogOutcome : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Outcome", - table: "ConfigAuditLog", - type: "nvarchar(16)", - maxLength: 16, - nullable: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Outcome", - table: "ConfigAuditLog"); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260608104706_NullableEquipmentDriverInstanceId.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260608104706_NullableEquipmentDriverInstanceId.Designer.cs deleted file mode 100644 index c3c8d817..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260608104706_NullableEquipmentDriverInstanceId.Designer.cs +++ /dev/null @@ -1,1758 +0,0 @@ -// -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("20260608104706_NullableEquipmentDriverInstanceId")] - partial class NullableEquipmentDriverInstanceId - { - /// - 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("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("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.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("NamespaceId") - .IsRequired() - .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("NamespaceId") - .HasDatabaseName("IX_DriverInstance_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("DriverInstanceId") - .HasDatabaseName("IX_Equipment_Driver"); - - 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.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId") - .HasDatabaseName("IX_Namespace_Cluster"); - - b.HasIndex("NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_NamespaceUri"); - - b.HasIndex("ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Cluster_Kind"); - - b.ToTable("Namespace", (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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - 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("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("EquipmentId") - .HasDatabaseName("IX_Tag_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Driver_Device"); - - b.HasIndex("EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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.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.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - 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.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.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260608104706_NullableEquipmentDriverInstanceId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260608104706_NullableEquipmentDriverInstanceId.cs deleted file mode 100644 index bc9e28f4..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260608104706_NullableEquipmentDriverInstanceId.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - public partial class NullableEquipmentDriverInstanceId : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "DriverInstanceId", - table: "Equipment", - type: "nvarchar(64)", - maxLength: 64, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(64)", - oldMaxLength: 64); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - // WARNING: this rollback converts any existing NULL (driver-less) rows to "" for DriverInstanceId. - // Only safe when no driver-less equipment exists in the database. - migrationBuilder.AlterColumn( - name: "DriverInstanceId", - table: "Equipment", - type: "nvarchar(64)", - maxLength: 64, - nullable: false, - defaultValue: "", - oldClrType: typeof(string), - oldType: "nvarchar(64)", - oldMaxLength: 64, - oldNullable: true); - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260613022355_CleanupSystemPlatformNamespaces.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260613022355_CleanupSystemPlatformNamespaces.Designer.cs deleted file mode 100644 index bbf9d7d3..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260613022355_CleanupSystemPlatformNamespaces.Designer.cs +++ /dev/null @@ -1,1758 +0,0 @@ -// -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("20260613022355_CleanupSystemPlatformNamespaces")] - partial class CleanupSystemPlatformNamespaces - { - /// - 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("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("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.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("NamespaceId") - .IsRequired() - .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("NamespaceId") - .HasDatabaseName("IX_DriverInstance_Namespace"); - - 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("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DriverInstanceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - 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("DriverInstanceId") - .HasDatabaseName("IX_Equipment_Driver"); - - 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.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (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.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId") - .HasDatabaseName("IX_Namespace_Cluster"); - - b.HasIndex("NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_NamespaceUri"); - - b.HasIndex("ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Cluster_Kind"); - - b.ToTable("Namespace", (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.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") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - 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("TagId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("WriteIdempotent") - .HasColumnType("bit"); - - b.HasKey("TagRowId"); - - b.HasIndex("EquipmentId") - .HasDatabaseName("IX_Tag_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("TagId") - .IsUnique() - .HasDatabaseName("UX_Tag_LogicalId") - .HasFilter("[TagId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Driver_Device"); - - b.HasIndex("EquipmentId", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); - - b.HasIndex("DriverInstanceId", "FolderPath", "Name") - .IsUnique() - .HasDatabaseName("UX_Tag_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); - - b.ToTable("Tag", null, t => - { - t.HasCheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); - }); - }); - - 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.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.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - - 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.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - 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.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.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => - { - b.Navigation("Namespaces"); - - b.Navigation("Nodes"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260613022355_CleanupSystemPlatformNamespaces.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260613022355_CleanupSystemPlatformNamespaces.cs deleted file mode 100644 index a15163e7..00000000 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260613022355_CleanupSystemPlatformNamespaces.cs +++ /dev/null @@ -1,181 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations -{ - /// - /// Forward-only DATA-cleanup migration for the Galaxy clean break: the - /// NamespaceKind.SystemPlatform enum member was removed (Galaxy is now an - /// Equipment-kind driver). Namespace.Kind is persisted as a string via - /// HasConversion<string>, so any leftover row with Kind = 'SystemPlatform' - /// would throw at materialisation time (no matching enum member) the moment the new code - /// reads the table. This deletes those namespaces plus everything that hung off them. - /// - /// - /// - /// There is NO schema/model change in this migration — the model snapshot is unchanged. - /// The unique index UX_Namespace_Cluster_Kind (unique on ClusterId, Kind) is - /// intentionally KEPT: Simulated remains a reserved kind, so one-of-each-kind-per-cluster - /// is still the correct constraint. - /// - /// - /// The cross-table relationships in this graph are LOGICAL foreign keys (string Id columns, - /// e.g. DriverInstance.NamespaceIdNamespace.NamespaceId, - /// Tag.DriverInstanceIdDriverInstance.DriverInstanceId) enforced by - /// sp_ValidateDraft, NOT physical DB FK constraints — only the *.ClusterId - /// relationships are real DB FKs. So no FK constraint can be violated here. The deletes are - /// nonetheless ordered child→parent so no orphaned rows are left behind, and every statement - /// is keyed off the set of SystemPlatform namespaces, so on a DB with zero such rows every - /// DELETE simply affects 0 rows (idempotent / safe to run repeatedly). - /// - /// - /// Two tables carry LOGICAL refs with no physical FK and so were easy to miss: NodeAcl - /// (per-scope grants keyed by ScopeKind + ScopeId) is cleaned for the - /// Namespace/Equipment/FolderSegment/Tag scopes that get deleted, and - /// ExternalIdReservation (fleet-wide ZTag/SAPID reservations keyed by - /// EquipmentUuid) is RELEASED — not deleted — for the affected equipment so the - /// reserved external IDs free up while the audit row survives. Both run before the entity - /// rows they reference are removed so the id subqueries still resolve. - /// - /// - /// - public partial class CleanupSystemPlatformNamespaces : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - // Delete in child -> parent order. Everything is keyed off the set of namespaces whose - // Kind = 'SystemPlatform' (the string form persisted by HasConversion), funnelled - // through the DriverInstances that lived in those namespaces. - migrationBuilder.Sql(@" --- Defensive: SystemPlatform namespaces historically held only EquipmentId-NULL mirror tags, but a --- stray equipment-scoped tag / Equipment could be bound to a SystemPlatform-namespace driver. Clean --- both, plus anything that FKs into the affected Equipment (VirtualTag / ScriptedAlarm / state). - --- Logical-reference cleanup that must run FIRST ------------------------------------------- --- NodeAcl rows carry purely LOGICAL scope refs (ScopeKind + ScopeId, no physical FK). When the --- scoped entity is deleted below the ScopeId dangles and the ACL evaluator would still match it, --- silently granting/denying on a node that no longer exists. ScopeKind persists as a string via --- HasConversion, so the values below ('Namespace'/'Equipment'/'FolderSegment'/'Tag') are --- the literal enum member names. These deletes must read the entity-id subqueries while those rows --- still exist, hence they run before the entity DELETEs further down. - --- Namespace-scoped grants pointing at the SystemPlatform namespaces themselves. -DELETE FROM [NodeAcl] -WHERE [ScopeKind] = 'Namespace' - AND [ScopeId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'); - --- Equipment- and FolderSegment-scoped grants pointing at Equipment that hangs off the affected --- DriverInstances (both share Equipment.EquipmentId as the ScopeId). -DELETE FROM [NodeAcl] -WHERE [ScopeKind] IN ('Equipment', 'FolderSegment') - AND [ScopeId] IN ( - SELECT [EquipmentId] FROM [Equipment] - WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'))); - --- Tag-scoped grants pointing at Tags bound to the affected DriverInstances (ScopeId = Tag.TagId). -DELETE FROM [NodeAcl] -WHERE [ScopeKind] = 'Tag' - AND [ScopeId] IN ( - SELECT [TagId] FROM [Tag] - WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'))); - --- ExternalIdReservation is NOT generation-versioned and must outlive equipment deletion as a --- RELEASE, not a delete: active rows (ReleasedAt IS NULL) hold a fleet-wide unique reservation of --- the ZTag/SAPID under a filtered unique index. If we left them active after dropping the --- Equipment, the same external IDs could never be reused. Release them so the IDs free up while the --- audit row survives. Run BEFORE the Equipment DELETE so the EquipmentUuid subquery still resolves. -UPDATE [ExternalIdReservation] -SET [ReleasedAt] = SYSUTCDATETIME(), - [ReleasedBy] = 'CleanupSystemPlatformNamespaces', - [ReleaseReason] = 'Equipment removed by SystemPlatform-namespace cleanup migration (retired NamespaceKind).' -WHERE [ReleasedAt] IS NULL - AND [EquipmentUuid] IN ( - SELECT [EquipmentUuid] FROM [Equipment] - WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'))); - --- Grandchildren of the affected Equipment ------------------------------------------------ --- ScriptedAlarmState is keyed by ScriptedAlarm.ScriptedAlarmId; remove before its ScriptedAlarm. -DELETE FROM [ScriptedAlarmState] -WHERE [ScriptedAlarmId] IN ( - SELECT [ScriptedAlarmId] FROM [ScriptedAlarm] - WHERE [EquipmentId] IN ( - SELECT [EquipmentId] FROM [Equipment] - WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform')))); - -DELETE FROM [ScriptedAlarm] -WHERE [EquipmentId] IN ( - SELECT [EquipmentId] FROM [Equipment] - WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'))); - -DELETE FROM [VirtualTag] -WHERE [EquipmentId] IN ( - SELECT [EquipmentId] FROM [Equipment] - WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'))); - --- Children of the affected DriverInstances ------------------------------------------------ --- Tags bound to those drivers: both EquipmentId-NULL mirror tags AND any equipment-scoped tag. -DELETE FROM [Tag] -WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform')); - -DELETE FROM [PollGroup] -WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform')); - -DELETE FROM [Device] -WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform')); - -DELETE FROM [Equipment] -WHERE [DriverInstanceId] IN ( - SELECT [DriverInstanceId] FROM [DriverInstance] - WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform')); - --- The DriverInstances themselves ---------------------------------------------------------- -DELETE FROM [DriverInstance] -WHERE [NamespaceId] IN ( - SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'); - --- The SystemPlatform namespaces (the rows that would crash EF on read) -------------------- -DELETE FROM [Namespace] WHERE [Kind] = 'SystemPlatform'; -"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - // Forward-only data cleanup: the deleted SystemPlatform namespaces and their dependent - // rows cannot be reconstructed (the data is gone, and SystemPlatform is no longer a valid - // NamespaceKind). Intentionally a no-op rather than a throw, so rolling back a LATER - // migration does not blow up on this one. - } - } -} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526081556_V2HostingAlignment.Designer.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.Designer.cs similarity index 89% rename from src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526081556_V2HostingAlignment.Designer.cs rename to src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.Designer.cs index 7b1008c2..8e0b28b7 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260526081556_V2HostingAlignment.Designer.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.Designer.cs @@ -12,8 +12,8 @@ using ZB.MOM.WW.OtOpcUa.Configuration; namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations { [DbContext(typeof(OtOpcUaConfigDbContext))] - [Migration("20260526081556_V2HostingAlignment")] - partial class V2HostingAlignment + [Migration("20260715230637_V3Initial")] + partial class V3Initial { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -168,9 +168,15 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .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) @@ -183,6 +189,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasMaxLength(64) .HasColumnType("nvarchar(64)"); + b.Property("Outcome") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)"); + b.Property("Principal") .IsRequired() .HasMaxLength(128) @@ -195,6 +205,11 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations 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"); @@ -361,6 +376,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations 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"); @@ -440,8 +459,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasMaxLength(128) .HasColumnType("nvarchar(128)"); - b.Property("NamespaceId") - .IsRequired() + b.Property("RawFolderId") .HasMaxLength(64) .HasColumnType("nvarchar(64)"); @@ -464,8 +482,18 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasDatabaseName("UX_DriverInstance_LogicalId") .HasFilter("[DriverInstanceId] IS NOT NULL"); - b.HasIndex("NamespaceId") - .HasDatabaseName("IX_DriverInstance_Namespace"); + 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 => { @@ -525,19 +553,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasMaxLength(256) .HasColumnType("nvarchar(256)"); - b.Property("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - b.Property("DeviceManualUri") .HasMaxLength(512) .HasColumnType("nvarchar(512)"); - b.Property("DriverInstanceId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - b.Property("Enabled") .HasColumnType("bit"); @@ -610,9 +629,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.HasKey("EquipmentRowId"); - b.HasIndex("DriverInstanceId") - .HasDatabaseName("IX_Equipment_Driver"); - b.HasIndex("EquipmentId") .IsUnique() .HasDatabaseName("UX_Equipment_LogicalId") @@ -643,148 +659,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.ToTable("Equipment", (string)null); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (string)null); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ExternalIdReservation", b => { b.Property("ReservationId") @@ -894,66 +768,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.ToTable("LdapGroupRoleMapping", (string)null); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId") - .HasDatabaseName("IX_Namespace_Cluster"); - - b.HasIndex("NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_NamespaceUri"); - - b.HasIndex("ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Cluster_Kind"); - - b.ToTable("Namespace", (string)null); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => { b.Property("NodeAclRowId") @@ -1109,6 +923,63 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations }); }); + 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") @@ -1388,22 +1259,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasColumnType("nvarchar(32)"); b.Property("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") .IsRequired() .HasMaxLength(64) .HasColumnType("nvarchar(64)"); - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - b.Property("Name") .IsRequired() .HasMaxLength(128) @@ -1423,6 +1282,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("TagGroupId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.Property("TagId") .HasMaxLength(64) .HasColumnType("nvarchar(64)"); @@ -1432,27 +1295,23 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.HasKey("TagRowId"); - b.HasIndex("EquipmentId") - .HasDatabaseName("IX_Tag_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - b.HasIndex("TagId") .IsUnique() .HasDatabaseName("UX_Tag_LogicalId") .HasFilter("[TagId] IS NOT NULL"); - b.HasIndex("DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Driver_Device"); - - b.HasIndex("EquipmentId", "Name") + b.HasIndex("DeviceId", "Name") .IsUnique() - .HasDatabaseName("UX_Tag_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); + .HasDatabaseName("UX_Tag_Device_Name") + .HasFilter("[TagGroupId] IS NULL"); - b.HasIndex("DriverInstanceId", "FolderPath", "Name") + b.HasIndex("DeviceId", "TagGroupId") + .HasDatabaseName("IX_Tag_Device"); + + b.HasIndex("DeviceId", "TagGroupId", "Name") .IsUnique() - .HasDatabaseName("UX_Tag_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); + .HasDatabaseName("UX_Tag_Group_Name") + .HasFilter("[TagGroupId] IS NOT NULL"); b.ToTable("Tag", null, t => { @@ -1460,6 +1319,63 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations }); }); + 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") @@ -1556,6 +1472,60 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations 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") @@ -1660,17 +1630,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.Navigation("Cluster"); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.LdapGroupRoleMapping", b => { b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") @@ -1681,17 +1640,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.Navigation("Cluster"); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeDeploymentState", b => { b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Deployment", "Deployment") @@ -1711,6 +1659,15 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations 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") @@ -1727,16 +1684,11 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.Navigation("Credentials"); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => { - b.Navigation("Namespaces"); - b.Navigation("Nodes"); + + b.Navigation("RawFolders"); }); #pragma warning restore 612, 618 } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.StoredProcedures.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.StoredProcedures.cs new file mode 100644 index 00000000..ad8dcf90 --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.StoredProcedures.cs @@ -0,0 +1,285 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations +{ + /// + /// Hand-authored SQL squashed into V3Initial from the retired per-migration proc files + /// (*_StoredProcedures.cs, *_ExtendComputeGenerationDiffWith*.cs) and + /// AuthorizationGrants.cs. + /// + /// + /// + /// Port audit (v3 WP1). The v1 stored procs were built entirely on the + /// ConfigGeneration / GenerationId / ClusterNodeGenerationState + /// generation model, which V2HostingAlignment (2026-05-26) dropped outright — so + /// those procs have been vestigial since v2 (SQL Server's deferred name resolution let them + /// keep existing while referencing phantom tables). No production code calls them; the v2/v3 + /// deploy + diff path is entirely C# (ControlPlane ConfigComposer, + /// AddressSpaceChangeClassifier, DraftValidator). Their only consumer is + /// AuthorizationTests, which exercises the DB-role EXECUTE grants and expects + /// RAISERROR / permission failures — never a successful data operation. + /// + /// + /// Under greenfield v3 the two-role authorization model (OtOpcUaNode / + /// OtOpcUaAdmin + EXECUTE grants) is retained as a real security feature, so the + /// eight proc names must exist for the grants + tests to bind. Each proc is rewritten + /// here to be schema-valid against the v3 schema (references NO dropped table/column): + /// + /// + /// sp_GetCurrentGenerationForCluster keeps its ClusterNodeCredential + + /// ClusterNode "Unauthorized" auth check (both tables retained), then RAISERRORs a + /// v3-retirement message — preserving the exact behavior AuthorizationTests asserts. + /// sp_PublishGeneration is granted to OtOpcUaAdmin only and RAISERRORs a + /// retirement message (never the word "permission"), so the Node-denied vs Admin-allowed + /// grant assertions still hold. + /// sp_ComputeGenerationDiff is rewritten to reference the v3 tables + /// (RawFolder / DriverInstance / Device / TagGroup / Tag / Equipment / UnsTagReference / + /// NodeAcl) as a schema-valid current-state signature inventory. A genuine + /// generation-to-generation diff is architecturally impossible now (no GenerationId column); + /// the real diff lives in the C# ControlPlane. + /// sp_ReleaseExternalIdReservation is ported verbatim — it only touches retained + /// tables (ExternalIdReservation, ConfigAuditLog). + /// + /// + public partial class V3Initial + { + private static void CreateStoredProcedures(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql(GetCurrentGenerationForCluster); + migrationBuilder.Sql(GetGenerationContent); + migrationBuilder.Sql(RegisterNodeGenerationApplied); + migrationBuilder.Sql(ValidateDraft); + migrationBuilder.Sql(PublishGeneration); + migrationBuilder.Sql(RollbackToGeneration); + migrationBuilder.Sql(ComputeGenerationDiff); + migrationBuilder.Sql(ReleaseExternalIdReservation); + } + + private static void DropStoredProcedures(MigrationBuilder migrationBuilder) + { + foreach (var name in new[] + { + "sp_ReleaseExternalIdReservation", "sp_ComputeGenerationDiff", "sp_RollbackToGeneration", + "sp_PublishGeneration", "sp_ValidateDraft", "sp_RegisterNodeGenerationApplied", + "sp_GetGenerationContent", "sp_GetCurrentGenerationForCluster", + }) + { + migrationBuilder.Sql($"IF OBJECT_ID(N'dbo.{name}', N'P') IS NOT NULL DROP PROCEDURE dbo.{name};"); + } + } + + private static void CreateAuthorizationGrants(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql(@" +IF DATABASE_PRINCIPAL_ID('OtOpcUaNode') IS NULL + CREATE ROLE OtOpcUaNode; +IF DATABASE_PRINCIPAL_ID('OtOpcUaAdmin') IS NULL + CREATE ROLE OtOpcUaAdmin; +"); + + migrationBuilder.Sql(@" +GRANT EXECUTE ON OBJECT::dbo.sp_GetCurrentGenerationForCluster TO OtOpcUaNode; +GRANT EXECUTE ON OBJECT::dbo.sp_GetGenerationContent TO OtOpcUaNode; +GRANT EXECUTE ON OBJECT::dbo.sp_RegisterNodeGenerationApplied TO OtOpcUaNode; + +GRANT EXECUTE ON OBJECT::dbo.sp_GetCurrentGenerationForCluster TO OtOpcUaAdmin; +GRANT EXECUTE ON OBJECT::dbo.sp_GetGenerationContent TO OtOpcUaAdmin; +GRANT EXECUTE ON OBJECT::dbo.sp_ValidateDraft TO OtOpcUaAdmin; +GRANT EXECUTE ON OBJECT::dbo.sp_PublishGeneration TO OtOpcUaAdmin; +GRANT EXECUTE ON OBJECT::dbo.sp_RollbackToGeneration TO OtOpcUaAdmin; +GRANT EXECUTE ON OBJECT::dbo.sp_ComputeGenerationDiff TO OtOpcUaAdmin; +GRANT EXECUTE ON OBJECT::dbo.sp_ReleaseExternalIdReservation TO OtOpcUaAdmin; + +DENY UPDATE, DELETE, INSERT ON SCHEMA::dbo TO OtOpcUaNode; +DENY UPDATE, DELETE, INSERT ON SCHEMA::dbo TO OtOpcUaAdmin; +DENY SELECT ON SCHEMA::dbo TO OtOpcUaNode; +-- Admins may SELECT for reporting views in the future — grant views explicitly, not the schema. +DENY SELECT ON SCHEMA::dbo TO OtOpcUaAdmin; +"); + } + + private static void DropAuthorizationGrants(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql(@" +IF DATABASE_PRINCIPAL_ID('OtOpcUaNode') IS NOT NULL + DROP ROLE OtOpcUaNode; +IF DATABASE_PRINCIPAL_ID('OtOpcUaAdmin') IS NOT NULL + DROP ROLE OtOpcUaAdmin; +"); + } + + // ------------------------------------------------------------------------------------------ + // v3 retirement stubs. The generation model is gone (see class remarks); these preserve the + // authorization surface + the AuthorizationTests behaviors while referencing only v3 tables. + // ------------------------------------------------------------------------------------------ + + private const string GetCurrentGenerationForCluster = @" +CREATE OR ALTER PROCEDURE dbo.sp_GetCurrentGenerationForCluster + @NodeId nvarchar(64), + @ClusterId nvarchar(64) +AS +BEGIN + SET NOCOUNT ON; + + -- Auth surface retained verbatim (ClusterNodeCredential + ClusterNode are v3 tables). An + -- unbound caller still gets 'Unauthorized', which AuthorizationTests asserts. + DECLARE @Caller nvarchar(128) = SUSER_SNAME(); + + IF NOT EXISTS ( + SELECT 1 FROM dbo.ClusterNodeCredential + WHERE NodeId = @NodeId AND Value = @Caller AND Enabled = 1) + BEGIN + RAISERROR('Unauthorized: caller %s is not bound to NodeId %s', 16, 1, @Caller, @NodeId); + RETURN; + END + + IF NOT EXISTS ( + SELECT 1 FROM dbo.ClusterNode + WHERE NodeId = @NodeId AND ClusterId = @ClusterId AND Enabled = 1) + BEGIN + RAISERROR('Forbidden: NodeId %s does not belong to ClusterId %s', 16, 1, @NodeId, @ClusterId); + RETURN; + END + + RAISERROR('sp_GetCurrentGenerationForCluster is retired under v3: config/deploy state moved to the C# ControlPlane (Deployment table).', 16, 1); +END +"; + + private const string GetGenerationContent = @" +CREATE OR ALTER PROCEDURE dbo.sp_GetGenerationContent + @NodeId nvarchar(64), + @GenerationId bigint +AS +BEGIN + SET NOCOUNT ON; + RAISERROR('sp_GetGenerationContent is retired under v3: generation content is sealed into Deployment.ArtifactBlob by the C# ControlPlane.', 16, 1); +END +"; + + private const string RegisterNodeGenerationApplied = @" +CREATE OR ALTER PROCEDURE dbo.sp_RegisterNodeGenerationApplied + @NodeId nvarchar(64), + @GenerationId bigint, + @Status nvarchar(16), + @Error nvarchar(max) = NULL +AS +BEGIN + SET NOCOUNT ON; + RAISERROR('sp_RegisterNodeGenerationApplied is retired under v3: node-apply state is tracked in NodeDeploymentState by the C# ControlPlane.', 16, 1); +END +"; + + private const string ValidateDraft = @" +CREATE OR ALTER PROCEDURE dbo.sp_ValidateDraft + @DraftGenerationId bigint +AS +BEGIN + SET NOCOUNT ON; + RAISERROR('sp_ValidateDraft is retired under v3: draft validation runs in the managed DraftValidator (Configuration.Validation).', 16, 1); +END +"; + + private const string PublishGeneration = @" +CREATE OR ALTER PROCEDURE dbo.sp_PublishGeneration + @ClusterId nvarchar(64), + @DraftGenerationId bigint, + @Notes nvarchar(1024) = NULL +AS +BEGIN + SET NOCOUNT ON; + -- Message intentionally omits the word 'permission' so AuthorizationTests can distinguish a + -- grant failure (Node role) from a body-level error (Admin role reaching the proc body). + RAISERROR('sp_PublishGeneration is retired under v3: publishing is done by the C# ControlPlane (ConfigComposer + Deployment).', 16, 1); +END +"; + + private const string RollbackToGeneration = @" +CREATE OR ALTER PROCEDURE dbo.sp_RollbackToGeneration + @ClusterId nvarchar(64), + @TargetGenerationId bigint, + @Notes nvarchar(1024) = NULL +AS +BEGIN + SET NOCOUNT ON; + RAISERROR('sp_RollbackToGeneration is retired under v3: rollback is a C# ControlPlane operation over the Deployment history.', 16, 1); +END +"; + + // Rewritten to the v3 schema. There is no GenerationId to diff (the per-generation table model + // was dropped in v2), so this emits a current-state signature inventory across the v3 tables — + // referencing RawFolder, DriverInstance, Device, TagGroup, Tag, Equipment, UnsTagReference, and + // NodeAcl. The genuine generation-to-generation diff now lives in the C# ControlPlane + // (AddressSpaceChangeClassifier); this proc is retained only to carry the OtOpcUaAdmin EXECUTE + // grant and to keep the v3 table surface referenced from SQL. + private const string ComputeGenerationDiff = @" +CREATE OR ALTER PROCEDURE dbo.sp_ComputeGenerationDiff + @FromGenerationId bigint, + @ToGenerationId bigint +AS +BEGIN + SET NOCOUNT ON; + + -- @FromGenerationId / @ToGenerationId are ignored: the v3 config tables are single live-state + -- (no GenerationId column). Emit a current-state signature per row so the shape (TableName, + -- LogicalId, Sig) still round-trips through any legacy caller. + SELECT TableName, LogicalId, Sig FROM ( + SELECT 'RawFolder' AS TableName, RawFolderId AS LogicalId, CHECKSUM(ClusterId, ParentRawFolderId, Name, SortOrder) AS Sig FROM dbo.RawFolder + UNION ALL + SELECT 'DriverInstance', DriverInstanceId, CHECKSUM(ClusterId, RawFolderId, Name, DriverType, Enabled, CONVERT(varchar(max), DriverConfig)) FROM dbo.DriverInstance + UNION ALL + SELECT 'Device', DeviceId, CHECKSUM(DriverInstanceId, Name, Enabled, CONVERT(varchar(max), DeviceConfig)) FROM dbo.Device + UNION ALL + SELECT 'TagGroup', TagGroupId, CHECKSUM(DeviceId, ParentTagGroupId, Name, SortOrder) FROM dbo.TagGroup + UNION ALL + SELECT 'Tag', TagId, CHECKSUM(DeviceId, TagGroupId, PollGroupId, Name, DataType, AccessLevel, WriteIdempotent, CONVERT(varchar(max), TagConfig)) FROM dbo.Tag + UNION ALL + SELECT 'Equipment', EquipmentId, CHECKSUM(EquipmentUuid, UnsLineId, Name, MachineCode, ZTag, SAPID, EquipmentClassRef, Manufacturer, Model, SerialNumber) FROM dbo.Equipment + UNION ALL + SELECT 'UnsTagReference', UnsTagReferenceId, CHECKSUM(EquipmentId, TagId, DisplayNameOverride, SortOrder) FROM dbo.UnsTagReference + UNION ALL + SELECT 'NodeAcl', NodeAclId, CHECKSUM(ClusterId, LdapGroup, ScopeKind, ScopeId, PermissionFlags, Notes) FROM dbo.NodeAcl + ) AS inventory; +END +"; + + // Ported verbatim — touches only retained tables (ExternalIdReservation, ConfigAuditLog). + private const string ReleaseExternalIdReservation = @" +CREATE OR ALTER PROCEDURE dbo.sp_ReleaseExternalIdReservation + @Kind nvarchar(16), + @Value nvarchar(64), + @ReleaseReason nvarchar(512) +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + + IF @ReleaseReason IS NULL OR LEN(@ReleaseReason) = 0 + BEGIN + RAISERROR('ReleaseReason is required', 16, 1); + RETURN; + END + + UPDATE dbo.ExternalIdReservation + SET ReleasedAt = SYSUTCDATETIME(), + ReleasedBy = SUSER_SNAME(), + ReleaseReason = @ReleaseReason + WHERE Kind = @Kind AND Value = @Value AND ReleasedAt IS NULL; + + IF @@ROWCOUNT = 0 + BEGIN + RAISERROR('No active reservation found for (%s, %s)', 16, 1, @Kind, @Value); + RETURN; + END + + -- Escape both caller-supplied values via STRING_ESCAPE so quotes/backslashes cannot break the + -- JSON document or inject additional structure into the audit record. + INSERT dbo.ConfigAuditLog (Principal, EventType, DetailsJson) + VALUES (SUSER_SNAME(), 'ExternalIdReleased', + CONCAT('{""kind"":""', STRING_ESCAPE(@Kind, 'json'), + '"",""value"":""', STRING_ESCAPE(@Value, 'json'), '""}')); +END +"; + } +} diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.cs new file mode 100644 index 00000000..d5224cab --- /dev/null +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260715230637_V3Initial.cs @@ -0,0 +1,1135 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations +{ + /// + public partial class V3Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ConfigAuditLog", + columns: table => new + { + AuditId = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Timestamp = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + Principal = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + EventType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + GenerationId = table.Column(type: "bigint", nullable: true), + DetailsJson = table.Column(type: "nvarchar(max)", nullable: true), + EventId = table.Column(type: "uniqueidentifier", nullable: true), + CorrelationId = table.Column(type: "uniqueidentifier", nullable: true), + Outcome = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ConfigAuditLog", x => x.AuditId); + table.CheckConstraint("CK_ConfigAuditLog_DetailsJson_IsJson", "DetailsJson IS NULL OR ISJSON(DetailsJson) = 1"); + }); + + migrationBuilder.CreateTable( + name: "ConfigEdit", + columns: table => new + { + EditId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + EntityType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + EntityId = table.Column(type: "uniqueidentifier", nullable: false), + FieldsJson = table.Column(type: "nvarchar(max)", nullable: false), + ExecutionId = table.Column(type: "uniqueidentifier", nullable: true), + EditedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + EditedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + SourceNode = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ConfigEdit", x => x.EditId); + table.CheckConstraint("CK_ConfigEdit_FieldsJson_IsJson", "ISJSON(FieldsJson) = 1"); + }); + + migrationBuilder.CreateTable( + name: "DataProtectionKeys", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FriendlyName = table.Column(type: "nvarchar(max)", nullable: true), + Xml = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DataProtectionKeys", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Deployment", + columns: table => new + { + DeploymentId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + RevisionHash = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Status = table.Column(type: "int", nullable: false), + CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + CreatedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + ArtifactBlob = table.Column(type: "varbinary(max)", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false), + FailureReason = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), + SealedAtUtc = table.Column(type: "datetime2(3)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Deployment", x => x.DeploymentId); + }); + + migrationBuilder.CreateTable( + name: "Device", + columns: table => new + { + DeviceRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + DeviceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Enabled = table.Column(type: "bit", nullable: false), + DeviceConfig = table.Column(type: "nvarchar(max)", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Device", x => x.DeviceRowId); + table.CheckConstraint("CK_Device_DeviceConfig_IsJson", "ISJSON(DeviceConfig) = 1"); + }); + + migrationBuilder.CreateTable( + name: "DriverHostStatus", + columns: table => new + { + NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + HostName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + State = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + StateChangedUtc = table.Column(type: "datetime2(3)", nullable: false), + LastSeenUtc = table.Column(type: "datetime2(3)", nullable: false), + Detail = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DriverHostStatus", x => new { x.NodeId, x.DriverInstanceId, x.HostName }); + }); + + migrationBuilder.CreateTable( + name: "DriverInstanceResilienceStatus", + columns: table => new + { + DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + HostName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + LastCircuitBreakerOpenUtc = table.Column(type: "datetime2(3)", nullable: true), + ConsecutiveFailures = table.Column(type: "int", nullable: false), + CurrentBulkheadDepth = table.Column(type: "int", nullable: false), + LastRecycleUtc = table.Column(type: "datetime2(3)", nullable: true), + BaselineFootprintBytes = table.Column(type: "bigint", nullable: false), + CurrentFootprintBytes = table.Column(type: "bigint", nullable: false), + LastSampledUtc = table.Column(type: "datetime2(3)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DriverInstanceResilienceStatus", x => new { x.DriverInstanceId, x.HostName }); + }); + + migrationBuilder.CreateTable( + name: "Equipment", + columns: table => new + { + EquipmentRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + EquipmentUuid = table.Column(type: "uniqueidentifier", nullable: false), + UnsLineId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + MachineCode = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ZTag = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + SAPID = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Manufacturer = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Model = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + SerialNumber = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + HardwareRevision = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), + SoftwareRevision = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), + YearOfConstruction = table.Column(type: "smallint", nullable: true), + AssetLocation = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ManufacturerUri = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + DeviceManualUri = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + EquipmentClassRef = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + Enabled = table.Column(type: "bit", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Equipment", x => x.EquipmentRowId); + }); + + migrationBuilder.CreateTable( + name: "ExternalIdReservation", + columns: table => new + { + ReservationId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + Kind = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + Value = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + EquipmentUuid = table.Column(type: "uniqueidentifier", nullable: false), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + FirstPublishedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + FirstPublishedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + LastPublishedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + ReleasedAt = table.Column(type: "datetime2(3)", nullable: true), + ReleasedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + ReleaseReason = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ExternalIdReservation", x => x.ReservationId); + }); + + migrationBuilder.CreateTable( + name: "NodeAcl", + columns: table => new + { + NodeAclRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + NodeAclId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + LdapGroup = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + ScopeKind = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + ScopeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + PermissionFlags = table.Column(type: "int", nullable: false), + Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_NodeAcl", x => x.NodeAclRowId); + }); + + migrationBuilder.CreateTable( + name: "PollGroup", + columns: table => new + { + PollGroupRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + PollGroupId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + IntervalMs = table.Column(type: "int", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PollGroup", x => x.PollGroupRowId); + table.CheckConstraint("CK_PollGroup_IntervalMs_Min", "IntervalMs >= 50"); + }); + + migrationBuilder.CreateTable( + name: "Script", + columns: table => new + { + ScriptRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + ScriptId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + SourceCode = table.Column(type: "nvarchar(max)", nullable: false), + SourceHash = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Language = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Script", x => x.ScriptRowId); + }); + + migrationBuilder.CreateTable( + name: "ScriptedAlarm", + columns: table => new + { + ScriptedAlarmRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + ScriptedAlarmId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + AlarmType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + Severity = table.Column(type: "int", nullable: false), + MessageTemplate = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), + PredicateScriptId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + HistorizeToAveva = table.Column(type: "bit", nullable: false), + Retain = table.Column(type: "bit", nullable: false), + Enabled = table.Column(type: "bit", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ScriptedAlarm", x => x.ScriptedAlarmRowId); + table.CheckConstraint("CK_ScriptedAlarm_AlarmType", "AlarmType IN ('AlarmCondition','LimitAlarm','OffNormalAlarm','DiscreteAlarm')"); + table.CheckConstraint("CK_ScriptedAlarm_Severity_Range", "Severity BETWEEN 1 AND 1000"); + }); + + migrationBuilder.CreateTable( + name: "ScriptedAlarmState", + columns: table => new + { + ScriptedAlarmId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + EnabledState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + AckedState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + ConfirmedState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + ShelvingState = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + ShelvingExpiresUtc = table.Column(type: "datetime2(3)", nullable: true), + LastAckUser = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + LastAckComment = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + LastAckUtc = table.Column(type: "datetime2(3)", nullable: true), + LastConfirmUser = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + LastConfirmComment = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + LastConfirmUtc = table.Column(type: "datetime2(3)", nullable: true), + CommentsJson = table.Column(type: "nvarchar(max)", nullable: false), + UpdatedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()") + }, + constraints: table => + { + table.PrimaryKey("PK_ScriptedAlarmState", x => x.ScriptedAlarmId); + table.CheckConstraint("CK_ScriptedAlarmState_CommentsJson_IsJson", "ISJSON(CommentsJson) = 1"); + }); + + migrationBuilder.CreateTable( + name: "ServerCluster", + columns: table => new + { + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Enterprise = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + Site = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + NodeCount = table.Column(type: "tinyint", nullable: false), + RedundancyMode = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + Enabled = table.Column(type: "bit", nullable: false), + Notes = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + ModifiedAt = table.Column(type: "datetime2(3)", nullable: true), + ModifiedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerCluster", x => x.ClusterId); + table.CheckConstraint("CK_ServerCluster_RedundancyMode_NodeCount", "((NodeCount = 1 AND RedundancyMode = 'None') OR (NodeCount = 2 AND RedundancyMode IN ('Warm', 'Hot')))"); + }); + + migrationBuilder.CreateTable( + name: "Tag", + columns: table => new + { + TagRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + TagId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + DeviceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + TagGroupId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + DataType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + AccessLevel = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: false), + WriteIdempotent = table.Column(type: "bit", nullable: false), + PollGroupId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TagConfig = table.Column(type: "nvarchar(max)", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Tag", x => x.TagRowId); + table.CheckConstraint("CK_Tag_TagConfig_IsJson", "ISJSON(TagConfig) = 1"); + }); + + migrationBuilder.CreateTable( + name: "TagGroup", + columns: table => new + { + TagGroupRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + TagGroupId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + DeviceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ParentTagGroupId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + SortOrder = table.Column(type: "int", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TagGroup", x => x.TagGroupRowId); + }); + + migrationBuilder.CreateTable( + name: "UnsLine", + columns: table => new + { + UnsLineRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + UnsLineId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + UnsAreaId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UnsLine", x => x.UnsLineRowId); + }); + + migrationBuilder.CreateTable( + name: "UnsTagReference", + columns: table => new + { + UnsTagReferenceRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + UnsTagReferenceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + TagId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DisplayNameOverride = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + SortOrder = table.Column(type: "int", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UnsTagReference", x => x.UnsTagReferenceRowId); + }); + + migrationBuilder.CreateTable( + name: "VirtualTag", + columns: table => new + { + VirtualTagRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + VirtualTagId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + EquipmentId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + DataType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + ScriptId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ChangeTriggered = table.Column(type: "bit", nullable: false), + TimerIntervalMs = table.Column(type: "int", nullable: true), + Historize = table.Column(type: "bit", nullable: false), + Enabled = table.Column(type: "bit", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_VirtualTag", x => x.VirtualTagRowId); + table.CheckConstraint("CK_VirtualTag_TimerInterval_Min", "TimerIntervalMs IS NULL OR TimerIntervalMs >= 50"); + table.CheckConstraint("CK_VirtualTag_Trigger_AtLeastOne", "ChangeTriggered = 1 OR TimerIntervalMs IS NOT NULL"); + }); + + migrationBuilder.CreateTable( + name: "ClusterNode", + columns: table => new + { + NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Host = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false), + OpcUaPort = table.Column(type: "int", nullable: false), + DashboardPort = table.Column(type: "int", nullable: false), + ApplicationUri = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + ServiceLevelBase = table.Column(type: "tinyint", nullable: false), + DriverConfigOverridesJson = table.Column(type: "nvarchar(max)", nullable: true), + Enabled = table.Column(type: "bit", nullable: false), + LastSeenAt = table.Column(type: "datetime2(3)", nullable: true), + CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClusterNode", x => x.NodeId); + table.ForeignKey( + name: "FK_ClusterNode_ServerCluster_ClusterId", + column: x => x.ClusterId, + principalTable: "ServerCluster", + principalColumn: "ClusterId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "DriverInstance", + columns: table => new + { + DriverInstanceRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + DriverInstanceId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + RawFolderId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + DriverType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + Enabled = table.Column(type: "bit", nullable: false), + DriverConfig = table.Column(type: "nvarchar(max)", nullable: false), + ResilienceConfig = table.Column(type: "nvarchar(max)", nullable: true), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DriverInstance", x => x.DriverInstanceRowId); + table.CheckConstraint("CK_DriverInstance_DriverConfig_IsJson", "ISJSON(DriverConfig) = 1"); + table.CheckConstraint("CK_DriverInstance_ResilienceConfig_IsJson", "ResilienceConfig IS NULL OR ISJSON(ResilienceConfig) = 1"); + table.ForeignKey( + name: "FK_DriverInstance_ServerCluster_ClusterId", + column: x => x.ClusterId, + principalTable: "ServerCluster", + principalColumn: "ClusterId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "LdapGroupRoleMapping", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + LdapGroup = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + Role = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IsSystemWide = table.Column(type: "bit", nullable: false), + CreatedAtUtc = table.Column(type: "datetime2(3)", nullable: false), + Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_LdapGroupRoleMapping", x => x.Id); + table.ForeignKey( + name: "FK_LdapGroupRoleMapping_ServerCluster_ClusterId", + column: x => x.ClusterId, + principalTable: "ServerCluster", + principalColumn: "ClusterId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "RawFolder", + columns: table => new + { + RawFolderRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + RawFolderId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ParentRawFolderId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + SortOrder = table.Column(type: "int", nullable: false), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RawFolder", x => x.RawFolderRowId); + table.ForeignKey( + name: "FK_RawFolder_ServerCluster_ClusterId", + column: x => x.ClusterId, + principalTable: "ServerCluster", + principalColumn: "ClusterId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "UnsArea", + columns: table => new + { + UnsAreaRowId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + UnsAreaId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + ClusterId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + Notes = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UnsArea", x => x.UnsAreaRowId); + table.ForeignKey( + name: "FK_UnsArea_ServerCluster_ClusterId", + column: x => x.ClusterId, + principalTable: "ServerCluster", + principalColumn: "ClusterId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "ClusterNodeCredential", + columns: table => new + { + CredentialId = table.Column(type: "uniqueidentifier", nullable: false, defaultValueSql: "NEWSEQUENTIALID()"), + NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Kind = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + Value = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + Enabled = table.Column(type: "bit", nullable: false), + RotatedAt = table.Column(type: "datetime2(3)", nullable: true), + CreatedAt = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + CreatedBy = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClusterNodeCredential", x => x.CredentialId); + table.ForeignKey( + name: "FK_ClusterNodeCredential_ClusterNode_NodeId", + column: x => x.NodeId, + principalTable: "ClusterNode", + principalColumn: "NodeId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "NodeDeploymentState", + columns: table => new + { + NodeId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeploymentId = table.Column(type: "uniqueidentifier", nullable: false), + Status = table.Column(type: "int", nullable: false), + StartedAtUtc = table.Column(type: "datetime2(3)", nullable: false, defaultValueSql: "SYSUTCDATETIME()"), + AppliedAtUtc = table.Column(type: "datetime2(3)", nullable: true), + FailureReason = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), + RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_NodeDeploymentState", x => new { x.NodeId, x.DeploymentId }); + table.ForeignKey( + name: "FK_NodeDeploymentState_ClusterNode_NodeId", + column: x => x.NodeId, + principalTable: "ClusterNode", + principalColumn: "NodeId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_NodeDeploymentState_Deployment_DeploymentId", + column: x => x.DeploymentId, + principalTable: "Deployment", + principalColumn: "DeploymentId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ClusterNode_ClusterId", + table: "ClusterNode", + column: "ClusterId"); + + migrationBuilder.CreateIndex( + name: "UX_ClusterNode_ApplicationUri", + table: "ClusterNode", + column: "ApplicationUri", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ClusterNodeCredential_NodeId", + table: "ClusterNodeCredential", + columns: new[] { "NodeId", "Enabled" }); + + migrationBuilder.CreateIndex( + name: "UX_ClusterNodeCredential_Value", + table: "ClusterNodeCredential", + columns: new[] { "Kind", "Value" }, + unique: true, + filter: "[Enabled] = 1"); + + migrationBuilder.CreateIndex( + name: "IX_ConfigAuditLog_Cluster_Time", + table: "ConfigAuditLog", + columns: new[] { "ClusterId", "Timestamp" }, + descending: new[] { false, true }); + + migrationBuilder.CreateIndex( + name: "IX_ConfigAuditLog_Generation", + table: "ConfigAuditLog", + column: "GenerationId", + filter: "[GenerationId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_ConfigAuditLog_EventId", + table: "ConfigAuditLog", + column: "EventId", + unique: true, + filter: "[EventId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_ConfigEdit_EditedAt", + table: "ConfigEdit", + column: "EditedAtUtc"); + + migrationBuilder.CreateIndex( + name: "IX_ConfigEdit_Entity", + table: "ConfigEdit", + columns: new[] { "EntityType", "EntityId" }); + + migrationBuilder.CreateIndex( + name: "IX_ConfigEdit_Execution", + table: "ConfigEdit", + column: "ExecutionId", + filter: "[ExecutionId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_Deployment_CreatedAt", + table: "Deployment", + column: "CreatedAtUtc"); + + migrationBuilder.CreateIndex( + name: "IX_Deployment_Status", + table: "Deployment", + column: "Status"); + + migrationBuilder.CreateIndex( + name: "IX_Device_Driver", + table: "Device", + column: "DriverInstanceId"); + + migrationBuilder.CreateIndex( + name: "UX_Device_Driver_Name", + table: "Device", + columns: new[] { "DriverInstanceId", "Name" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "UX_Device_LogicalId", + table: "Device", + column: "DeviceId", + unique: true, + filter: "[DeviceId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_DriverHostStatus_LastSeen", + table: "DriverHostStatus", + column: "LastSeenUtc"); + + migrationBuilder.CreateIndex( + name: "IX_DriverHostStatus_Node", + table: "DriverHostStatus", + column: "NodeId"); + + migrationBuilder.CreateIndex( + name: "IX_DriverInstance_Cluster", + table: "DriverInstance", + column: "ClusterId"); + + migrationBuilder.CreateIndex( + name: "IX_DriverInstance_RawFolder", + table: "DriverInstance", + column: "RawFolderId"); + + migrationBuilder.CreateIndex( + name: "UX_DriverInstance_ClusterRoot_Name", + table: "DriverInstance", + columns: new[] { "ClusterId", "Name" }, + unique: true, + filter: "[RawFolderId] IS NULL"); + + migrationBuilder.CreateIndex( + name: "UX_DriverInstance_Folder_Name", + table: "DriverInstance", + columns: new[] { "ClusterId", "RawFolderId", "Name" }, + unique: true, + filter: "[RawFolderId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_DriverInstance_LogicalId", + table: "DriverInstance", + column: "DriverInstanceId", + unique: true, + filter: "[DriverInstanceId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_DriverResilience_LastSampled", + table: "DriverInstanceResilienceStatus", + column: "LastSampledUtc"); + + migrationBuilder.CreateIndex( + name: "IX_Equipment_Line", + table: "Equipment", + column: "UnsLineId"); + + migrationBuilder.CreateIndex( + name: "IX_Equipment_MachineCode", + table: "Equipment", + column: "MachineCode"); + + migrationBuilder.CreateIndex( + name: "IX_Equipment_SAPID", + table: "Equipment", + column: "SAPID", + filter: "[SAPID] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_Equipment_ZTag", + table: "Equipment", + column: "ZTag", + filter: "[ZTag] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_Equipment_LinePath", + table: "Equipment", + columns: new[] { "UnsLineId", "Name" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "UX_Equipment_LogicalId", + table: "Equipment", + column: "EquipmentId", + unique: true, + filter: "[EquipmentId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_Equipment_Uuid", + table: "Equipment", + column: "EquipmentUuid", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ExternalIdReservation_Equipment", + table: "ExternalIdReservation", + column: "EquipmentUuid"); + + migrationBuilder.CreateIndex( + name: "UX_ExternalIdReservation_KindValue_Active", + table: "ExternalIdReservation", + columns: new[] { "Kind", "Value" }, + unique: true, + filter: "[ReleasedAt] IS NULL"); + + migrationBuilder.CreateIndex( + name: "IX_LdapGroupRoleMapping_ClusterId", + table: "LdapGroupRoleMapping", + column: "ClusterId"); + + migrationBuilder.CreateIndex( + name: "IX_LdapGroupRoleMapping_Group", + table: "LdapGroupRoleMapping", + column: "LdapGroup"); + + migrationBuilder.CreateIndex( + name: "UX_LdapGroupRoleMapping_Group_Cluster", + table: "LdapGroupRoleMapping", + columns: new[] { "LdapGroup", "ClusterId" }, + unique: true, + filter: "[ClusterId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_NodeAcl_Cluster", + table: "NodeAcl", + column: "ClusterId"); + + migrationBuilder.CreateIndex( + name: "IX_NodeAcl_Group", + table: "NodeAcl", + column: "LdapGroup"); + + migrationBuilder.CreateIndex( + name: "IX_NodeAcl_Scope", + table: "NodeAcl", + columns: new[] { "ScopeKind", "ScopeId" }, + filter: "[ScopeId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_NodeAcl_GroupScope", + table: "NodeAcl", + columns: new[] { "ClusterId", "LdapGroup", "ScopeKind", "ScopeId" }, + unique: true, + filter: "[ScopeId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_NodeAcl_LogicalId", + table: "NodeAcl", + column: "NodeAclId", + unique: true, + filter: "[NodeAclId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_NodeDeploymentState_Deployment", + table: "NodeDeploymentState", + column: "DeploymentId"); + + migrationBuilder.CreateIndex( + name: "IX_NodeDeploymentState_Status", + table: "NodeDeploymentState", + column: "Status"); + + migrationBuilder.CreateIndex( + name: "IX_PollGroup_Driver", + table: "PollGroup", + column: "DriverInstanceId"); + + migrationBuilder.CreateIndex( + name: "UX_PollGroup_LogicalId", + table: "PollGroup", + column: "PollGroupId", + unique: true, + filter: "[PollGroupId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_RawFolder_Cluster", + table: "RawFolder", + column: "ClusterId"); + + migrationBuilder.CreateIndex( + name: "UX_RawFolder_ClusterRoot_Name", + table: "RawFolder", + columns: new[] { "ClusterId", "Name" }, + unique: true, + filter: "[ParentRawFolderId] IS NULL"); + + migrationBuilder.CreateIndex( + name: "UX_RawFolder_LogicalId", + table: "RawFolder", + column: "RawFolderId", + unique: true, + filter: "[RawFolderId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_RawFolder_Parent_Name", + table: "RawFolder", + columns: new[] { "ClusterId", "ParentRawFolderId", "Name" }, + unique: true, + filter: "[ParentRawFolderId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_Script_SourceHash", + table: "Script", + column: "SourceHash"); + + migrationBuilder.CreateIndex( + name: "UX_Script_LogicalId", + table: "Script", + column: "ScriptId", + unique: true, + filter: "[ScriptId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_ScriptedAlarm_Script", + table: "ScriptedAlarm", + column: "PredicateScriptId"); + + migrationBuilder.CreateIndex( + name: "UX_ScriptedAlarm_EquipmentPath", + table: "ScriptedAlarm", + columns: new[] { "EquipmentId", "Name" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "UX_ScriptedAlarm_LogicalId", + table: "ScriptedAlarm", + column: "ScriptedAlarmId", + unique: true, + filter: "[ScriptedAlarmId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_ServerCluster_Site", + table: "ServerCluster", + column: "Site"); + + migrationBuilder.CreateIndex( + name: "UX_ServerCluster_Name", + table: "ServerCluster", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Tag_Device", + table: "Tag", + columns: new[] { "DeviceId", "TagGroupId" }); + + migrationBuilder.CreateIndex( + name: "UX_Tag_Device_Name", + table: "Tag", + columns: new[] { "DeviceId", "Name" }, + unique: true, + filter: "[TagGroupId] IS NULL"); + + migrationBuilder.CreateIndex( + name: "UX_Tag_Group_Name", + table: "Tag", + columns: new[] { "DeviceId", "TagGroupId", "Name" }, + unique: true, + filter: "[TagGroupId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_Tag_LogicalId", + table: "Tag", + column: "TagId", + unique: true, + filter: "[TagId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_TagGroup_Device", + table: "TagGroup", + column: "DeviceId"); + + migrationBuilder.CreateIndex( + name: "UX_TagGroup_DeviceRoot_Name", + table: "TagGroup", + columns: new[] { "DeviceId", "Name" }, + unique: true, + filter: "[ParentTagGroupId] IS NULL"); + + migrationBuilder.CreateIndex( + name: "UX_TagGroup_LogicalId", + table: "TagGroup", + column: "TagGroupId", + unique: true, + filter: "[TagGroupId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "UX_TagGroup_Parent_Name", + table: "TagGroup", + columns: new[] { "DeviceId", "ParentTagGroupId", "Name" }, + unique: true, + filter: "[ParentTagGroupId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_UnsArea_Cluster", + table: "UnsArea", + column: "ClusterId"); + + migrationBuilder.CreateIndex( + name: "UX_UnsArea_ClusterName", + table: "UnsArea", + columns: new[] { "ClusterId", "Name" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "UX_UnsArea_LogicalId", + table: "UnsArea", + column: "UnsAreaId", + unique: true, + filter: "[UnsAreaId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_UnsLine_Area", + table: "UnsLine", + column: "UnsAreaId"); + + migrationBuilder.CreateIndex( + name: "UX_UnsLine_AreaName", + table: "UnsLine", + columns: new[] { "UnsAreaId", "Name" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "UX_UnsLine_LogicalId", + table: "UnsLine", + column: "UnsLineId", + unique: true, + filter: "[UnsLineId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_UnsTagReference_Equipment", + table: "UnsTagReference", + column: "EquipmentId"); + + migrationBuilder.CreateIndex( + name: "IX_UnsTagReference_Tag", + table: "UnsTagReference", + column: "TagId"); + + migrationBuilder.CreateIndex( + name: "UX_UnsTagReference_Equip_Tag", + table: "UnsTagReference", + columns: new[] { "EquipmentId", "TagId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "UX_UnsTagReference_LogicalId", + table: "UnsTagReference", + column: "UnsTagReferenceId", + unique: true, + filter: "[UnsTagReferenceId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_VirtualTag_Script", + table: "VirtualTag", + column: "ScriptId"); + + migrationBuilder.CreateIndex( + name: "UX_VirtualTag_EquipmentPath", + table: "VirtualTag", + columns: new[] { "EquipmentId", "Name" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "UX_VirtualTag_LogicalId", + table: "VirtualTag", + column: "VirtualTagId", + unique: true, + filter: "[VirtualTagId] IS NOT NULL"); + + // Hand-authored SQL squashed in from the retired per-migration proc + grant files + // (see V3Initial.StoredProcedures.cs for the full rationale + the v3 rewrites). + CreateStoredProcedures(migrationBuilder); + CreateAuthorizationGrants(migrationBuilder); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + DropAuthorizationGrants(migrationBuilder); + DropStoredProcedures(migrationBuilder); + + migrationBuilder.DropTable( + name: "ClusterNodeCredential"); + + migrationBuilder.DropTable( + name: "ConfigAuditLog"); + + migrationBuilder.DropTable( + name: "ConfigEdit"); + + migrationBuilder.DropTable( + name: "DataProtectionKeys"); + + migrationBuilder.DropTable( + name: "Device"); + + migrationBuilder.DropTable( + name: "DriverHostStatus"); + + migrationBuilder.DropTable( + name: "DriverInstance"); + + migrationBuilder.DropTable( + name: "DriverInstanceResilienceStatus"); + + migrationBuilder.DropTable( + name: "Equipment"); + + migrationBuilder.DropTable( + name: "ExternalIdReservation"); + + migrationBuilder.DropTable( + name: "LdapGroupRoleMapping"); + + migrationBuilder.DropTable( + name: "NodeAcl"); + + migrationBuilder.DropTable( + name: "NodeDeploymentState"); + + migrationBuilder.DropTable( + name: "PollGroup"); + + migrationBuilder.DropTable( + name: "RawFolder"); + + migrationBuilder.DropTable( + name: "Script"); + + migrationBuilder.DropTable( + name: "ScriptedAlarm"); + + migrationBuilder.DropTable( + name: "ScriptedAlarmState"); + + migrationBuilder.DropTable( + name: "Tag"); + + migrationBuilder.DropTable( + name: "TagGroup"); + + migrationBuilder.DropTable( + name: "UnsArea"); + + migrationBuilder.DropTable( + name: "UnsLine"); + + migrationBuilder.DropTable( + name: "UnsTagReference"); + + migrationBuilder.DropTable( + name: "VirtualTag"); + + migrationBuilder.DropTable( + name: "ClusterNode"); + + migrationBuilder.DropTable( + name: "Deployment"); + + migrationBuilder.DropTable( + name: "ServerCluster"); + } + } +} 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 0d9924f3..b5522bd5 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/OtOpcUaConfigDbContextModelSnapshot.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/OtOpcUaConfigDbContextModelSnapshot.cs @@ -373,6 +373,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations 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"); @@ -452,8 +456,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasMaxLength(128) .HasColumnType("nvarchar(128)"); - b.Property("NamespaceId") - .IsRequired() + b.Property("RawFolderId") .HasMaxLength(64) .HasColumnType("nvarchar(64)"); @@ -476,8 +479,18 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasDatabaseName("UX_DriverInstance_LogicalId") .HasFilter("[DriverInstanceId] IS NOT NULL"); - b.HasIndex("NamespaceId") - .HasDatabaseName("IX_DriverInstance_Namespace"); + 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 => { @@ -537,18 +550,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasMaxLength(256) .HasColumnType("nvarchar(256)"); - b.Property("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - b.Property("DeviceManualUri") .HasMaxLength(512) .HasColumnType("nvarchar(512)"); - b.Property("DriverInstanceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - b.Property("Enabled") .HasColumnType("bit"); @@ -621,9 +626,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.HasKey("EquipmentRowId"); - b.HasIndex("DriverInstanceId") - .HasDatabaseName("IX_Equipment_Driver"); - b.HasIndex("EquipmentId") .IsUnique() .HasDatabaseName("UX_Equipment_LogicalId") @@ -654,148 +656,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.ToTable("Equipment", (string)null); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("CreatedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("CreatedBy") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("FinalisedAtUtc") - .HasColumnType("datetime2(3)"); - - b.Property("RowsAccepted") - .HasColumnType("int"); - - b.Property("RowsRejected") - .HasColumnType("int"); - - b.Property("RowsStaged") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CreatedBy", "FinalisedAtUtc") - .HasDatabaseName("IX_EquipmentImportBatch_Creator_Finalised"); - - b.ToTable("EquipmentImportBatch", (string)null); - }); - - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("AssetLocation") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("BatchId") - .HasColumnType("uniqueidentifier"); - - b.Property("DeviceManualUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("EquipmentId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("EquipmentUuid") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("HardwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsAccepted") - .HasColumnType("bit"); - - b.Property("LineNumberInFile") - .HasColumnType("int"); - - b.Property("MachineCode") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Manufacturer") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ManufacturerUri") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Model") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("RejectReason") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("SAPID") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SerialNumber") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("SoftwareRevision") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsAreaName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("UnsLineName") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("YearOfConstruction") - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("ZTag") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("BatchId") - .HasDatabaseName("IX_EquipmentImportRow_Batch"); - - b.ToTable("EquipmentImportRow", (string)null); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ExternalIdReservation", b => { b.Property("ReservationId") @@ -905,66 +765,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.ToTable("LdapGroupRoleMapping", (string)null); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.Property("NamespaceRowId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier") - .HasDefaultValueSql("NEWSEQUENTIALID()"); - - b.Property("ClusterId") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("Kind") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NamespaceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("NamespaceUri") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Notes") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("RowVersion") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.HasKey("NamespaceRowId"); - - b.HasIndex("ClusterId") - .HasDatabaseName("IX_Namespace_Cluster"); - - b.HasIndex("NamespaceId") - .IsUnique() - .HasDatabaseName("UX_Namespace_LogicalId") - .HasFilter("[NamespaceId] IS NOT NULL"); - - b.HasIndex("NamespaceUri") - .IsUnique() - .HasDatabaseName("UX_Namespace_NamespaceUri"); - - b.HasIndex("ClusterId", "Kind") - .IsUnique() - .HasDatabaseName("UX_Namespace_Cluster_Kind"); - - b.ToTable("Namespace", (string)null); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeAcl", b => { b.Property("NodeAclRowId") @@ -1120,6 +920,63 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations }); }); + 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") @@ -1399,22 +1256,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .HasColumnType("nvarchar(32)"); b.Property("DeviceId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("DriverInstanceId") .IsRequired() .HasMaxLength(64) .HasColumnType("nvarchar(64)"); - b.Property("EquipmentId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("FolderPath") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - b.Property("Name") .IsRequired() .HasMaxLength(128) @@ -1434,6 +1279,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("TagGroupId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + b.Property("TagId") .HasMaxLength(64) .HasColumnType("nvarchar(64)"); @@ -1443,27 +1292,23 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.HasKey("TagRowId"); - b.HasIndex("EquipmentId") - .HasDatabaseName("IX_Tag_Equipment") - .HasFilter("[EquipmentId] IS NOT NULL"); - b.HasIndex("TagId") .IsUnique() .HasDatabaseName("UX_Tag_LogicalId") .HasFilter("[TagId] IS NOT NULL"); - b.HasIndex("DriverInstanceId", "DeviceId") - .HasDatabaseName("IX_Tag_Driver_Device"); - - b.HasIndex("EquipmentId", "Name") + b.HasIndex("DeviceId", "Name") .IsUnique() - .HasDatabaseName("UX_Tag_EquipmentPath") - .HasFilter("[EquipmentId] IS NOT NULL"); + .HasDatabaseName("UX_Tag_Device_Name") + .HasFilter("[TagGroupId] IS NULL"); - b.HasIndex("DriverInstanceId", "FolderPath", "Name") + b.HasIndex("DeviceId", "TagGroupId") + .HasDatabaseName("IX_Tag_Device"); + + b.HasIndex("DeviceId", "TagGroupId", "Name") .IsUnique() - .HasDatabaseName("UX_Tag_FolderPath") - .HasFilter("[EquipmentId] IS NULL"); + .HasDatabaseName("UX_Tag_Group_Name") + .HasFilter("[TagGroupId] IS NOT NULL"); b.ToTable("Tag", null, t => { @@ -1471,6 +1316,63 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations }); }); + 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") @@ -1567,6 +1469,60 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations 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") @@ -1671,17 +1627,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.Navigation("Cluster"); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportRow", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", "Batch") - .WithMany("Rows") - .HasForeignKey("BatchId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Batch"); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.LdapGroupRoleMapping", b => { b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") @@ -1692,17 +1637,6 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.Navigation("Cluster"); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Namespace", b => - { - b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", "Cluster") - .WithMany("Namespaces") - .HasForeignKey("ClusterId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Cluster"); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.NodeDeploymentState", b => { b.HasOne("ZB.MOM.WW.OtOpcUa.Configuration.Entities.Deployment", "Deployment") @@ -1722,6 +1656,15 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations 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") @@ -1738,16 +1681,11 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations b.Navigation("Credentials"); }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.EquipmentImportBatch", b => - { - b.Navigation("Rows"); - }); - modelBuilder.Entity("ZB.MOM.WW.OtOpcUa.Configuration.Entities.ServerCluster", b => { - b.Navigation("Namespaces"); - b.Navigation("Nodes"); + + b.Navigation("RawFolders"); }); #pragma warning restore 612, 618 } diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs index dbc97b3e..defa00de 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs @@ -18,8 +18,12 @@ public sealed class OtOpcUaConfigDbContext(DbContextOptions ClusterNodes => Set(); /// Gets the DbSet of cluster node credentials. public DbSet ClusterNodeCredentials => Set(); - /// Gets the DbSet of namespaces. - public DbSet Namespaces => Set(); + /// Gets the DbSet of v3 Raw-tree driver-organizing folders. + public DbSet RawFolders => Set(); + /// Gets the DbSet of v3 Raw-tree tag groups (nestable under a device). + public DbSet TagGroups => Set(); + /// Gets the DbSet of v3 UNS tag references (equipment → raw tag projection). + public DbSet UnsTagReferences => Set(); /// Gets the DbSet of UNS areas. public DbSet UnsAreas => Set(); /// Gets the DbSet of UNS lines. @@ -46,10 +50,6 @@ public sealed class OtOpcUaConfigDbContext(DbContextOptions DriverInstanceResilienceStatuses => Set(); /// Gets the DbSet of LDAP group role mappings. public DbSet LdapGroupRoleMappings => Set(); - /// Gets the DbSet of equipment import batches. - public DbSet EquipmentImportBatches => Set(); - /// Gets the DbSet of equipment import rows. - public DbSet EquipmentImportRows => Set(); /// Gets the DbSet of scripts. public DbSet