docs: convert standard diagrams from draw.io PNGs to inline Mermaid
Gitea renders mermaid inline, so the flow/state/hierarchy/DAG diagrams move to text-in-markdown: auto-layout (removes the manual overlap-prone draw.io step), diffable source, no committed binaries, and a dark-text theme so labels stay legible. Keep draw.io PNGs only for the two complex bespoke diagrams (logical architecture, env2 topology) where pixel control still wins. All 24 mermaid blocks validated by rendering.
@@ -167,8 +167,55 @@ Keepalive settings are configurable via `CommunicationOptions`:
|
||||
|
||||
## Topology
|
||||
|
||||

|
||||
<!-- source: diagrams/communication-topology.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart LR
|
||||
subgraph Central["Central Cluster"]
|
||||
CCA["ClusterClient<br/>(command/control)"]
|
||||
CCB["ClusterClient<br/>(command/control)"]
|
||||
CCN["ClusterClient<br/>(command/control)"]
|
||||
GRPCC["SiteStreamGrpcClient<br/>(real-time data)"]
|
||||
end
|
||||
|
||||
subgraph SiteA["Site A Cluster"]
|
||||
SACOMM["SiteCommunicationActor<br/>(via Receptionist)"]
|
||||
SAGRPC["SiteStreamGrpcServer<br/>(Kestrel HTTP/2, port 8083)"]
|
||||
SACC["ClusterClient to Central<br/>(CentralCommunicationActor)"]
|
||||
end
|
||||
|
||||
subgraph SiteB["Site B Cluster"]
|
||||
SBCOMM["SiteCommunicationActor<br/>(via Receptionist)"]
|
||||
SBGRPC["SiteStreamGrpcServer"]
|
||||
end
|
||||
|
||||
subgraph SiteN["Site N Cluster"]
|
||||
SNCOMM["SiteCommunicationActor<br/>(via Receptionist)"]
|
||||
SNGRPC["SiteStreamGrpcServer"]
|
||||
end
|
||||
|
||||
CCA -->|command/control| SACOMM
|
||||
CCB -->|command/control| SBCOMM
|
||||
CCN -->|command/control| SNCOMM
|
||||
|
||||
SAGRPC -->|"gRPC stream (real-time data)"| GRPCC
|
||||
SBGRPC -->|gRPC stream| GRPCC
|
||||
SNGRPC -->|gRPC stream| GRPCC
|
||||
|
||||
SACC -.->|command/control| Central
|
||||
|
||||
NOTE["Sites do NOT communicate with each other.<br/>All inter-cluster communication flows through Central."]
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
classDef muted fill:#f5f5f5,stroke:#999999,color:#666666;
|
||||
class CCA,CCB,CCN,SACOMM,SACC,SBCOMM,SNCOMM dec
|
||||
class GRPCC,SAGRPC,SBGRPC,SNGRPC start
|
||||
class NOTE muted
|
||||
class Central proc
|
||||
class SiteA,SiteB,SiteN alt
|
||||
```
|
||||
|
||||
- Sites do **not** communicate with each other.
|
||||
- All inter-cluster communication flows through central.
|
||||
|
||||
@@ -143,8 +143,33 @@ EF Core's DbContext naturally provides unit-of-work semantics:
|
||||
|
||||
### Example Transactional Flow
|
||||
|
||||

|
||||
<!-- source: diagrams/configdb-transactional-flow.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
start(["Template Engine: Create Template"])
|
||||
add1["repository.AddTemplate(template)<br/>// template is a Commons POCO"]
|
||||
add2["repository.AddAttributes(attributes)<br/>// attributes are Commons POCOs"]
|
||||
add3["repository.AddAlarms(alarms)<br/>// alarms are Commons POCOs"]
|
||||
add4["repository.AddScripts(scripts)<br/>// scripts are Commons POCOs"]
|
||||
save["repository.SaveChangesAsync()<br/>// single transaction commits all"]
|
||||
db[("Configuration DB<br/>(MS SQL)")]
|
||||
|
||||
start --> add1
|
||||
add1 --> add2
|
||||
add2 --> add3
|
||||
add3 --> add4
|
||||
add4 --> save
|
||||
save -. "single transaction" .-> db
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef muted fill:#f5f5f5,stroke:#999999,color:#666666;
|
||||
class start start
|
||||
class add1,add2,add3,add4 proc
|
||||
class save dec
|
||||
class db muted
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -177,8 +202,31 @@ Audit entries are written **synchronously** within the same database transaction
|
||||
|
||||
### Integration Example
|
||||
|
||||

|
||||
<!-- source: diagrams/configdb-integration-example.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
start(["Template Engine: Update Template"])
|
||||
upd["repository.UpdateTemplate(template)"]
|
||||
audit["auditService.LogAsync(user, "Update", "Template",<br/>template.Id, template.Name, template)"]
|
||||
save["repository.SaveChangesAsync()"]
|
||||
note["both the change and audit entry<br/>commit together"]
|
||||
|
||||
start --> upd
|
||||
upd --> audit
|
||||
audit --> save
|
||||
save -.- note
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
class start start
|
||||
class upd proc
|
||||
class audit alt
|
||||
class save dec
|
||||
class note warn
|
||||
```
|
||||
|
||||
### Audit Entry Schema
|
||||
|
||||
|
||||
@@ -80,8 +80,39 @@ Data connections support an optional backup endpoint for automatic failover when
|
||||
|
||||
**Failover state machine:**
|
||||
|
||||

