docs(config): correct OtOpcUa draft-validation description
The C# DraftValidator/DraftSnapshot has NO live caller in OtOpcUa src/ (verified repo-wide) — it is dormant complement code. The enforced pre-publish draft validation runs DB-side in the sp_ValidateDraft stored procedure (Status='Draft' -> sp_PublishGeneration lifecycle). Reframe across current-state/SPEC/GAPS/README/ CLAUDE.md from 'runtime draft validation' + a false publish-pipeline caller to 'dormant managed validator; enforcement is DB-side'. Out-of-scope conclusion for ZB.MOM.WW.Configuration is unchanged.
This commit is contained in:
@@ -64,12 +64,14 @@ three apps already do this; they do it with three private copies of the same plu
|
||||
`AuditLogOptions` (payload caps, retention bounds), and ScadaBridge's `Node` topology rules
|
||||
(gRPC port ≠ remoting port, seed nodes must not target the gRPC port) all stay where they
|
||||
live. Only the *plumbing they sit on* is shared; the *rules* are theirs.
|
||||
- **OtOpcUa's runtime draft/snapshot validation** (`DraftValidator` + `DraftSnapshot`). This is
|
||||
**not** options/config validation at all — it is managed pre-publish validation of an operator's
|
||||
*configuration draft* (UNS segment regex, EquipmentId derivation, cross-cluster namespace
|
||||
binding, reservation pre-flight), run in the publish pipeline against database rows, not against
|
||||
`IConfiguration`. It shares only a *philosophy* (return every failure in one pass) with this
|
||||
component and is **out of scope** for the shared library. It stays entirely in OtOpcUa.
|
||||
- **OtOpcUa's draft/generation-content validation** (the dormant C# `DraftValidator` /
|
||||
`DraftSnapshot`, plus the live DB stored procedure `sp_ValidateDraft` it was designed to
|
||||
complement). This is **not** options/config validation at all — it is pre-publish validation of an
|
||||
operator's *configuration draft content* (UNS segment regex, EquipmentId derivation, cross-cluster
|
||||
namespace binding, reservation pre-flight) against database rows, not against `IConfiguration`;
|
||||
enforcement lives DB-side in `sp_ValidateDraft` and the managed `DraftValidator` has **no live
|
||||
caller** in `src/` today. It shares only a *philosophy* (return every failure in one pass) with
|
||||
this component and is **out of scope** for the shared library. It stays entirely in OtOpcUa.
|
||||
|
||||
## 1. `IValidateOptions` base — `OptionsValidatorBase<TOptions>`
|
||||
|
||||
@@ -179,7 +181,7 @@ security / gRPC-port keys when the node is `Central` or `Site` respectively) wit
|
||||
|
||||
| Project | Current state | Primary gaps | What normalizes |
|
||||
|---|---|---|---|
|
||||
| **OtOpcUa** | **No options validation at all** — options bound with bare `.Bind()` (`LdapOptions`, `OpcUa`); zero `IValidateOptions` / `ValidateOnStart` in the repo. Only validator is `DraftValidator` (runtime draft/snapshot, **out of scope**). | No startup validation of `Ldap` / `OpcUa` sections — a bad value fails opaquely on first use. | *Optional* adoption: add `OptionsValidatorBase` subclasses + `AddValidatedOptions` for the sections worth guarding. `DraftValidator`/`DraftSnapshot` stay per-project untouched. Lightest consumer. |
|
||||
| **OtOpcUa** | **No options validation at all** — options bound with bare `.Bind()` (`LdapOptions`, `OpcUa`); zero `IValidateOptions` / `ValidateOnStart` in the repo. The only validation-shaped type is the dormant C# `DraftValidator` (draft/generation content; real enforcement is DB-side `sp_ValidateDraft`) — **out of scope**. | No startup validation of `Ldap` / `OpcUa` sections — a bad value fails opaquely on first use. | *Optional* adoption: add `OptionsValidatorBase` subclasses + `AddValidatedOptions` for the sections worth guarding. `DraftValidator`/`DraftSnapshot` stay per-project untouched. Lightest consumer. |
|
||||
| **MxGateway** | One large `GatewayOptionsValidator : IValidateOptions<GatewayOptions>` (~360 LOC, 9 sub-validators, private `AddIfBlank`/`AddIfNotPositive`/`AddIfInvalidPath` helpers); wired via `AddGatewayConfiguration` (`AddOptions().BindConfiguration().ValidateOnStart()`). | Hand-rolled accumulation + helpers duplicate the base; bespoke DI wiring duplicates `AddValidatedOptions`. | `GatewayOptionsValidator` → `OptionsValidatorBase<GatewayOptions>` (delete the `List<string>`/tail/helpers; keep the domain rules); `AddGatewayConfiguration` → `AddValidatedOptions<GatewayOptions, GatewayOptionsValidator>`. Domain rules unchanged. |
|
||||
| **ScadaBridge** | **Heaviest.** Four per-module `*OptionsValidator : IValidateOptions<T>` (Cluster / Security / HealthMonitoring / AuditLog) each with their own `List<string>` accumulation, wired through bespoke `AddXxx` extensions; **plus** a raw-config pre-Akka `StartupValidator`. | Four copies of the accumulation plumbing + bespoke DI wiring; `StartupValidator` open-codes the preflight envelope. | Each `*OptionsValidator` → `OptionsValidatorBase<T>`; each module's `AddXxx` → `AddValidatedOptions`; `StartupValidator` → `ConfigPreflight` (byte-compatible message, §4). Domain rules unchanged. |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user