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.
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user