Documentation

Graph Model

The graph is built from nodes and edges with structure driven by persisted relationships.

Species

Current taxonomy has exactly 4 species.

LevelSpeciesRoleReact Flow node type
1flowOrdered sequence containerflow
0viewReusable page/screenview
data-modelData entity/tabledataModel
api-endpointAPI endpointapiEndpoint

Config source: lib/config/species.ts

Canvas Visibility

  • Canvas rendering currently shows only flow and view as visible React Flow nodes.
  • data-model and api-endpoint remain persisted graph species and can still be edited from panels/import-export, but they are not rendered as standalone canvas cards.
  • View cards surface API relationships inline via embedded actions instead of separate API nodes.

Source: app/project/[id]/canvas/page.tsx, components/graph/nodes/ViewNode.tsx

Library Views

Project library is available at /project/[id]/library with two browsing modes:

  • Gallery: card grid with title, prefixed ID, species/status badges, platforms, and flow playlist preview.
  • Directory: sortable table for id, title, species, status, and used in flow count.

Filtering:

  • Species filter supports all, flow, view, data-model, api-endpoint.
  • Search matches node title and description text.

Library source:

Composition Model

Root Node

  • project.root_node_id is the explicit canvas anchor when present.
  • If root_node_id is not set, the canvas infers roots from nodes with no incoming composes edge.

Source: app/project/[id]/canvas/page.tsx, lib/data/types.ts

Playlist Expansion

  • Persisted parent/child links are composes edges.
  • Child ordering is read from node.metadata.playlist.entries.
  • When playlist entries do not reference all compose-edge children, missing children are appended after playlist-derived ordering.

Source: app/project/[id]/canvas/page.tsx

All flows start collapsed. Any visible flow can be expanded in-canvas. Top-level expansion (root flow and/or direct flow children of project.root_node_id, or inferred root flows when no explicit root exists) is accordion-style: opening one top-level flow collapses any other top-level flow already open.

Expanded flow children follow a strict alternating drill layout:

  • Root children are rendered horizontally below the root.
  • Level 2 children are rendered vertically below each level 1 node.
  • Level 3 children are rendered horizontally below each level 2 node.
  • The pattern continues alternating by depth.
  • Vertical drill segments always use top/bottom handles for both flow and view nodes.

Layout is computed by elkjs (Eclipse Layout Kernel, layered algorithm). The page builds a flat list of nodes and compose edges with position: {x:0, y:0}, then an async useEffect calls computeElkLayout() which runs the ELK layered algorithm and returns positioned nodes.

Layout source: lib/utils/elk-layout.ts

Source: app/project/[id]/canvas/page.tsx

Node Reuse

  • view and flow nodes are reusable and can appear multiple times across playlists.
  • Reuse is many-to-many: a single node can be referenced by many flow playlists, and one flow playlist can reference many nodes.
  • The source of truth for sequence semantics is the playlist (metadata.playlist.entries), while composes edges provide structural connectivity.
  • The detail panel's where-used UI derives reverse references by scanning all flow playlists.

Source: components/panels/NodeDetailPanel.tsx, lib/utils/where-used.ts, lib/data/types.ts

Playlist Entry Types

flow nodes store ordered playlist data in node.metadata.playlist.entries.

Entry TypeRequired FieldsNotes
viewview_idReference to an existing view node
flowflow_idReference to an existing flow node (cycle-checked before persist)
conditionlabel, if_true, if_falseTwo branch lists, each a recursive PlaylistEntry[]
junctionlabel, cases[]Each case has label + entries: PlaylistEntry[]

Editing source: components/panels/PlaylistEditor.tsx, components/panels/PlaylistEntryRow.tsx

Type source: lib/data/types.ts

Status Model

Statuses are configured in:

Rollup behavior:

  • view is the only species with editable per-platform status values (metadata.platformStatuses).
  • flow status is computed for display by recursively walking playlist entries and aggregating descendant view platform statuses, including nested sub-flows and branch entries.
  • data-model and api-endpoint use single lifecycle status.

Sources:

Platforms

Platforms are configured in:

Views can target one or more platforms; per-platform notes/statuses are stored in node metadata.

Source:

Edge Types

Edge TypeUse
composesComposition hierarchy and ordered flow sequences
callsView to API relationship
displaysView to data-model relationship
queriesAPI to data-model relationship

Config source: lib/config/edge-types.ts

Rendering mapping source: app/project/[id]/canvas/page.tsx

calls edges between a view and API endpoint are projected into View card UI:

  • API -> View: inbound/read affordance (cloud-download icon)
  • View -> API: outbound/write affordance (cloud-upload icon)

Source: app/project/[id]/canvas/page.tsx, components/graph/nodes/ViewNode.tsx

Node And Edge Components

Node registration is in:

Current custom registrations:

  • flow -> FlowNode
  • view -> ViewNode
  • dataModel -> DataModelNode
  • apiEndpoint -> ApiEndpointNode

dataModel and apiEndpoint remain registered node types for compatibility, but the current project page renderer does not add those species into visibleNodes.

Edge registration is also in components/graph/Canvas.tsx.

Taxonomy Update Checklist

  1. Update config array in lib/config/*.
  2. Update page mappings and rendering filters in app/project/[id]/canvas/page.tsx.
  3. Update Canvas registrations in components/graph/Canvas.tsx.
  4. Update forms/panels that branch by species.
  5. Update seed data in seed/pebbles.json.
  6. Update this document.