Skip to content

feat: Multi-Model Workspace — Merge Team Models into Platform View #293

@paulefl

Description

@paulefl

Beschreibung

Allow merging multiple architecture.jsonc files (one per team, bounded context, or domain) into a unified workspace view. Each team owns their local model; a workspace.jsonc config references all models and generates cross-team views showing inter-domain dependencies.

Motivation

  • Large organizations have multiple teams, each with their own architecture model
  • There is currently no way to generate a platform-level view spanning multiple models
  • Teams should not need to copy elements from other teams' models into their own
  • Cross-model relationships (e.g. Orders → Payments) need a central place to be defined

Proposed Implementation

Workspace config:

// workspace.jsonc
{
  "workspace": {
    "name": "E-Commerce Platform",
    "models": [
      { "id": "orders",   "path": "teams/orders/architecture.jsonc",   "prefix": "orders" },
      { "id": "payments", "path": "teams/payments/architecture.jsonc", "prefix": "payments" }
    ]
  },
  "crossModelRelationships": [
    { "id": "xr-001", "from": "orders/order-service", "to": "payments/payment-service", "label": "charges via" }
  ],
  "views": [
    { "key": "platform", "title": "Platform Overview", "include-from": ["orders", "payments"], "include-kinds": ["system", "service"] }
  ]
}

New commands:

bausteinsicht workspace init
bausteinsicht workspace merge    [--workspace workspace.jsonc]
bausteinsicht workspace validate [--workspace workspace.jsonc]
bausteinsicht workspace list     [--workspace workspace.jsonc]

ID namespacing: elements are prefixed with model idorders/order-service, payments/payment-service — no ID collisions.

Validation: missing model paths, conflicting kind definitions, unresolved cross-model references.

Implementation Plan

Plan: Multi-Model Workspace

Purpose

Allow merging multiple architecture.jsonc files (e.g. one per team, bounded context, or domain) into a unified workspace view. Teams own their local model; a workspace config references all team models and generates cross-team views showing inter-domain relationships.

CLI Interface

bausteinsicht workspace init     [--output workspace.jsonc]
bausteinsicht workspace merge    [--workspace <file>] [--output <drawio-file>]
bausteinsicht workspace validate [--workspace <file>]
bausteinsicht workspace list     [--workspace <file>]

Example

bausteinsicht workspace merge --workspace workspace.jsonc
# → Merges all referenced models, generates workspace-architecture.drawio

Workspace Config Format

// workspace.jsonc
{
  "workspace": {
    "name": "E-Commerce Platform",
    "models": [
      { "id": "orders",   "path": "teams/orders/architecture.jsonc",   "prefix": "orders" },
      { "id": "payments", "path": "teams/payments/architecture.jsonc", "prefix": "payments" },
      { "id": "catalog",  "path": "teams/catalog/architecture.jsonc",  "prefix": "catalog" }
    ]
  },
  "views": [
    {
      "key": "platform-context",
      "title": "Platform Context",
      "include-from": ["orders", "payments", "catalog"],
      "include-kinds": ["system", "service"],   // only top-level kinds
      "show-cross-model-relationships": true
    }
  ],
  "crossModelRelationships": [
    {
      "id": "xr-001",
      "from": "orders/order-service",    // prefixed element ID
      "to": "payments/payment-service",
      "label": "charges via"
    }
  ]
}

ID Namespacing

Each model's elements are prefixed with the model's id to avoid collisions:

  • orders/order-service (from orders model)
  • payments/payment-service (from payments model)

Elements already prefixed in cross-model relationships are resolved at merge time.

Merge Algorithm

  1. Load all referenced model files
  2. Prefix all element and relationship IDs with model id
  3. Merge spec.elementKinds (deduplicate by id)
  4. Merge model.elements and model.relationships
  5. Add crossModelRelationships to merged relationships
  6. Resolve workspace views against merged element set
  7. Run standard forward sync to generate draw.io output

Validation

  • Warn if a model path does not exist
  • Error if two models define conflicting element kinds with different properties
  • Warn if a cross-model relationship references a non-existent prefixed element ID
  • Validate that workspace views only reference valid model IDs in include-from

View Filtering for Workspace Views

Workspace views support include-kinds to show only high-level elements (avoiding low-level noise in cross-team views):

{
  "key": "domain-overview",
  "include-from": ["orders", "payments"],
  "include-kinds": ["system"],         // show only system-level elements
  "exclude-kinds": ["database", "cache"]
}

File Layout (Recommended)

platform/
├── workspace.jsonc                    ← workspace config
├── workspace-architecture.drawio      ← generated merged diagram
├── teams/
│   ├── orders/
│   │   ├── architecture.jsonc         ← orders team model
│   │   └── architecture.drawio        ← orders team diagram
│   ├── payments/
│   │   ├── architecture.jsonc
│   │   └── architecture.drawio
│   └── catalog/
│       ├── architecture.jsonc
│       └── architecture.drawio

Architecture

New / Modified Files

File Change
internal/workspace/types.go New: WorkspaceConfig, ModelRef, CrossModelRelationship
internal/workspace/loader.go New: load and prefix all referenced models
internal/workspace/merge.go New: MergeModels(refs []LoadedModel) BausteinsichtModel
internal/workspace/validate.go New: cross-model reference validation
cmd/bausteinsicht/workspace.go New workspace command with subcommands

Testing

  • Unit test: MergeModels with two models → verify ID prefixing
  • Unit test: conflicting kind definitions → error
  • Unit test: cross-model relationship resolves correctly after prefix
  • E2E test: workspace with 3 models → merge → draw.io contains elements from all models
  • Test: missing model path → clear error message

Affected Components

  • internal/workspace/ — new package (loader, merge, validate)
  • cmd/bausteinsicht/workspace.go — new command with subcommands

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpost-releaseShould be done after v1 releasepriority:4-laterTier 4: long-term, needs ecosystem maturitystoryStory: implementable unit of work

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions