// C4 diagram AST structures based on C4 model package ast // C4Diagram represents a base C4 diagram type C4Diagram struct { Title *string `json:"title,omitempty"` Elements []*C4Element `json:"elements"` Relations []*C4Relation `json:"relations"` Boundaries []*C4Boundary `json:"boundaries"` Config map[string]any `json:"config,omitempty"` } // C4Element represents a C4 element (Person, System, Container, Component) type C4Element struct { ID string `json:"id"` Type C4ElementType `json:"type"` Name string `json:"name"` Description string `json:"description"` Technology *string `json:"technology,omitempty"` Properties map[string]any `json:"properties,omitempty"` } // C4ElementType represents the type of C4 element type C4ElementType string const ( C4ElementPerson C4ElementType = "person" C4ElementSystem C4ElementType = "system" C4ElementContainer C4ElementType = "container" C4ElementComponent C4ElementType = "component" C4ElementDatabase C4ElementType = "database" C4ElementQueue C4ElementType = "queue" C4ElementExternal C4ElementType = "external" ) // C4Relation represents a relationship between C4 elements type C4Relation struct { From string `json:"from"` To string `json:"to"` Label *string `json:"label,omitempty"` Technology *string `json:"technology,omitempty"` Type C4RelationType `json:"type"` Properties map[string]any `json:"properties,omitempty"` } // C4RelationType represents the type of C4 relation type C4RelationType string const ( C4RelationSync C4RelationType = "sync" C4RelationAsync C4RelationType = "async" C4RelationWebSocket C4RelationType = "websocket" ) // C4Boundary represents a boundary in C4 diagrams type C4Boundary struct { ID string `json:"id"` Type C4BoundaryType `json:"type"` Name string `json:"name"` Description *string `json:"description,omitempty"` Elements []string `json:"elements"` // IDs of elements within this boundary } // C4BoundaryType represents the type of C4 boundary type C4BoundaryType string const ( C4BoundarySystem C4BoundaryType = "system" C4BoundaryContainer C4BoundaryType = "container" ) // C4ContextDiagram represents a C4 Context diagram type C4ContextDiagram struct { C4Diagram } // Type returns the diagram type func (c *C4ContextDiagram) Type() DiagramType { return DiagramTypeC4Context } // Validate checks if the C4 Context diagram is valid func (c *C4ContextDiagram) Validate() error { // Basic validation - ensure all relations reference valid elements elementMap := make(map[string]bool) for _, element := range c.Elements { elementMap[element.ID] = true } for _, relation := range c.Relations { if !elementMap[relation.From] { return NewValidationError("relation references non-existent element: " + relation.From) } if !elementMap[relation.To] { return NewValidationError("relation references non-existent element: " + relation.To) } } return nil } // NewC4ContextDiagram creates a new C4 Context diagram func NewC4ContextDiagram() *C4ContextDiagram { return &C4ContextDiagram{ C4Diagram: C4Diagram{ Elements: make([]*C4Element, 0), Relations: make([]*C4Relation, 0), Boundaries: make([]*C4Boundary, 0), Config: make(map[string]any), }, } } // C4ContainerDiagram represents a C4 Container diagram type C4ContainerDiagram struct { C4Diagram } // Type returns the diagram type func (c *C4ContainerDiagram) Type() DiagramType { return DiagramTypeC4Container } // Validate checks if the C4 Container diagram is valid func (c *C4ContainerDiagram) Validate() error { return c.C4Diagram.validate() } // NewC4ContainerDiagram creates a new C4 Container diagram func NewC4ContainerDiagram() *C4ContainerDiagram { return &C4ContainerDiagram{ C4Diagram: C4Diagram{ Elements: make([]*C4Element, 0), Relations: make([]*C4Relation, 0), Boundaries: make([]*C4Boundary, 0), Config: make(map[string]any), }, } } // C4ComponentDiagram represents a C4 Component diagram type C4ComponentDiagram struct { C4Diagram } // Type returns the diagram type func (c *C4ComponentDiagram) Type() DiagramType { return DiagramTypeC4Component } // Validate checks if the C4 Component diagram is valid func (c *C4ComponentDiagram) Validate() error { return c.C4Diagram.validate() } // NewC4ComponentDiagram creates a new C4 Component diagram func NewC4ComponentDiagram() *C4ComponentDiagram { return &C4ComponentDiagram{ C4Diagram: C4Diagram{ Elements: make([]*C4Element, 0), Relations: make([]*C4Relation, 0), Boundaries: make([]*C4Boundary, 0), Config: make(map[string]any), }, } } // C4DynamicDiagram represents a C4 Dynamic diagram type C4DynamicDiagram struct { C4Diagram } // Type returns the diagram type func (c *C4DynamicDiagram) Type() DiagramType { return DiagramTypeC4Dynamic } // Validate checks if the C4 Dynamic diagram is valid func (c *C4DynamicDiagram) Validate() error { return c.C4Diagram.validate() } // NewC4DynamicDiagram creates a new C4 Dynamic diagram func NewC4DynamicDiagram() *C4DynamicDiagram { return &C4DynamicDiagram{ C4Diagram: C4Diagram{ Elements: make([]*C4Element, 0), Relations: make([]*C4Relation, 0), Boundaries: make([]*C4Boundary, 0), Config: make(map[string]any), }, } } // C4DeploymentDiagram represents a C4 Deployment diagram type C4DeploymentDiagram struct { C4Diagram } // Type returns the diagram type func (c *C4DeploymentDiagram) Type() DiagramType { return DiagramTypeC4Deployment } // Validate checks if the C4 Deployment diagram is valid func (c *C4DeploymentDiagram) Validate() error { return c.C4Diagram.validate() } // NewC4DeploymentDiagram creates a new C4 Deployment diagram func NewC4DeploymentDiagram() *C4DeploymentDiagram { return &C4DeploymentDiagram{ C4Diagram: C4Diagram{ Elements: make([]*C4Element, 0), Relations: make([]*C4Relation, 0), Boundaries: make([]*C4Boundary, 0), Config: make(map[string]any), }, } } // validate is a helper method for common C4 diagram validation func (c *C4Diagram) validate() error { elementMap := make(map[string]bool) for _, element := range c.Elements { elementMap[element.ID] = true } for _, relation := range c.Relations { if !elementMap[relation.From] { return NewValidationError("relation references non-existent element: " + relation.From) } if !elementMap[relation.To] { return NewValidationError("relation references non-existent element: " + relation.To) } } return nil } // AddElement adds an element to the C4 diagram func (c *C4Diagram) AddElement(element *C4Element) { c.Elements = append(c.Elements, element) } // AddRelation adds a relation to the C4 diagram func (c *C4Diagram) AddRelation(relation *C4Relation) { c.Relations = append(c.Relations, relation) } // AddBoundary adds a boundary to the C4 diagram func (c *C4Diagram) AddBoundary(boundary *C4Boundary) { c.Boundaries = append(c.Boundaries, boundary) } // FindElement finds an element by ID func (c *C4Diagram) FindElement(id string) *C4Element { for _, element := range c.Elements { if element.ID == id { return element } } return nil } // FindBoundary finds a boundary by ID func (c *C4Diagram) FindBoundary(id string) *C4Boundary { for _, boundary := range c.Boundaries { if boundary.ID == id { return boundary } } return nil }