{
"$schema": "https://raw.githubusercontent.com/docToolchain/Bausteinsicht/main/schema/bausteinsicht.schema.json",
// Define available element and relationship kinds
"specification": {
"elements": {
"actor": {
"notation": "Actor",
"description": "A person or external system that interacts with the system"
},
"system": {
"notation": "Software System",
"description": "A top-level software system",
"container": true
},
"container": {
"notation": "Container",
"description": "A deployable unit within a system",
"container": true
},
"component": {
"notation": "Component",
"description": "A logical grouping within a container",
"container": true
}
},
"relationships": {
"uses": { "notation": "uses" },
"async": { "notation": "async", "dashed": true }
}
},
// The actual architecture elements and their hierarchy
"model": {
"customer": {
"kind": "actor",
"title": "Customer",
"description": "End user of the webshop"
},
"webshop": {
"kind": "system",
"title": "Webshop",
"description": "Online shopping platform",
"children": {
"api": {
"kind": "container",
"title": "REST API",
"technology": "Spring Boot",
"description": "Handles all HTTP requests",
"children": {
"auth": {
"kind": "component",
"title": "Auth Module",
"technology": "Spring Security"
}
}
},
"db": {
"kind": "container",
"title": "Database",
"technology": "PostgreSQL",
"description": "Stores all persistent data"
}
}
}
},
// Connections between elements
"relationships": [
{
"from": "customer",
"to": "webshop.api",
"label": "uses",
"kind": "uses",
"description": "Sends HTTP requests"
},
{
"from": "webshop.api",
"to": "webshop.db",
"label": "reads/writes",
"kind": "uses"
}
],
// View definitions
"views": {
"context": {
"title": "System Context",
"include": ["customer", "webshop"],
"description": "High-level system overview"
},
"containers": {
"title": "Container View",
"scope": "webshop",
"include": ["customer", "webshop.*"],
"description": "Webshop internals"
}
}
}
Data Models
Overview
Bausteinsicht works with three data formats that must be kept in sync:
| Format | Purpose | Location |
|---|---|---|
JSON Model (JSONC) |
Single source of truth for the architecture |
|
JSON Schema |
Validation and IDE support for the model |
Published schema file |
draw.io XML (mxGraph) |
Visual representation of architecture views |
|
JSON Model Structure
The model consists of four top-level sections:
Element Properties
| Property | Type | Required | Description |
|---|---|---|---|
|
string |
yes |
Element kind as defined in specification |
|
string |
yes |
Display name shown in diagrams |
|
string |
no |
Detailed description (shown in tooltips) |
|
string |
no |
Technology/framework used |
|
string[] |
no |
Tags for filtering and styling |
|
object |
no |
Nested child elements (only if kind has |
|
object |
no |
Arbitrary key-value metadata |
The key of each element in the model object (e.g., "customer", "api") serves as its unique ID.
Nested elements are referenced using dot notation: "webshop.api.auth".
Relationship Properties
| Property | Type | Required | Description |
|---|---|---|---|
|
string |
yes |
Source element ID (dot notation for nested) |
|
string |
yes |
Target element ID (dot notation for nested) |
|
string |
no |
Display label on the connector |
|
string |
no |
Relationship kind as defined in specification |
|
string |
no |
Detailed description |
View Properties
| Property | Type | Required | Description |
|---|---|---|---|
|
string |
yes |
View title displayed as tab/page name |
|
string |
no |
Parent element whose children are shown |
|
string[] |
no |
Element IDs to include (supports wildcard patterns, see [Wildcard Patterns]) |
|
string[] |
no |
Element IDs to exclude from the view (supports wildcard patterns, see [Wildcard Patterns]) |
|
string |
no |
View description |
|
string |
no |
Auto-layout mode for new pages: |
[[Wildcard Patterns]] ==== Wildcard Patterns
The include and exclude arrays support the following patterns for matching elements:
| Pattern | Description |
|---|---|
|
Exact match — includes only the element with the given ID |
|
All top-level elements only (IDs without dots) |
|
All elements at all levels (entire model) |
|
Direct children of |
|
All descendants of |
JSONC Comment Support
Model files use the JSONC (JSON with Comments) format. Both comment styles are supported:
-
//— single-line comments -
/\* … */— block comments (can span multiple lines)
draw.io XML Structure
Bausteinsicht generates and reads uncompressed draw.io XML (compressed="false") for Git-friendliness.
File Structure
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="bausteinsicht" compressed="false">
<!-- One <diagram> per view -->
<diagram id="view-context" name="System Context">
<mxGraphModel dx="1422" dy="794" grid="1" gridSize="10"
page="1" pageWidth="1169" pageHeight="827"
background="#ffffff">
<root>
<!-- Mandatory base cells (always present) -->
<mxCell id="0" />
<mxCell id="1" parent="0" />
<!-- All diagram content goes here -->
</root>
</mxGraphModel>
</diagram>
</mxfile>
Mandatory Base Cells
Every page requires exactly two base cells:
-
id="0"— root cell, no parent -
id="1" parent="0"— default drawing layer, parent for all top-level content
These are never modified by Bausteinsicht.
Elements as <object> with Custom Properties
Every Bausteinsicht element is wrapped in an <object> element to carry custom metadata.
The nested <mxCell> has no id — the <object> owns the ID.
The parent <mxCell> uses container=1 so that child text sub-cells are grouped inside it.
<object label=""
id="containers--webshop.api"
bausteinsicht_id="webshop.api"
bausteinsicht_kind="container"
technology="Spring Boot"
tooltip="Handles all HTTP requests">
<mxCell style="rounded=1;whiteSpace=wrap;html=1;
fillColor=#438DD5;strokeColor=#3C7FC0;fontSize=13;container=1;"
vertex="1"
parent="1">
<mxGeometry x="200" y="150" width="240" height="150" as="geometry" />
</mxCell>
</object>
<!-- Text sub-cells: separate mxCell children for title, technology, description -->
<mxCell id="containers--webshop.api-title" value="REST API"
style="text;html=1;fontSize=14;fontStyle=1;fontColor=#ffffff;fillColor=none;strokeColor=none;align=center;verticalAlign=middle;movable=0;resizable=0;deletable=0;editable=0;"
vertex="1" parent="containers--webshop.api">
<mxGeometry x="0" y="20" width="240" height="30" as="geometry" />
</mxCell>
<mxCell id="containers--webshop.api-tech" value="[Spring Boot]"
style="text;html=1;fontSize=11;fontStyle=2;fontColor=#CCCCCC;fillColor=none;strokeColor=none;align=center;verticalAlign=middle;movable=0;resizable=0;deletable=0;editable=0;"
vertex="1" parent="containers--webshop.api">
<mxGeometry x="0" y="55" width="240" height="20" as="geometry" />
</mxCell>
<mxCell id="containers--webshop.api-desc" value="Handles all HTTP requests"
style="text;html=1;fontSize=10;fontColor=#BBBBBB;fillColor=none;strokeColor=none;align=center;verticalAlign=middle;movable=0;resizable=0;deletable=0;editable=0;"
vertex="1" parent="containers--webshop.api">
<mxGeometry x="0" y="80" width="240" height="40" as="geometry" />
</mxCell>
Custom properties on <object>:
| Property | Purpose |
|---|---|
|
Empty string ( |
|
Cell ID — page-scoped for file-wide uniqueness: |
|
The canonical element ID from the model (e.g., |
|
Element kind (actor, system, container, component) |
|
Technology string from the model |
|
Element description — shown on hover in draw.io |
|
Drill-down navigation link (see Navigation section) |
Text Sub-Cells (Grouped Labels)
Each element’s display text is decomposed into independent child <mxCell> elements, giving full control over font size, color, weight, and vertical positioning. The parent element has label="" and container=1.
Three child cell types exist, identified by their ID suffix:
| Sub-Cell | ID Suffix | Style |
|---|---|---|
Title |
|
Bold, larger font (14px), element’s font color |
Technology |
|
Italic, smaller font (11px), |
Description |
|
Smallest font (10px), lighter color |
Child cells use movable=0;resizable=0;deletable=0;editable=0; to prevent accidental manipulation in draw.io.
Technology and description sub-cells are only created when the corresponding field is non-empty. Actor elements have only a title sub-cell.
HTML Labels (Backward Compatible)
Legacy draw.io files may still use HTML-formatted label attributes instead of sub-cells. Bausteinsicht reads both formats: it checks for child text sub-cells first, and falls back to parsing the HTML label if none are found.
The legacy label format has up to three lines:
-
Title — bold (
<b>Title</b>) -
Technology — grey, wrapped in square brackets, italic
-
Description — lighter grey, smaller font
Entity escaping rules for HTML labels:
| Character | Escaped |
|---|---|
|
|
|
|
|
|
|
|
Containers (Nested Elements)
Systems and containers that hold children use the swimlane style.
Child elements set parent to the container’s ID.
Child coordinates are relative to the container’s top-left corner (below the header).
<!-- Container (system boundary) -->
<object label="Webshop" id="webshop"
bausteinsicht_id="webshop"
bausteinsicht_kind="system">
<mxCell style="swimlane;startSize=30;fillColor=#f5f5f5;
strokeColor=#666666;fontColor=#333333;
whiteSpace=wrap;html=1;rounded=1;container=1;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="500" height="300" as="geometry" />
</mxCell>
</object>
<!-- Child element — parent references the container -->
<object label=""
id="containers--webshop.api"
bausteinsicht_id="webshop.api"
bausteinsicht_kind="container"
technology="Spring Boot">
<mxCell style="rounded=1;whiteSpace=wrap;html=1;
fillColor=#438DD5;strokeColor=#3C7FC0;container=1;"
vertex="1"
parent="webshop">
<mxGeometry x="30" y="60" width="240" height="150" as="geometry" />
</mxCell>
</object>
<!-- Sub-cells for the child element (parent = child's cell ID) -->
<mxCell id="containers--webshop.api-title" value="REST API"
style="text;html=1;fontSize=14;fontStyle=1;..." vertex="1"
parent="containers--webshop.api">
<mxGeometry x="0" y="20" width="240" height="30" as="geometry" />
</mxCell>
Connectors (Relationships)
Connectors use edge="1" and reference source/target by their page-scoped cell IDs.
Connectors always use parent="1" (the layer), even when connecting shapes inside containers.
<mxCell id="rel-containers--customer-containers--webshop.api-0"
value="uses"
style="edgeStyle=orthogonalEdgeStyle;rounded=1;html=1;
endArrow=block;endFill=1;strokeColor=#666666;"
edge="1"
source="containers--customer"
target="containers--webshop.api"
parent="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
Connection point strategy:
By omitting exitX/exitY/entryX/entryY style properties, draw.io auto-routes connectors from the nearest perimeter point. This ensures connectors look correct when elements are moved by the user.
Connector ID convention: rel-<scopedSource>-<scopedTarget>-<index> where scoped IDs use the <viewID>--<elementID> format and <index> is a zero-based integer for disambiguation when multiple relationships exist between the same pair (e.g., rel-containers—customer-containers—webshop.api-0).
Cross-Page Navigation (Drill-Down)
Elements link to detail views using the link attribute on <object>:
<!-- System element with link to container view -->
<object label="Webshop" id="webshop"
bausteinsicht_id="webshop"
bausteinsicht_kind="system"
link="data:page/id,view-containers">
<mxCell style="..." vertex="1" parent="1">
<mxGeometry ... />
</mxCell>
</object>
Link format: data:page/id,<diagram-id> where <diagram-id> matches the id attribute of the target <diagram> element.
Back-navigation buttons are generated in detail views:
<object label="&larr; System Context" id="nav-back-context"
link="data:page/id,view-context">
<mxCell style="rounded=1;fillColor=#f8cecc;strokeColor=#b85450;html=1;fontSize=10;"
vertex="1" parent="1">
<mxGeometry x="20" y="20" width="140" height="30" as="geometry" />
</mxCell>
</object>
Multi-Page Structure
Each view is a separate <diagram> element. The id attribute uses the format view-<viewKey> (e.g., view-context for a view with key "context").
The name attribute is the view title displayed as the tab label.
<mxfile host="bausteinsicht" compressed="false">
<diagram id="view-context" name="System Context">
<mxGraphModel ...>...</mxGraphModel>
</diagram>
<diagram id="view-containers" name="Container View">
<mxGraphModel ...>...</mxGraphModel>
</diagram>
</mxfile>
Base cells (id="0" and id="1") exist on every page with the same IDs — this is standard draw.io convention.
Element cell IDs are page-scoped using <viewID>--<elementID> to ensure file-wide uniqueness (e.g., context—customer and containers—customer for the same element on different pages). The bausteinsicht_id attribute always holds the canonical element ID.
Go Struct Mappings
// Top-level model file
type BausteinsichtModel struct {
Schema string `json:"$schema,omitempty"`
Specification Specification `json:"specification"`
Model map[string]Element `json:"model"`
Relationships []Relationship `json:"relationships"`
Views map[string]View `json:"views"`
}
// Specification defines available element and relationship kinds
type Specification struct {
Elements map[string]ElementKind `json:"elements"`
Relationships map[string]RelationshipKind `json:"relationships,omitempty"`
}
type ElementKind struct {
Notation string `json:"notation"`
Description string `json:"description,omitempty"`
Container bool `json:"container,omitempty"`
}
type RelationshipKind struct {
Notation string `json:"notation"`
Dashed bool `json:"dashed,omitempty"`
}
// Element represents an architecture building block
type Element struct {
Kind string `json:"kind"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
Technology string `json:"technology,omitempty"`
Tags []string `json:"tags,omitempty"`
Children map[string]Element `json:"children,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}
// Relationship connects two elements
type Relationship struct {
From string `json:"from"`
To string `json:"to"`
Label string `json:"label,omitempty"`
Kind string `json:"kind,omitempty"`
Description string `json:"description,omitempty"`
}
// View defines which elements appear in a diagram
type View struct {
Title string `json:"title"`
Scope string `json:"scope,omitempty"`
Include []string `json:"include,omitempty"`
Exclude []string `json:"exclude,omitempty"`
Description string `json:"description,omitempty"`
}
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.