diff --git a/README.md b/README.md index 76058b35..b75ef691 100644 --- a/README.md +++ b/README.md @@ -110,102 +110,10 @@ Both stacks share the infrastructure services in [`infra/`](infra/) (MS SQL, LDA ### Architecture Diagram (Logical) -``` - Users (Blazor Server) - │ - Load Balancer - │ -┌────────────────────────┼────────────────────────────┐ -│ CENTRAL CLUSTER │ -│ (2-node active/standby) │ -│ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ Template │ │Deployment│ │ Central │ │ -│ │ Engine │ │ Manager │ │ UI │ Blazor Svr │ -│ └──────────┘ └──────────┘ └──────────┘ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ Security │ │ Config │ │ Health │ │ -│ │ & Auth │ │ DB │ │ Monitor │ │ -│ │ (JWT/LDAP)│ │ (EF+IAud)│ │ │ │ -│ └──────────┘ └──────────┘ └──────────┘ │ -│ ┌──────────┐ │ -│ │ Inbound │ ◄── External Systems (X-API-Key) │ -│ │ API │ POST /api/{method}, JSON │ -│ └──────────┘ │ -│ ┌──────────┐ │ -│ │ Mgmt │ ◄── CLI (ClusterClient) │ -│ │ Service │ ManagementActor + Receptionist │ -│ └──────────┘ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ Ntf │ │ Site │ │ Audit │ Observ. / │ -│ │ Outbox │ │ Call │ │ Log │ Audit area │ -│ │ (#21) │ │ Audit │ │ (#23) │ │ -│ │ │ │ (#22) │ │ │ │ -│ └────▲─────┘ └────▲─────┘ └────▲─────┘ │ -│ │ ingests │ ingests │ ingests │ -│ │ (S&F) │ (telemetry)│ (telemetry + │ -│ │ │ │ direct-write │ -│ │ │ │ from Ntf Outbox │ -│ │ │ │ & Inbound API) │ -│ ┌───────────────────────────────────┐ │ -│ │ Akka.NET Communication Layer │ │ -│ │ ClusterClient: command/control │ │ -│ │ gRPC Client: real-time streams │ │ -│ │ (correlation IDs, per-pattern │ │ -│ │ timeouts, message ordering) │ │ -│ └──────────────┬────────────────────┘ │ -│ ┌──────────────┴────────────────────┐ │ -│ │ Configuration Database (EF) │──► MS SQL │ -│ └───────────────────────────────────┘ (Config DB)│ -│ │ Machine Data DB│ -└─────────────────┼───────────────────────────────────┘ - │ Akka.NET Remoting (command/control) - │ gRPC HTTP/2 (real-time data, port 8083) - ┌────────────┼────────────┐ - ▼ ▼ ▼ -┌─────────┐ ┌─────────┐ ┌─────────┐ -│ SITE A │ │ SITE B │ │ SITE N │ -│ (2-node)│ │ (2-node)│ │ (2-node)│ -│ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ -│ │Data │ │ │ │Data │ │ │ │Data │ │ -│ │Conn │ │ │ │Conn │ │ │ │Conn │ │ -│ │Layer │ │ │ │Layer │ │ │ │Layer │ │ -│ ├─────┤ │ │ ├─────┤ │ │ ├─────┤ │ -│ │Site │ │ │ │Site │ │ │ │Site │ │ -│ │Runtm│ │ │ │Runtm│ │ │ │Runtm│ │ -│ ├─────┤ │ │ ├─────┤ │ │ ├─────┤ │ -│ │gRPC │ │ │ │gRPC │ │ │ │gRPC │ │ -│ │Srvr │ │ │ │Srvr │ │ │ │Srvr │ │ -│ ├─────┤ │ │ ├─────┤ │ │ ├─────┤ │ -│ │S&F │ │ │ │S&F │ │ │ │S&F │ │ -│ │Engine│ │ │ │Engine│ │ │ │Engine│ │ -│ ├─────┤ │ │ ├─────┤ │ │ ├─────┤ │ -│ │ExtSys│ │ │ │ExtSys│ │ │ │ExtSys│ │ -│ │Gatwy │ │ │ │Gatwy │ │ │ │Gatwy │ │ -│ └─────┘ │ │ └─────┘ │ │ └─────┘ │ -│ SQLite │ │ SQLite │ │ SQLite │ -└─────────┘ └─────────┘ └─────────┘ - │ │ │ - OPC UA / OPC UA / OPC UA / - Custom Custom Custom - Protocol Protocol Protocol -``` +![Logical architecture](diagrams/architecture-logical.png) + ### Site Runtime Actor Hierarchy -``` -Deployment Manager Singleton (Cluster Singleton) -├── Instance Actor (one per deployed, enabled instance) -│ ├── Script Actor (coordinator, one per instance script) -│ │ └── Script Execution Actor (short-lived, per invocation) -│ ├── Alarm Actor (coordinator, one per alarm definition) -│ │ └── Alarm Execution Actor (short-lived, per on-trigger invocation) -│ └── ... (more Script/Alarm Actors) -├── Instance Actor -│ └── ... -└── ... (more Instance Actors) - -Site-Wide Akka Stream (attribute + alarm state changes) -├── All Instance Actors publish to the stream -└── Debug view subscribes with instance-level filtering -``` +![Site runtime actor hierarchy](diagrams/site-runtime-actor-hierarchy.png) + diff --git a/diagrams/architecture-logical.drawio b/diagrams/architecture-logical.drawio new file mode 100644 index 00000000..d7f39cad --- /dev/null +++ b/diagrams/architecture-logical.drawio @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/diagrams/architecture-logical.png b/diagrams/architecture-logical.png new file mode 100644 index 00000000..d47bf636 Binary files /dev/null and b/diagrams/architecture-logical.png differ diff --git a/diagrams/site-runtime-actor-hierarchy.drawio b/diagrams/site-runtime-actor-hierarchy.drawio new file mode 100644 index 00000000..e2da42a3 --- /dev/null +++ b/diagrams/site-runtime-actor-hierarchy.drawio @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/diagrams/site-runtime-actor-hierarchy.png b/diagrams/site-runtime-actor-hierarchy.png new file mode 100644 index 00000000..1159aa07 Binary files /dev/null and b/diagrams/site-runtime-actor-hierarchy.png differ diff --git a/docs/deployment/diagrams/topology-architecture-overview.drawio b/docs/deployment/diagrams/topology-architecture-overview.drawio new file mode 100644 index 00000000..5b923205 --- /dev/null +++ b/docs/deployment/diagrams/topology-architecture-overview.drawio @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/deployment/diagrams/topology-architecture-overview.png b/docs/deployment/diagrams/topology-architecture-overview.png new file mode 100644 index 00000000..85163317 Binary files /dev/null and b/docs/deployment/diagrams/topology-architecture-overview.png differ diff --git a/docs/deployment/topology-guide.md b/docs/deployment/topology-guide.md index 3dff1941..4452ed7f 100644 --- a/docs/deployment/topology-guide.md +++ b/docs/deployment/topology-guide.md @@ -6,24 +6,8 @@ ScadaBridge uses a hub-and-spoke architecture: - **Central Cluster**: Two-node active/standby Akka.NET cluster for management, UI, and coordination. - **Site Clusters**: Two-node active/standby Akka.NET clusters at each remote site for data collection and local processing. -``` - ┌──────────────────────────┐ - │ Central Cluster │ - │ ┌──────┐ ┌──────┐ │ - Users ──────────► │ │Node A│◄──►│Node B│ │ - (HTTPS/LB) │ │Active│ │Stby │ │ - │ └──┬───┘ └──┬───┘ │ - └─────┼───────────┼────────┘ - │ │ - ┌───────────┼───────────┼───────────┐ - │ │ │ │ - ┌─────▼─────┐ ┌──▼──────┐ ┌──▼──────┐ ┌──▼──────┐ - │ Site 01 │ │ Site 02 │ │ Site 03 │ │ Site N │ - │ ┌──┐ ┌──┐ │ │ ┌──┐┌──┐│ │ ┌──┐┌──┐│ │ ┌──┐┌──┐│ - │ │A │ │B │ │ │ │A ││B ││ │ │A ││B ││ │ │A ││B ││ - │ └──┘ └──┘ │ │ └──┘└──┘│ │ └──┘└──┘│ │ └──┘└──┘│ - └───────────┘ └─────────┘ └─────────┘ └─────────┘ -``` +![topology-architecture-overview](diagrams/topology-architecture-overview.png) + ## Central Cluster Setup diff --git a/docs/plans/2026-03-22-primary-backup-data-connections-design.md b/docs/plans/2026-03-22-primary-backup-data-connections-design.md index b59b76e7..a921da38 100644 --- a/docs/plans/2026-03-22-primary-backup-data-connections-design.md +++ b/docs/plans/2026-03-22-primary-backup-data-connections-design.md @@ -39,28 +39,8 @@ Both endpoints use the same `Protocol`. EF Core migration renames `Configuration The `DataConnectionActor` Reconnecting state is extended: -``` -Connected - │ disconnect detected - ▼ -Push bad quality to all subscribers - │ - ▼ -Retry active endpoint (5s interval) - │ failure - ▼ -_consecutiveFailures++ - │ - ├─ < FailoverRetryCount → retry same endpoint - │ - ├─ ≥ FailoverRetryCount AND backup exists - │ → dispose adapter, switch _activeEndpoint, reset counter - │ → create fresh adapter with other config - │ → attempt connect - │ - └─ ≥ FailoverRetryCount AND no backup - → keep retrying indefinitely (current behavior) -``` +![primary-backup-failover-state-machine](diagrams/primary-backup-failover-state-machine.png) + **On successful reconnect (either endpoint):** 1. Reset `_consecutiveFailures = 0` diff --git a/docs/plans/2026-05-12-opcua-config-model-design.md b/docs/plans/2026-05-12-opcua-config-model-design.md index 3551385b..aa877234 100644 --- a/docs/plans/2026-05-12-opcua-config-model-design.md +++ b/docs/plans/2026-05-12-opcua-config-model-design.md @@ -32,34 +32,8 @@ We want a strongly-typed model for OPC UA endpoint configuration, a validator th ## Architecture -``` -┌──────────────────────────────────────┐ -│ ZB.MOM.WW.ScadaBridge.Commons │ -│ Types/DataConnections/ │ -│ OpcUaEndpointConfig.cs (POCO) │ -│ OpcUaHeartbeatConfig.cs (POCO) │ -│ OpcUaSecurityMode.cs (enum) │ -│ Validators/ │ -│ OpcUaEndpointConfigValidator.cs │ -│ Serialization/ │ -│ OpcUaEndpointConfigSerializer.cs │ -└──────────────────────────────────────┘ - ▲ - │ (referenced by both) - ┌───────┴────────────────────────┐ - ▼ ▼ -┌──────────────────────────┐ ┌────────────────────────────┐ -│ ZB.MOM.WW.ScadaBridge.CentralUI │ │ ZB.MOM.WW.ScadaBridge.SiteRuntime │ -│ Components/Forms/ │ │ Actors/ │ -│ OpcUaEndpointEditor │ │ DeploymentManagerActor │ -│ .razor (shared) │ │ (passes raw JSON to │ -│ │ │ DataConnectionFactory)│ -│ Pages/Admin/ │ │ │ -│ DataConnectionForm │ │ DataConnections.OpcUa/ │ -│ .razor │ │ OpcUaDataConnection.cs │ -└──────────────────────────┘ │ (consumes typed model) │ - └────────────────────────────┘ -``` +![opcua-config-model-architecture](diagrams/opcua-config-model-architecture.png) + Both sides deserialize from `DataConnection.PrimaryConfiguration` / `BackupConfiguration` strings into the same `OpcUaEndpointConfig` instance. The DB column type does not change. diff --git a/docs/plans/2026-05-24-second-environment-design.md b/docs/plans/2026-05-24-second-environment-design.md index 5de231f4..24e23814 100644 --- a/docs/plans/2026-05-24-second-environment-design.md +++ b/docs/plans/2026-05-24-second-environment-design.md @@ -17,29 +17,8 @@ A sibling `docker-env2/` directory with `deploy.sh` / `teardown.sh` / `seed-site ## Architecture Overview -``` - (host machine) - - Primary stack (already existing — unchanged) Env2 stack (new) - ┌────────────────────────────────────┐ ┌──────────────────────────────┐ - │ Traefik :9000 ◄── 9001/9002 UI │ │ Traefik :9100 ◄── 9101/9102 UI│ - │ Central A/B (9011/9012 Akka) │ │ Central A/B (9111/9112 Akka) │ - │ Site-A/B/C (9021..9044) │ │ Site-X (9121/9122 Akka, │ - └─────────────┬──────────────────────┘ │ 9123/9124 gRPC) │ - │ └──────────┬───────────────────┘ - │ │ - ▼ scadabridge-net (shared bridge network) ◄──────┘ - ┌──────────────────────────────────────────────────────────────┐ - │ scadabridge-mssql ScadaBridgeConfig (primary DB) │ - │ ScadaBridgeMachineData (primary DB) │ - │ ScadaBridgeConfig2 (env2 DB) ← new │ - │ ScadaBridgeMachineData2(env2 DB) ← new │ - │ scadabridge-ldap (shared — same test users) │ - │ scadabridge-smtp (shared Mailpit) │ - │ scadabridge-opcua (shared) │ - │ scadabridge-restapi (shared) │ - └──────────────────────────────────────────────────────────────┘ -``` +![env2-architecture-overview](diagrams/env2-architecture-overview.png) + Both stacks attach to the same `scadabridge-net` Docker bridge so env2's app containers can reach the infra services by container hostname (`scadabridge-mssql`, `scadabridge-ldap`, etc.). Akka clusters are independent — each side's `SeedNodes` lists only its own central nodes, so they never gossip-merge despite sharing the network. diff --git a/docs/plans/2026-05-24-second-environment.md b/docs/plans/2026-05-24-second-environment.md index c06ccdeb..ac99d799 100644 --- a/docs/plans/2026-05-24-second-environment.md +++ b/docs/plans/2026-05-24-second-environment.md @@ -14,19 +14,8 @@ ## Task Dependency Graph -``` -T0 ─┐ ┐ -T1 ─┤ (all independent, all │ -T2 ─┤ parallelizable, all ├─► T10 (manual smoke test) -T3 ─┤ ready from the start) │ -T4 ─┤ │ -T6 ─┤ │ -T7 ─┤ │ -T8 ─┤ │ -T9 ─┘ │ - │ -T0,T4 ──► T5 (lifecycle scripts) ─────────┘ -``` +![env2-task-dependency-graph](diagrams/env2-task-dependency-graph.png) + T10 is the only task that requires all of T0–T9 done. Everything else can run in parallel. diff --git a/docs/plans/2026-05-28-opcua-tag-browser-design.md b/docs/plans/2026-05-28-opcua-tag-browser-design.md index 36bfbb21..32b23eec 100644 --- a/docs/plans/2026-05-28-opcua-tag-browser-design.md +++ b/docs/plans/2026-05-28-opcua-tag-browser-design.md @@ -18,27 +18,8 @@ ## Section 1 — Architecture -``` -[Blazor Server browser] - │ SignalR - ▼ -[CentralUI: InstanceConfigure.razor] - │ opens - ▼ -[CentralUI: ] - │ uses - ▼ -[CentralUI: IOpcUaBrowseService] ── implementation calls - │ - ▼ -[CommunicationService.SendCommandToSiteAsync(siteId, BrowseOpcUaNodeCommand)] - │ ClusterClient Ask, ManagementEnvelope { User, Command, CorrelationId } - ▼ -[Site: CentralCommunicationActor → DataConnectionManagerActor] - │ dispatches to IBrowsableDataConnection (RealOpcUaClient) - ▼ -[OPC UA server] ◄── OPC Foundation .NET SDK Browse service -``` +![opcua-tag-browser-architecture](diagrams/opcua-tag-browser-architecture.png) + Three slices, top-to-bottom: 1. **Data model.** Add a per-instance OPC UA address override (new column on `InstanceConnectionBinding`). @@ -164,25 +145,8 @@ Returning failure inside `BrowseOpcUaNodeResult` (rather than exceptions across **Wire flow.** -``` -CentralUI.OpcUaBrowseService.BrowseChildrenAsync(siteId, connId, parent) - → CommunicationService.SendCommandToSiteAsync( - siteId, - new BrowseOpcUaNodeCommand(connId, parent)) - → ManagementEnvelope { User, Command, CorrelationId } over ClusterClient - → Site: CentralCommunicationActor unwraps envelope - → Site: DataConnectionManagerActor receives BrowseOpcUaNodeCommand - - Look up IDataConnection by Id - - if not found → ConnectionNotFound - - if !(conn is IBrowsableDataConnection) → NotBrowsable - - else await conn.BrowseChildrenAsync(ParentNodeId, ct) - - Catch ConnectionNotConnectedException → ConnectionNotConnected - - Catch OperationCanceledException → Timeout - - Catch ServiceResultException → ServerError + verbatim msg - - Else success: BrowseOpcUaNodeResult(children, truncated, null) - → Reply travels back via CentralCommunicationActor → CommunicationService - → returned to CentralUI page -``` +![opcua-tag-browser-command-flow](diagrams/opcua-tag-browser-command-flow.png) + Handler lives in the **DCL coordinator actor** (the same actor that owns the per-connection `IDataConnection` instances) — keeps lifecycle and browse co-located so we don't race against reconnect. diff --git a/docs/plans/2026-05-29-native-alarms.md b/docs/plans/2026-05-29-native-alarms.md index 42267222..ae6038ac 100644 --- a/docs/plans/2026-05-29-native-alarms.md +++ b/docs/plans/2026-05-29-native-alarms.md @@ -16,23 +16,8 @@ ## Task dependency overview -``` -T1 ─┬─ T2 ─┬─ T17 (computed AlarmActor enrich) - │ ├─ T18 (proto) ── T19 (grpc mapping) ── T23 (DebugView) -T3 ─┼─ T10 (DCL actor) - ├─ T11 (OPC UA adapter) - └─ T12 (MxGateway adapter) -T4 ─┬─ T5 ── T6 ── T21 (mgmt handlers) - ├─ T7 (migration) - ├─ T8 ── T9 (validation) - └─ T20 ─┬─ T21 ── T26 (seed) - ├─ T22 (CLI) - ├─ T24 (template UI) - └─ T25 (instance UI) -T13, T14 ──┐ -T1,T2,T3,T4(Resolved),T13,T14 ── T15 (NativeAlarmActor) ── T16 (InstanceActor wiring) -(everything) ── T27 (docs) , T28 (integration/manual verify) -``` +![native-alarms-task-dependency](diagrams/native-alarms-task-dependency.png) + --- diff --git a/docs/plans/diagrams/env2-architecture-overview.drawio b/docs/plans/diagrams/env2-architecture-overview.drawio new file mode 100644 index 00000000..d593ae81 --- /dev/null +++ b/docs/plans/diagrams/env2-architecture-overview.drawio @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/env2-architecture-overview.png b/docs/plans/diagrams/env2-architecture-overview.png new file mode 100644 index 00000000..b013cbf2 Binary files /dev/null and b/docs/plans/diagrams/env2-architecture-overview.png differ diff --git a/docs/plans/diagrams/env2-task-dependency-graph.drawio b/docs/plans/diagrams/env2-task-dependency-graph.drawio new file mode 100644 index 00000000..b6ec6e99 --- /dev/null +++ b/docs/plans/diagrams/env2-task-dependency-graph.drawio @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/env2-task-dependency-graph.png b/docs/plans/diagrams/env2-task-dependency-graph.png new file mode 100644 index 00000000..37efac82 Binary files /dev/null and b/docs/plans/diagrams/env2-task-dependency-graph.png differ diff --git a/docs/plans/diagrams/generate-plans-per-work-package.drawio b/docs/plans/diagrams/generate-plans-per-work-package.drawio new file mode 100644 index 00000000..a6cc5f76 --- /dev/null +++ b/docs/plans/diagrams/generate-plans-per-work-package.drawio @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/generate-plans-per-work-package.png b/docs/plans/diagrams/generate-plans-per-work-package.png new file mode 100644 index 00000000..bfcf4fce Binary files /dev/null and b/docs/plans/diagrams/generate-plans-per-work-package.png differ diff --git a/docs/plans/diagrams/grpc-channel-bridging.drawio b/docs/plans/diagrams/grpc-channel-bridging.drawio new file mode 100644 index 00000000..23f1aafc --- /dev/null +++ b/docs/plans/diagrams/grpc-channel-bridging.drawio @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/grpc-channel-bridging.png b/docs/plans/diagrams/grpc-channel-bridging.png new file mode 100644 index 00000000..42280836 Binary files /dev/null and b/docs/plans/diagrams/grpc-channel-bridging.png differ diff --git a/docs/plans/diagrams/grpc-reconnection-state-machine.drawio b/docs/plans/diagrams/grpc-reconnection-state-machine.drawio new file mode 100644 index 00000000..6393b5f8 --- /dev/null +++ b/docs/plans/diagrams/grpc-reconnection-state-machine.drawio @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/grpc-reconnection-state-machine.png b/docs/plans/diagrams/grpc-reconnection-state-machine.png new file mode 100644 index 00000000..578abe3c Binary files /dev/null and b/docs/plans/diagrams/grpc-reconnection-state-machine.png differ diff --git a/docs/plans/diagrams/grpc-streams-architecture.drawio b/docs/plans/diagrams/grpc-streams-architecture.drawio new file mode 100644 index 00000000..a18bba91 --- /dev/null +++ b/docs/plans/diagrams/grpc-streams-architecture.drawio @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/grpc-streams-architecture.png b/docs/plans/diagrams/grpc-streams-architecture.png new file mode 100644 index 00000000..3a5d663f Binary files /dev/null and b/docs/plans/diagrams/grpc-streams-architecture.png differ diff --git a/docs/plans/diagrams/native-alarms-task-dependency.drawio b/docs/plans/diagrams/native-alarms-task-dependency.drawio new file mode 100644 index 00000000..45780879 --- /dev/null +++ b/docs/plans/diagrams/native-alarms-task-dependency.drawio @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/native-alarms-task-dependency.png b/docs/plans/diagrams/native-alarms-task-dependency.png new file mode 100644 index 00000000..636dc69a Binary files /dev/null and b/docs/plans/diagrams/native-alarms-task-dependency.png differ diff --git a/docs/plans/diagrams/opcua-config-model-architecture.drawio b/docs/plans/diagrams/opcua-config-model-architecture.drawio new file mode 100644 index 00000000..950d9533 --- /dev/null +++ b/docs/plans/diagrams/opcua-config-model-architecture.drawio @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/opcua-config-model-architecture.png b/docs/plans/diagrams/opcua-config-model-architecture.png new file mode 100644 index 00000000..d9041018 Binary files /dev/null and b/docs/plans/diagrams/opcua-config-model-architecture.png differ diff --git a/docs/plans/diagrams/opcua-tag-browser-architecture.drawio b/docs/plans/diagrams/opcua-tag-browser-architecture.drawio new file mode 100644 index 00000000..c65b5d98 --- /dev/null +++ b/docs/plans/diagrams/opcua-tag-browser-architecture.drawio @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/opcua-tag-browser-architecture.png b/docs/plans/diagrams/opcua-tag-browser-architecture.png new file mode 100644 index 00000000..98328236 Binary files /dev/null and b/docs/plans/diagrams/opcua-tag-browser-architecture.png differ diff --git a/docs/plans/diagrams/opcua-tag-browser-command-flow.drawio b/docs/plans/diagrams/opcua-tag-browser-command-flow.drawio new file mode 100644 index 00000000..b8a4b9a7 --- /dev/null +++ b/docs/plans/diagrams/opcua-tag-browser-command-flow.drawio @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/opcua-tag-browser-command-flow.png b/docs/plans/diagrams/opcua-tag-browser-command-flow.png new file mode 100644 index 00000000..257e51c3 Binary files /dev/null and b/docs/plans/diagrams/opcua-tag-browser-command-flow.png differ diff --git a/docs/plans/diagrams/primary-backup-failover-state-machine.drawio b/docs/plans/diagrams/primary-backup-failover-state-machine.drawio new file mode 100644 index 00000000..d22bcacc --- /dev/null +++ b/docs/plans/diagrams/primary-backup-failover-state-machine.drawio @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/plans/diagrams/primary-backup-failover-state-machine.png b/docs/plans/diagrams/primary-backup-failover-state-machine.png new file mode 100644 index 00000000..32088bfb Binary files /dev/null and b/docs/plans/diagrams/primary-backup-failover-state-machine.png differ diff --git a/docs/plans/generate_plans.md b/docs/plans/generate_plans.md index 33c96365..582defeb 100644 --- a/docs/plans/generate_plans.md +++ b/docs/plans/generate_plans.md @@ -547,27 +547,8 @@ This section governs how implementation plans are executed. The goal is autonomo For each work package, follow this sequence: -``` -┌─────────────────────────────────────────────────────┐ -│ 1. READ the WP description and acceptance criteria │ -│ 2. READ all traced requirements (HLR bullets, KDD, │ -│ CD constraints) to understand intent │ -│ 3. IMPLEMENT the WP │ -│ - Write code │ -│ - Write unit tests for acceptance criteria │ -│ - Write negative tests for prohibition criteria │ -│ 4. VERIFY acceptance criteria │ -│ - Run tests: all must pass │ -│ - Walk each acceptance criterion line by line │ -│ - If a criterion cannot be verified yet (depends │ -│ on a later WP), note it as "deferred to WP-N" │ -│ 5. UPDATE the phase execution checklist │ -│ - Mark WP as complete with date │ -│ - Note any deferred criteria │ -│ - Note any questions logged │ -│ 6. COMMIT with message: "Phase N WP-M: " │ -└─────────────────────────────────────────────────────┘ -``` +![generate-plans-per-work-package](diagrams/generate-plans-per-work-package.png) + ### Mid-Phase Compliance Check diff --git a/docs/plans/grpc_streams.md b/docs/plans/grpc_streams.md index d4668eea..31a60a07 100644 --- a/docs/plans/grpc_streams.md +++ b/docs/plans/grpc_streams.md @@ -23,29 +23,8 @@ gRPC server-streaming is an established pattern for real-time tag value updates; ## Architecture -``` -Central Cluster Site Cluster -───────────── ──────────── - -DebugStreamBridgeActor InstanceActor - │ │ - │── SubscribeDebugView ──► │ (ClusterClient: command/control) - │◄── DebugViewSnapshot ── │ - │ │ - │ │ publishes AttributeValueChanged - │ │ publishes AlarmStateChanged - │ ▼ -SiteStreamGrpcClient ◄──── gRPC stream ───── SiteStreamGrpcServer - (per-site, on central) (HTTP/2) (Kestrel, on site) - │ │ - │ reads from gRPC stream │ receives from SiteStreamManager - │ routes by correlationId │ filters by instance name - ▼ │ -DebugStreamBridgeActor │ - │ │ - ▼ │ -SignalR Hub / Blazor UI │ -``` +![grpc-streams-architecture](diagrams/grpc-streams-architecture.png) + **Key separation**: ClusterClient handles subscribe/unsubscribe/snapshot (request-response). gRPC handles the ongoing value stream (server-streaming). @@ -271,17 +250,8 @@ public override async Task SubscribeInstance( `IServerStreamWriter` is **not thread-safe**. Multiple Akka actors may publish events concurrently. The `Channel` bridges these worlds: -``` -Akka Actor Thread(s) gRPC Response Stream - │ ▲ - │ channel.Writer.TryWrite(evt) │ await responseStream.WriteAsync(evt) - ▼ │ - ┌─────────────────────────────────────────┐ - │ Channel │ - │ BoundedChannelOptions(1000) │ - │ FullMode = DropOldest │ - └─────────────────────────────────────────┘ -``` +![grpc-channel-bridging](diagrams/grpc-channel-bridging.png) + - **Bounded capacity** (1000): prevents unbounded memory growth if the gRPC client is slow - **DropOldest**: matches the existing `SiteStreamManager` overflow strategy @@ -431,32 +401,8 @@ private void HandleGrpcStreamError(Exception ex) ### Reconnection State Machine (DebugStreamBridgeActor) -``` - ┌──────────────────┐ - │ Streaming │ ◄── Normal state: gRPC stream active - └────────┬─────────┘ - │ gRPC stream error / keepalive timeout - ▼ - ┌──────────────────┐ - ┌──► │ Reconnecting │ ── try other node endpoint - │ └────────┬─────────┘ - │ │ - │ ┌────────┴─────────┐ - │ │ │ - │ success failure (retry < max) - │ │ │ - │ ▼ │ - │ Streaming schedule retry (5s backoff) - │ │ - └───────────────────────┘ - │ - failure (retry >= max) - │ - ▼ - ┌──────────────────┐ - │ Terminated │ ── notify consumer, stop actor - └──────────────────┘ -``` +![grpc-reconnection-state-machine](diagrams/grpc-reconnection-state-machine.png) + ### Summary diff --git a/docs/requirements/Component-Communication.md b/docs/requirements/Component-Communication.md index d2dfb7d5..452bcd3f 100644 --- a/docs/requirements/Component-Communication.md +++ b/docs/requirements/Component-Communication.md @@ -167,20 +167,8 @@ Keepalive settings are configurable via `CommunicationOptions`: ## Topology -``` -Central Cluster - ├── ClusterClient → Site A Cluster (SiteCommunicationActor via Receptionist) [command/control] - ├── ClusterClient → Site B Cluster (SiteCommunicationActor via Receptionist) [command/control] - └── ClusterClient → Site N Cluster (SiteCommunicationActor via Receptionist) [command/control] - │ - ├── SiteStreamGrpcClient ◄── gRPC stream ── Site A (SiteStreamGrpcServer) [real-time data] - ├── SiteStreamGrpcClient ◄── gRPC stream ── Site B (SiteStreamGrpcServer) [real-time data] - └── SiteStreamGrpcClient ◄── gRPC stream ── Site N (SiteStreamGrpcServer) [real-time data] - -Site Clusters - └── ClusterClient → Central Cluster (CentralCommunicationActor via Receptionist) [command/control] - └── SiteStreamGrpcServer (Kestrel HTTP/2, port 8083) → serves gRPC streams [real-time data] -``` +![communication-topology](diagrams/communication-topology.png) + - Sites do **not** communicate with each other. - All inter-cluster communication flows through central. diff --git a/docs/requirements/Component-ConfigurationDatabase.md b/docs/requirements/Component-ConfigurationDatabase.md index a11d83dd..61fe6e61 100644 --- a/docs/requirements/Component-ConfigurationDatabase.md +++ b/docs/requirements/Component-ConfigurationDatabase.md @@ -143,15 +143,8 @@ EF Core's DbContext naturally provides unit-of-work semantics: ### Example Transactional Flow -``` -Template Engine: Create Template - │ - ├── repository.AddTemplate(template) // template is a Commons POCO - ├── repository.AddAttributes(attributes) // attributes are Commons POCOs - ├── repository.AddAlarms(alarms) // alarms are Commons POCOs - ├── repository.AddScripts(scripts) // scripts are Commons POCOs - └── repository.SaveChangesAsync() // single transaction commits all -``` +![configdb-transactional-flow](diagrams/configdb-transactional-flow.png) + --- @@ -184,14 +177,8 @@ Audit entries are written **synchronously** within the same database transaction ### Integration Example -``` -Template Engine: Update Template - │ - ├── repository.UpdateTemplate(template) - ├── auditService.LogAsync(user, "Update", "Template", template.Id, - │ template.Name, template) - └── repository.SaveChangesAsync() ← both the change and audit entry commit together -``` +![configdb-integration-example](diagrams/configdb-integration-example.png) + ### Audit Entry Schema diff --git a/docs/requirements/Component-DataConnectionLayer.md b/docs/requirements/Component-DataConnectionLayer.md index 1f649ee7..a39aecf2 100644 --- a/docs/requirements/Component-DataConnectionLayer.md +++ b/docs/requirements/Component-DataConnectionLayer.md @@ -80,12 +80,8 @@ Data connections support an optional backup endpoint for automatic failover when **Failover state machine:** -``` -Connected → disconnect → push bad quality → retry active endpoint (5s) - → N failures (≥ FailoverRetryCount) → switch to other endpoint - → dispose adapter, create fresh adapter with other config - → reconnect → ReSubscribeAll → Connected -``` +![dcl-endpoint-redundancy](diagrams/dcl-endpoint-redundancy.png) + - **Round-robin**: primary → backup → primary → backup. No preferred endpoint after first failover — the connection stays on whichever endpoint is working. - **No auto-failback**: The connection remains on the active endpoint until it fails. diff --git a/docs/requirements/Component-DeploymentManager.md b/docs/requirements/Component-DeploymentManager.md index 8674162a..d194bdf9 100644 --- a/docs/requirements/Component-DeploymentManager.md +++ b/docs/requirements/Component-DeploymentManager.md @@ -22,24 +22,8 @@ Central cluster only. The site-side deployment responsibilities (receiving confi ## Deployment Flow -``` -Engineer (UI) → Deployment Manager (Central) - │ - ├── 1. Request validated + flattened config from Template Engine - │ (validation includes flattening, script compilation, - │ trigger references, connection binding completeness) - ├── 2. If validation fails → return errors to UI, stop - ├── 3. Send config to site via Communication Layer - │ │ - │ ▼ - │ Site Runtime (Deployment Manager Singleton) - │ ├── 4. Store new flattened config locally (SQLite) - │ ├── 5. Compile scripts at site - │ ├── 6. Create/update Instance Actor (with child Script + Alarm Actors) - │ └── 7. Report success/failure back to central - │ - └── 8. Update deployment status in config DB -``` +![deployment-flow](diagrams/deployment-flow.png) + ## Deployment Identity & Idempotency diff --git a/docs/requirements/Component-InboundAPI.md b/docs/requirements/Component-InboundAPI.md index ad089eb3..30c67aa7 100644 --- a/docs/requirements/Component-InboundAPI.md +++ b/docs/requirements/Component-InboundAPI.md @@ -123,20 +123,8 @@ API method scripts are compiled at central startup — all method definitions ar ## Request Flow -``` -External System - │ - ▼ -Inbound API (Central) - ├── 1. Extract API key from request - ├── 2. Validate key exists and is enabled - ├── 3. Resolve method by name - ├── 4. Check API key is in method's approved list - ├── 5. Validate and deserialize parameters - ├── 6. Execute implementation script (subject to method timeout) - ├── 7. Serialize return value - └── 8. Return response -``` +![inboundapi-request-flow](diagrams/inboundapi-request-flow.png) + ## Implementation Script Capabilities diff --git a/docs/requirements/Component-NotificationOutbox.md b/docs/requirements/Component-NotificationOutbox.md index 39f27132..bb5d170f 100644 --- a/docs/requirements/Component-NotificationOutbox.md +++ b/docs/requirements/Component-NotificationOutbox.md @@ -24,24 +24,8 @@ SMTP and HTTP delivery is blocking I/O. Delivery work runs on a **dedicated bloc ## End-to-End Flow -``` -Site script: Notify.To("list").Send(subject, body) - │ generate NotificationId (GUID) locally; return it to the script immediately - ▼ -Site Store-and-Forward Engine (notification category, target = central) - │ durably forwards to central via Central–Site Communication (ClusterClient); - │ buffers/retries if central is unreachable - ▼ -Central ingest: insert-if-not-exists on NotificationId → Notifications table (Pending) - │ ack the site → site S&F clears the message - ▼ -Central Notification Outbox actor (singleton, active central node) - │ polls due rows; resolves the list; delivers via the matching adapter - ├── success → Delivered - ├── transient failure → Retrying (schedule NextAttemptAt) - └── permanent failure - / retries exhausted → Parked -``` +![notificationoutbox-flow](diagrams/notificationoutbox-flow.png) + The site forwards only `(listName, subject, body)` plus provenance — recipient resolution happens at central, at delivery time. This keeps notification-list definitions in one place and removes the deploy-to-sites artifact entirely. diff --git a/docs/requirements/Component-SiteRuntime.md b/docs/requirements/Component-SiteRuntime.md index be8efc7d..a4f717e5 100644 --- a/docs/requirements/Component-SiteRuntime.md +++ b/docs/requirements/Component-SiteRuntime.md @@ -27,21 +27,8 @@ Site clusters only. ## Actor Hierarchy -``` -Deployment Manager Singleton (Cluster Singleton) -├── Instance Actor ("MachineA-001") -│ ├── Script Actor ("MonitorSpeed") — coordinator -│ │ └── Script Execution Actor — short-lived, per invocation -│ ├── Script Actor ("CalculateOEE") — coordinator -│ │ └── Script Execution Actor — short-lived, per invocation -│ ├── Alarm Actor ("OverTemp") — coordinator (computed) -│ │ └── Alarm Execution Actor — short-lived, per on-trigger invocation -│ ├── Alarm Actor ("LowPressure") — coordinator (computed) -│ └── Native Alarm Actor ("OpcUaServer1") — read-only mirror, peer to Alarm Actor -├── Instance Actor ("MachineA-002") -│ └── ... -└── ... -``` +![siteruntime-actor-hierarchy](diagrams/siteruntime-actor-hierarchy.png) + --- diff --git a/docs/requirements/Component-StoreAndForward.md b/docs/requirements/Component-StoreAndForward.md index aaacbaab..4b6fa379 100644 --- a/docs/requirements/Component-StoreAndForward.md +++ b/docs/requirements/Component-StoreAndForward.md @@ -25,23 +25,8 @@ Site clusters only. The central cluster does not buffer messages. ## Message Lifecycle -``` -Script submits message - │ - ▼ -Attempt immediate delivery - │ - ├── Success → Remove from buffer - │ - └── Failure → Buffer message - │ - ▼ - Retry loop (per retry policy) - │ - ├── Success → Remove from buffer + notify standby - │ - └── Max retries exhausted → Park message -``` +![storeforward-message-lifecycle](diagrams/storeforward-message-lifecycle.png) + For notifications, "delivery" means forwarding the message to the central cluster via Central–Site Communication; "success" is central's ack, on which the message is cleared. Notifications are retried at the fixed forward interval until central acks, but — like every other category — they are bounded by the engine's `DefaultMaxRetries` cap: a sustained central outage that exceeds `DefaultMaxRetries × forward-interval` will park the buffered notification, after which an operator can Retry/Discard it via the parked-message UI. Operationally, the cap is sized so the normal central-recovery window stays well inside it; "do not park" is the design's operational intent on the happy path, not an absolute invariant. Callers that genuinely require unbounded retry pass `maxRetries: 0` on `EnqueueAsync` (the documented "no limit" escape hatch — see `StoreAndForward-015`). diff --git a/docs/requirements/Component-Transport.md b/docs/requirements/Component-Transport.md index bf48c791..fd4dc4de 100644 --- a/docs/requirements/Component-Transport.md +++ b/docs/requirements/Component-Transport.md @@ -92,20 +92,8 @@ The manifest is plaintext so the import wizard can preview bundle contents and s ## Architecture -``` -ZB.MOM.WW.ScadaBridge.Transport -├── IBundleExporter -│ ExportAsync(ExportSelection, Passphrase?, ct) → Stream -├── IBundleImporter -│ LoadAsync(stream, Passphrase?, ct) → BundleSession -│ PreviewAsync(sessionId, ct) → ImportPreview -│ ApplyAsync(sessionId, resolutions, ct) → ImportResult -├── DependencyResolver -├── BundleSerializer (manifest + content JSON; ZIP packer) -├── BundleSecretEncryptor (AES-256-GCM + PBKDF2) -├── BundleSessionStore (in-memory, TTL'd) -└── ManifestValidator (schema/version gating, hash check) -``` +![transport-architecture](diagrams/transport-architecture.png) + The component is central-only. It is registered in `ZB.MOM.WW.ScadaBridge.Host` for central roles only, never for site roles. All persistence flows through existing audited repository interfaces in `ZB.MOM.WW.ScadaBridge.ConfigurationDatabase` — the component does not call `DbContext.SaveChangesAsync` directly. `BundleSessionStore` is in-process on the active central node (matching Blazor Server circuit affinity): 30-minute TTL, eviction on expiry, 3-strike passphrase lockout per session. @@ -132,22 +120,8 @@ The user can toggle "include all dependencies" off (with a warning that the bund ### Backend -``` -User (Design role) ─► Central UI Export wizard - │ - ▼ - IBundleExporter - │ - ├─► DependencyResolver ─► repositories (read) - ├─► EntitySerializer ─► content.json - ├─► BundleSecretEncryptor ► content.enc (if passphrase) - ├─► ManifestBuilder ─► manifest.json - ▼ - ZIP packer → temp file → browser download - │ - ▼ - IAuditService.LogAsync(BundleExported …) -``` +![transport-export-flow](diagrams/transport-export-flow.png) + Audit event: `BundleExported` — caller, artifact count, content hash, encrypted yes/no, bundle filename. @@ -179,35 +153,8 @@ Bundle references that cannot be satisfied in either the bundle or the target DB ### Backend -``` -User (Admin role) ─► uploads bundle - │ - ▼ - IBundleImporter.LoadAsync - · verify SHA-256 (manifest vs content) - · check bundleFormatVersion supported - · decrypt content.enc with passphrase (if encrypted) - · deserialize entities - · open BundleSession (30-min TTL) - │ - ▼ - PreviewAsync → diff vs target DB → ImportPreview - │ - ▼ (user reviews + resolves conflicts) - │ - ApplyAsync (single EF transaction) - · run two-tier semantic validation (minimal name scan + full SemanticValidator) - · apply resolutions (add / overwrite / skip / rename) - · upsert TemplateFolder hierarchy - · IAuditService.LogAsync(BundleImported …) - · commit - │ - ▼ - ImportResult → UI step 5 - │ - ▼ - "View on Deployments →" (existing page) -``` +![transport-import-flow](diagrams/transport-import-flow.png) + Authorization: `RequireAdmin` on both the Razor page and `IBundleImporter.*` entrypoints. diff --git a/docs/requirements/diagrams/communication-topology.drawio b/docs/requirements/diagrams/communication-topology.drawio new file mode 100644 index 00000000..e04988a8 --- /dev/null +++ b/docs/requirements/diagrams/communication-topology.drawio @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/communication-topology.png b/docs/requirements/diagrams/communication-topology.png new file mode 100644 index 00000000..1db8a2f2 Binary files /dev/null and b/docs/requirements/diagrams/communication-topology.png differ diff --git a/docs/requirements/diagrams/configdb-integration-example.drawio b/docs/requirements/diagrams/configdb-integration-example.drawio new file mode 100644 index 00000000..109c1d41 --- /dev/null +++ b/docs/requirements/diagrams/configdb-integration-example.drawio @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/configdb-integration-example.png b/docs/requirements/diagrams/configdb-integration-example.png new file mode 100644 index 00000000..08896e75 Binary files /dev/null and b/docs/requirements/diagrams/configdb-integration-example.png differ diff --git a/docs/requirements/diagrams/configdb-transactional-flow.drawio b/docs/requirements/diagrams/configdb-transactional-flow.drawio new file mode 100644 index 00000000..ca3e4c36 --- /dev/null +++ b/docs/requirements/diagrams/configdb-transactional-flow.drawio @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/configdb-transactional-flow.png b/docs/requirements/diagrams/configdb-transactional-flow.png new file mode 100644 index 00000000..473f7c58 Binary files /dev/null and b/docs/requirements/diagrams/configdb-transactional-flow.png differ diff --git a/docs/requirements/diagrams/dcl-endpoint-redundancy.drawio b/docs/requirements/diagrams/dcl-endpoint-redundancy.drawio new file mode 100644 index 00000000..6ecdc9c2 --- /dev/null +++ b/docs/requirements/diagrams/dcl-endpoint-redundancy.drawio @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/dcl-endpoint-redundancy.png b/docs/requirements/diagrams/dcl-endpoint-redundancy.png new file mode 100644 index 00000000..d9a6a574 Binary files /dev/null and b/docs/requirements/diagrams/dcl-endpoint-redundancy.png differ diff --git a/docs/requirements/diagrams/deployment-flow.drawio b/docs/requirements/diagrams/deployment-flow.drawio new file mode 100644 index 00000000..f9f72f66 --- /dev/null +++ b/docs/requirements/diagrams/deployment-flow.drawio @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/deployment-flow.png b/docs/requirements/diagrams/deployment-flow.png new file mode 100644 index 00000000..617f8b9d Binary files /dev/null and b/docs/requirements/diagrams/deployment-flow.png differ diff --git a/docs/requirements/diagrams/inboundapi-request-flow.drawio b/docs/requirements/diagrams/inboundapi-request-flow.drawio new file mode 100644 index 00000000..a6224027 --- /dev/null +++ b/docs/requirements/diagrams/inboundapi-request-flow.drawio @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/inboundapi-request-flow.png b/docs/requirements/diagrams/inboundapi-request-flow.png new file mode 100644 index 00000000..2d050a54 Binary files /dev/null and b/docs/requirements/diagrams/inboundapi-request-flow.png differ diff --git a/docs/requirements/diagrams/notificationoutbox-flow.drawio b/docs/requirements/diagrams/notificationoutbox-flow.drawio new file mode 100644 index 00000000..3c1ac72f --- /dev/null +++ b/docs/requirements/diagrams/notificationoutbox-flow.drawio @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/notificationoutbox-flow.png b/docs/requirements/diagrams/notificationoutbox-flow.png new file mode 100644 index 00000000..7d81d2d6 Binary files /dev/null and b/docs/requirements/diagrams/notificationoutbox-flow.png differ diff --git a/docs/requirements/diagrams/siteruntime-actor-hierarchy.drawio b/docs/requirements/diagrams/siteruntime-actor-hierarchy.drawio new file mode 100644 index 00000000..db10f222 --- /dev/null +++ b/docs/requirements/diagrams/siteruntime-actor-hierarchy.drawio @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/siteruntime-actor-hierarchy.png b/docs/requirements/diagrams/siteruntime-actor-hierarchy.png new file mode 100644 index 00000000..1584c20d Binary files /dev/null and b/docs/requirements/diagrams/siteruntime-actor-hierarchy.png differ diff --git a/docs/requirements/diagrams/storeforward-message-lifecycle.drawio b/docs/requirements/diagrams/storeforward-message-lifecycle.drawio new file mode 100644 index 00000000..a88c1ecb --- /dev/null +++ b/docs/requirements/diagrams/storeforward-message-lifecycle.drawio @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/storeforward-message-lifecycle.png b/docs/requirements/diagrams/storeforward-message-lifecycle.png new file mode 100644 index 00000000..835d3471 Binary files /dev/null and b/docs/requirements/diagrams/storeforward-message-lifecycle.png differ diff --git a/docs/requirements/diagrams/transport-architecture.drawio b/docs/requirements/diagrams/transport-architecture.drawio new file mode 100644 index 00000000..c767292a --- /dev/null +++ b/docs/requirements/diagrams/transport-architecture.drawio @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/transport-architecture.png b/docs/requirements/diagrams/transport-architecture.png new file mode 100644 index 00000000..dc7a9344 Binary files /dev/null and b/docs/requirements/diagrams/transport-architecture.png differ diff --git a/docs/requirements/diagrams/transport-export-flow.drawio b/docs/requirements/diagrams/transport-export-flow.drawio new file mode 100644 index 00000000..558ac422 --- /dev/null +++ b/docs/requirements/diagrams/transport-export-flow.drawio @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/transport-export-flow.png b/docs/requirements/diagrams/transport-export-flow.png new file mode 100644 index 00000000..cffaa557 Binary files /dev/null and b/docs/requirements/diagrams/transport-export-flow.png differ diff --git a/docs/requirements/diagrams/transport-import-flow.drawio b/docs/requirements/diagrams/transport-import-flow.drawio new file mode 100644 index 00000000..c0831bbb --- /dev/null +++ b/docs/requirements/diagrams/transport-import-flow.drawio @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/requirements/diagrams/transport-import-flow.png b/docs/requirements/diagrams/transport-import-flow.png new file mode 100644 index 00000000..b3646b96 Binary files /dev/null and b/docs/requirements/diagrams/transport-import-flow.png differ