Domain-Driven Design (DDD) and Event Storming domain-modeling preset for Choreo.
Choreo.Domain is a domain-specific vocabulary layer that adds DDD concepts —
Bounded Contexts, Aggregates, Commands, Domain Events, Policies, and Workflows —
on top of Choreo's underlying graph and rendering engine.
It draws inspiration from Scott Wlaschin's Domain Modeling Made Functional and classic tactical/strategic DDD patterns.
Tactical Node Types (Event Storming & Workflows)
:actor- The user or external trigger initiating a command.:command- An action requested (blue sticky note).:aggregate- Consistency boundary / entity (yellow sticky note).:event- Business domain event (orange sticky note).:read_model- Projection / dashboard (green sticky note).:policy- Saga or reaction policy (purple/lilac sticky note).:external_system- Third-party system boundary (red/rose).:type- Algebraic data type (Slate table card displaying field names and types).:workflow- Wlaschin-style pipeline action (Teal rounded box).:acl- Anti-Corruption Layer translation gateway.
Strategic Modeling (Context Mapping)
add_context/3- Adds a Bounded Context node for high-level mapping.add_context_boundary/3- Adds a Bounded Context cluster boundary for tactical grouping.connect_contexts/4- Connects Bounded Context nodes with relationship labels (e.g. ACL, Shared Kernel).
Summary
Functions
Adds an Anti-Corruption Layer translation gateway component.
Adds a user or actor initiating a command.
Adds an Aggregate/Entity boundary node.
Adds a Command node (actions requested).
Adds a Bounded Context node for high-level Strategic Context Maps.
Adds a Bounded Context cluster boundary for Tactical design layouts.
Adds a Domain Event node.
Adds an External System node.
Adds a Policy / Saga handler node.
Adds a Read Model / Projection node.
Adds an Algebraic Data Type node.
Adds a Workflow pipeline function node.
Returns all ancestor causes of a target node.
Clears the current scenario highlight.
Connects two domain nodes.
Connects two strategic Bounded Context nodes with DDD relationship semantics.
Returns all edges in the domain model.
Focuses the diagram on a specific execution path scenario, highlighting it while leaving the rest of the diagram visible.
Initializes a new empty domain model.
Returns all node definitions in the domain model.
Renders the domain model to DOT format.
Renders the domain model to Mermaid.js native syntax.
Types
@type t() :: %Choreo.Domain{ clusters: %{required(String.t()) => map()}, edge_meta: %{optional(Yog.Multi.Graph.edge_id()) => map()}, graph: Yog.Multi.Graph.t(), highlighted_edges: [ Yog.Multi.Graph.edge_id() | {Yog.node_id(), Yog.node_id()} ], highlighted_nodes: [Yog.node_id()] }
Functions
@spec add_acl(t(), Yog.node_id(), keyword()) :: t()
Adds an Anti-Corruption Layer translation gateway component.
@spec add_actor(t(), Yog.node_id(), keyword()) :: t()
Adds a user or actor initiating a command.
@spec add_aggregate(t(), Yog.node_id(), keyword()) :: t()
Adds an Aggregate/Entity boundary node.
@spec add_command(t(), Yog.node_id(), keyword()) :: t()
Adds a Command node (actions requested).
@spec add_context(t(), Yog.node_id(), keyword()) :: t()
Adds a Bounded Context node for high-level Strategic Context Maps.
Adds a Bounded Context cluster boundary for Tactical design layouts.
@spec add_event(t(), Yog.node_id(), keyword()) :: t()
Adds a Domain Event node.
@spec add_external_system(t(), Yog.node_id(), keyword()) :: t()
Adds an External System node.
@spec add_policy(t(), Yog.node_id(), keyword()) :: t()
Adds a Policy / Saga handler node.
@spec add_read_model(t(), Yog.node_id(), keyword()) :: t()
Adds a Read Model / Projection node.
@spec add_type(t(), Yog.node_id(), keyword()) :: t()
Adds an Algebraic Data Type node.
@spec add_workflow(t(), Yog.node_id(), keyword()) :: t()
Adds a Workflow pipeline function node.
@spec causes(t(), Yog.node_id()) :: [Yog.node_id()]
Returns all ancestor causes of a target node.
This is a set, not an ordered path — for branching cause graphs (DAGs with multiple parents), all ancestors are returned collapsed into one list with no path structure.
Examples
iex> domain = Choreo.Domain.new()
...> |> Choreo.Domain.add_actor(:customer)
...> |> Choreo.Domain.add_command(:place_order)
...> |> Choreo.Domain.add_aggregate(:order_agg)
...> |> Choreo.Domain.add_event(:order_placed)
...> |> Choreo.Domain.connect(:customer, :place_order)
...> |> Choreo.Domain.connect(:place_order, :order_agg)
...> |> Choreo.Domain.connect(:order_agg, :order_placed)
iex> ancestors = Choreo.Domain.causes(domain, :order_placed)
iex> :customer in ancestors
true
iex> :order_agg in ancestors
true
Clears the current scenario highlight.
Examples
iex> domain = Choreo.Domain.new()
...> |> Choreo.Domain.add_actor(:customer)
...> |> Choreo.Domain.add_command(:place_order)
...> |> Choreo.Domain.focus_path([:customer, :place_order])
...> |> Choreo.Domain.clear_focus()
iex> domain.highlighted_nodes
[]
iex> domain.highlighted_edges
[]
@spec connect(t(), Yog.node_id(), Yog.node_id(), keyword()) :: t()
Connects two domain nodes.
@spec connect_contexts(t(), Yog.node_id(), Yog.node_id(), keyword()) :: t()
Connects two strategic Bounded Context nodes with DDD relationship semantics.
@spec edges(t()) :: [{Yog.node_id(), Yog.node_id(), number()}]
Returns all edges in the domain model.
@spec focus_path(t(), [Yog.node_id()]) :: t()
Focuses the diagram on a specific execution path scenario, highlighting it while leaving the rest of the diagram visible.
@spec new() :: t()
Initializes a new empty domain model.
@spec nodes(t()) :: %{required(Yog.node_id()) => map()}
Returns all node definitions in the domain model.
Renders the domain model to DOT format.
Renders the domain model to Mermaid.js native syntax.
Options
:syntax-:flowchart(default),:class_diagram, or:erd- Other options matching selected syntax engine