diff --git a/Component-Host.md b/Component-Host.md index c24d187..3f79ba5 100644 --- a/Component-Host.md +++ b/Component-Host.md @@ -39,11 +39,37 @@ Components not applicable to the current role must not be registered in the DI c ### REQ-HOST-3: Configuration Binding -The Host must bind configuration sections from `appsettings.json` to strongly-typed options classes using the .NET Options pattern: +The Host must bind configuration sections from `appsettings.json` to strongly-typed options classes using the .NET **Options pattern** (`IOptions` / `IOptionsSnapshot`). Each component has its own configuration section under `ScadaLink`, mapped to a dedicated configuration class owned by that component. -- `ScadaLink:Node` section bound to `NodeConfiguration` (Role, NodeHostname, SiteId, RemotingPort). -- `ScadaLink:Cluster` section bound to `ClusterConfiguration` (SeedNodes, SplitBrainResolverStrategy, StableAfter). -- `ScadaLink:Database` section bound to `DatabaseConfiguration` (Central: ConfigurationDb, MachineDataDb connection strings; Site: SQLite paths). +#### Infrastructure Sections + +| Section | Options Class | Owner | Contents | +|---------|--------------|-------|----------| +| `ScadaLink:Node` | `NodeOptions` | Host | Role, NodeHostname, SiteId, RemotingPort | +| `ScadaLink:Cluster` | `ClusterOptions` | ClusterInfrastructure | SeedNodes, SplitBrainResolverStrategy, StableAfter, HeartbeatInterval, FailureDetectionThreshold, MinNrOfMembers | +| `ScadaLink:Database` | `DatabaseOptions` | Host | Central: ConfigurationDb, MachineDataDb connection strings; Site: SQLite paths | + +#### Per-Component Sections + +| Section | Options Class | Owner | Contents | +|---------|--------------|-------|----------| +| `ScadaLink:DataConnection` | `DataConnectionOptions` | Data Connection Layer | ReconnectInterval, TagResolutionRetryInterval, WriteTimeout | +| `ScadaLink:StoreAndForward` | `StoreAndForwardOptions` | Store-and-Forward | SqliteDbPath, ReplicationEnabled | +| `ScadaLink:HealthMonitoring` | `HealthMonitoringOptions` | Health Monitoring | ReportInterval, OfflineTimeout | +| `ScadaLink:SiteEventLog` | `SiteEventLogOptions` | Site Event Logging | RetentionDays, MaxStorageMb, PurgeScheduleCron | +| `ScadaLink:Communication` | `CommunicationOptions` | Communication | DeploymentTimeout, LifecycleTimeout, QueryTimeout, TransportHeartbeatInterval, TransportFailureThreshold | +| `ScadaLink:Security` | `SecurityOptions` | Security & Auth | LdapServer, LdapPort, LdapUseTls, JwtSigningKey, JwtExpiryMinutes, IdleTimeoutMinutes | +| `ScadaLink:InboundApi` | `InboundApiOptions` | Inbound API | DefaultMethodTimeout | +| `ScadaLink:Notification` | `NotificationOptions` | Notification Service | (SMTP config is stored in config DB and deployed to sites, not in appsettings) | +| `ScadaLink:Logging` | `LoggingOptions` | Host | Serilog sink configuration, log level overrides | + +#### Convention + +- Each component defines its own options class (e.g., `DataConnectionOptions`) in its own project. The class is a plain POCO with properties matching the JSON section keys. +- The Host binds each section during startup via `services.Configure(configuration.GetSection("ScadaLink:"))`. +- Each component's `AddXxx()` extension method accepts `IServiceCollection` and reads its options via `IOptions` — the component never reads `IConfiguration` directly. +- Options classes live in the component project, not in Commons, because they are component-specific configuration — not shared contracts. +- Startup validation (REQ-HOST-4) validates all required options before the actor system starts. ### REQ-HOST-4: Startup Validation