|
||||
<!-- source: diagrams/dcl-endpoint-redundancy.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
connected(["Connected"])
|
||||
pushbad["push bad quality"]
|
||||
retry["retry active endpoint<br/>(5s)"]
|
||||
decide{"N failures<br/>(≥ FailoverRetryCount)?"}
|
||||
switch["switch to other endpoint"]
|
||||
dispose["dispose adapter,<br/>create fresh adapter<br/>with other config"]
|
||||
reconnect["reconnect"]
|
||||
resub["ReSubscribeAll"]
|
||||
|
||||
connected -->|disconnect| pushbad
|
||||
pushbad --> retry
|
||||
retry --> decide
|
||||
decide -->|"no (retry again)"| retry
|
||||
decide -->|yes| switch
|
||||
switch --> dispose
|
||||
dispose --> reconnect
|
||||
reconnect --> resub
|
||||
resub -->|back to Connected| connected
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef bad fill:#f8cecc,stroke:#b85450,color:#111111;
|
||||
class connected start
|
||||
class pushbad bad
|
||||
class retry,reconnect,resub proc
|
||||
class decide dec
|
||||
class switch,dispose warn
|
||||
```
|
||||
|
||||
- **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.
|
||||
|
||||
@@ -22,8 +22,47 @@ Central cluster only. The site-side deployment responsibilities (receiving confi
|
||||
|
||||
## Deployment Flow
|
||||
|
||||

|
||||
<!-- source: diagrams/deployment-flow.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
engineer(["Engineer (UI)"])
|
||||
|
||||
subgraph DMC["Deployment Manager (Central)"]
|
||||
step1["1. Request validated and flattened config from Template Engine<br/>(validation: flattening, script compilation, trigger references,<br/>connection binding completeness)"]
|
||||
step2{"2. Validation fails?"}
|
||||
step2fail(["Return errors to UI, stop"])
|
||||
step3["3. Send config to site via Communication Layer"]
|
||||
step8[("8. Update deployment status in config DB")]
|
||||
end
|
||||
|
||||
subgraph SR["Site Runtime (Deployment Manager Singleton)"]
|
||||
step4[("4. Store new flattened config locally (SQLite)")]
|
||||
step5["5. Compile scripts at site"]
|
||||
step6["6. Create/update Instance Actor<br/>(with child Script + Alarm Actors)"]
|
||||
step7["7. Report success/failure back to central"]
|
||||
end
|
||||
|
||||
engineer --> step1
|
||||
step1 --> step2
|
||||
step2 -->|yes| step2fail
|
||||
step2 -->|no| step3
|
||||
step3 -->|config| step4
|
||||
step4 --> step5
|
||||
step5 --> step6
|
||||
step6 --> step7
|
||||
step7 -. "report success/failure" .-> step8
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef bad fill:#f8cecc,stroke:#b85450,color:#111111;
|
||||
class engineer start
|
||||
class step1,step5,step6,step7 dec
|
||||
class step2,step2fail bad
|
||||
class step3 dec
|
||||
class step8 proc
|
||||
class step4 start
|
||||
```
|
||||
|
||||
## Deployment Identity & Idempotency
|
||||
|
||||
|
||||
@@ -123,8 +123,41 @@ API method scripts are compiled at central startup — all method definitions ar
|
||||
|
||||
## Request Flow
|
||||
|
||||

