Files
lmxopcua/docs/plans/2026-07-15-v3-batch1-PR.md
T
Joseph Doherty 080e958d94
v2-ci / build (pull_request) Successful in 3m31s
v2-ci / unit-tests (pull_request) Failing after 11m16s
docs(v3): Batch 1 schema/identity note in Configuration.md + PR description
2026-07-15 22:05:19 -04:00

4.7 KiB
Raw Blame History

v3 Batch 1 — greenfield schema + RawPath identity rewiring

Branch: v3/batch1-schema-identitymaster 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 (<Folder/…>/<Driver>/<Device>/<TagGroup/…>/<Tag>). 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<TDef> 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 TagsRawTags, 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 24 (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 24 land.
  • Live driver IntegrationTests + one pre-existing AbCip_Green_AgainstSim fixture-probe failure (AB CIP sim handshake — environment/fixture gate, untouched).