# `Choreo.UML`
[🔗](https://github.com/code-shoily/choreo/blob/v0.14.1/lib/choreo/uml.ex#L1)

UML Class and Struct Diagram builder on top of Yog.

`Choreo.UML` models software component architectures — classes, structs,
behaviors, protocols, and interfaces — with fields and functions, and
standard structural UML relationships.

## Node types
* `:class` / `:struct` / `:behavior` / `:protocol` / `:interface`

## Relationship types
* `:inherits` — solid line with hollow arrowhead (`--|>`) representing inheritance or behavior adoption.
* `:realizes` — dashed line with hollow arrowhead (`..|>`) representing protocol implementation.
* `:associates` — solid line with solid arrowhead (`-->`) representing composition or nesting.
* `:depends` — dashed line with open arrowhead (`..>`) representing invocation or dependency.

## Quick Start

    uml =
      Choreo.UML.new()
      |> Choreo.UML.add_class(:user,
        type: :struct,
        fields: [%{name: :id, type: :integer}],
        functions: [%{name: "authenticate", arity: 1}]
      )
      |> Choreo.UML.add_class(:auth_provider,
        type: :behavior,
        functions: [%{name: "verify", arity: 1}]
      )
      |> Choreo.UML.add_relationship(:user, :auth_provider, type: :realizes, label: "implements")

    dot = Choreo.UML.to_dot(uml)
    mermaid = Choreo.UML.to_mermaid(uml)

## Diagram

<div class="graphviz">
  digraph G {
    graph [rankdir=TB, bgcolor="#ffffff", splines=spline, nodesep=1.2, ranksep=1.2];
    node [shape=plain, style=filled, fillcolor="transparent", fontname="Helvetica", fontsize=11, fontcolor="#1e293b"];
    edge [color="#475569", style=solid, fontname="Helvetica", fontsize=9, penwidth=1.0];

    user [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" PORT="f0" COLOR="#cbd5e1"><TR><TD BGCOLOR="#10b981"><FONT COLOR="#ffffff"><B>«struct»<BR/>user</B></FONT></TD></TR><TR><TD BGCOLOR="#f8fafc" ALIGN="LEFT"><FONT COLOR="#1e293b">+ id : integer</FONT></TD></TR><TR><TD BGCOLOR="#f8fafc" ALIGN="LEFT"><FONT COLOR="#1e293b">+ authenticate(1)</FONT></TD></TR></TABLE>>];
    auth_provider [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4" PORT="f0" COLOR="#cbd5e1"><TR><TD BGCOLOR="#f59e0b"><FONT COLOR="#ffffff"><B>«behavior»<BR/>auth_provider</B></FONT></TD></TR><TR><TD BGCOLOR="#f8fafc" HEIGHT="10"></TD></TR><TR><TD BGCOLOR="#f8fafc" ALIGN="LEFT"><FONT COLOR="#1e293b">+ verify(1)</FONT></TD></TR></TABLE>>];

    user -> auth_provider [penwidth="1.0", color="#475569", arrowhead="empty", style="dashed", fontsize="9", fontname="Helvetica", label="implements"];
  }
</div>

# `class_id`

```elixir
@type class_id() :: Yog.node_id()
```

# `t`

```elixir
@type t() :: %Choreo.UML{
  edge_meta: %{optional(Yog.Multi.Graph.edge_id()) =&gt; map()},
  graph: Yog.Multi.Graph.t(),
  strict: boolean(),
  strict_contract_validation: boolean()
}
```

# `add_class`

```elixir
@spec add_class(t(), class_id(), keyword()) :: t()
```

Adds a class, struct, behavior, or protocol to the diagram.

## Options

* `:label` (`t:String.t/0`) - Visual label for the class (defaults to ID string).

* `:type` - The UML class type: :class, :struct, :behavior, :protocol, or :interface. The default value is `:class`.

* `:fields` (`t:term/0`) - List of fields/attributes. The default value is `[]`.

* `:functions` (`t:term/0`) - List of functions/operations. The default value is `[]`.

## Examples

    iex> uml = Choreo.UML.new()
    ...> |> Choreo.UML.add_class(:user, type: :struct, fields: [%{name: :id, type: :integer}])
    iex> %Choreo.UML{} = uml
    iex> Map.has_key?(uml.graph.nodes, :user)
    true

# `add_relationship`

```elixir
@spec add_relationship(t(), class_id(), class_id(), keyword()) :: t()
```

Adds a structural relationship between two classes/components.

## Options

* `:type` - Required. The connection relationship type.

* `:label` (`t:String.t/0`) - Optional label/text on the relationship line.

## Examples

    iex> uml = Choreo.UML.new()
    ...> |> Choreo.UML.add_class(:user)
    ...> |> Choreo.UML.add_class(:profile)
    ...> |> Choreo.UML.add_relationship(:user, :profile, type: :associates, label: "has_one")
    iex> %Choreo.UML{} = uml
    iex> map_size(uml.graph.edges)
    1

# `new`

```elixir
@spec new(keyword()) :: t()
```

Initializes a new, empty UML diagram.

## Options

  * `:strict_contract_validation` - if `true`, validates that any class implementing a behavior/protocol/interface implements all its required functions (default: `false`).
  * `:strict` - if `true`, `add_relationship/4` raises when an endpoint does not already exist (default: `false`).

## Examples

    iex> uml = Choreo.UML.new()
    iex> %Choreo.UML{} = uml
    iex> uml.strict_contract_validation
    false

# `theme`

```elixir
@spec theme(atom(), keyword()) :: Choreo.Theme.t()
```

Returns a theme for the UML diagram.

## Examples

    iex> theme = Choreo.UML.theme(:dark)
    iex> theme.graph_bgcolor
    "#0f172a"

# `to_dot`

```elixir
@spec to_dot(t(), keyword()) :: String.t()
```

Renders the UML diagram to Graphviz DOT syntax.

## Examples

    iex> uml = Choreo.UML.new() |> Choreo.UML.add_class(:user)
    iex> dot = Choreo.UML.to_dot(uml)
    iex> dot =~ "digraph"
    true

# `to_mermaid`

```elixir
@spec to_mermaid(t(), keyword()) :: String.t()
```

Renders the UML diagram to Mermaid.js syntax.

## Examples

    iex> uml = Choreo.UML.new() |> Choreo.UML.add_class(:user)
    iex> Choreo.UML.to_mermaid(uml, syntax: :flowchart) =~ "graph"
    true
    iex> Choreo.UML.to_mermaid(uml, syntax: :class_diagram) =~ "classDiagram"
    true

---

*Consult [api-reference.md](api-reference.md) for complete listing*
