## ProcessDiagram Component Hierarchy

How the SVG rendering is structured — from data fetch to pixels

Component Tree
ProcessDiagram — root, fetches layout, manages state
<svg> container with viewBox (zoom/pan transforms)
DiagramSection label="Main Route"
<g> edges layer (rendered first, behind nodes)
DiagramEdge × N — SVG <path> with arrowhead
<g> nodes layer
DiagramNode × N — top-bar card
ConfigBadge × 0..N — tap/trace indicators
NodeToolbar — floating on hover
CompoundNode × 0..N — choice/split container
DiagramNode × N — children inside compound
DiagramSection label="onException" variant="error"
same edge + node structure as above
ZoomControls — HTML overlay (not SVG)
SVG Structure (simplified)

    <div class="process-diagram">            /* wrapper div */
      <svg viewBox="0 0 {w} {h}">            /* zoom = viewBox transform */
        <g class="diagram-content">           /* pan offset */

          <!-- Main Route section -->
          <g class="section section--main">
            <g class="edges">
              <path d="M 100 40 C ..." />     /* cubic bezier edge */
              <marker>...</marker>             /* arrowhead def */
            </g>
            <g class="nodes">
              <g transform="translate(x, y)"> /* positioned by ELK */
                <rect .../>                    /* card background */
                <rect .../>                    /* color top bar */
                <text>LOG</text>              /* label */
                <g class="badges">...</g>     /* config indicators */
              </g>
            </g>
          </g>

          <!-- Error Handler section -->
          <g class="section section--error"
             transform="translate(0, {mainH + gap})">
            <text>onException</text>          /* section label */
            <line .../>                        /* divider line */
            <g class="edges">...</g>
            <g class="nodes">...</g>
          </g>

        </g>
      </svg>
      <div class="zoom-controls">...</div>    /* HTML overlay */
    </div>

Data Flow

    GET /diagrams/{hash}/render?direction=LR
            │
            ▼
      DiagramLayout { nodes[], edges[], width, height }
            │
            ▼
      separateFlows(nodes)  →  mainNodes[] + errorSections[]
            │                       │
            ▼                       ▼
      renderMainSection()    renderErrorSection()
            │                       │
            ▼                       ▼
      SVG groups with              SVG groups offset below
      ELK x/y coordinates         main section by mainHeight + gap