Blueprints
Blueprints sind versionierte, deklarative Bündel aus Construction-Kit-(CK-)Modellen und Runtime-Seed-Daten, die einen Tenant initialisieren (bootstrappen) — und ihn über seine gesamte Lebensdauer hinweg weiter verwalten. Ein Blueprint kann installiert, erneut angewendet, aktualisiert, zurückgerollt und deinstalliert werden und kann von anderen Blueprints abhängen. Versionierte Migrationsskripte transformieren die Tenant-Daten, wenn die eigene Version eines Blueprints vorwärts wandert.
Was ein Blueprint ist
Ein Blueprint ist im Wesentlichen dreierlei, zusammengefasst in einem einzigen Artefakt:
- CK-Modell-Abhängigkeiten — das Schema (Typen, Attribute, Assoziationen), das der Tenant benötigt, bevor die Seed-Daten importiert werden können. Die Engine löst diese CK-Modelle beim Anwenden auf und importiert sie.
- Seed-Daten — eine Runtime-Modell-YAML-Datei mit den Entitäten, die nach dem Anwenden im Tenant vorhanden sein sollen.
- Migrationsskripte — optionale, versionierte Transformationen, die ausgeführt werden, wenn der Blueprint in einem bereits installierten Tenant von einer älteren zu einer neueren Version wandert.
Während ein CK-Modell die Form der Daten definiert, legt ein Blueprint die ersten echten Daten in einen Tenant. Beide arbeiten Hand in Hand: CK-Modelle allein lassen einen Tenant leer; Blueprints machen aus einem leeren Tenant einen funktionierenden.
Eigenschaften
| Eigenschaft | Beschreibung |
|---|---|
| Versioniert | SemVer (MyBlueprint-1.2.3). Versionsbereiche drücken Kompatibilität aus, wie bei CK-Modellen. |
| Abhängigkeitsbewusst | Ein Blueprint kann von anderen Blueprints abhängen, die zur Installationszeit transitiv aufgelöst werden. |
| Eigentümerverfolgt | Jede Seed-Entität wird mit rtBlueprintSource und rtBlueprintLocked markiert. |
| Aktualisierbar | Tenants werden über die Modi Safe / Merge / Full / Migration auf neuere Versionen gebracht. |
| Zurückrollbar | Destruktive Operationen erstellen ein Tenant-Backup; Rollback stellt den Snapshot wieder her. |
| Mehrfachinstallation | Ein Tenant kann mehrere Blueprints gleichzeitig hosten. Refcounted, kaskadierende Deinstallation optional. |
Tenant-bezogene Speicherung
Registry-Zeilen von Blueprints (BlueprintInstallation, BlueprintHistory, BlueprintBackup) existieren als CK-Entitäten innerhalb des eigenen Runtime-Repositorys des Tenants, neben den Seed-Daten, die sie beschreiben. Es gibt keine tenant-übergreifende Sammlung — ein Anwenden in Tenant X schreibt niemals außerhalb von Tenant X. mongodump --db=<tenant> erfasst die Registry zusammen mit den Entitäten.
Blueprint-Struktur
Ein Blueprint ist ein Verzeichnis, das eine blueprint.yaml, eine optionale Seed-Daten-Datei und optionale Migrationsskripte enthält:
MyBlueprint-1.0.0/
├── blueprint.yaml
├── seed-data/
│ └── entities.yaml
└── migrations/
└── from-1.0.0.yaml
Blueprint-YAML-Schema
$schema: https://schemas.meshmakers.cloud/blueprint-meta.schema.json
blueprintId: InfrastructureStarter-1.0.0
description: Infrastructure management starter blueprint
# CK models loaded into the tenant when this blueprint is applied
ckModelDependencies:
- System-[2.0,3.0)
- Commerce-[1.0,2.0)
# Other blueprints required before this one (resolved transitively, topo-sorted)
blueprintDependencies:
- BaseEntities-[1.0,)
- SecurityModel-[2.0,)
# Optional path to seed data (relative to blueprint root)
seedDataPath: seed-data/entities.yaml
# ... oder ein auf mehrere Dateien aufgeteilter Seed, der vor dem Import zu einem Modell
# zusammengeführt wird
seedDataPaths:
- seed-data/configurations/base.yaml
- seed-data/data-flows/camt053.yaml
- seed-data/identity/roles.yaml
# Optional migrations from older versions of this blueprint
migrations:
- fromVersion: "0.9.0"
scriptPath: "migrations/from-0.9.0.yaml"
| Feld | Typ | Beschreibung |
|---|---|---|
$schema | string | Schema-URI für die Validierung |
blueprintId | string | Eindeutige ID mit Version (Name-Major.Minor.Patch) |
description | string | Optionale Beschreibung |
ckModelDependencies | string[] | CK-Modelle mit Versionsbereichen (beim Anwenden automatisch importiert) |
blueprintDependencies | string[] | Andere Blueprints mit Versionsbereichen (transitiv aufgelöst) |
seedDataPath | string | Optionaler Pfad zur Seed-Daten-Datei (Runtime-Modell-Format) |
seedDataPaths | string[] | Optionale Liste von Seed-Daten-Dateien, vor dem Import zu einem Modell zusammengeführt |
migrations | array | Optionale Liste von Migrationsskripten, nach Quellversion geschlüsselt |
Versionsbereiche
Sowohl ckModelDependencies als auch blueprintDependencies verwenden dieselbe Bereichssyntax wie CK-Modelle:
| Format | Bedeutung |
|---|---|
1.0.0 | Exakte Version |
[1.0.0,) | Version 1.0.0 oder höher |
[1.0.0,2.0.0) | Version >= 1.0.0 und < 2.0.0 |
(1.0.0,2.0.0] | Version > 1.0.0 und <= 2.0.0 |
[1.5.0] | Genau Version 1.5.0 |
Für ckModelDependencies installiert die Blueprint-Engine die untere Grenze des Bereichs auf einem frischen Tenant (ein Tenant, der dasselbe Modell bereits auf oder über dem Floor hält, bleibt unberührt — kein Downgrade). Die Floor-Version muss daher zusammen mit allen benachbarten Abhängigkeiten installierbar sein; nach einem Abhängigkeits-Bump heben Sie den Floor auf die erste dagegen kompilierte Version an. Die Seed-Daten-Datei deklariert ihre eigenen dependencies:-Pins unabhängig vom Manifest — halten Sie beide synchron. Siehe Versionierungsregeln für das vollständige Bild.
Seed-Daten-Format
Seed-Daten sind eine Runtime-Modell-YAML-Datei. Die Blueprint-Engine stempelt die Quellattribute während des Imports ein; Sie schreiben sie nicht selbst.
$schema: https://schemas.meshmakers.cloud/runtime-model.schema.json
dependencies:
- System-2.0.0
entities:
- rtId: 507f1f77bcf86cd799439011
ckTypeId: System/Entity
rtWellKnownName: InitialEntity
attributes:
- id: System/Name
value: My Initial Entity
- id: System/Description
value: Created by blueprint
Seed-Daten werden mit der Upsert-Strategie angewendet: bestehende Entitäten (über rtId abgeglichen) werden aktualisiert; neue werden eingefügt.
Seed auf mehrere Dateien aufteilen
Eine einzelne entities.yaml wird unlesbar, lange bevor ein umfangreicher Blueprint fertig ist —
Data-Flows, Pipelines, Konfigurationen, Identity-Rollen und Stammdaten liegen ineinander
verschachtelt in einer Datei, in der kein Diff mehr review-fähig ist und kein Feature einen
Eigentümer hat. seedDataPaths ersetzt den einzelnen seedDataPath durch eine Liste, sodass der
Seed nach Features gegliedert werden kann:
MyBlueprint/
├── blueprint.yaml
└── seed-data/
├── configurations/base.yaml
├── data-flows/camt053.yaml # eine Pipeline + ihr Data-Flow pro Datei
├── identity/roles.yaml
└── master-data/accounts.yaml
seedDataPaths:
- seed-data/configurations/base.yaml
- seed-data/identity/roles.yaml
- seed-data/data-flows/camt053.yaml
- seed-data/master-data/accounts.yaml
Jede Datei ist ein vollständiges Runtime-Modell-Dokument mit eigenem $schema und eigenen
dependencies. Die Engine lädt alle, vereinigt ihre dependencies, hängt ihre entities
aneinander und importiert das Ergebnis als ein Modell:
- Die Reihenfolge spielt keine Rolle. Der zusammengeführte Import schreibt alle Entitäten vor jeder Assoziation — eine Assoziation in der ersten Datei darf also eine Entität referenzieren, die erst in der letzten deklariert wird.
- Doppelte Entitäten über Dateien hinweg werden abgelehnt — die Identität ist der CK-Typ
plus die
rtId; dieselbe id unter zwei Typen bleibt also erlaubt (octo-bpm validatewarnt davor), eine echte Dublette wird zurückgewiesen. - Eine fehlende Datei ist ein Fehler, sobald mehr als eine Datei deklariert ist: den Rest zu importieren würde den Tenant unvollständig provisionieren und trotzdem Erfolg melden.
octo-bpm validatewarnt vor YAML-Dateien unterseed-data/, die kein Pfad referenziert.- Abwärtskompatibel —
seedDataPathfunktioniert unverändert weiter.
Eine Verzeichnis- oder Glob-Form gibt es nicht: Blueprints werden der Runtime über GitHub Pages ausgeliefert, das kein Verzeichnis-Listing anbietet — die Menge der Dateien steht deshalb in dem Manifest, das ohnehin geladen wird.
Lebenszyklus
Anwendungsablauf
ApplyBlueprintAsync(tenantId, blueprintId, force)
│
├── 1. Resolve transitive blueprint dependency closure (topo-sorted)
│
├── 2. Conflict-check (CK versions, entity ownership, rtId collisions)
│ → BlueprintApplicationResult.Conflicts; abort on hard conflicts
│
├── 3. For each blueprint in topo order:
│ ├── Idempotency: same version installed → no-op
│ │ same version installed + --force → re-apply (upsert)
│ │ different version installed → Update path
│ ├── Import CK model dependencies (auto-resolve via ICkModelUpgradeService)
│ ├── Apply seed data via IImportRtModelCommand (Upsert)
│ ├── Tag entities with rtBlueprintSource / rtBlueprintLocked / rtBlueprintAppliedAt
│ ├── Persist BlueprintInstallation
│ └── Publish BlueprintApplied event
│
└── 4. Append history entry, return result
Erzwungenes erneutes Anwenden und Runtime-State
Das erneute Anwenden einer installierten Blueprint-Version mit --force (octo-cli -c InstallBlueprint -b MyBlueprint-1.0.0 -f) upsertet jede Seed-Entität auf ihre Seed-Werte zurück. Dies ist der vorgesehene Weg, um driftende Seed-Daten zu reparieren — es bedeutet aber auch, dass jeder Attributwert, den Operatoren oder Services nach der Installation geändert haben, auf das zurückgesetzt wird, was das Seed ausliefert, sofern ihn nicht eines der folgenden Dinge schützt:
- Entsperrte Entitäten (
rtBlueprintLocked = false) durchlaufen die Konfliktauflösung, anstatt stillschweigend überschrieben zu werden. - Runtime-State-Attribute bleiben erhalten. Ein CK-Attribut, das in seinem Modell mit
isRuntimeState: truegekennzeichnet ist, deklariert, dass sein Wert dem laufenden System gehört, nicht den Seed-Daten: Der Runtime-Import behält beim Upsert den aktuellen Wert des Tenants bei und wendet den Seed-Wert nur an, wenn die Entität erstmals eingefügt wird. Die Erhaltungslogik sitzt im gemeinsam genutzten Runtime-Modell-Import, sodass sie sowohl Blueprint-Anwendungen als auch das einfacheImportRt -rabdeckt.
Bekannte Runtime-State-Attribute:
| Modell | Attribute | Seit |
|---|---|---|
System.StreamData | Archive.Status — ein erzwungenes erneutes Anwenden deaktiviert aktivierte Archive nicht mehr | 1.7.0 |
System.Communication | Hostname, IngressEnabled, ChartVersion, ValuesYaml, Values auf Workloads — von Operator oder CD gesetzte Deployment-Werte überstehen ein erzwungenes erneutes Anwenden | 3.28.0 |
Vermeiden Sie beim Erstellen eines Blueprints das Ausliefern veränderlichen operativen States (Status-Flags, Zähler, Deployment-Werte) in Seed-Entitäten. Wenn das Attribut in seinem CK-Modell nicht als isRuntimeState gekennzeichnet ist, setzt jedes erzwungene erneute Anwenden es auf den Seed-Wert zurück — was auf einem Produktions-Tenant stillschweigend Archive deaktivieren, die Deployment-Konfiguration rückgängig machen oder Verarbeitungs-Watermarks zurücksetzen kann. Lassen Sie solche Attribute entweder aus dem Seed heraus oder kennzeichnen Sie sie im besitzenden CK-Modell als isRuntimeState (eine MINOR-Modelländerung).
Secret-Attribute in Seed-Daten
Ein Blueprint liefert niemals Zugangsdaten aus. Für Attribute vom Werttyp Secret dürfen Seed-Daten nur keinen Wert, einen leeren Wert oder null enthalten. Platzhalter wie <set-after-install> oder TODO_SET_CLIENT_SECRET sind nicht erlaubt — sie würden als gewöhnlicher (verschlüsselter) Wert importiert.
entities:
- rtId: 65f1c0a2b3d4e5f601234567
ckTypeId: System.Communication/EMailReceiverConfiguration
rtWellKnownName: SupportMailbox
attributes:
- id: System.Communication/UserName
value: support@example.com
- id: System.Communication/Password
value: ""
Das Secret wird als „nicht gesetzt" importiert. Da die Ownership eines Secret-Attributs immer Secret ist, behält ein erneutes Anwenden — auch ein erzwungenes — einen Wert, der nach der Installation gesetzt wurde. Setzen Sie die Secrets nach der Installation des Blueprints im Studio, mit octo-cli oder über die API (siehe Secret-Attribute in der API).
Der Blueprint-Build-Lint schlägt fehl, wenn ein Seed einen nicht leeren Wert für ein Secret-Attribut setzt, Platzhalter eingeschlossen; die Fehlermeldung nennt Entität und Attribut, niemals den Wert. Secret-Unterattribute in Records werden ebenfalls geprüft. Wurden echte Zugangsdaten jemals eingecheckt, müssen sie rotiert werden — sie aus dem Seed zu entfernen reicht nicht.
Nachverfolgung der Entitätsquelle
Jede Seed-Entität wird beim Anwenden mit drei Systemattributen gestempelt:
| Attribut | Typ | Beschreibung |
|---|---|---|
rtBlueprintSource | string | Besitzender Blueprint, vollständige ID (Infrastructure-1.0.0). Genau ein Eigentümer pro Entität. |
rtBlueprintLocked | bool | true = durch Blueprint verwaltet, Updates überschreiben; false = vom Benutzer freigegeben. |
rtBlueprintAppliedAt | DateTime | UTC-Zeitstempel des letzten Anwendens/Updates, das diese Entität berührt hat. |
Ein Blueprint, der eine Entität ausliefert, sie aber von Anfang an vom Benutzer bearbeitbar lassen möchte, kann in seinen Seed-Daten rtBlueprintLocked: false setzen.
Schreibgeschützt für Benutzer: ProtectBlueprintLocked
Standardmäßig steuert rtBlueprintLocked nur Blueprint-Updates: Ein Benutzer kann eine gesperrte Entität weiterhin
bearbeiten oder löschen. Ein Blueprint-Autor kann die produktseitigen Entitäten eines CK-Typs in den geschützten Entitäts-Schreibpfaden (alle GraphQL-Mutationen) für Benutzer
schreibgeschützt machen, indem er eine Datenrichtlinie ausliefert, die den Typ aktiviert. Das geschieht in den Seed-Daten
des Blueprints, nicht im Code.
- Fügen Sie den Seed-Daten eine
System.Identity/DataPolicy-Entität hinzu, mit dem Typ inTargetCkTypeIdsund dem AttributProtectBlueprintLocked: true(Boolean, Standardfalse). Verwenden Sie je geschütztem Typ eine eigene Richtlinie; setzen Sie das Flag nicht auf gemeinsam genutzten Richtlinien wie einer Stammdaten-Richtlinie. - Die Richtlinie ist eine Einschränkung, keine Berechtigung: Sie gilt unabhängig davon, was andere Richtlinien
erlauben, und abgeleitete Typen des Zieltyps erben sie. Da der Typ nun von einer Richtlinie erfasst wird, geben Sie den
Rollen, die mit dem Typ arbeiten dürfen, wie bei jeder Datenrichtlinie die üblichen Berechtigungen (
Read,Write,Delete) über die Berechtigung der Richtlinie. - Erhöhen Sie die Abhängigkeit des Blueprints von
System.Identityauf die Version, dieProtectBlueprintLockedeingeführt hat.
Wirkung für Aufrufer außerhalb des Systems auf einem geschützten Typ (die nicht abgedeckten Pfade stehen am Ende dieses Abschnitts):
- Das Aktualisieren, Ersetzen oder Löschen einer Entität, deren gespeichertes
rtBlueprintLockedtrueist, wird mit dem stabilen FehlerBLUEPRINT_LOCKED(Meldungsnummer6384) abgewiesen. Die gesamte Änderungsmenge wird abgelehnt, es wird nichts geschrieben. - Entitäten mit
rtBlueprintLockedfalseoder ohne Wert bleiben voll bearbeitbar. Legen Sie die Entitäten, die dem Mandanten gehören sollen, mitrtBlueprintLocked: falsean. - Benutzer können
rtBlueprintLocked,rtBlueprintSourceundrtBlueprintAppliedAtweder beim Einfügen setzen noch beim Aktualisieren ändern; ein unveränderter Rundlauf eines Formulars wird akzeptiert. Andere Typen bleiben unverändert. - Lesezugriffe sind nie betroffen.
- Der Durchsetzungsmodus der Richtlinie gilt:
Enforceweist ab,AuditOnlylässt die Änderung durch und veröffentlicht ein Audit-EreignisDataPermissions.BlueprintLockViolation.
Blueprint-Installation, -Update und erzwungenes erneutes Anwenden laufen im System-Kontext und werden nicht blockiert.
Models/ImportRt wendet dieselbe Regel durchgängig an: Der Import-Job läuft im Namen des auslösenden Aufrufers und
schlägt als Ganzes fehl, bevor etwas geschrieben wird, wenn die Datei eine gesperrte Entität eines geschützten Typs
überschreiben würde (AB#6392). rtBlueprintLocked, rtBlueprintSource und rtBlueprintAppliedAt einer exportierten
Datei werden bei den eingehenden Entitäten geschützter Typen entfernt, sodass ein Export aus einem anderen Tenant
weiterhin importiert werden kann (die Entitäten gehören dann dem Tenant). Ein Pipeline-Knoten mit Identity: ServiceAccount wird wie ein
Benutzer behandelt; verwenden Sie Identity: System für Pipelines, die produktseitige Entitäten schreiben müssen. Die
Einstellung wird aus einem Cache gelesen, der innerhalb einer Minute aktualisiert wird. Assoziationen gesperrter
Entitäten sind nicht abgedeckt.
Einen Blueprint erstellen
Ein Blueprint besteht aus nur drei Dateien (oder zwei, wenn er keine Migrationen hat). Der minimal lauffähige Fall:
Schritt 1 — Die Ordnerstruktur anlegen
HelloBlueprint-1.0.0/
├── blueprint.yaml
└── seed-data/
└── entities.yaml
Schritt 2 — blueprint.yaml schreiben
$schema: https://schemas.meshmakers.cloud/blueprint-meta.schema.json
blueprintId: HelloBlueprint-1.0.0
description: |
Seeds two AutoIncrement counters used by the demo invoice and order flow.
ckModelDependencies:
- System-[2.0,3.0)
seedDataPath: seed-data/entities.yaml
Schritt 3 — seed-data/entities.yaml schreiben
$schema: https://schemas.meshmakers.cloud/runtime-model.schema.json
dependencies:
- System-2.0.0
entities:
- rtId: 65d5c447b420da3fb1238201
ckTypeId: System/AutoIncrement
rtWellKnownName: InvoiceCounter
attributes:
- id: System/AutoIncrement.End
value: 999999
- id: System/AutoIncrement.CurrentValue
value: 1000
- id: System/AutoIncrement.Format
value: "INV-{0:D6}"
- rtId: 65d5c447b420da3fb1238202
ckTypeId: System/AutoIncrement
rtWellKnownName: OrderCounter
attributes:
- id: System/AutoIncrement.End
value: 99999
- id: System/AutoIncrement.CurrentValue
value: 100
- id: System/AutoIncrement.Format
value: "ORD-{0:D5}"
Schritt 4 — Den Ordner in einen Katalog legen
Der einfachste Katalog ist das lokale Dateisystem. Der asset-repo-Service erwartet Blueprints unter dem Pfad, der über LocalFileSystemBlueprintCatalogOptions.RootPath konfiguriert wird. Für die lokale Entwicklung ist der Standardwert ~/.octo/local-blueprint-catalog/:
~/.octo/local-blueprint-catalog/
└── blueprints/v1/
└── HelloBlueprint/
└── 1.0.0/
├── blueprint.yaml
└── seed-data/
└── entities.yaml
Für veröffentlichte Kataloge (über GitHub Pages gehostet) gilt dasselbe Layout, aber auf jeder Ebene liegt ein generierter catalog.json-Index — siehe GitHub-Katalog-Layout weiter unten.
Schritt 5 — Installieren
octo-cli -c InstallBlueprint -b HelloBlueprint-1.0.0
Oder über Refinery Studio: siehe das Studio-Benutzerhandbuch.
Auf einem anderen Blueprint aufbauen
Blueprints setzen sich über Abhängigkeiten zusammen, nicht durch Bündelung. Um einen bestehenden Blueprint zu erweitern:
-
Deklarieren Sie die Abhängigkeit in Ihrer
blueprint.yaml:blueprintDependencies:- HelloBlueprint-[1.0,2.0) -
Referenzieren Sie seine CK-Modelle indirekt. Sie listen sie nicht erneut auf — die Abhängigkeitshülle importiert sie bereits.
-
Fügen Sie Ihre eigenen Seed-Daten hinzu. Ihre Entitäten leben im
rtBlueprintSource-Namespace Ihres Blueprints; die Entitäten vonHelloBlueprintbleiben dessen Eigentum. -
Wenden Sie normal an. Die Engine löst die transitive Hülle auf, wendet zuerst die Abhängigkeiten an (topologisch sortiert), dann Ihren Blueprint:
octo-cli -c InstallBlueprint -b ExtendedHello-1.0.0ListBlueprintInstallationszeigt dann beide Blueprints —HelloBlueprintträgtIsDependency: true.
Eigentumsregeln
- Jede Entität hat genau einen besitzenden Blueprint (
rtBlueprintSource). - Ein abhängiger Blueprint kann Entitäten, die seinen Abhängigkeiten gehören, nicht über Seed-Daten verändern — dieser Weg löst beim Anwenden einen
UserModified/OwnershipConflictaus. - Wenn der abhängige Blueprint diese Entitäten wirklich weiterentwickeln muss, liefern Sie ein Migrationsskript aus, das sie über
rtIdoder überrtWellKnownName + blueprintSourceOnly: trueals Ziel adressiert.
Deinstallation und Refcounts
- Das Deinstallieren von
ExtendedHelloentferntHelloBlueprintnicht, wenn irgendein anderer installierter Blueprint noch davon abhängt (Refcount > 0). octo-cli -c UninstallBlueprint -n ExtendedHello -ckaskadiert: entferntExtendedHellound bereinigt transitiv abhängige Blueprints als verwaist, deren Refcount auf null fällt.
Update-Modi
| Modus | Verhalten |
|---|---|
Safe | Nur neue Entitäten hinzufügen. Bestehende Entitäten werden in Ruhe gelassen, selbst wenn sie gesperrt sind. |
Merge | Neue hinzufügen + gesperrte Entitäten upserten. Entsperrte Entitäten lösen UserModified-Konflikte aus (Standard: skip). |
Full | Wie Merge, zusätzlich Entitäten löschen, die im Tenant existieren, aber nicht mehr im Seed. Entsperrt → Konflikt. |
Migration | Das Migrationsskript von der installierten Version zur Zielversion ausführen. Erforderlich für jede nicht-additive Änderung. |
Ein Pre-Update-Backup wird standardmäßig erstellt (CreateBackup = true). Deaktivieren Sie es mit CreateBackup = false nur, wenn Sie über einen alternativen Snapshot-Mechanismus verfügen.
Konfliktauflösung
Ein Konflikt wird ausgelöst, wenn eine entsperrte Entität (rtBlueprintLocked = false) einem Update im Weg steht.
| Typ | Ausgelöst, wenn |
|---|---|
UserModified | Das Seed möchte diese Entität aktualisieren, aber die Tenant-Entität wurde entsperrt. |
DeleteModified | Der Full-Modus möchte diese Entität löschen (nicht mehr im Seed), aber die Tenant-Entität wurde entsperrt. |
Die Standardauflösung pro Entität ist Skip. Der Aufrufer kann sie pro Entität überschreiben:
| Auflösung | Verhalten |
|---|---|
KeepUser | Die Version des Benutzers behalten, die Blueprint-Änderung überspringen. |
KeepBlueprint | Die Version des Blueprints anwenden. UserModified: Das Seed wird erneut angewendet und die Entität wird erneut gesperrt. DeleteModified (nur Full): Die Entität wird gelöscht. |
Merge | Wird derzeit als KeepUser behandelt (semantisches 3-Wege-Merge ist außerhalb des Umfangs). |
Skip | Diese Entität überspringen. |
Migrationsskripte
Für nicht-additive Änderungen (Umbenennen, Löschen, Transformieren) liefern Sie ein Migrationsskript aus und referenzieren es aus blueprint.yaml:
# MyBlueprint-2.0.0/migrations/from-1.0.0.yaml
$schema: https://schemas.meshmakers.cloud/blueprint-migration.schema.json
sourceVersion: "1.0.0"
targetVersion: "2.0.0"
description: "Migration from v1 to v2"
preConditions:
- type: EntityExists
target:
ckTypeId: System/Entity
rtWellKnownName: MainConfig
steps:
- stepId: rename-config-field
action: Transform
target:
ckTypeId: System/Entity
blueprintSourceOnly: true
transform:
type: Rename
sourceAttribute: LegacyVersion
targetAttribute: Version
- stepId: delete-deprecated
action: Delete
target:
ckTypeId: System/Entity
rtWellKnownName: LegacyConfig
blueprintSourceOnly: true
postValidations:
- validationId: still-have-config
type: EntityCount
target:
ckTypeId: System/Entity
expectedCount: 5
severity: Error
Referenz aus dem Manifest:
migrations:
- fromVersion: "1.0.0"
scriptPath: "migrations/from-1.0.0.yaml"
Unterstützte Schritt-Aktionen
| Aktion | Zweck |
|---|---|
Add | Eine Entität einfügen (die Daten tragen das vollständige RtEntityTcDto-Payload). |
Update | Attribute auf passenden Entitäten aktualisieren (die Daten sind ein { attributeName: value }-Dict). |
Delete | Passende Entitäten löschen (DeleteOptions.Erase — dauerhaft). |
Rename | Ein Attribut auf passenden Entitäten umbenennen (Kurzform für Transform vom Typ Rename). |
Transform | Typgesteuert: Rename, Copy, Delete, SetValue, MapValue. |
Für CK-Modell-Migrationen (wenn sich das Schema selbst weiterentwickelt) siehe CK-Modell-Migrationen. Blueprint-Migrationen transformieren Runtime-Entitäten; CK-Migrationen transformieren das Schema und die Entitäten gemeinsam.
Mehrfach-Blueprint-Installation
Ein Tenant kann beliebig viele Blueprints gleichzeitig hosten. Zwei Services verfolgen diesen State:
| Schnittstelle | Zweck |
|---|---|
ITenantBlueprintInstallations | Die aktuelle Menge installierter Blueprints (eine Zeile pro Blueprint, mit IsDependency-Flag). |
ITenantBlueprintHistory | Nur anhängbares Operationsprotokoll (Install, Update, Rollback, Uninstall) mit Zeitstempeln und Zählwerten. |
Beide werden als CK-Entitäten (System/BlueprintInstallation, System/BlueprintHistory) innerhalb des eigenen Runtime-Repositorys des Tenants persistiert.
Backup und Rollback
Jedes Update erstellt standardmäßig ein Pre-Update-Backup. Rollback stellt den gesamten Tenant-Snapshot wieder her — es ist eine vollständige Wiederherstellung, kein semantisches Rückgängigmachen einzelner Migrationsschritte. Nach dem Rollback stimmen die BlueprintInstallation-Zeilen mit dem Snapshot überein; ein partielles Rückgängigmachen wird nicht unterstützt.
Kataloge
| Katalog | Beschreibung |
|---|---|
LocalFileSystemBlueprintCatalog | Lädt Blueprints aus dem Dateisystem. |
EmbeddedResourceBlueprintCatalog | Lädt Blueprints aus Assembly-Ressourcen. |
PublicGitHubBlueprintCatalog | Liest Blueprints von einer öffentlichen GitHub-Pages-Site. |
PrivateGitHubBlueprintCatalog | Liest Blueprints aus einem privaten/internen GitHub-Repository (Schreibvorgänge über Octokit). |
GitHub-Katalog-Layout
blueprints/v1/
├── catalog.json # Root catalog index
└── m/ # First letter of blueprint name (lowercase)
└── MyBlueprint/
├── catalog.json # Library catalog (one entry per major version)
└── 1/
├── catalog.json # Version catalog (list of versions)
└── MyBlueprint-1.0.0/
├── blueprint.yaml
├── seed-data/
└── migrations/
Die drei catalog.json-Ebenen werden vom Publish-Ablauf auf der Engine-Seite generiert — Anwendungscode spricht mit IBlueprintCatalogManager, nicht direkt mit den Katalogdateien.
Best Practices
- Kleine, fokussierte Blueprints. Ein Blueprint pro Domäne/Feature. Setzen Sie über
blueprintDependencieszusammen, nicht durch Bündelung nicht zusammengehöriger Entitäten. - Verwenden Sie Versionsbereiche für Abhängigkeiten.
[1.0,)hält die Dinge flexibel; das Pinnen exakter Versionen ist fürblueprintIdin Ordnung, aber bei Abhängigkeiten selten sinnvoll. - Sparsame Seed-Daten. Liefern Sie nur essenzielle Bootstrap-Daten aus — keine Testdaten, keine kundenspezifischen Details und niemals Zugangsdaten (siehe Secret-Attribute in Seed-Daten).
- Verwaltete Entitäten sperren. Der Standard von
rtBlueprintLockedisttrue; überschreiben Sie ihn nur mitfalse, wenn Sie beabsichtigen, dass der Benutzer sofort das Eigentum übernimmt. Damit Benutzer gesperrte Entitäten nicht bearbeiten können, aktivieren Sie den Typ mitProtectBlueprintLocked. - Migrationsskripte für breaking changes. Schema-Umbenennungen, Löschungen und Werttransformationen benötigen ein explizites Skript. Additive Änderungen funktionieren allein über Merge.
- Mit Dry-Run testen.
UpdateBlueprint -drsimuliert, ohne zu persistieren. - Backups behalten. Die standardmäßige Backup-Erstellung ist aktiviert; deaktivieren Sie sie nur, wenn Sie über einen alternativen Snapshot-Mechanismus verfügen.
Siehe auch
- CK-Modell-Migrationen — wenn sich das Schema selbst ändert
- octo-cli — ListBlueprints und verwandte Blueprint-Befehle (Install / Update / Rollback / Uninstall) — CLI-Befehle für Blueprint-Operationen
- Studio: Blueprints — UI-Rundgang im Data Refinery Studio