Skip to Content
This documentation is provided with the HEAT environment and is relevant for this HEAT instance only.
RunnersDashboard Toolsdashboard-v2 upstream contract

dashboard-v2 upstream contract

Upstream nodes (for example json-template, analytics runners) pass JSON into the dashboard-v2 node template. The runner stores canonical payloads and merged layout so the v2 dashboard API and ui/dashboard data service can ingest data without extra transforms.

Top-level envelope

The JSON object submitted to dashboard-v2 should include:

FieldRequiredPurpose
$heat-dataserviceYesChannel data and groups in the format below.
dashboard_usersRecommendedArray of HEAT Auth external user GUID strings for dimension access control (snake_case key matches the runner).

The dashboard-v2 node configuration supplies dataSourceName, layoutConfiguration, and dashboardName. Those are platform settings. They are not realm identifiers.

Canonical $heat-dataservice

This matches HeatDirectIngestionPayload in the dashboard app TypeScript types (ui/dashboard, direct ingestion types).

{ "version": "1.0", "groups": [ { "id": "metrics", "name": "Metrics" } ], "realms": [ { "name": "pilot-a", "channels": [ /* HeatDirectChannelData */ ] }, { "name": "pilot-b", "channels": [ /* HeatDirectChannelData */ ] } ] }
  • version: Schema version string (use "1.0").
  • groups: UI grouping for channel pickers; each group has id and name.
  • realms: Non-empty array. Each item has name (realm id used by the UI and data store) and channels.

Accepted legacy input (normalized by the runner)

For convenience, upstream may send flat channels at the top level of $heat-dataservice instead of realms:

  • Optional top-level realm string applies to every channel that does not set its own realm field.
  • Optional per-channel realm string splits channels into multiple realms (first-seen order is preserved).

Do not combine non-empty realms and non-empty channels in the same payload.

The dashboard-v2 processor rewrites storage to canonical nested realms only.

Channel object (HeatDirectChannelData)

Each channel has:

FieldRequiredDescription
idYesStable id; layout configuration.channels and timeline items reference this string. Unique within a realm.
nameYesDisplay name.
groupIdYesMust match a groups[].id.
shapeYesOne of: series, timestamps, value, events, ranges.
dataYesShape-specific payload (see below).
metadataNoHints for widgets (units, channelType, and so on).

Shape guidelines

shapeWhen to usedata
seriesTime-varying data, playback, interpolationArray of { "timeMs": number, "value": number | string | boolean }
timestampsLabelled instantsArray of { "timeMs", "annotation", "metadata?" }
valueNon-time-series or arbitrary structured values (scores, summaries, nested objects)Object { "value": <json>, "metadata?" : {} } — put structured payloads under value.
eventsBoolean or instantaneous events over timeArray of { "timeMs", "occurred", "metadata?" }
rangesPhases or intervalsArray of { "startTimeMs", "endTimeMs", "durationMs", "metadata?" }

For arbitrary objects that are not inherently time-indexed, prefer shape: "value" with a JSON-serializable value. Use metadata for presentation hints. Keep id stable so the v2 layout can bind components to the channel.

Realms

  • A realm is a namespace: the same id and name pair in two realms refers to different channel payloads (for example two trainees or two simulation runs side by side).
  • Realm names are taken from realms[].name in the payload (after normalization).
  • layoutConfiguration.realms is a string array of realm ids for the session UI (realm filter, default selection). The runner merges payload realm names into the stored layout and sets sensible defaults for configuration.defaultRealm and configuration.showRealmFilterDropdown when multiple realms exist.

Realm count soft cap (50)

  • Recommended maximum: 50 realms per dashboard payload.
  • Beyond that, prefer more channels, separate dimensions, or separate dashboards instead of encoding high-cardinality sets as realms.
  • The runner logs a warning when normalized realm count exceeds 50.
  • Set node configuration failOnRealmCountExceeded: true to fail the node instead of only warning (for strict templates).

Layout (layoutConfiguration)

The v2 layout follows the layout schema: version, optional configuration, realms, and components.rows. Component rows reference channel id values from $heat-dataservice. The runner ensures realms on the stored layout aligns with payload realm names where possible.

Further reading