structurizr-architecture-sync
Structurizr Architecture Synchronization
Context (Input)
Use this skill when:
- Adding new components (controllers, handlers, services, repositories)
- Creating new entities or aggregates
- Modifying component relationships or dependencies
- Implementing new architectural patterns (CQRS, events, subscribers)
- Adding infrastructure components (databases, caches, message brokers)
- Refactoring that changes component structure
- After fixing Deptrac violations (may indicate architecture drift)
- Creating new bounded contexts or modules
- Implementing new API endpoints with significant handlers
Task (Function)
Keep the Structurizr workspace (workspace.dsl) synchronized with codebase changes, ensuring C4 model diagrams accurately represent the current system architecture.
Success Criteria:
workspace.dslcontains all significant components- Component relationships match actual code dependencies
- Layer groupings (Application/Domain/Infrastructure) are accurate
- Component descriptions reflect current purpose
- All infrastructure dependencies are documented
- C4 diagrams render without errors (check at
http://localhost:${STRUCTURIZR_PORT:-8080})
Quick Start: Update Architecture in 5 Steps
Complete Template: See reference/workspace-template.md for full workspace.dsl structure.
Step 1: Identify Architectural Changes
Determine if your code changes are architecturally significant:
✅ DO update workspace.dsl when adding:
- Processors (HTTP/GraphQL handlers)
- Command Handlers (CQRS pattern)
- Event Subscribers (event-driven patterns)
- Entities (core domain objects)
- Domain Events (significant business events)
- Repositories (data access)
- Event Bus or infrastructure services
- External dependencies (DB, Cache, Message Broker)
❌ DON'T update for:
- Factory classes
- Transformer classes (unless critical)
- Value objects (unless architecturally significant)
- Interface definitions (except hexagonal ports)
- Base classes
- DTOs and input/output objects
- Utility classes and helpers
Target: 15-25 components per diagram for clarity.
Step 2: Add Component to Appropriate Group
Edit workspace.dsl and add component in the correct layer group:
group "Application" {
newProcessor = component "NewProcessor" "Handles new requests" "RequestProcessor" {
tags "Item"
}
}
Layers:
group "Application"- Controllers, Processors, Handlers, Subscribersgroup "Domain"- Entities, Domain Eventsgroup "Infrastructure"- Repositories, Event Bus, Infrastructure services
External dependencies (database, cache, messageBroker) go OUTSIDE groups at container level.
See: reference/dsl-syntax.md for complete syntax.
Step 3: Define Relationships
Add relationships showing how your component interacts:
// After all component definitions
newProcessor -> commandHandler "dispatches NewCommand"
commandHandler -> repository "uses"
repository -> database "accesses data"
Common patterns: See reference/relationship-patterns.md
Step 4: Verify Diagram Renders
View the updated diagram:
# Refresh browser (Structurizr Lite auto-reloads)
# Port is configurable via STRUCTURIZR_PORT in .env (default: 8080)
open http://localhost:${STRUCTURIZR_PORT:-8080}
# Navigate to "Diagrams" → "Components_All"
Check for:
- No syntax errors displayed
- New component appears
- Relationships are visible
- Component is in correct layer group
Step 5: Position and Commit
- Drag components in the UI to improve layout
- Click "Save workspace" button (saves to
workspace.json) - Commit both files:
git add workspace.dsl workspace.json
git commit -m "feat: update architecture with new processor"
Diagram as Code Workflow
Setup (Already Configured)
Docker: Structurizr Lite runs in docker-compose.override.yml:
structurizr:
image: structurizr/lite:2024.07.02
ports:
- '${STRUCTURIZR_PORT}:8080'
volumes:
- ./:/usr/local/structurizr
Access: http://localhost:${STRUCTURIZR_PORT:-8080} (port configurable via .env)
Standard Development Flow
- Implement code changes → Add handler, entity, repository
- Update workspace.dsl → Add component + relationships
- View locally → Refresh browser at configured port
- Position components → Drag in UI, click "Save workspace"
- Commit together → Code + workspace.dsl + workspace.json in same PR
Manual Positioning in UI
Automatic layout doesn't work well - use manual positioning:
- Open Structurizr UI in browser
- Navigate to "Diagrams" → "Components_All"
- Drag components to arrange (left-to-right flow recommended)
- Click "Save workspace" button in top-right
- Positions saved to
workspace.jsonin project root - Commit
workspace.jsonwithworkspace.dsl
Layout best practices:
- Processors/Controllers on the left (entry points)
- Command Handlers in the middle (business logic)
- Repositories to the right of handlers
- Database/Cache/Message Broker on far right (external)
Common mistakes: See reference/common-mistakes.md for complete guide.
Reference Documentation
Detailed Guides
- C4 Model Fundamentals - Understanding C4 modeling
- DSL Syntax Reference - Complete Structurizr DSL syntax
- Component Identification - What to document
- Relationship Patterns - Common relationship types
- Workspace Template - Complete workspace.dsl template
- Common Mistakes - Pitfalls and solutions
Examples
- Adding CQRS Pattern - Command handlers, events, subscribers
- Adding API Endpoint - Controllers, processors, transformers
- Adding Domain Entity - Entities, value objects, factories
- Refactoring Components - Updating relationships during refactoring
Critical Principles
What Makes a Good Architecture Diagram
Clarity over Completeness:
- 15-25 components (optimal readability)
- Focus on architectural significance
- Clear left-to-right or top-to-bottom flow
- External dependencies clearly visible
Layer Separation:
- Application: Entry points and orchestration
- Domain: Business logic and entities
- Infrastructure: Technical implementation
Meaningful Relationships:
- Show actual code dependencies
- Use descriptive labels
- Avoid circular dependencies
Alignment with Deptrac
Layer groupings in workspace.dsl MUST match Deptrac configuration:
group "Application" ↔ Application layer in deptrac.yaml
group "Domain" ↔ Domain layer in deptrac.yaml
group "Infrastructure" ↔ Infrastructure layer in deptrac.yaml
This ensures architecture documentation matches enforced boundaries.
Integration with Other Skills
Use this skill after:
- implementing-ddd-architecture - After creating domain model
- api-platform-crud - After adding API endpoints
- deptrac-fixer - After fixing layer violations
Use this skill before:
- documentation-sync - Update docs with architecture
- ci-workflow - Validate all changes
Troubleshooting
Common Issues
Issue: Structurizr UI shows "Element does not exist" error
Solution: Check component variable names in relationships match the component definitions exactly. See common-mistakes.md.
Issue: Diagram shows components in wrong positions after pull
Solution: Ensure workspace.json is committed along with workspace.dsl. The JSON file stores manual positions.
Issue: DSL syntax validation fails
Solution:
- Check balanced braces
{} - Verify all components are defined before relationships
- Ensure no duplicate variable names
- Compare with workspace-template.md
Issue: Too many components (30+), diagram is cluttered
Solution: Follow component-identification.md - aim for 15-25 components. Omit DTOs, utilities, and factories.
Issue: Can't determine if component should be documented
Solution: Use the decision matrix in component-identification.md or the TL;DR section.
External Resources
- Structurizr DSL Documentation: https://docs.structurizr.com/dsl
- C4 Model: https://c4model.com/
- Structurizr Lite: https://docs.structurizr.com/lite
- User Service Example (VilnaCRM organization reference): https://github.com/VilnaCRM-Org/user-service/wiki/Design-and-Architecture-Documentation