Dieser Post setzt den fünfundzwanzigsten Teil fort. Ein Architekturmodell das nur eine Person pflegt, hat kein Merge-Problem. Sobald mehrere Teams am gleichen Repository arbeiten, ändert sich das. Bausteinsicht bringt dafür gute Voraussetzungen mit — aber man muss wissen wo die Grenzen liegen.
Was in JSONC gut mergebar ist
JSONC ist ein Textformat. Git merged Textdateien zeilenbasiert. Das bedeutet:
Gut mergebar:
Neue Elemente hinzufügen in
model— solange die Elemente unterschiedliche IDs haben, sind das verschiedene Zeilen ohne ÜberschneidungNeue Views hinzufügen in
views— analoges PrinzipNeue Tags in
specification.tagsergänzen
Konfliktanfällig:
Dasselbe Element gleichzeitig ändern (title, description, technology)
Die Reihenfolge von Elementen ändern — Git sieht das als Löschung + Einfügung
specification.elementsundspecification.relationships— diese Bereiche werden seltener geändert, aber wenn, dann oft von mehreren gleichzeitig
draw.io XML ist schwieriger: Die .drawio-Datei enthält XML mit IDs und Positionen. Merge-Konflikte dort sind schwerer aufzulösen als JSONC. Faustregel: das JSONC-Modell ist der Wahrheitsspeicher, die draw.io-Datei ist regenerierbar per sync.
Ownership-Conventions
In einem größeren System hat jedes Team einen Bereich im Modell den es pflegt. Conventions helfen dabei Konflikte strukturell zu vermeiden, nicht nur zu reparieren.
Empfehlung: Element-IDs mit Team-Präfix:
{
"model": {
"backend.auth-service": { "kind": "service", "title": "Auth Service" },
"backend.user-service": { "kind": "service", "title": "User Service" },
"frontend.shop-ui": { "kind": "frontend", "title": "Shop UI" },
"infra.postgres": { "kind": "database", "title": "PostgreSQL" }
}
}Das Backend-Team ändert backend., das Frontend-Team ändert frontend..
Beziehungen zwischen Teams — backend.auth-service → infra.postgres — liegen im Einflussbereich des Consumers (wer die Beziehung initiiert, definiert sie).
CODEOWNERS-Datei: In GitHub lässt sich das mit CODEOWNERS durchsetzen:
# CODEOWNERS
architecture/ @architecture-team # jede Änderung braucht ReviewOder feiner (wenn das Modell aufgeteilt ist):
architecture/specification/ @all-teams
architecture/model/backend/ @backend-team
architecture/model/frontend/ @frontend-team| Bausteinsicht speichert alles in einer JSONC-Datei. Wenn Teams wirklich unabhängig arbeiten wollen, ist das Workspace-Feature (Teil 16) die Lösung — separate Modelle mit expliziten Querverweisen. |
Merge-Konflikte auflösen
Ein typischer JSONC-Konflikt sieht so aus:
{
"model": {
<<<<<<< HEAD
"backend.auth-service": {
"kind": "service",
"title": "Authentication Service",
"technology": "Go"
},
=======
"backend.auth-service": {
"kind": "service",
"title": "Auth Service",
"technology": "Go 1.22"
},
>>>>>>> feature/update-auth
}
}Strategie:
Konflikt in einem JSON-Editor öffnen (kein reines Text-Merge)
Inhaltliche Entscheidung treffen — welcher Titel, welche Technology-Version?
Manuell zusammenführen,
bausteinsicht validateausführenWenn draw.io-Datei ebenfalls Konflikt hat: verwerfen und
bausteinsicht syncneu ausführen — die JSONC-Seite ist der Wahrheitsspeicher
bausteinsicht validate --format json nach jedem Merge ausführen. Der Exit-Code 1 bei Fehlern verhindert dass ein kaputtes Modell in main landet. |
Architektur-Review im Pull Request
Architekturänderungen im PR sichtbar zu machen ist der eigentliche Vorteil von Architecture-as-Code.
Workflow:
Entwickler öffnet Feature-Branch, ändert das Modell
CI führt
bausteinsicht validateundbausteinsicht diffaus (→ Teil 24)Diff-Output erscheint als PR-Kommentar: welche Elemente wurden hinzugefügt, geändert, entfernt
Reviewer sieht die Architekturänderung direkt im PR ohne lokale Installation
Was ein guter Architektur-PR enthält:
Nur Änderungen am Modell die zum Feature passen — kein Refactoring im gleichen PR
validate-Ergebnis ist grünBeschreibung die erklärt warum das Modell so geändert wurde, nicht nur was
Wann braucht eine Änderung ein Review?
| Änderung | Review nötig? |
|---|---|
Neues Blatt-Element im bestehenden System | Optional — Team-internes Review reicht |
Neue externe Abhängigkeit | Ja — betrifft andere Teams |
Änderung in | Ja — ändert das Schema für alle |
View hinzufügen oder entfernen | Optional — betrifft keine Logik |
Element löschen das andere referenzieren | Ja — |
Ein realistischer Team-Workflow
git checkout -b feature/add-notification-service
# Modell ändern: notification-service zu model hinzufügen
# Beziehungen: shop-api → notification-service, notification-service → sendgrid
bausteinsicht validate # lokal prüfen
bausteinsicht sync # draw.io aktualisieren
git add architecture/
git commit -m "arch: add notification service"
git push && gh pr createCI validiert, diff zeigt:
- ` Element `notification-service` (kind: service)
- ` Element sendgrid (kind: external)
- ` Relationship `shop-api` → `notification-service`
- ` Relationship notification-service → sendgrid
Reviewer sieht genau was sich architektonisch geändert hat — ohne die draw.io-Datei öffnen zu müssen.
Beispiel-Modell
Das Beispiel für diesen Teil (Team-Ownership per Tags, separate Team-Views) liegt unter teil_26.jsonc.
So sieht das Ergebnis in draw.io aus (bausteinsicht sync):
Das draw.io-File dafür findest du hier: teil_26.drawio
Generierte PNG-Dateien via bausteinsicht export --image-format png:



Generierte PlantUML-Diagramme via bausteinsicht export-diagram:
Weiter geht es mit Custom Notations
Sobald Teams eigene Sprache mitbringen — AUTOSAR-Komponenten, Hardware-Elemente, Domain-spezifische Konzepte — reicht die Standard-C4-Notation nicht mehr. Im nächsten Teil geht es darum wie man eigene Elementtypen mit eigenen Shapes in draw.io definiert.
Offizielle Dokumentation: User Manual · Tutorial auf doctoolchain.org