# 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`**: 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`) 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-5a: Message Contract Versioning Since the system supports cross-site artifact version skew (sites may temporarily run different versions), message contracts must follow **additive-only evolution rules**: - New fields may be added with default values. Existing fields must not be removed or have their types changed. - Serialization must tolerate unknown fields (forward compatibility) and missing optional fields (backward compatibility). - Breaking changes require a new message type and a coordinated deployment to all nodes. - The Akka.NET serialization binding configuration (in the Host component) must explicitly map message types to serializers to prevent accidental binary serialization. ### 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.