Files
scadalink-design/Component-Commons.md
2026-03-16 07:39:26 -04:00

143 lines
8.7 KiB
Markdown

# Component: Commons
## Purpose
The Commons component provides the shared foundation of data types, interfaces, enums, message contracts, data transfer objects, and persistence-ignorant domain entity classes used across all other ScadaLink components. It ensures consistent type definitions for cross-component communication, data access, and eliminates duplication of common abstractions.
## Location
Referenced by all component libraries and the Host.
## Responsibilities
- Define shared data types (enums, value objects, result types) used across multiple components.
- Define **persistence-ignorant domain entity classes** (POCOs) representing all configuration database entities. These classes have no dependency on Entity Framework or any persistence framework — EF mapping is handled entirely by the Configuration Database component via Fluent API.
- Define **per-component repository interfaces** that consuming components use for data access. Repository implementations are owned by the Configuration Database component.
- Define protocol abstraction interfaces for the Data Connection Layer.
- Define cross-component message contracts and DTOs for deployment, health, communication, instance lifecycle, and other inter-component data flows.
- Contain **no business logic** — only data structures, interfaces, and enums.
- Maintain **minimal dependencies** — only core .NET libraries; no Akka.NET, no ASP.NET, no Entity Framework.
---
## Requirements
### REQ-COM-1: Shared Data Type System
Commons must define shared primitive and utility types used across multiple components, including but not limited to:
- **`DataType` enum**: Enumerates the data types supported by the system (e.g., Boolean, Int32, Float, Double, String, DateTime, Binary).
- **`RetryPolicy`**: A record or immutable class describing retry behavior (max retries, fixed delay between retries).
- **`Result<T>`**: A discriminated result type that represents either a success value or an error, enabling consistent error handling across component boundaries without exceptions.
- **`InstanceState` enum**: Enabled, Disabled.
- **`DeploymentStatus` enum**: Pending, InProgress, Success, Failed.
- **`AlarmState` enum**: Active, Normal.
- **`AlarmTriggerType` enum**: ValueMatch, RangeViolation, RateOfChange.
- **`ConnectionHealth` enum**: Connected, Disconnected, Connecting, Error.
Types defined here must be immutable and thread-safe.
### REQ-COM-2: Protocol Abstraction
Commons must define the protocol abstraction interfaces that the Data Connection Layer implements and other components consume:
- **`IDataConnection`**: The common interface for reading, writing, and subscribing to device data regardless of the underlying protocol (OPC UA, custom legacy, etc.).
- **Related types**: Tag identifiers, read/write results, subscription callbacks, connection status enums, and quality codes.
These interfaces must not reference any specific protocol implementation.
### REQ-COM-3: Domain Entity Classes (POCOs)
Commons must define persistence-ignorant POCO entity classes for all configuration database entities. These classes:
- Are plain C# classes with properties — no EF attributes, no base classes from EF, no navigation property annotations.
- May include navigation properties (e.g., `Template.Attributes` as `ICollection<TemplateAttribute>`) defined as plain collections. The Configuration Database component configures the relationships via Fluent API.
- May include constructors that enforce invariants (e.g., required fields).
- Must have **no dependency** on Entity Framework Core or any persistence library.
Entity classes are organized by domain area:
- **Template & Modeling**: `Template`, `TemplateAttribute`, `TemplateAlarm`, `TemplateScript`, `TemplateComposition`, `Instance`, `InstanceAttributeOverride`, `InstanceConnectionBinding`, `Area`.
- **Shared Scripts**: `SharedScript`.
- **Sites & Data Connections**: `Site`, `DataConnection`, `SiteDataConnectionAssignment`.
- **External Systems & Database Connections**: `ExternalSystemDefinition`, `ExternalSystemMethod`, `DatabaseConnectionDefinition`.
- **Notifications**: `NotificationList`, `NotificationRecipient`, `SmtpConfiguration`.
- **Inbound API**: `ApiKey`, `ApiMethod`.
- **Security**: `LdapGroupMapping`, `SiteScopeRule`.
- **Deployment**: `DeploymentRecord`, `SystemArtifactDeploymentRecord`.
- **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.
- `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.
- `ICentralUiRepository` — Read-oriented queries spanning multiple domain areas for display purposes.
All repository interfaces must:
- Accept and return the POCO entity classes defined in Commons.
- Include a `SaveChangesAsync()` method (or equivalent) to support unit-of-work commit.
- Have **no dependency** on Entity Framework Core — they are pure interfaces.
Implementations of these interfaces are owned by the Configuration Database component.
### REQ-COM-4a: Cross-Cutting Service Interfaces
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.
### REQ-COM-5: Cross-Component Message Contracts
Commons must define the shared DTOs and message contracts used for inter-component communication, including:
- **Deployment DTOs**: Configuration snapshots, deployment commands, deployment status, validation results.
- **Instance Lifecycle DTOs**: Disable, enable, delete commands and responses.
- **Health DTOs**: Health check results, site status reports, heartbeat messages. Includes script error rates and alarm evaluation error rates.
- **Communication DTOs**: Site identity, connection state, routing metadata.
- **Attribute Stream DTOs**: Attribute value change messages (instance name, attribute path, value, quality, timestamp) and alarm state change messages (instance name, alarm name, state, priority, timestamp) for the site-wide Akka stream.
- **Debug View DTOs**: Subscribe/unsubscribe requests, initial snapshot, stream filter criteria.
- **Script Execution DTOs**: Script call requests (with recursion depth), return values, error results.
- **System-Wide Artifact DTOs**: Shared script packages, external system definitions, database connection definitions, notification list definitions.
All message types must be `record` types or immutable classes suitable for use as Akka.NET messages (though Commons itself must not depend on Akka.NET).
### REQ-COM-6: No Business Logic
Commons must contain only:
- Data structures (records, classes, structs)
- Interfaces
- Enums
- Constants
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).
### REQ-COM-7: Minimal Dependencies
Commons must depend only on core .NET libraries (`System.*`, `Microsoft.Extensions.Primitives` if needed). It must **not** reference:
- Akka.NET or any Akka.* packages
- ASP.NET Core or any Microsoft.AspNetCore.* packages
- Entity Framework Core or any Microsoft.EntityFrameworkCore.* packages
- Any third-party libraries requiring paid licenses
This ensures Commons can be referenced by all components without introducing transitive dependency conflicts.
---
## Dependencies
- **None** — only core .NET SDK.
## Interactions
- **All component libraries**: Reference Commons for shared types, interfaces, entity classes, and contracts.
- **Configuration Database**: Implements the repository interfaces defined in Commons. Maps the POCO entity classes to the database via EF Core Fluent API.
- **Host**: References Commons transitively through the component libraries.