|
||||
<!-- source: diagrams/inboundapi-request-flow.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
ext(["External System"])
|
||||
api["Inbound API (Central)"]
|
||||
s1["1. Extract API key from request"]
|
||||
s2["2. Validate key exists and is enabled"]
|
||||
s3["3. Resolve method by name"]
|
||||
s4["4. Check API key is in method's approved list"]
|
||||
s5["5. Validate and deserialize parameters"]
|
||||
s6["6. Execute implementation script<br/>(subject to method timeout)"]
|
||||
s7["7. Serialize return value"]
|
||||
s8["8. Return response"]
|
||||
|
||||
ext --> api
|
||||
api --> s1
|
||||
s1 --> s2
|
||||
s2 --> s3
|
||||
s3 --> s4
|
||||
s4 --> s5
|
||||
s5 --> s6
|
||||
s6 --> s7
|
||||
s7 --> s8
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
class ext start
|
||||
class api proc
|
||||
class s1,s2,s3,s4,s5,s7 dec
|
||||
class s6 alt
|
||||
class s8 warn
|
||||
```
|
||||
|
||||
## Implementation Script Capabilities
|
||||
|
||||
|
||||
@@ -24,8 +24,40 @@ SMTP and HTTP delivery is blocking I/O. Delivery work runs on a **dedicated bloc
|
||||
|
||||
## End-to-End Flow
|
||||
|
||||

|
||||
<!-- source: diagrams/notificationoutbox-flow.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
SCRIPT(["Site script: Notify.To('list').Send(subject, body)<br/>generate NotificationId (GUID) locally;<br/>return it to the script immediately"])
|
||||
SNF["Site Store-and-Forward Engine<br/>(notification category, target = central)<br/>durably forwards to central via Central-Site Communication<br/>(ClusterClient); buffers/retries if central is unreachable"]
|
||||
INGEST[("Central ingest: insert-if-not-exists on NotificationId<br/>to Notifications table (Pending)<br/>ack the site, site S and F clears the message")]
|
||||
OUTBOX["Central Notification Outbox actor<br/>(singleton, active central node)<br/>polls due rows; resolves the list;<br/>delivers via the matching adapter"]
|
||||
D1{Delivery outcome}
|
||||
DELIVERED(["Delivered"])
|
||||
RETRYING["Retrying<br/>(schedule NextAttemptAt)"]
|
||||
PARKED(["Parked"])
|
||||
|
||||
SCRIPT --> SNF
|
||||
SNF --> INGEST
|
||||
INGEST --> OUTBOX
|
||||
OUTBOX --> D1
|
||||
D1 -->|success| DELIVERED
|
||||
D1 -->|transient failure| RETRYING
|
||||
D1 -->|"permanent failure /<br/>retries exhausted"| PARKED
|
||||
RETRYING -.->|retry due| OUTBOX
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef bad fill:#f8cecc,stroke:#b85450,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
class SCRIPT,DELIVERED start
|
||||
class SNF warn
|
||||
class INGEST proc
|
||||
class OUTBOX alt
|
||||
class D1,RETRYING dec
|
||||
class PARKED bad
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -27,8 +27,57 @@ Site clusters only.
|
||||
|
||||
## Actor Hierarchy
|
||||
|
||||

|
||||
<!-- source: diagrams/siteruntime-actor-hierarchy.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
DMS["Deployment Manager Singleton<br/>(Cluster Singleton)"]
|
||||
IA1["Instance Actor<br/>('MachineA-001')"]
|
||||
IA2["Instance Actor<br/>('MachineA-002')"]
|
||||
IAMORE["… more Instance Actors"]
|
||||
|
||||
SA1["Script Actor ('MonitorSpeed')<br/>— coordinator"]
|
||||
SA2["Script Actor ('CalculateOEE')<br/>— coordinator"]
|
||||
AA1["Alarm Actor ('OverTemp')<br/>— coordinator (computed)"]
|
||||
AA2["Alarm Actor ('LowPressure')<br/>— coordinator (computed)"]
|
||||
NAA1["Native Alarm Actor ('OpcUaServer1')<br/>— read-only mirror, peer to Alarm Actor"]
|
||||
|
||||
SEA1["Script Execution Actor<br/>— short-lived, per invocation"]
|
||||
SEA2["Script Execution Actor<br/>— short-lived, per invocation"]
|
||||
AEA1["Alarm Execution Actor<br/>— short-lived, per on-trigger invocation"]
|
||||
|
||||
IA2CHILD["… (Script / Alarm Actors)"]
|
||||
|
||||
DMS --> IA1
|
||||
DMS --> IA2
|
||||
DMS -.-> IAMORE
|
||||
|
||||
IA1 --> SA1
|
||||
IA1 --> SA2
|
||||
IA1 --> AA1
|
||||
IA1 --> AA2
|
||||
IA1 --> NAA1
|
||||
|
||||
SA1 --> SEA1
|
||||
SA2 --> SEA2
|
||||
AA1 --> AEA1
|
||||
|
||||
IA2 -.-> IA2CHILD
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef bad fill:#f8cecc,stroke:#b85450,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
classDef muted fill:#f5f5f5,stroke:#999999,color:#666666;
|
||||
class DMS proc
|
||||
class IA1,IA2 start
|
||||
class SA1,SA2 dec
|
||||
class AA1,AA2 bad
|
||||
class NAA1 alt
|
||||
class SEA1,SEA2,AEA1 warn
|
||||
class IAMORE,IA2CHILD muted
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -92,8 +92,32 @@ The manifest is plaintext so the import wizard can preview bundle contents and s
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
<!-- source: diagrams/transport-architecture.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
subgraph T["ZB.MOM.WW.ScadaBridge.Transport"]
|
||||
EXPORTER["IBundleExporter<br/>ExportAsync(ExportSelection, Passphrase?, ct) → Stream"]
|
||||
IMPORTER["IBundleImporter<br/>LoadAsync(stream, Passphrase?, ct) → BundleSession<br/>PreviewAsync(sessionId, ct) → ImportPreview<br/>ApplyAsync(sessionId, resolutions, ct) → ImportResult"]
|
||||
RESOLVER["DependencyResolver"]
|
||||
SERIALIZER["BundleSerializer<br/>(manifest + content JSON; ZIP packer)"]
|
||||
ENCRYPTOR["BundleSecretEncryptor<br/>(AES-256-GCM + PBKDF2)"]
|
||||
SESSIONSTORE["BundleSessionStore<br/>(in-memory, TTL'd)"]
|
||||
MANIFESTVALIDATOR["ManifestValidator<br/>(schema/version gating, hash check)"]
|
||||
end
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
classDef muted fill:#f5f5f5,stroke:#999999,color:#666666;
|
||||
class EXPORTER,IMPORTER proc
|
||||
class RESOLVER,SERIALIZER start
|
||||
class ENCRYPTOR alt
|
||||
class SESSIONSTORE warn
|
||||
class MANIFESTVALIDATOR dec
|
||||
class T muted
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
@@ -120,8 +144,50 @@ The user can toggle "include all dependencies" off (with a warning that the bund
|
||||
|
||||
### Backend
|
||||
|
||||

|
||||
<!-- source: diagrams/transport-export-flow.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
USER(["User (Design role)"])
|
||||
WIZARD["Central UI Export wizard"]
|
||||
EXPORTER["IBundleExporter"]
|
||||
RESOLVER["DependencyResolver"]
|
||||
REPOS[("repositories (read)")]
|
||||
SERIALIZER["EntitySerializer"]
|
||||
CONTENTJSON["content.json"]
|
||||
ENCRYPTOR["BundleSecretEncryptor"]
|
||||
CONTENTENC["content.enc<br/>(if passphrase)"]
|
||||
MANIFESTBUILDER["ManifestBuilder"]
|
||||
MANIFESTJSON["manifest.json"]
|
||||
ZIP["ZIP packer → temp file → browser download"]
|
||||
AUDIT["IAuditService.LogAsync(BundleExported …)"]
|
||||
|
||||
USER --> WIZARD
|
||||
WIZARD --> EXPORTER
|
||||
EXPORTER --> RESOLVER
|
||||
RESOLVER --> SERIALIZER
|
||||
SERIALIZER --> ENCRYPTOR
|
||||
ENCRYPTOR --> MANIFESTBUILDER
|
||||
MANIFESTBUILDER --> ZIP
|
||||
ZIP --> AUDIT
|
||||
|
||||
RESOLVER --> REPOS
|
||||
SERIALIZER --> CONTENTJSON
|
||||
ENCRYPTOR --> CONTENTENC
|
||||
MANIFESTBUILDER --> MANIFESTJSON
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
classDef muted fill:#f5f5f5,stroke:#999999,color:#666666;
|
||||
class USER,AUDIT start
|
||||
class WIZARD,EXPORTER,ZIP proc
|
||||
class RESOLVER,SERIALIZER,MANIFESTBUILDER dec
|
||||
class ENCRYPTOR alt
|
||||
class CONTENTJSON,CONTENTENC,MANIFESTJSON warn
|
||||
class REPOS muted
|
||||
```
|
||||
|
||||
Audit event: `BundleExported` — caller, artifact count, content hash, encrypted yes/no, bundle filename.
|
||||
|
||||
@@ -153,8 +219,37 @@ Bundle references that cannot be satisfied in either the bundle or the target DB
|
||||
|
||||
### Backend
|
||||
|
||||

