Portal Community

NodeInspectorData Type

// nodeInspector.ts (flow-observer-core)
export interface NodeInspectorData {
    nodeId      : string;
    nodeLabel   : string;
    status      : NodeExecutionStatus;
    inputData   : unknown;           // Data the node received as input
    outputData  : unknown;           // Ephemeral output from this run
    pinnedData  : unknown | null;    // Persistent pinned data — null if not set
    logs        : LogEntry[];
    metrics     : NodeMetrics;
}

How pinnedData Is Loaded

When the user clicks a node in the Observer Panel, handleNodeClick fetches all inspector data including pinned data from the REST API:

// NodeInspectorTabContent.tsx
async function handleNodeClick(nodeId: string) {
    const data = await executionApiClient.getNodeInspectorData(executionId, nodeId);
    // data.pinnedData comes from the API — it reads Process_NodePinnedData for this processId+nodeId
    useExecutionStore.getState().setNodeInspectorData(data);
}

// API endpoint (backend)
// GET /api/executions/{executionId}/nodes/{nodeId}/inspector
// Response includes: { inputData, outputData, pinnedData, logs, metrics, ... }

Pinned Data Section Rendering

// NodeInspectorTabContent.tsx (Pinned Data section)
function PinnedDataSection({ pinnedData }: { pinnedData: unknown }) {
    const [isExpanded, setIsExpanded] = useState(false);

    // Section only rendered when pinnedData is non-null
    if (pinnedData === null || pinnedData === undefined) {
        return null;
    }

    return (
        <div className="inspector-section">
            <div
                className="inspector-section-header"
                onClick={() => setIsExpanded(prev => !prev)}
            >
                <span>Pinned Data</span>
                <span className="badge badge-pinned">Persistent</span>
                <i className={isExpanded ? 'fa-chevron-up' : 'fa-chevron-down'} />
            </div>
            {isExpanded && (
                <JsonViewer data={pinnedData} />
            )}
        </div>
    );
}

Pinned Data Badge

The Pinned Data section header shows a "Persistent" badge to distinguish it visually from the ephemeral Output Data section. This helps workflow designers understand at a glance that this data survives across runs.

SectionBadgeWhen Visible
Input DataThis RunAlways (when node has been executed)
Output DataThis RunWhen output is non-null for this execution
Pinned DataPersistentOnly when pinnedData !== null
Node LogsAlways (may be empty list)
Node MetricsAlways (shows duration, retries, result)

Pinned Data in Historical Executions

When viewing a past execution, the Inspector API still fetches pinned data from Process_NodePinnedData — but this returns the CURRENT pinned data, not what was pinned at the time of the historical run. If the workflow has run many times since the historical execution, the pinned data shown in the inspector reflects the most recent write, not the historical run's output.

Pinned Data is always current-state, not point-in-time. The Process_NodePinnedData table stores only the latest value (one row per node). The Node Inspector always shows what is currently pinned — it has no history of previous pinned values. If point-in-time auditability of pinned data is needed, write it to a separate audit table as well.