7 — Objects, Record Types and Lineage

Objects, record types and lineage

This is the glossary you reach for when "what counts as backbone here?" or "why is this custom object showing up under Opportunity?" comes up.

Backbone vs everything else

The enabled objects are the ones Stood Flows actively manages. By default for a Salesforce graph that's:

You can enable additional custom objects to be treated the same way — their record types get rows, their volumes get scanned, their related custom objects get pulled into the lineage. The toggle is in the objects panel (click an empty object cell in the KPI table or use the objects section in graph settings).

A custom object that you enable behaves identically to a standard one. The "standard" vs "custom" distinction is purely about the default seed list and the existence of BusinessProcess records on it (Lead/Opportunity/Case/Campaign).

Objects that are not enabled still surface in two contexts:

  1. As related custom objects with their own column in the KPI Custom Objects group, when they have a lookup or master-detail relationship back to an enabled object.

  2. As referenced entities in Apex SOQL/DML and I/O traffic, where they're shown but not given full RT treatment.

Record types

For every enabled object, Stood Flows pulls every record type (including inactive ones) with developer name, label, business process binding, and the picklist value sets that go with that BP.

A record type only gets a row in the KPI table if it's bound to a business process (or if the object has no BP at all, in which case all RTs get rows). Inactive RTs are kept — they're often the most interesting (high complexity, zero usage = retire candidate).

Business processes

A business process on Lead/Opportunity/Case/Campaign is a named ordering of picklist values (LeadSource → status, StageName for Opp, Status for Case, Status for Campaign Member). Stood Flows reads the BP definitions, expands the stage order, and uses them to:

When two RTs share a BP, they appear as separate rows but share the same s-column layout.

Lineage: how custom objects are pulled in

Refresh-time logic, walked once and persisted:

  1. Start with the enabled objects.

  2. For each, describe the object via Tooling API to enumerate child relationships (lookup and master-detail).

  3. For each child custom object: record (parent, child, relationshipType). If a row count is available, attach volume.

  4. For each child, recurse — pulling its children too — up to a depth limit, dropping anything that becomes circular or hits an unrelated standard object.

The result is stored under customObjectRelationships in the version snapshot and drives the Custom Objects column group in the KPI table.

Each custom-object column header carries an icon:

The column name is the object label (not the API name). Hover for the full API name.

Standard child objects: Items

OpportunityLineItem and CampaignMember are standard child objects with significant volume. They're shown as a combined Items column rather than per-object — partly because they're always there for every Opportunity / Campaign RT and partly to keep the table readable. The number is the total related rows in scope.

Other standard relationships (OpportunityContactRole, AccountContactRelation, etc.) aren't volume-tracked by default; you can pull them via the Apex tab if they show up as DML targets.

Why this matters

Record types are the right unit of analysis because almost all Salesforce permissions, layouts, automation, and reporting are scoped to them. A single Opportunity object can hide six businesses depending on its RT mix — they share data but nothing else. Treating each as a row in the KPI table is what lets you compare them head-to-head.

When you start adding tags, anchoring issues, or generating Apex packages, you're typically operating per (object, RT) cell. That's the unit. Everything else aggregates up to it or drills down from it.

When the lineage looks wrong

A custom object you expected to see is missing from the KPI custom-objects columns:

  1. Is it actually reachable from an enabled object via a relationship? If not, enable an intermediate object or treat the CO as a separate analysis.

  2. Did the relationship come into existence after your last Refresh? Re-run Refresh to pick it up.

  3. Is the relationship blocked by perms? The connected sf user needs read access to both parent and child.

A custom object appearing in too many columns:

A custom object appearing with 0 everywhere:

Published with Nuclino