|
||||
<!-- source: diagrams/transport-import-flow.drawio — edit, then re-export with export-drawio.sh -->
|
||||
```mermaid
|
||||
%%{init: {'theme':'base', 'themeVariables': {'textColor':'#111111','lineColor':'#555555','edgeLabelBackground':'#ffffff','fontSize':'15px'}}}%%
|
||||
flowchart TD
|
||||
USER(["User (Admin role) → uploads bundle"])
|
||||
LOAD["IBundleImporter.LoadAsync<br/>· verify SHA-256 (manifest vs content)<br/>· check bundleFormatVersion supported<br/>· decrypt content.enc with passphrase (if encrypted)<br/>· deserialize entities<br/>· open BundleSession (30-min TTL)"]
|
||||
PREVIEW["PreviewAsync → diff vs target DB → ImportPreview"]
|
||||
REVIEW["(user reviews + resolves conflicts)"]
|
||||
APPLY["ApplyAsync (single EF transaction)<br/>· run two-tier semantic validation<br/> (minimal name scan + full SemanticValidator)<br/>· apply resolutions (add / overwrite / skip / rename)<br/>· upsert TemplateFolder hierarchy<br/>· IAuditService.LogAsync(BundleImported …)<br/>· commit"]
|
||||
RESULT["ImportResult → UI step 5"]
|
||||
DEPLOYMENTS["'View on Deployments →' (existing page)"]
|
||||
|
||||
USER --> LOAD
|
||||
LOAD --> PREVIEW
|
||||
PREVIEW --> APPLY
|
||||
PREVIEW -.- REVIEW
|
||||
APPLY --> RESULT
|
||||
RESULT --> DEPLOYMENTS
|
||||
|
||||
classDef start fill:#d5e8d4,stroke:#82b366,color:#111111;
|
||||
classDef proc fill:#dae8fc,stroke:#6c8ebf,color:#111111;
|
||||
classDef dec fill:#fff2cc,stroke:#d6b656,color:#111111;
|
||||
classDef warn fill:#ffe6cc,stroke:#d79b00,color:#111111;
|
||||
classDef alt fill:#e1d5e7,stroke:#9673a6,color:#111111;
|
||||
classDef muted fill:#f5f5f5,stroke:#999999,color:#666666;
|
||||
class USER start
|
||||
class LOAD,RESULT proc
|
||||
class PREVIEW dec
|
||||
class APPLY alt
|
||||
class DEPLOYMENTS warn
|
||||
class REVIEW muted
|
||||
```
|
||||
|
||||
Authorization: `RequireAdmin` on both the Razor page and `IBundleImporter.*` entrypoints.
|
||||
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="topology" name="Topology">
|
||||
<mxGraphModel dx="1400" dy="900" grid="1" gridSize="10" guides="1" arrows="1"
|
||||
fold="1" page="1" pageScale="1" pageWidth="1300" pageHeight="900" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
||||
<!-- Central Cluster container -->
|
||||
<mxCell id="central" value="Central Cluster" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="60" y="60" width="380" height="320" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="cc-a" value="ClusterClient (command/control)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="90" y="110" width="150" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="cc-b" value="ClusterClient (command/control)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="90" y="170" width="150" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="cc-n" value="ClusterClient (command/control)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="90" y="230" width="150" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="grpc-client" value="SiteStreamGrpcClient (real-time data)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="90" y="300" width="150" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Site A -->
|
||||
<mxCell id="siteA" value="Site A Cluster" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="720" y="60" width="380" height="250" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="siteA-comm" value="SiteCommunicationActor (via Receptionist)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="110" width="190" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="siteA-grpc" value="SiteStreamGrpcServer (Kestrel HTTP/2, port 8083)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="180" width="190" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="siteA-clusterclient" value="ClusterClient → Central (CentralCommunicationActor)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="245" width="190" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Site B -->
|
||||
<mxCell id="siteB" value="Site B Cluster" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="720" y="370" width="380" height="130" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="siteB-comm" value="SiteCommunicationActor (via Receptionist)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="410" width="190" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="siteB-grpc" value="SiteStreamGrpcServer" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="455" width="190" height="35" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Site N -->
|
||||
<mxCell id="siteN" value="Site N Cluster" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="720" y="560" width="380" height="130" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="siteN-comm" value="SiteCommunicationActor (via Receptionist)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="600" width="190" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="siteN-grpc" value="SiteStreamGrpcServer" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="645" width="190" height="35" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Command/control edges: Central ClusterClients -> Site comm actors -->
|
||||
<mxCell id="e-cca" value="command/control" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;" edge="1" parent="1" source="cc-a" target="siteA-comm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-ccb" value="command/control" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;" edge="1" parent="1" source="cc-b" target="siteB-comm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-ccn" value="command/control" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;" edge="1" parent="1" source="cc-n" target="siteN-comm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- gRPC stream edges: site servers -> central grpc client (data flows site->central) -->
|
||||
<mxCell id="e-grpca" value="gRPC stream (real-time data)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="siteA-grpc" target="grpc-client">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="540" y="205" />
|
||||
<mxPoint x="540" y="325" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e-grpcb" value="gRPC stream" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="siteB-grpc" target="grpc-client">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="600" y="472" />
|
||||
<mxPoint x="600" y="335" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e-grpcn" value="gRPC stream" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="siteN-grpc" target="grpc-client">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="660" y="662" />
|
||||
<mxPoint x="660" y="345" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
|
||||
<!-- Site A -> Central command/control (ClusterClient to central) -->
|
||||
<mxCell id="e-sa-central" value="command/control" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;dashed=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.7;entryDx=0;entryDy=0;" edge="1" parent="1" source="siteA-clusterclient" target="central">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="480" y="270" />
|
||||
<mxPoint x="480" y="284" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
|
||||
<!-- Note: sites do not talk to each other -->
|
||||
<mxCell id="note" value="Sites do NOT communicate with each other. All inter-cluster communication flows through Central." style="shape=note;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="60" y="560" width="380" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 341 KiB |
@@ -1,37 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="configdb-integration-example" name="Integration Example">
|
||||
<mxGraphModel dx="800" dy="600" grid="1" gridSize="10" guides="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="start" value="Template Engine: Update Template" style="rounded=1;arcSize=40;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="40" width="360" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="upd" value="repository.UpdateTemplate(template)" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="150" width="360" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="audit" value="auditService.LogAsync(user, "Update", "Template",     template.Id, template.Name, template)" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="230" width="360" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="save" value="repository.SaveChangesAsync()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="330" width="360" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="note" value="both the change and audit entry commit together" style="shape=note;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;size=14;align=left;spacingLeft=10;" vertex="1" parent="1">
|
||||
<mxGeometry x="630" y="330" width="180" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="start" target="upd">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="upd" target="audit">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="audit" target="save">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=none;dashed=1;" edge="1" parent="1" source="save" target="note">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 109 KiB |
@@ -1,49 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="configdb-transactional-flow" name="Transactional Flow">
|
||||
<mxGraphModel dx="800" dy="600" grid="1" gridSize="10" guides="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="start" value="Template Engine: Create Template" style="rounded=1;arcSize=40;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="40" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="add1" value="repository.AddTemplate(template) // template is a Commons POCO" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="150" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="add2" value="repository.AddAttributes(attributes) // attributes are Commons POCOs" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="230" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="add3" value="repository.AddAlarms(alarms) // alarms are Commons POCOs" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="310" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="add4" value="repository.AddScripts(scripts) // scripts are Commons POCOs" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="390" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="save" value="repository.SaveChangesAsync() // single transaction commits all" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="480" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="db" value="Configuration DB (MS SQL)" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1">
|
||||
<mxGeometry x="640" y="475" width="120" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="start" target="add1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="add1" target="add2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="add2" target="add3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="add3" target="add4">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="add4" target="save">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" value="single transaction" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;dashed=1;" edge="1" parent="1" source="save" target="db">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 182 KiB |
@@ -1,71 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="dcl-endpoint-redundancy" name="Failover State Machine">
|
||||
<mxGraphModel dx="900" dy="700" grid="1" gridSize="10" guides="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="connected" value="Connected" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="40" width="160" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="pushbad" value="push bad quality" style="whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="150" width="160" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="retry" value="retry active endpoint (5s)" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="250" width="160" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="decide" value="N failures (≥ FailoverRetryCount)?" style="rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
|
||||
<mxGeometry x="350" y="350" width="180" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="switch" value="switch to other endpoint" style="whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="500" width="160" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="dispose" value="dispose adapter, create fresh adapter with other config" style="whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="600" width="160" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="reconnect" value="reconnect" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="710" width="160" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="resub" value="ReSubscribeAll" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="800" width="160" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e0" value="disconnect" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="connected" target="pushbad">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="pushbad" target="retry">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="retry" target="decide">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2b" value="no (retry again)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="decide" target="retry">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="620" y="400" />
|
||||
<mxPoint x="620" y="275" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="e3" value="yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="decide" target="switch">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="switch" target="dispose">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="dispose" target="reconnect">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="reconnect" target="resub">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e7" value="back to Connected" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="resub" target="connected">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="240" y="825" />
|
||||
<mxPoint x="240" y="65" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 128 KiB |
@@ -1,96 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="deployflow" name="Deployment Flow">
|
||||
<mxGraphModel dx="1200" dy="1400" grid="1" gridSize="10" guides="1" arrows="1"
|
||||
fold="1" page="1" pageScale="1" pageWidth="900" pageHeight="1500" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
||||
<!-- Start: Engineer -->
|
||||
<mxCell id="engineer" value="Engineer (UI)" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="320" y="40" width="200" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Deployment Manager (Central) container header -->
|
||||
<mxCell id="dm-central" value="Deployment Manager (Central)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;verticalAlign=top;fontStyle=1;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="130" width="640" height="430" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step1" value="1. Request validated + flattened config from Template Engine (validation: flattening, script compilation, trigger references, connection binding completeness)" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="180" width="560" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step2" value="2. Validation fails?" style="rhombus;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="350" y="270" width="180" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step2fail" value="Return errors to UI, stop" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="600" y="280" width="140" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step3" value="3. Send config to site via Communication Layer" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="390" width="440" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step8" value="8. Update deployment status in config DB" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="480" width="320" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Site Runtime container -->
|
||||
<mxCell id="site-runtime" value="Site Runtime (Deployment Manager Singleton)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;verticalAlign=top;fontStyle=1;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="620" width="640" height="380" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step4" value="4. Store new flattened config locally (SQLite)" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="670" width="480" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step5" value="5. Compile scripts at site" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="770" width="400" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step6" value="6. Create/update Instance Actor (with child Script + Alarm Actors)" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="850" width="400" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="step7" value="7. Report success/failure back to central" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="940" width="400" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges -->
|
||||
<mxCell id="e0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="engineer" target="step1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="step1" target="step2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2yes" value="yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="step2" target="step2fail">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2no" value="no" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="step2" target="step3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" value="config" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="step3" target="step4">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="step4" target="step5">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="step5" target="step6">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="step6" target="step7">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e7" value="report success/failure" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="step7" target="step8">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="780" y="965" />
|
||||
<mxPoint x="780" y="515" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 354 KiB |
@@ -1,67 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="inboundapi-request-flow" name="Request Flow">
|
||||
<mxGraphModel dx="900" dy="900" grid="1" gridSize="10" guides="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="ext" value="External System" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="320" y="40" width="200" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="api" value="Inbound API (Central)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="320" y="140" width="200" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s1" value="1. Extract API key from request" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="240" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s2" value="2. Validate key exists and is enabled" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="300" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s3" value="3. Resolve method by name" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="360" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s4" value="4. Check API key is in method's approved list" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="420" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s5" value="5. Validate and deserialize parameters" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="480" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s6" value="6. Execute implementation script (subject to method timeout)" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="540" width="280" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s7" value="7. Serialize return value" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="610" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="s8" value="8. Return response" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;align=left;spacingLeft=12;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="670" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="ext" target="api">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="api" target="s1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="s1" target="s2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="s2" target="s3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="s3" target="s4">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="s4" target="s5">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="s5" target="s6">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="s6" target="s7">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="s7" target="s8">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 146 KiB |
@@ -1,83 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="outboxflow" name="End-to-End Flow">
|
||||
<mxGraphModel dx="1000" dy="1400" grid="1" gridSize="10" guides="1" arrows="1"
|
||||
fold="1" page="1" pageScale="1" pageWidth="950" pageHeight="1400" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
||||
<!-- Site script -->
|
||||
<mxCell id="script" value="Site script: Notify.To("list").Send(subject, body) generate NotificationId (GUID) locally; return it to the script immediately" style="rounded=1;arcSize=20;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="40" width="380" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Site S&F Engine -->
|
||||
<mxCell id="snf" value="Site Store-and-Forward Engine (notification category, target = central) durably forwards to central via Central–Site Communication (ClusterClient); buffers/retries if central is unreachable" style="whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="170" width="460" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Central ingest -->
|
||||
<mxCell id="ingest" value="Central ingest: insert-if-not-exists on NotificationId → Notifications table (Pending) ack the site → site S&F clears the message" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="270" y="310" width="400" height="90" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Central Notification Outbox actor -->
|
||||
<mxCell id="outbox" value="Central Notification Outbox actor (singleton, active central node) polls due rows; resolves the list; delivers via the matching adapter" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="460" width="380" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Delivery decision -->
|
||||
<mxCell id="d1" value="Delivery outcome" style="rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="610" width="140" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Delivered -->
|
||||
<mxCell id="delivered" value="Delivered" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="630" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Retrying -->
|
||||
<mxCell id="retrying" value="Retrying (schedule NextAttemptAt)" style="rounded=1;arcSize=20;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="380" y="790" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Parked -->
|
||||
<mxCell id="parked" value="Parked" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="650" y="630" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges -->
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="script" target="snf">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="snf" target="ingest">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="ingest" target="outbox">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="outbox" target="d1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" value="success" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="d1" target="delivered">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e6" value="transient failure" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="d1" target="retrying">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e7" value="permanent failure / retries exhausted" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="d1" target="parked">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<!-- Retrying loops back to outbox poll -->
|
||||
<mxCell id="e8" value="retry due" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=11;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="retrying" target="outbox">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="780" y="820" />
|
||||
<mxPoint x="780" y="500" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 333 KiB |
@@ -1,104 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="actorhierarchy" name="Actor Hierarchy">
|
||||
<mxGraphModel dx="1400" dy="1000" grid="1" gridSize="10" guides="1" arrows="1"
|
||||
fold="1" page="1" pageScale="1" pageWidth="1320" pageHeight="560" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
||||
<!-- Root: Deployment Manager Singleton -->
|
||||
<mxCell id="dms" value="Deployment Manager Singleton (Cluster Singleton)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontStyle=1;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="490" y="30" width="280" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Instance Actors -->
|
||||
<mxCell id="ia1" value="Instance Actor ("MachineA-001")" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="368" y="160" width="184" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="ia2" value="Instance Actor ("MachineA-002")" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="980" y="160" width="184" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="iamore" value="… more Instance Actors" style="text;html=1;align=center;verticalAlign=middle;fontSize=12;fontStyle=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="1190" y="170" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Children of MachineA-001 (top row) -->
|
||||
<mxCell id="sa1" value="Script Actor ("MonitorSpeed") — coordinator" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="16" y="300" width="164" height="74" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sa2" value="Script Actor ("CalculateOEE") — coordinator" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="196" y="300" width="164" height="74" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="aa1" value="Alarm Actor ("OverTemp") — coordinator (computed)" style="whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="376" y="300" width="164" height="74" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="aa2" value="Alarm Actor ("LowPressure") — coordinator (computed)" style="whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="556" y="300" width="164" height="74" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="naa1" value="Native Alarm Actor ("OpcUaServer1") — read-only mirror, peer to Alarm Actor" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="736" y="300" width="164" height="74" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Execution actors (bottom row, under their coordinators) -->
|
||||
<mxCell id="sea1" value="Script Execution Actor — short-lived, per invocation" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;dashed=1;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="16" y="430" width="164" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sea2" value="Script Execution Actor — short-lived, per invocation" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;dashed=1;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="196" y="430" width="164" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="aea1" value="Alarm Execution Actor — short-lived, per on-trigger invocation" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;dashed=1;fontSize=11;" vertex="1" parent="1">
|
||||
<mxGeometry x="376" y="430" width="164" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Child of MachineA-002 -->
|
||||
<mxCell id="ia2child" value="… (Script / Alarm Actors)" style="text;html=1;align=center;verticalAlign=middle;fontSize=12;fontStyle=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="992" y="304" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges: root -> instances -->
|
||||
<mxCell id="e-dms-ia1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="dms" target="ia1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-dms-ia2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="dms" target="ia2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-dms-more" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;dashed=1;" edge="1" parent="1" source="dms" target="iamore">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges: MachineA-001 -> its children (all top-row, no box in between) -->
|
||||
<mxCell id="e-ia1-sa1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="ia1" target="sa1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-ia1-sa2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="ia1" target="sa2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-ia1-aa1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="ia1" target="aa1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-ia1-aa2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="ia1" target="aa2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-ia1-naa1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="ia1" target="naa1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges: coordinator -> execution actor (short vertical, own column) -->
|
||||
<mxCell id="e-sa1-sea1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="sa1" target="sea1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-sa2-sea2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="sa2" target="sea2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e-aa1-aea1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="aa1" target="aea1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edge: MachineA-002 -> its child -->
|
||||
<mxCell id="e-ia2-child" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;dashed=1;" edge="1" parent="1" source="ia2" target="ia2child">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 217 KiB |
@@ -1,82 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="msglifecycle" name="Message Lifecycle">
|
||||
<mxGraphModel dx="1000" dy="1300" grid="1" gridSize="10" guides="1" arrows="1"
|
||||
fold="1" page="1" pageScale="1" pageWidth="900" pageHeight="1300" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
||||
<!-- Start -->
|
||||
<mxCell id="submit" value="Script submits message" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="320" y="40" width="220" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Attempt immediate delivery -->
|
||||
<mxCell id="attempt" value="Attempt immediate delivery" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=13;" vertex="1" parent="1">
|
||||
<mxGeometry x="320" y="140" width="220" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Decision: success or failure -->
|
||||
<mxCell id="d1" value="Delivered?" style="rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="350" y="240" width="160" height="90" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Success -> Remove from buffer -->
|
||||
<mxCell id="remove1" value="Remove from buffer" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="255" width="200" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Failure -> Buffer message -->
|
||||
<mxCell id="buffer" value="Buffer message" style="whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="330" y="390" width="200" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Retry loop -->
|
||||
<mxCell id="retry" value="Retry loop (per retry policy)" style="whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="330" y="490" width="200" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Retry decision -->
|
||||
<mxCell id="d2" value="Retry outcome" style="rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="350" y="610" width="160" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Retry success -> Remove from buffer + notify standby -->
|
||||
<mxCell id="remove2" value="Remove from buffer + notify standby" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="625" width="200" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Max retries exhausted -> Park message -->
|
||||
<mxCell id="park" value="Park message (dead-letter)" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="330" y="770" width="200" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges -->
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="submit" target="attempt">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="attempt" target="d1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" value="Success" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="d1" target="remove1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" value="Failure" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="d1" target="buffer">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="buffer" target="retry">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="retry" target="d2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e7" value="Success" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="d2" target="remove2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e8" value="Max retries exhausted" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;fontSize=12;" edge="1" parent="1" source="d2" target="park">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 154 KiB |
@@ -1,34 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="transport-architecture" name="Architecture">
|
||||
<mxGraphModel dx="900" dy="800" grid="1" gridSize="10" guides="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="container" value="ZB.MOM.WW.ScadaBridge.Transport" style="swimlane;whiteSpace=wrap;html=1;startSize=34;fillColor=#f5f5f5;strokeColor=#666666;fontStyle=1;fontSize=14;verticalAlign=top;" vertex="1" parent="1">
|
||||
<mxGeometry x="80" y="40" width="560" height="610" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="exporter" value="IBundleExporter ExportAsync(ExportSelection, Passphrase?, ct) → Stream" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;verticalAlign=top;spacingTop=8;" vertex="1" parent="container">
|
||||
<mxGeometry x="30" y="50" width="500" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="importer" value="IBundleImporter LoadAsync(stream, Passphrase?, ct) → BundleSession PreviewAsync(sessionId, ct) → ImportPreview ApplyAsync(sessionId, resolutions, ct) → ImportResult" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;verticalAlign=top;spacingTop=8;" vertex="1" parent="container">
|
||||
<mxGeometry x="30" y="140" width="500" height="110" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="resolver" value="DependencyResolver" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;align=left;spacingLeft=12;" vertex="1" parent="container">
|
||||
<mxGeometry x="30" y="270" width="500" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="serializer" value="BundleSerializer (manifest + content JSON; ZIP packer)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;align=left;spacingLeft=12;" vertex="1" parent="container">
|
||||
<mxGeometry x="30" y="330" width="500" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="encryptor" value="BundleSecretEncryptor (AES-256-GCM + PBKDF2)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;spacingLeft=12;" vertex="1" parent="container">
|
||||
<mxGeometry x="30" y="390" width="500" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sessionstore" value="BundleSessionStore (in-memory, TTL'd)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;align=left;spacingLeft=12;" vertex="1" parent="container">
|
||||
<mxGeometry x="30" y="450" width="500" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="manifestvalidator" value="ManifestValidator (schema/version gating, hash check)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;align=left;spacingLeft=12;" vertex="1" parent="container">
|
||||
<mxGeometry x="30" y="510" width="500" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 228 KiB |
@@ -1,85 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="transport-export-flow" name="Export Flow (Backend)">
|
||||
<mxGraphModel dx="1000" dy="800" grid="1" gridSize="10" guides="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="900" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="user" value="User (Design role)" style="rounded=1;arcSize=50;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="40" width="160" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="wizard" value="Central UI Export wizard" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="40" width="200" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="exporter" value="IBundleExporter" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="150" width="200" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="resolver" value="DependencyResolver" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="250" width="200" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="repos" value="repositories (read)" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1">
|
||||
<mxGeometry x="600" y="245" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="serializer" value="EntitySerializer" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="310" width="200" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="contentjson" value="content.json" style="shape=note;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;size=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="610" y="310" width="110" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="encryptor" value="BundleSecretEncryptor" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="370" width="200" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="contentenc" value="content.enc (if passphrase)" style="shape=note;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;size=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="610" y="368" width="110" height="44" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="manifestbuilder" value="ManifestBuilder" style="whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="430" width="200" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="manifestjson" value="manifest.json" style="shape=note;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;size=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="610" y="430" width="110" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="zip" value="ZIP packer → temp file → browser download" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="520" width="280" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="audit" value="IAuditService.LogAsync(BundleExported …)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="620" width="280" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="user" target="wizard">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="wizard" target="exporter">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="exporter" target="resolver">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="resolver" target="serializer">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="serializer" target="encryptor">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="encryptor" target="manifestbuilder">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="manifestbuilder" target="zip">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="zip" target="audit">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="b1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="resolver" target="repos">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="b2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="serializer" target="contentjson">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="b3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="encryptor" target="contentenc">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="b4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="manifestbuilder" target="manifestjson">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 164 KiB |
@@ -1,49 +0,0 @@
|
||||
<mxfile host="app.diagrams.net">
|
||||
<diagram id="transport-import-flow" name="Import Flow (Backend)">
|
||||
<mxGraphModel dx="1000" dy="900" grid="1" gridSize="10" guides="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="900" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="user" value="User (Admin role) ─► uploads bundle" style="rounded=1;arcSize=30;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="260" y="40" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="load" value="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)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;align=left;spacingLeft=12;verticalAlign=top;spacingTop=8;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="150" width="400" height="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="preview" value="PreviewAsync → diff vs target DB → ImportPreview" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="350" width="400" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="review" value="(user reviews + resolves conflicts)" style="whiteSpace=wrap;html=1;fillColor=none;strokeColor=none;fontStyle=2;align=left;" vertex="1" parent="1">
|
||||
<mxGeometry x="630" y="425" width="240" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="apply" value="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" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;spacingLeft=12;verticalAlign=top;spacingTop=8;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="460" width="400" height="160" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="result" value="ImportResult → UI step 5" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
||||
<mxGeometry x="260" y="680" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="deployments" value=""View on Deployments →" (existing page)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;fontStyle=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="260" y="780" width="320" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="user" target="load">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="load" target="preview">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="preview" target="apply">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2b" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=none;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="preview" target="review">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="apply" target="result">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;" edge="1" parent="1" source="result" target="deployments">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
|
Before Width: | Height: | Size: 282 KiB |