docs(components): verification pass — fix cross-link targets, tag code fences, correct type names

- Fix 15 link-text/target mismatches (ConfigurationDatabase ×8 to Commons,
  NotificationOutbox ×4, ClusterInfrastructure case, HealthMonitoring,
  SiteCallAudit) caught by a link-text-vs-target consistency check.
- Tag 14 untagged code-fence openers (ASCII diagrams/trees, JSON, HTTP).
- Correct 4 type names to match source (ValidationService, HealthReportSender,
  CentralCommunicationActor, DebugSnapshotCommand set).
- Soften Traefik version prose per the style guide.
This commit is contained in:
Joseph Doherty
2026-06-03 16:09:06 -04:00
parent a26f4a5f81
commit 66f0f96328
16 changed files with 36 additions and 36 deletions
+4 -4
View File
@@ -202,7 +202,7 @@ The management URL is resolved in this order: `--url` flag → `SCADABRIDGE_MANA
### No management URL
```
```json
{"error":"No management URL specified. Use --url, set SCADABRIDGE_MANAGEMENT_URL, or add 'managementUrl' to ~/.scadabridge/config.json.","code":"NO_URL"}
```
@@ -210,7 +210,7 @@ The URL is not set via `--url`, `SCADABRIDGE_MANAGEMENT_URL`, or the config file
### Connection failed
```
```json
{"error":"Connection failed: Connection refused (localhost:9000)","code":"CONNECTION_FAILED"}
```
@@ -222,7 +222,7 @@ The server returned HTTP 403 or an error code of `FORBIDDEN`/`UNAUTHORIZED`. The
### Malformed config file warning
```
```text
warning: ignoring malformed or unreadable /home/user/.scadabridge/config.json: ...
```
@@ -230,7 +230,7 @@ warning: ignoring malformed or unreadable /home/user/.scadabridge/config.json: .
### `audit-log` deprecation warning
```
```text
Warning: 'audit-log' is deprecated and will be removed in a future release. Use 'audit-config' instead.
```
+1 -1
View File
@@ -176,7 +176,7 @@ The same keys are accepted by `GET /api/centralui/audit/export` for filtered CSV
- [Configuration Database (#17)](./ConfigurationDatabase.md) — all central CRUD (templates, instances, sites, external systems, notifications, audit log, etc.) via scoped EF Core repositories (`ICentralUiRepository`, `IAuditLogRepository`, `ISiteRepository`, `ITemplateEngineRepository`, and others). The Data Protection keys that make sessions portable across failover are also stored here.
- [Communication (#5)](./Communication.md) — `CommunicationService` for cross-site commands (deploy, disable, enable, delete, browse OPC UA nodes, read tag values); `DebugStreamService` for gRPC-backed debug stream sessions; KPI request/response messages for Notification Outbox and Site Calls KPIs.
- [Deployment Manager (#2)](./DeploymentManager.md) — `IDeploymentStatusNotifier` for real-time deployment status push; deployment command routing.
- [Template Engine (#1)](./TemplateEngine.md) — `TemplateService`, `TemplateFolderService`, `TemplateValidationService` for template authoring, on-demand validation, and diff calculation.
- [Template Engine (#1)](./TemplateEngine.md) — `TemplateService`, `TemplateFolderService`, `ValidationService` for template authoring, on-demand validation, and diff calculation.
- [Health Monitoring (#11)](./HealthMonitoring.md) — `ICentralHealthAggregator` for in-memory site health state on the Health Dashboard and audit backlog KPI tile.
- [Audit Log (#23)](./AuditLog.md) — `IAuditLogRepository` (via `AuditLogQueryService`) for the Audit Log page query/drilldown/export; `IAuditLogQueryService.GetKpiSnapshotAsync` for the three Audit KPI tiles on the Health Dashboard.
- [Notification Outbox (#21)](./NotificationOutbox.md) — Notification Report page queries and Retry/Discard actions; Notification KPI tiles on the Health Dashboard.
+1 -1
View File
@@ -256,7 +256,7 @@ This returns `false` while the actor system is warming up — the safe-by-defaul
- [Site Runtime (#3)](./SiteRuntime.md) — the Deployment Manager singleton is the most operationally critical singleton this infrastructure hosts. It re-creates the full Instance Actor hierarchy from local SQLite on failover. Staggered Instance Actor startup after failover is Site Runtime's responsibility; this component provides the singleton placement guarantee.
- [Notification Outbox (#21)](./NotificationOutbox.md), [Site Call Audit (#22)](./SiteCallAudit.md), [Audit Log (#23)](./AuditLog.md) — each hosts one or more central singletons wired by `RegisterCentralActors`. Cluster Infrastructure provides the `ClusterSingletonManager`/`ClusterSingletonProxy` boilerplate and the graceful-shutdown hooks; the business logic lives in the owning component.
- [CentralSite Communication (#5)](./Communication.md) — `CentralCommunicationActor` and `SiteCommunicationActor` are created and registered with `ClusterClientReceptionist` inside the same `AkkaHostedService` startup, making them addressable by remote `ClusterClient` instances. The transport-level heartbeat (`TransportHeartbeatInterval`, `TransportFailureThreshold`) is configured separately from the cluster failure-detector and comes from `CommunicationOptions`.
- [Inbound API (#14)](./InboundApi.md) — resolves `IActiveNodeGate` to return HTTP 503 on standby central nodes. Gate returns `false` until the actor system is `Up` and this node is the cluster leader.
- [Inbound API (#14)](./InboundAPI.md) — resolves `IActiveNodeGate` to return HTTP 503 on standby central nodes. Gate returns `false` until the actor system is `Up` and this node is the cluster leader.
- Design spec: [Component-ClusterInfrastructure.md](../requirements/Component-ClusterInfrastructure.md).
## Troubleshooting
+1 -1
View File
@@ -56,7 +56,7 @@ Commons may contain stateless, side-effect-free helper types that transform or v
### Namespace and folder structure
```
```text
ZB.MOM.WW.ScadaBridge.Commons/
├── Types/ # Enums/, Alarms/, Audit/, DataConnections/,
│ # Flattening/, InboundApi/, Notifications/,
+1 -1
View File
@@ -259,7 +259,7 @@ After a site node failover, the `DebugStreamBridgeActor` attempts to reconnect t
### Heartbeats arrive but health reports do not
`SiteCommunicationActor` sends heartbeats and health reports via separate paths. Health reports are sent only when the site's `SiteHealthReportActor` publishes them (every 30 s by default). If heartbeats arrive but reports do not, the health reporting actor on the site may have faulted — check site-side logs for errors in `SiteHealthReportActor`.
`SiteCommunicationActor` sends heartbeats and health reports via separate paths. Health reports are sent only when the site's `HealthReportSender` publishes them (every 30 s by default). If heartbeats arrive but reports do not, the health-report sender on the site may have faulted — check site-side logs for errors in `HealthReportSender`.
## Related Documentation
+8 -8
View File
@@ -212,16 +212,16 @@ The `SCADABRIDGE_DESIGNTIME_CONNECTIONSTRING` environment variable is an alterna
- [Commons (#16)](./Commons.md) — all POCO entity classes (`Templates`, `Instances`, `Sites`, `AuditLogEntry`, `SiteCall`, …) and all repository interfaces (`ITemplateEngineRepository`, `IDeploymentManagerRepository`, `ISecurityRepository`, `IInboundApiRepository`, `IExternalSystemRepository`, `INotificationRepository`, `INotificationOutboxRepository`, `ISiteCallAuditRepository`, `IAuditLogRepository`, `ICentralUiRepository`) live there. Commons also declares `IAuditService`, `IAuditCorrelationContext`, `IPartitionMaintenance`, and `IInstanceLocator` — all implemented here.
- [Audit Log (#23)](./AuditLog.md) — `IAuditLogRepository` (implemented by `AuditLogRepository`) is the sole central write path for `dbo.AuditLog`. `AuditLogIngestActor`, `CentralAuditWriter`, and `SiteAuditReconciliationActor` all resolve it from a fresh per-message DI scope; the Audit Log component hosts the `AuditLogPartitionMaintenanceService` and `AuditLogPurgeActor` that drive the `IPartitionMaintenance` implementation registered here.
- [Template Engine (#1)](./Commons.md) — consumes `ITemplateEngineRepository` for all template, attribute, alarm, native alarm source, script, composition, instance, override, connection binding, and area operations.
- [Deployment Manager (#2)](./Commons.md) — consumes `IDeploymentManagerRepository` for deployment records and configuration snapshots.
- [Security & Auth (#10)](./Commons.md) — consumes `ISecurityRepository` for LDAP group mappings and site scoping rules.
- [Inbound API (#14)](./Commons.md) — consumes `IInboundApiRepository` for API method definitions.
- [External System Gateway (#7)](./Commons.md) — consumes `IExternalSystemRepository` for external system and database connection definitions.
- [Notification Service (#8)](./Commons.md) — consumes `INotificationRepository` for notification lists, recipients, and SMTP configuration.
- [Template Engine (#1)](./TemplateEngine.md) — consumes `ITemplateEngineRepository` for all template, attribute, alarm, native alarm source, script, composition, instance, override, connection binding, and area operations.
- [Deployment Manager (#2)](./DeploymentManager.md) — consumes `IDeploymentManagerRepository` for deployment records and configuration snapshots.
- [Security & Auth (#10)](./Security.md) — consumes `ISecurityRepository` for LDAP group mappings and site scoping rules.
- [Inbound API (#14)](./InboundAPI.md) — consumes `IInboundApiRepository` for API method definitions.
- [External System Gateway (#7)](./ExternalSystemGateway.md) — consumes `IExternalSystemRepository` for external system and database connection definitions.
- [Notification Service (#8)](./NotificationService.md) — consumes `INotificationRepository` for notification lists, recipients, and SMTP configuration.
- [Notification Outbox (#21)](./NotificationOutbox.md) — consumes `INotificationOutboxRepository` for `dbo.Notifications` ingest, dispatcher polling, status transitions, KPI queries, and bulk purge of terminal rows.
- [Site Call Audit (#22)](./SiteCallAudit.md) — consumes `ISiteCallAuditRepository` for `dbo.SiteCalls` ingest, KPI queries, and bulk purge of terminal rows.
- [Central UI (#9)](./Commons.md) — consumes `ICentralUiRepository` for read-oriented cross-domain queries and the configuration audit log viewer.
- [Host (#15)](./Commons.md) — provides the connection string, calls `AddConfigurationDatabase`, and invokes `MigrationHelper.ApplyOrValidateMigrationsAsync` at startup.
- [Central UI (#9)](./CentralUI.md) — consumes `ICentralUiRepository` for read-oriented cross-domain queries and the configuration audit log viewer.
- [Host (#15)](./Host.md) — provides the connection string, calls `AddConfigurationDatabase`, and invokes `MigrationHelper.ApplyOrValidateMigrationsAsync` at startup.
- All central components that modify configuration state — call `IAuditService.LogAsync()` and then `SaveChangesAsync()` so audit entries commit atomically with entity changes.
- Design spec: [Component-ConfigurationDatabase.md](../requirements/Component-ConfigurationDatabase.md)
+1 -1
View File
@@ -45,7 +45,7 @@ Adding a new protocol requires implementing `IDataConnection` (and optionally `I
### Actor hierarchy
```
```text
DataConnectionManagerActor (one per site; child of DeploymentManagerActor)
├── DataConnectionActor "OpcSrv1" (one per configured connection)
├── DataConnectionActor "Gateway2"
+1 -1
View File
@@ -151,7 +151,7 @@ The offline-check cadence is derived at runtime as `min(OfflineTimeout, CentralO
- [Store-and-Forward Engine (#6)](./StoreAndForward.md) — `HealthReportSender` queries `StoreAndForwardStorage` for `GetParkedMessageCountAsync` and `GetBufferDepthByCategoryAsync`; the results populate `ParkedMessageCount` and `StoreAndForwardBufferDepths` (keyed by `StoreAndForwardCategory` name).
- [Cluster Infrastructure (#13)](./ClusterInfrastructure.md) — `IClusterNodeProvider` supplies cluster node list and `SelfIsPrimary` flag to both `HealthReportSender` and `CentralHealthReportLoop`. Heartbeat cadence (default 5 s) is owned by Cluster Infrastructure / `SiteCommunicationActor`.
- [Audit Log (#23)](./AuditLog.md) — `AddAuditLogHealthMetricsBridge` wires `HealthMetricsAuditWriteFailureCounter` and `HealthMetricsAuditRedactionFailureCounter` into the site collector, and registers `SiteAuditBacklogReporter` to poll the site-local SQLite drain backlog. On central, `AuditCentralHealthSnapshot` exposes `CentralAuditWriteFailures`, `AuditRedactionFailure`, and per-site `SiteAuditTelemetryStalled` alongside the aggregated site states on the health dashboard.
- [Central UI (#9)](./Host.md) — the health dashboard resolves `ICentralHealthAggregator` and polls `GetAllSiteStates()` on a ~10 s timer. Notification Outbox and Site Call Audit KPIs are computed on demand from their own central tables by those components; Health Monitoring does not own or cache them.
- [Central UI (#9)](./CentralUI.md) — the health dashboard resolves `ICentralHealthAggregator` and polls `GetAllSiteStates()` on a ~10 s timer. Notification Outbox and Site Call Audit KPIs are computed on demand from their own central tables by those components; Health Monitoring does not own or cache them.
- [Host (#15)](./Host.md) — implements `ISiteIdentityProvider` (supplies `SiteId` for report payloads) and `IClusterNodeProvider`, and calls the appropriate `Add*` entry points from the role-specific composition root.
## Troubleshooting
+2 -2
View File
@@ -63,7 +63,7 @@ Parameter and return field definitions share the same six-type vocabulary:
### Request pipeline
```
```text
POST /api/{methodName}
├─ AuditWriteMiddleware ← mints ExecutionId; buffers bodies; emits audit row in finally
@@ -241,7 +241,7 @@ The inbound body-capture cap for audit is configured separately under `AuditLog:
- [Commons (#16)](./Commons.md) — owns `ApiMethod`, `ParameterDefinition`, `ScriptParameters`, `ScriptParameterException`, the `RouteToCall*` / `RouteToGetAttributes*` / `RouteToSetAttributes*` message records, `IInboundApiRepository`, and `IInstanceLocator`. Also owns `ICentralAuditWriter` (via `ZB.MOM.WW.Audit`), `AuditChannel`, `AuditKind`, `AuditStatus`, and `ScadaBridgeAuditEventFactory`.
- [Configuration Database (#17)](./ConfigurationDatabase.md) — provides the `IInboundApiRepository` implementation (`GetMethodByNameAsync`, `GetAllApiMethodsAsync`, CRUD). Method definitions persist in the central MS SQL configuration database.
- [CentralSite Communication (#5)](./Communication.md) — `CommunicationServiceInstanceRouter` delegates every `Route.To()` operation to `CommunicationService`. The routed call travels from the central `CommunicationActor` to the target site via `ClusterClient`, reaches the target `InstanceActor`, and a `ScriptExecutionActor` executes the named script. The return value flows back synchronously.
- [CentralSite Communication (#5)](./Communication.md) — `CommunicationServiceInstanceRouter` delegates every `Route.To()` operation to `CommunicationService`. The routed call travels from the central `CentralCommunicationActor` to the target site via `ClusterClient`, reaches the target `InstanceActor`, and a `ScriptExecutionActor` executes the named script. The return value flows back synchronously.
- [Audit Log (#23)](./AuditLog.md) — `AuditWriteMiddleware` resolves `ICentralAuditWriter` to emit the `ApiInbound` row via the central direct-write path. The inbound request is the parent execution for any site script it spawns: the middleware's `ExecutionId` becomes `RouteToCallRequest.ParentExecutionId` on every routed `Call`. Cross-link: `AuditWriteMiddleware.InboundExecutionIdItemKey` / `AuditWriteMiddleware.AuditActorItemKey` are the `HttpContext.Items` keys that tie the endpoint handler and middleware together.
- [Security (#10)](./Security.md) — API key verification (`IApiKeyVerifier`, `AddZbApiKeyAuth`) is registered by the Host. The inbound API uses a dedicated key scheme independent of LDAP/AD session auth.
- [Cluster Infrastructure (#13)](./ClusterInfrastructure.md) — `IActiveNodeGate` (interface in this project; implementation in the Host) gates the endpoint to the active central node. A standby returns `503` without running any script logic.
+3 -3
View File
@@ -141,7 +141,7 @@ Both endpoints apply the same HTTP Basic Auth / LDAP / role flow as `/management
The CLI sends a single `POST /management` with JSON body and Basic Auth; it does not use `ClusterClient` directly. A typical request:
```
```http
POST /management
Authorization: Basic base64(username:password)
Content-Type: application/json
@@ -178,7 +178,7 @@ The `ManagementActor` is also reachable from any `ClusterClient` that has a cont
| Security | `ListRoleMappings`, `CreateRoleMapping`, `UpdateRoleMapping`, `DeleteRoleMapping`, `ListApiKeys`, `CreateApiKey`, `UpdateApiKey`, `DeleteApiKey`, `SetApiKeyMethods`, `ListScopeRules`, `AddScopeRule`, `DeleteScopeRule` | Administrator |
| Deployments | `MgmtDeployArtifacts`, `QueryDeployments`, `GetDeploymentDiff` | Deployer |
| Health | `GetHealthSummary`, `GetSiteHealth` | Any authenticated user |
| Remote queries | `QueryEventLogs`, `QueryParkedMessages`, `RetryParkedMessage`, `DiscardParkedMessage`, `DebugSnapshot` | Deployer |
| Remote queries | `QueryEventLogsCommand`, `QueryParkedMessagesCommand`, `RetryParkedMessageCommand`, `DiscardParkedMessageCommand`, `DebugSnapshotCommand` | Deployer |
| Audit (legacy) | `QueryAuditLog` | Administrator |
| Transport | `ExportBundle` (Designer), `PreviewBundle`, `ImportBundle` (Administrator) | Varies |
@@ -200,7 +200,7 @@ The 200 MB per-request body cap (`ManagementEndpoints.MaxManagementRequestBodyBy
- [Configuration Database (#17)](./ConfigurationDatabase.md) — every repository (`ITemplateEngineRepository`, `ISiteRepository`, `IExternalSystemRepository`, `INotificationRepository`, `ISecurityRepository`, `IInboundApiRepository`, `IDeploymentManagerRepository`, `ICentralUiRepository`) and `IAuditService` are backed by EF Core against the central MS SQL database. Management Service resolves them per-command through scoped DI.
- [Template Engine (#1)](./TemplateEngine.md) — `TemplateService`, `TemplateFolderService`, `SharedScriptService`, and the `ValidationService` handle template authoring and validation. Management Service is the sole entry point for template mutations from outside the Central UI.
- [Deployment Manager (#2)](./DeploymentManager.md) — `DeploymentService` and `ArtifactDeploymentService` own the deployment pipeline. `MgmtDeployInstance` and `MgmtDeployArtifacts` delegate here.
- [CentralSite Communication (#5)](./Communication.md) — `CommunicationService` routes `QueryEventLogs`, `QueryParkedMessages`, `RetryParkedMessage`, `DiscardParkedMessage`, and `DebugSnapshot` to site actors via `ClusterClient`. Deployment commands also flow through the communication layer.
- [CentralSite Communication (#5)](./Communication.md) — `CommunicationService` routes `QueryEventLogsCommand`, `QueryParkedMessagesCommand`, `RetryParkedMessageCommand`, `DiscardParkedMessageCommand`, and `DebugSnapshotCommand` to site actors via `ClusterClient`. Deployment commands also flow through the communication layer.
- [Security & Auth (#10)](./Security.md) — `ILdapAuthService` and `RoleMapper` authenticate and map roles on every HTTP request; the `Roles` constants and `IInboundApiKeyAdmin` are also consumed here.
- [Health Monitoring (#11)](./HealthMonitoring.md) — `ICentralHealthAggregator` answers `GetHealthSummary` and `GetSiteHealth` queries synchronously from its in-memory state.
- [Audit Log (#23)](./AuditLog.md) — `AuditEndpoints` reads the central `AuditLog` table via `IAuditLogRepository` directly (no actor hop). `QueryAuditLogCommand` through `/management` is a legacy path for the configuration-change audit via `ICentralUiRepository`.
+4 -4
View File
@@ -220,12 +220,12 @@ Delivery retry policy (`MaxRetries`, `RetryDelay`) is read at runtime from `Smtp
- [Commons (#16)](./Commons.md) — owns `Notification`, `NotificationStatus`, `NotificationType`, `INotificationOutboxRepository`, `INotificationRepository`, and all message contracts (`NotificationSubmit`, `NotificationSubmitAck`, `NotificationStatusQuery`, `NotificationKpiRequest`, and their responses). Also owns `ScadaBridgeAuditEventFactory` and the `AuditChannel`/`AuditKind`/`AuditStatus` enums used to build dispatch audit rows.
- [Configuration Database (#17)](./ConfigurationDatabase.md) — registers the scoped `INotificationOutboxRepository` (the central `dbo.Notifications` table) and `INotificationRepository` (notification-list, recipient, and SMTP configuration tables). Central hosts must call `AddConfigurationDatabase` before `AddNotificationOutbox`.
- [Notification Service (#8)](./StoreAndForward.md) — supplies `ISmtpClientWrapper`, `OAuth2TokenService`, `NotificationOptions`, `SmtpTlsModeParser`, `SmtpErrorClassifier`, and the `SmtpPermanentException` type. `AddNotificationOutbox` relies on `AddNotificationService` being called by the Host to register these shared SMTP primitives; registering them twice would duplicate them.
- [Notification Service (#8)](./NotificationService.md) — supplies `ISmtpClientWrapper`, `OAuth2TokenService`, `NotificationOptions`, `SmtpTlsModeParser`, `SmtpErrorClassifier`, and the `SmtpPermanentException` type. `AddNotificationOutbox` relies on `AddNotificationService` being called by the Host to register these shared SMTP primitives; registering them twice would duplicate them.
- [CentralSite Communication (#5)](./Communication.md) — carries `NotificationSubmit` / `NotificationSubmitAck` between sites and central via ClusterClient, and `NotificationStatusQuery` / `NotificationStatusResponse` for the `Notify.Status` round-trip.
- [Store-and-Forward Engine (#6)](./StoreAndForward.md) — the site-side component that durably buffers notifications in SQLite and retries forwarding until central acks. The outbox is the receiving end of the S&F handoff.
- [Audit Log (#23)](./AuditLog.md) — the outbox is a central direct-write caller of `ICentralAuditWriter`. It emits `NotifyDeliver` rows (Attempted + terminal) per delivery attempt and per operator Discard. The upstream `NotifySend` row is emitted by the site and arrives at central via standard audit telemetry.
- [Health Monitoring (#11)](./Host.md) — polls `NotificationKpiRequest` / `PerSiteNotificationKpiRequest` for the headline KPI tiles on the health dashboard (queue depth, stuck count, parked count). These are central-computed from the `Notifications` table and are separate from the site S&F backlog metric.
- [Central UI (#9)](./Host.md) — hosts the Notification Outbox page: KPI tiles, a queryable/filterable notification list, per-row Retry/Discard actions on parked notifications, and a stuck-row badge.
- [Health Monitoring (#11)](./HealthMonitoring.md) — polls `NotificationKpiRequest` / `PerSiteNotificationKpiRequest` for the headline KPI tiles on the health dashboard (queue depth, stuck count, parked count). These are central-computed from the `Notifications` table and are separate from the site S&F backlog metric.
- [Central UI (#9)](./CentralUI.md) — hosts the Notification Outbox page: KPI tiles, a queryable/filterable notification list, per-row Retry/Discard actions on parked notifications, and a stuck-row badge.
## Troubleshooting
@@ -257,4 +257,4 @@ A central failover while a delivery attempt is in flight leaves the row in its p
- [Configuration Database](./ConfigurationDatabase.md)
- [CentralSite Communication](./Communication.md)
- [Store-and-Forward Engine](./StoreAndForward.md)
- [Health Monitoring](./Host.md)
- [Health Monitoring](./HealthMonitoring.md)
+3 -3
View File
@@ -20,7 +20,7 @@ The Notification Outbox (#21) ingests notifications and dispatches them centrall
The `SiteCalls` table holds one row per `TrackedOperationId`. `ISiteCallAuditRepository.UpsertAsync` implements insert-if-not-exists followed by a conditional update that only applies when the incoming status has a strictly higher rank than the stored status:
```
```text
Submitted=0, Forwarded=1, Attempted=2, Skipped=2,
Delivered=3, Failed=3, Parked=3, Discarded=3
```
@@ -119,7 +119,7 @@ Unlike the `AuditLog` table, `SiteCalls` is a standard non-partitioned table on
### Status lifecycle
```
```text
Submitted → Forwarded → Attempted ──→ Delivered (terminal, success)
└──→ Parked (non-terminal, awaiting operator action)
└──→ Failed (terminal, permanent failure)
@@ -221,7 +221,7 @@ Registration is via `ServiceCollectionExtensions.AddSiteCallAudit`, which binds
- [CentralSite Communication (#5)](./Communication.md) — the `CentralCommunicationActor` is the transport the relay handlers use. It is registered via `RegisterCentralCommunication` by the Host after both actors are running. `CommunicationService` also provides the async wrappers (`RetrySiteCallAsync`, `DiscardSiteCallAsync`) that the Central UI calls; those methods Ask the `SiteCallAuditActor` with the outer `CommunicationOptions.QueryTimeout`.
- [Store-and-Forward Engine (#6)](./StoreAndForward.md) — site-side executor of `RetryParkedOperation` and `DiscardParkedOperation`. The site's S&F buffer is the source of truth for parked cached calls; it emits updated telemetry after applying an operator action.
- [Health Monitoring (#11)](./HealthMonitoring.md) — consumes `SiteCallKpiResponse` / `PerSiteSiteCallKpiResponse` to surface buffered count, parked count, stuck count, and throughput KPI tiles on the health dashboard alongside the Notification Outbox tiles.
- [Central UI (#9)](./Host.md) — the Site Calls page queries this actor for the paginated list, detail modal, and KPIs; it issues Retry/Discard actions that flow through `CommunicationService` to the relay handlers here.
- [Central UI (#9)](./CentralUI.md) — the Site Calls page queries this actor for the paginated list, detail modal, and KPIs; it issues Retry/Discard actions that flow through `CommunicationService` to the relay handlers here.
- [Cluster Infrastructure (#13)](./ClusterInfrastructure.md) — hosts the `SiteCallAuditActor` singleton with active/standby failover via `ClusterSingletonManager`.
## Troubleshooting
+1 -1
View File
@@ -58,7 +58,7 @@ All in-memory state mutations (attribute values, qualities, alarm states) run in
### Actor hierarchy
```
```text
DeploymentManagerActor (Akka.NET cluster singleton)
└── InstanceActor "MachineA-001"
├── ScriptActor "MonitorSpeed" (coordinator)
+1 -1
View File
@@ -112,7 +112,7 @@ Template edits use **last-write-wins** — there is no optimistic concurrency to
### Service map
```
```text
AddTemplateEngine()
├── TemplateService (scoped) — template + member CRUD, collision/acyclicity pre-checks
├── SharedScriptService (scoped) — system-wide shared script CRUD + syntax validation
+3 -3
View File
@@ -4,7 +4,7 @@ The Traefik Proxy is the reverse proxy and load balancer that fronts the central
## Overview
The proxy runs as the `scadabridge-traefik` Docker container in the main compose stack (`docker/docker-compose.yml`). It is a third-party infrastructure component (Traefik v3.4) — there is no C# project for it. Its entire configuration is two YAML files mounted read-only into the container:
The proxy runs as the `scadabridge-traefik` Docker container in the main compose stack (`docker/docker-compose.yml`). It is a third-party infrastructure component (Traefik; the image tag is pinned in `docker/docker-compose.yml`) — there is no C# project for it. Its entire configuration is two YAML files mounted read-only into the container:
- `docker/traefik/traefik.yml` — static config: entrypoints, API dashboard, and file provider declaration.
- `docker/traefik/dynamic.yml` — routing rules: the router that catches all traffic, the `central` load-balancer service listing both backend nodes, and the `/health/active` health-check settings.
@@ -47,13 +47,13 @@ When the active central node goes down, the Akka cluster's keep-oldest split-bra
### Docker topology
```
```text
Clients (CLI, browser, external API)
host:9000 (HTTP)
┌───────▼──────────────────┐
│ scadabridge-traefik │ (Traefik v3.4 container)
│ scadabridge-traefik │ (Traefik container)
│ entrypoint :80 │
└──────┬──────────┬─────────┘
│ /health/active poll (5s)
+1 -1
View File
@@ -18,7 +18,7 @@ The single DI entry point is `ServiceCollectionExtensions.AddTransport`, registe
A `.scadabundle` file is a ZIP archive with exactly two entries:
```
```text
bundle.scadabundle
├── manifest.json # always plaintext; never encrypted
└── content.json # plaintext artifact data (no passphrase)