Aggregate Designer
Part of the Designer guide. Previous: Bounded Context Editor · Next: Process Designer.
An aggregate is the consistency boundary of your model. In the Aggregate Designer you decide which tables belong to it, which entity is the root and how they relate, as an ER diagram. One click on Build generates the complete code tree from it.

The Tabs
The Designer leads from table selection to finished code, all in one surface:
| Tab | What you see |
|---|---|
| Tables | The imported BC schema — tables, columns, keys. Here you pick the subset that belongs to the aggregate. |
| Designer | The ER canvas: tables as nodes, relationships as edges. |
| Code | The generated PHP code, read-only in the browser. See Code, API & Reports. |
| API | The exposed command/query/event surface of the aggregate, read-only. |
| Report / Validation | Build status and validator findings. |

Step by Step
- Choose tables — in the Tables tab, select the aggregate's tables from the BC schema. They appear as nodes on the canvas.
- Mark the root — the set-as-root header on the node establishes the root entity. It is the only door into the entity graph.
- Draw relationships — edges between nodes represent the ER structure (PK/FK/UK/IK). A freshly drawn edge is immediately selected and gets confirmed or discarded in the side panel.
- Maintain details — a side panel opens on the right for each node (see below).
- Save & Build — Save persists the current state; Build generates the code.

The Node Side Panel
Each node opens a side panel with two tabs:
- Defaults — presets in two modes.
onCreatesets values once at birth (constants, UUID7, FK references such as<entity>.id).syncre-inherits ancestor fields (<entity>.field) on every persist. The mode follows automatically from the value type: a wrong placement isn't possible here. - Order — the
OrderBysort order for1:nrelationships.
The Edge Side Panel
Clicking an edge shows its variant in the same side panel: swap parent/child, 1:1 vs. 1:n cardinality, and (for aggregate-internal edges) the required / optional toggle (the existence invariant of the relationship, default required). This is directly visible on the canvas: a required edge is drawn solid, an optional edge dashed and slightly dimmed.
Auto-Layout
A kebab entry Auto-Layout arranges the graph hierarchically from left to right along the edges; it collects unconnected tables as a compact block below. This only changes the in-memory positions: they are persisted only on the next Save/Build.
Draft and Build Lock
Save always succeeds. If the canvas is inconsistent (e.g. a table is unreachable from the root), Jardis persists the state as a draft instead of aborting with an error: the last consistent state remains untouched. A draft badge appears, with the kebab action "discard draft".
As long as a draft is open, Build is blocked, at every entry point (build dialog, headless build, CLI). Headless this surfaces as a DRAFT_EXISTS error (MCP).
From Model to Code
A build generates a hermetic, generator-owned tree per aggregate under {BC}/Aggregate/{Agg}/. Never edit by hand. It holds two facades:
- Read facade
{Agg}Read— the "front door":get{Agg}ById/ByIds/By{Key}and{agg}List. Reachable via the BC facade:$bc->{agg}(). - Write facade
{Agg}— commands andevent(); reachable only family-internally via the Kernel seam, not from the transport layer.
Write flows therefore go through processes, not directly against the aggregate. How you wire the generated code in is shown in Get Started; depth is in the skills (platform-usage, platform-implementation).
Need a new operation?
A new aggregate operation is created by remodeling in the Designer, not by hand-editing the generated code. A flow spanning several aggregates belongs in a process.