fix(commons): resolve Commons-005..007,009..012 — OPC UA parse status, TryConvert correctness, Result null guard, invariant formatting, doc refresh
This commit is contained in:
@@ -60,26 +60,28 @@ Commons must define persistence-ignorant POCO entity classes for all configurati
|
||||
|
||||
Entity classes are organized by domain area:
|
||||
|
||||
- **Template & Modeling**: `Template`, `TemplateAttribute`, `TemplateAlarm`, `TemplateScript`, `TemplateComposition`, `Instance`, `InstanceAttributeOverride`, `InstanceConnectionBinding`, `Area`.
|
||||
- **Template & Modeling**: `Template`, `TemplateAttribute`, `TemplateAlarm`, `TemplateScript`, `TemplateComposition`, `TemplateFolder`.
|
||||
- **Instances**: `Instance`, `InstanceAttributeOverride`, `InstanceConnectionBinding`, `InstanceAlarmOverride`, `Area`.
|
||||
- **Shared Scripts**: `SharedScript`.
|
||||
- **Sites & Data Connections**: `Site`, `DataConnection`, `SiteDataConnectionAssignment`.
|
||||
- **Sites & Data Connections**: `Site`, `DataConnection`.
|
||||
- **External Systems & Database Connections**: `ExternalSystemDefinition`, `ExternalSystemMethod`, `DatabaseConnectionDefinition`.
|
||||
- **Notifications**: `NotificationList`, `NotificationRecipient`, `SmtpConfiguration`.
|
||||
- **Inbound API**: `ApiKey`, `ApiMethod`.
|
||||
- **Security**: `LdapGroupMapping`, `SiteScopeRule`.
|
||||
- **Deployment**: `DeploymentRecord`, `SystemArtifactDeploymentRecord`.
|
||||
- **Deployment**: `DeploymentRecord`, `SystemArtifactDeploymentRecord`, `DeployedConfigSnapshot`.
|
||||
- **Audit**: `AuditLogEntry`.
|
||||
|
||||
### REQ-COM-4: Per-Component Repository Interfaces
|
||||
|
||||
Commons must define repository interfaces that consuming components use for data access. Each interface is tailored to the data needs of its consuming component:
|
||||
|
||||
- `ITemplateEngineRepository` — Templates, attributes, alarms, scripts, compositions, instances, overrides, connection bindings, areas.
|
||||
- `ITemplateEngineRepository` — Templates, attributes, alarms, scripts, compositions, template folders, instances, overrides, alarm overrides, connection bindings, areas.
|
||||
- `IDeploymentManagerRepository` — Deployment records, deployed configuration snapshots, system-wide artifact deployment records.
|
||||
- `ISecurityRepository` — LDAP group mappings, site scoping rules.
|
||||
- `IInboundApiRepository` — API keys, API method definitions.
|
||||
- `IExternalSystemRepository` — External system definitions, method definitions, database connection definitions.
|
||||
- `INotificationRepository` — Notification lists, recipients, SMTP configuration.
|
||||
- `ISiteRepository` — Sites, data connections, and their site assignments.
|
||||
- `ICentralUiRepository` — Read-oriented queries spanning multiple domain areas for display purposes.
|
||||
|
||||
All repository interfaces must:
|
||||
@@ -93,7 +95,13 @@ Implementations of these interfaces are owned by the Configuration Database comp
|
||||
|
||||
Commons must define service interfaces for cross-cutting concerns that multiple components consume:
|
||||
|
||||
- **`IAuditService`**: Provides a single method for components to log audit entries: `LogAsync(user, action, entityType, entityId, entityName, afterState)`. The implementation (owned by the Audit Logging component) serializes the state as JSON and adds the audit entry to the current unit-of-work transaction. Defined in Commons so any central component can call it without depending on the Audit Logging component directly.
|
||||
- **`IAuditService`**: Provides a single method for components to log audit entries: `LogAsync(user, action, entityType, entityId, entityName, afterState)`. The implementation (owned by the Configuration Database component) serializes the state as JSON and adds the audit entry to the current unit-of-work transaction. Defined in Commons so any central component can call it without depending on the Configuration Database component directly.
|
||||
- **`IDatabaseGateway`**: Provides script-facing ADO.NET database access via named database connections. Implemented by the External System Gateway, consumed by the Site Runtime's script runtime context.
|
||||
- **`IExternalSystemClient`**: Provides script-facing invocation of external system HTTP APIs (synchronous `Call` and store-and-forward `CachedCall`). Implemented by the External System Gateway, consumed by the script runtime context.
|
||||
- **`IInstanceLocator`**: Resolves an instance unique name to its site identifier. Used by the Inbound API's `Route.To()` to determine the destination site.
|
||||
- **`INotificationDeliveryService`**: Sends notifications to a named notification list, routing transient failures to store-and-forward. Implemented by the Notification Service, consumed by the script runtime context.
|
||||
|
||||
These interfaces are defined in Commons so that consuming components depend only on the abstraction, not on the implementing component.
|
||||
|
||||
### REQ-COM-5: Cross-Component Message Contracts
|
||||
|
||||
@@ -126,20 +134,23 @@ All types in Commons are organized by **category** and **domain area** using a c
|
||||
```
|
||||
ScadaLink.Commons/
|
||||
├── Types/ # REQ-COM-1: Shared data types
|
||||
│ ├── DataType.cs
|
||||
│ ├── RetryPolicy.cs
|
||||
│ ├── Result.cs
|
||||
│ └── Enums/
|
||||
│ ├── InstanceState.cs
|
||||
│ ├── DeploymentStatus.cs
|
||||
│ ├── AlarmState.cs
|
||||
│ ├── AlarmTriggerType.cs
|
||||
│ └── ConnectionHealth.cs
|
||||
│ ├── RetryPolicy.cs
|
||||
│ ├── ScriptArgs.cs # script-call parameter normalization helper
|
||||
│ ├── ScriptParameters.cs # typed script-parameter access helper
|
||||
│ ├── StaleTagMonitor.cs # heartbeat staleness watchdog
|
||||
│ ├── ValueFormatter.cs # culture-invariant value-to-string helper
|
||||
│ ├── DynamicJsonElement.cs # dynamic JSON wrapper for scripts
|
||||
│ ├── Enums/ # InstanceState, DeploymentStatus, AlarmState,
|
||||
│ │ # AlarmLevel, AlarmTriggerType, ConnectionHealth,
|
||||
│ │ # DataType, StoreAndForwardCategory,
|
||||
│ │ # StoreAndForwardMessageStatus
|
||||
│ ├── DataConnections/ # OPC UA endpoint config value objects + enums
|
||||
│ ├── Flattening/ # FlattenedConfiguration, ConfigurationDiff,
|
||||
│ │ # DeploymentPackage, ValidationResult
|
||||
│ └── Scripts/ # AlarmContext, ScriptScope
|
||||
├── Interfaces/ # Shared interfaces by concern
|
||||
│ ├── Protocol/ # REQ-COM-2: Protocol abstraction
|
||||
│ │ ├── IDataConnection.cs
|
||||
│ │ ├── TagValue.cs
|
||||
│ │ └── SubscriptionCallback.cs
|
||||
│ ├── Protocol/ # REQ-COM-2: Protocol abstraction (IDataConnection, etc.)
|
||||
│ ├── Repositories/ # REQ-COM-4: Per-component repository interfaces
|
||||
│ │ ├── ITemplateEngineRepository.cs
|
||||
│ │ ├── IDeploymentManagerRepository.cs
|
||||
@@ -147,55 +158,46 @@ ScadaLink.Commons/
|
||||
│ │ ├── IInboundApiRepository.cs
|
||||
│ │ ├── IExternalSystemRepository.cs
|
||||
│ │ ├── INotificationRepository.cs
|
||||
│ │ ├── ISiteRepository.cs
|
||||
│ │ └── ICentralUiRepository.cs
|
||||
│ └── Services/ # REQ-COM-4a: Cross-cutting service interfaces
|
||||
│ └── IAuditService.cs
|
||||
│ ├── IAuditService.cs
|
||||
│ ├── IDatabaseGateway.cs
|
||||
│ ├── IExternalSystemClient.cs
|
||||
│ ├── IInstanceLocator.cs
|
||||
│ └── INotificationDeliveryService.cs
|
||||
├── Entities/ # REQ-COM-3: Domain entity POCOs, by domain area
|
||||
│ ├── Templates/
|
||||
│ │ ├── Template.cs
|
||||
│ │ ├── TemplateAttribute.cs
|
||||
│ │ ├── TemplateAlarm.cs
|
||||
│ │ ├── TemplateScript.cs
|
||||
│ │ └── TemplateComposition.cs
|
||||
│ ├── Instances/
|
||||
│ │ ├── Instance.cs
|
||||
│ │ ├── InstanceAttributeOverride.cs
|
||||
│ │ ├── InstanceConnectionBinding.cs
|
||||
│ │ └── Area.cs
|
||||
│ ├── Sites/
|
||||
│ │ ├── Site.cs
|
||||
│ │ ├── DataConnection.cs
|
||||
│ │ └── SiteDataConnectionAssignment.cs
|
||||
│ ├── ExternalSystems/
|
||||
│ │ ├── ExternalSystemDefinition.cs
|
||||
│ │ ├── ExternalSystemMethod.cs
|
||||
│ │ └── DatabaseConnectionDefinition.cs
|
||||
│ ├── Notifications/
|
||||
│ │ ├── NotificationList.cs
|
||||
│ │ ├── NotificationRecipient.cs
|
||||
│ │ └── SmtpConfiguration.cs
|
||||
│ ├── InboundApi/
|
||||
│ │ ├── ApiKey.cs
|
||||
│ │ └── ApiMethod.cs
|
||||
│ ├── Security/
|
||||
│ │ ├── LdapGroupMapping.cs
|
||||
│ │ └── SiteScopeRule.cs
|
||||
│ ├── Templates/ # Template, TemplateAttribute, TemplateAlarm,
|
||||
│ │ # TemplateScript, TemplateComposition, TemplateFolder
|
||||
│ ├── Instances/ # Instance, InstanceAttributeOverride,
|
||||
│ │ # InstanceConnectionBinding, InstanceAlarmOverride, Area
|
||||
│ ├── Sites/ # Site, DataConnection
|
||||
│ ├── ExternalSystems/ # ExternalSystemDefinition, ExternalSystemMethod,
|
||||
│ │ # DatabaseConnectionDefinition
|
||||
│ ├── Notifications/ # NotificationList, NotificationRecipient, SmtpConfiguration
|
||||
│ ├── InboundApi/ # ApiKey, ApiMethod
|
||||
│ ├── Security/ # LdapGroupMapping, SiteScopeRule
|
||||
│ ├── Deployment/ # DeploymentRecord, SystemArtifactDeploymentRecord,
|
||||
│ │ # DeployedConfigSnapshot
|
||||
│ ├── Scripts/ # SharedScript
|
||||
│ └── Audit/ # AuditLogEntry
|
||||
├── Messages/ # REQ-COM-5: Cross-component message contracts, by concern
|
||||
│ ├── Deployment/
|
||||
│ │ ├── DeploymentRecord.cs
|
||||
│ │ └── SystemArtifactDeploymentRecord.cs
|
||||
│ ├── Scripts/
|
||||
│ │ └── SharedScript.cs
|
||||
│ └── Audit/
|
||||
│ └── AuditLogEntry.cs
|
||||
└── Messages/ # REQ-COM-5: Cross-component message contracts, by concern
|
||||
├── Deployment/
|
||||
├── Lifecycle/
|
||||
├── Health/
|
||||
├── Communication/
|
||||
├── Streaming/
|
||||
├── DebugView/
|
||||
├── ScriptExecution/
|
||||
└── Artifacts/
|
||||
│ ├── Lifecycle/
|
||||
│ ├── Health/
|
||||
│ ├── Communication/
|
||||
│ ├── Streaming/
|
||||
│ ├── DebugView/
|
||||
│ ├── ScriptExecution/
|
||||
│ ├── Artifacts/
|
||||
│ ├── DataConnection/ # data-connection subscribe/write/health messages
|
||||
│ ├── Instance/ # attribute get/set request/command messages
|
||||
│ ├── Integration/ # external-integration call request/response
|
||||
│ ├── InboundApi/ # Route.To() request messages
|
||||
│ ├── RemoteQuery/ # event-log and parked-message query messages
|
||||
│ └── Management/ # HTTP/ClusterClient management commands + registry
|
||||
├── Serialization/ # OpcUaEndpointConfigSerializer (typed↔legacy JSON)
|
||||
└── Validators/ # OpcUaEndpointConfigValidator
|
||||
```
|
||||
|
||||
**Naming rules**:
|
||||
@@ -205,7 +207,7 @@ ScadaLink.Commons/
|
||||
- Message contracts are named as commands, events, or responses: `DeployInstanceCommand`, `DeploymentStatusResponse`, `AttributeValueChanged`.
|
||||
- Enums use singular names: `AlarmState`, not `AlarmStates`.
|
||||
|
||||
### REQ-COM-6: No Business Logic
|
||||
### REQ-COM-6: No Business Logic; Pure Helpers Permitted
|
||||
|
||||
Commons must contain only:
|
||||
|
||||
@@ -213,8 +215,17 @@ Commons must contain only:
|
||||
- Interfaces
|
||||
- Enums
|
||||
- Constants
|
||||
- **Pure, stateless helpers** — see the carve-out below.
|
||||
|
||||
It must **not** contain any business logic, service implementations, actor definitions, or orchestration code. Any method bodies must be limited to trivial data-access logic (e.g., factory methods, validation of invariants in constructors).
|
||||
It must **not** contain any business logic that orchestrates other components, service implementations that perform I/O (database, network, file system), actor definitions, or orchestration code.
|
||||
|
||||
**Pure-helper carve-out.** Commons *may* contain stateless, side-effect-free helper types whose behavior is confined to transforming, formatting, parsing, or validating the data types Commons already defines, provided they:
|
||||
|
||||
- have no dependency on Akka.NET, ASP.NET Core, EF Core, or any I/O surface (consistent with REQ-COM-7);
|
||||
- hold no shared mutable state across calls (a self-contained instance helper such as `StaleTagMonitor`, which owns only its own timer, is acceptable);
|
||||
- do not call into other components or perform orchestration.
|
||||
|
||||
Examples currently in Commons that fall under this carve-out: `Result<T>`, `ScriptParameters` and `ScriptArgs` (script-parameter shaping), `ValueFormatter` (value-to-string formatting), `DynamicJsonElement` (dynamic JSON access), `StaleTagMonitor` (a self-contained heartbeat watchdog), `OpcUaEndpointConfigSerializer` (typed↔legacy JSON conversion of a Commons value object) and `OpcUaEndpointConfigValidator` (rule checks over a Commons value object). These are intentionally placed in Commons so every consuming component shares one implementation rather than duplicating the logic. Anything that would require an I/O dependency, mutable cross-call state, or knowledge of another component's behavior does **not** qualify and must live in the owning component.
|
||||
|
||||
### REQ-COM-7: Minimal Dependencies
|
||||
|
||||
|
||||
Reference in New Issue
Block a user