Adds the curated reference library the skill loads on demand, plus
four synthetic sample BDTs used by docs, tests, and LLM-mode demos.
references/ (4 curated Markdown files):
- bdt-reference.md — top-level BDT JSON anatomy: envelope,
nodes, edges, UI layer, definitions,
businessType semantics. Cites the core-262
upstream JSON schema and Connect API spec.
- bdt-node-catalog.md — every node type (DMO Source, DMO Sink,
Filter, Join, Union, Aggregate, Window,
Formula, Split, Append, etc.) with its
required/optional fields and typical
usage. Audited against core-262 enums.
- bdt-function-catalog.md — the expression-language function surface
(string, numeric, date, conditional,
aggregate). Grouped by category with
signature + one-line semantics.
- bdt-window-functions.md — windowing operators (ROW_NUMBER, RANK,
LEAD/LAG, running aggregates) with PARTITION
BY / ORDER BY grammar and gotchas.
assets/sample_bdts/ (4 synthetic, dependency-free BDTs):
- minimal_dmo_to_dmo.json — smallest valid BDT (1 source, 1 sink).
- joins_and_filters.json — join + filter composition.
- window_and_aggregate.json — window function + aggregate in one graph.
- append_and_split.json — append-then-split branching topology.
Grounding rules enforced in this commit:
- Every claim in references/ cites an upstream source (core-262 JSON
schema, Connect API reference, or the Data Cloud BDT editor spec).
No speculative content.
- No raw DITA or internal-only documentation is shipped; references
are synthesized from public-facing material.
- BusinessTypeEnum values use the canonical camelCase casing from
core-262 (case-cleanup fix included here).
- Sample BDTs are original synthetic fixtures, not redacted customer
data. Each is small enough to read end-to-end.
@W-22196528@
7.9 KiB
BDT Reference — Overview (always loaded)
Last synced: 2026-04-23 from canonical BDT Connect API Java sources (
cdp-connect-apimodule,sfdc.cdp.connect.api.{input,enums}.datatransformpackages, release 264). Cross-verified identical across releases 260, 262, and 264. Seeresearch/bdt-schema-canonical.mdfor the full machine-extracted schema.
What a BDT is
Batch Data Transform (BDT) — a repeatable, scheduled or on-demand data pipeline inside Salesforce Data Cloud. It reads from one or more source objects, applies a DAG of transformations (joins, filters, formulas, aggregations, etc.), and writes one or more outputs. BDTs run over batches; their streaming counterpart is SDT (Streaming Data Transform).
- Salesforce object type:
MktDataTransform. - Typical export: a JSON file from the BDT viewer, or via Workbench
/ssot/data-transforms?htmlEncode=false. - Underlying runtime: the Data Processing Engine (DPE) / DCSQL.
Top-level JSON shape
A BDT JSON can arrive in three shapes. The skill's parser accepts all three
transparently (since commit ee2485c); the inner node graph is identical in every case.
1. Editor export (the default "download" shape)
What you get when you export a BDT from the BDT editor UI, or fetch it via
/ssot/data-transforms?htmlEncode=false on Workbench. The outer object is the
definition itself, with no wrapper metadata:
{
"version": "66.0", // Schema version string
"nodes": { /* NodeName → Node */ },
"ui": { // Optional: layout hints + human-readable labels
"nodes": { /* NodeName → { label, description, type, top, left } */ },
"connectors": [ /* { source, target } edges */ ],
"hiddenColumns": []
}
}
Note: editor exports have no top-level type field. The definition-type
discriminator ("STL") only appears when the definition is nested inside a Connect
API payload (see below).
2. Connect API create payload — single definition
What developers POST to the MktDataTransform Connect API when authoring
programmatically. The outer object is a DataTransformInputRepresentation; the
editor-export shape is nested inside under definition:
{
"name": "MyTransform", // Required — API name of the transform
"label": "My Transform", // Required — user-visible label
"description": "…", // Optional
"type": "BATCH", // DataTransformType: "BATCH" | "STREAMING"
"dataSpaceName": "default", // Data space the transform lives in
"definition": {
"version": "66.0",
"type": "STL", // DataTransformDefinitionType: "STL" | "SQL" | "DCSQL" | …
"nodes": { /* … */ },
"ui": { /* … */ }
}
}
Two distinct type fields live at different nesting levels:
- Outer
type=DataTransformType(batch vs streaming). - Inner
definition.type=DataTransformDefinitionType(STL for batch BDTs; SQL / DCSQL for raw-SQL transforms; hidden variants exist but are not surfaced to users).
3. Connect API create payload — multi-definition variant
For transforms with multiple definitions. Same outer fields; instead of a single
definition object there's a definitions array:
{
"name": "…", "label": "…", "type": "BATCH", "dataSpaceName": "default",
"definitions": [
{ "version": "66.0", "type": "STL", "nodes": { /* … */ }, "ui": { /* … */ } },
/* … additional definitions … */
]
}
v1 of this skill reads the first definition and explains only that one; multi-definition explanations are out of scope.
Each node (inner shape, identical in all three outer shapes)
{
"action": "<action-type>", // One of the 25 documented action strings below
"sources": ["NODE_A", "NODE_B"], // Array of node names (empty for load/roots)
"parameters": { /* action-specific */ },
"schema": { /* optional — slice/rename at node boundary */ }
}
The 25 canonical action types
action string |
Purpose (one line) |
|---|---|
load |
Read rows from a DMO or DLO |
filter |
Keep rows matching structured filter criteria |
sqlFilter |
Keep rows matching a raw SQL predicate |
join |
Join two upstream streams by key |
formula |
Add derived columns via per-row SQL formulas |
computeRelative |
Window function over partitioned / ordered rows |
aggregate |
Group-by aggregation |
extractGrains |
Fan out rows across time grains |
extractTable |
Extract a table from a flatten-JSON output |
schema |
Rename / drop / reshape columns |
outputD360 |
Write rows to a target DMO or DLO |
appendV2 |
Union rows from multiple upstream streams (v2 variant) |
flatten |
Flatten nested structure |
flattenJson |
Flatten a JSON field into rows/columns |
split |
Split rows into multiple downstream branches |
typeCast |
Cast field types |
update |
Update records |
bucket |
Assign bucket labels to field values |
formatDate |
Reformat date values |
extension |
Run a custom extension node |
extensionFunction |
Run a custom extension function |
cdpPredict |
Apply a prediction model |
jsonAggregate |
Aggregate JSON fields |
save |
Save an intermediate result |
recommendation |
Apply a recommendation model |
For full parameter shapes, enums, and examples: see references/bdt-node-catalog.md.
For SFSQL functions used in formula expressions: see references/bdt-function-catalog.md.
For window functions used in computeRelative: see references/bdt-window-functions.md.
Terminology
- DMO — Data Model Object. Canonical modeled entity. Suffix convention:
__dlm. - DLO — Data Lake Object. Raw-lake table. Suffix convention:
__dll. - SFSQL — Salesforce's internal SQL dialect used in formula expressions and SQL filters.
- DCSQL — a related SQL dialect used for Spark push-down execution (you may see it as
an
expressionTypevalue). ssot__prefix — Salesforce Standard Schema field, canonical / semantic.__csuffix — Custom field.KQ_prefix — Key-qualifier pattern (external ID / composite-key helper). Observed in practice; not always documented.- UI label vs. JSON action name — The JSON uses concise strings (e.g.,
computeRelative); the BDT editor shows friendlier labels (e.g., "Window Transform"). Theui.nodes[X].labelfield in the JSON carries the user-specified human-readable name per node. Always use the UI label in explanations when present.
Key enums (for quick orientation)
DataTransformType:BATCH,STREAMINGJoinType:INNER,OUTER,LEFT_OUTER,RIGHT_OUTER,LOOKUP,MULTI_VALUE_LOOKUP,CROSSWriteModeEnum(outputD360):APPEND,MERGE,OVERWRITE,MERGE_UPSERT_DELETE,DELETE_ONLYD360OutputTypeEnum:dataLakeObject,dataModelObjectSliceMode:SELECT,DROPAggregateType:UNIQUE,SUM,AVG,COUNT,MAX,MIN,MEDIAN,STDDEVP,STDDEV,VARP,VARDataType:TEXT,NUMBER,DATE_ONLY,DATETIME,BOOLEANSortDirection:ASC,DESC
For exhaustive enum lists with semantics: bdt-node-catalog.md or (for the raw extraction)
research/bdt-schema-canonical.md.
How this skill uses these references
bdt-reference.md(this file) — always in context.bdt-node-catalog.md— consulted before explaining any node type not previously covered in the current conversation.bdt-function-catalog.md— consulted before interpreting anyformulaExpression(job I1) or reasoning about conditional logic (I2).bdt-window-functions.md— consulted whenever acomputeRelativenode is narrated.
If a node type or function isn't in any of the reference files, the skill narrates what's visible in the JSON and explicitly flags the item as undocumented in the materials available. It does not guess at semantics.