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

8.7 KiB

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.