--- name: crm-analytics-wave-generate description: "Use to build a Wave Recipe, deploy a CRM Analytics dataset or dashboard, or author the full CRMA asset stack — apps, Wave Recipes (.wdpr), datasets, and dashboards — against a connected Salesforce org via REST and Metadata APIs, without CRM Analytics Studio or Dashboard Builder. TRIGGER when: user asks to build or create a Wave Recipe, generate a .wdpr or .wdpr-meta.xml, deploy a .wdash or .wapp, run a recipe or dataflowjob programmatically, upload CSV data via InsightsExternalData, validate a dataset schema with synthetic data, fetch dataset XMD, audit dashboard SAQL re-encoding, or find unused dataset fields. TRIGGER on keywords: Wave Recipe, CRMA, CRM Analytics, wdpr, wdash, wapp, WaveRecipe, Wave dataflow, dataflowjob, InsightsExternalData, SAQL, dataset XMD, Analytics Studio, R3 format, wave/recipes, wave/dashboards, or analytics on Salesforce objects (opportunities, leads, cases, accounts, sales). DO NOT TRIGGER for standard Salesforce reports or LWC components unrelated to CRM Analytics." metadata: version: "1.0" minApiVersion: "59.0" cliTools: - tool: ["curl"] semver: ">=7.0.0" - tool: ["node"] semver: ">=18.0.0" - tool: ["sf"] semver: ">=2.0.0" --- # Authoring CRM Analytics Assets End-to-end workflow for authoring the full CRM Analytics asset stack — application, Wave Recipe, dataset, and Wave Dashboard — against a Salesforce org from a local SFDX project, without the UI. ## Scope - **In scope**: WaveApplication, WaveRecipe (R3 format), Wave datasets (recipe-driven + CSV upload via InsightsExternalData), Wave Dashboards (.wdash deploy + PATCH styling), SAQL step authoring, dataset XMD inspection, dashboard auditing. - **Out of scope**: Standard Salesforce reports/dashboards, LWC analytics bridge components, Tableau CRM managed packages, org provisioning. --- ## Decision Tree — Pick the Right Method Before acting, read `references/method-decision-tree.md` to select the correct API path for the user's goal. Wrong method choices (e.g. multipart upload instead of R3 JSON body) cause silent failures that are hard to diagnose. --- ## Required Inputs - Authenticated org alias (verify with `sf org display -o --json`) - Target CRMA app name (folder developer name) - Recipe or dashboard name and output dataset alias - Source sObjects to load (API names, e.g. `Opportunity`, `Account`) - Field list per sObject - Transformation intent: formula fields, aggregations, filter conditions Defaults: - Local Salesforce connector name: `SFDC_LOCAL` (verify via `GET /wave/dataConnectors`) - API version: use `result.apiVersion` from `sf org display` - Node.js binary: `/usr/local/lib/sf/bin/node` (bundled with sf CLI) --- ## Workflow ### Phase Selection Before starting, identify the user's goal and determine which phases to run: | User goal | Phases to run | |-----------|--------------| | Build or update a recipe and dataset | 0 → 1 → 2 | | Validate recipe output schema after run | 0 → 1 → 2 → 3 | | Build or update a dashboard | 0 → 1 → 2 → 4 | | Full end-to-end: recipe + validation + dashboard | 0 → 1 → 2 → 3 → 4 | | Audit dataset for unused fields / stale SAQL | 0 → 1 → 5 | Execute only the phases in the selected path. Do not revisit this table mid-workflow. ### Phase 0 — Bootstrap Scripts 1. **Check for helper scripts** — before running any script referenced in this workflow, verify the `scripts/` directory exists in the skill root. All 11 scripts listed in `references/scripts-reference.md` are bundled with this skill. If a script is somehow missing, check that the skill was installed from the full repo (not a partial clone). Do not regenerate scripts from the descriptions — the implementations are authoritative. ### Phase 1 — Setup 2. **Verify org connection** — run `sf org display -o --json`. Capture `accessToken` and `instanceUrl`. If EPERM error, shell is sandboxed — re-run with full permissions. 3. **Look up or create the CRMA app** — run `scripts/create_app.js `. The script lists existing folders and only creates if missing. Do NOT include `assetIcon`. ### Phase 2 — Recipe Authoring 4. **Read the R3 node schema** — load `references/r3-node-schema.md` before writing any recipe JSON. Every node shape, critical field rule, and formula gotcha is documented there. 5. **Author the recipe JSON** — the `.wdpr` file contains only the `recipeDefinition` object (the `nodes` map, `runMode`, and `ui` section). Do NOT wrap it in an API envelope (`fileFormat`, `label`, `name`, `recipe: {}`) — the deploy script reads this file directly as the `recipeDefinition` body; wrapping it causes the wrong JSON structure to be POSTed at `?format=R3`, leaving `targetDataflowId` null. Save to `force-app/main/default/wave/.wdpr`. Key rules: - `runMode` must be `"full"` for generated recipes — NOT `"R3"` (which is only used as a query param on the API endpoint). Use `"incremental"` instead of `"full"` for large objects where reprocessing the entire source on every run is too slow; use `"streaming"` for near-real-time pipelines. `"full"` is the safe default for new recipes. - Use `sources` (array), never `source` (singular) - One field per formula node — chain them in sequence - Use `expressionType: "SQL"` and `type: "NUMBER"` or `type: "TEXT"` on formula fields - For text date dimensions use `date_format(field, 'yyyy')` or `date_format(field, 'MM/yyyy')` - Formula node action is `"formula"` — NOT `"computeExpression"`, `"augmentColumns"`, or `"transform"`. Fields array key is `"fields"` (NOT `"columns"`). Expression key is `"formulaExpression"` (NOT `"expression"`). Do NOT use backtick quotes around field names in expressions. - Insert an `EXTRACT0` (`extractGrains`) node between the last formula node and aggregate - Use the Designer-native `ui` section format — read `references/ui-section-template.md` **CRITICAL — top-level `.wdpr` file structure.** `nodes` is a ROOT-LEVEL object with UPPERCASE string keys. Do NOT put nodes inside `ui`. Do NOT use an array for `ui.nodes`. The file has exactly three top-level keys: `runMode`, `nodes`, `ui`. See `examples/wdpr-skeleton.wdpr` for a minimal 5-node skeleton (load → formula → extractGrains → aggregate → save). See the wrong-variant reference table in `references/r3-node-schema.md → "Common wrong variants"` for the full list of correct vs incorrect field names per node type. 6. **Write SFDX metadata wrappers** — every `.wdpr` file MUST be accompanied by a `.wdpr-meta.xml` in the same directory. These are always created as a pair — outputting the recipe JSON without its metadata wrapper is incomplete. Use the template at `assets/wdpr-meta-template.xml`. Required fields: ``, ``, ``, `` (set to the same value as ``). Do NOT add ``, `