improvement(salesforce): align tools + block with Salesforce API and harden CRUD/analytics#5040
Conversation
…harden CRUD/analytics - Migrate all 4 Account tools to shared getInstanceUrl + extractErrorMessage helpers (drop ~40 lines of inlined idToken decode per file) - Use extractErrorMessage consistently across every CRUD tool; add loggers to the opportunity tools - Trim ID path params on all update/delete/single-get tools; URL-encode single-record field lists - Fix dashboard tools: read name/metadata from dashboardMetadata.attributes (was always null); refresh now returns status/statusUrl defensively; drop no-op list_dashboards folderName filter - Expose update_case origin/contact/account and update_task who/what fields end-to-end - Block: mark create-required (Name, LastName, Company, StageName, Subject) and update/delete IDs conditionally required; add account billing*/revenue/employees and contact mailing*/department subBlocks; convert includeDetails to a Yes/No dropdown; move optional fields to advanced mode - Trim over-declared dashboard output types; make Task.Status optional - Regenerate integration docs
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Shared tooling: CRUD and query tools now route instance URLs and API errors through Analytics: Updates & UI: Docs: Integration MDX and Reviewed by Cursor Bugbot for commit e4cb146. Configure here. |
Greptile SummaryThis PR hardens the Salesforce integration by centralising instance URL resolution and error extraction into shared helpers, trimming ID path params across all CRUD tools to prevent copy-paste 404s, fixing dashboard metadata field paths (
Confidence Score: 4/5Safe to merge after fixing the dashboard ID trimming gap — all other changes are clean refactors and additive features. Both apps/sim/tools/salesforce/get_dashboard.ts and apps/sim/tools/salesforce/refresh_dashboard.ts — both need Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Tool request params] --> B{instanceUrl provided?}
B -- Yes --> C[getInstanceUrl returns instanceUrl]
B -- No --> D{idToken provided?}
D -- Yes --> E[Decode JWT payload]
E --> F{profile or sub claim?}
F -- profile --> G[Extract host from profile]
F -- sub --> H[Extract host from sub]
G --> C
H --> C
D -- No --> I[Throw: instance URL required]
C --> J{ID param present?}
J -- Yes --> K[requireId: trim + validate]
K -- empty --> L[Throw: ID required]
K -- valid --> M[Build URL with trimmed ID]
J -- No --> N[Build list/create URL]
M --> O[Fetch Salesforce API]
N --> O
O --> P{response.ok?}
P -- No --> Q[extractErrorMessage]
Q --> R[Throw Error]
P -- Yes --> S[transformResponse]
S --> T[Return structured output]
|
- list_dashboards: GET /analytics/dashboards returns a bare top-level array, not a {dashboards} wrapper (fixes always-empty result)
- refresh_dashboard: statusUrl is returned at the top level of the PUT response, read it there first
- list_reports: the list resource only returns report name/id/url/describeUrl/instancesUrl, so drop the no-op folderName filter and match searchTerm on name only
Validated tool-by-tool against the live Salesforce REST/Analytics/Object-Reference docs (API v67.0).
|
@greptile |
|
@cursor review |
- Add shared requireId() guard so whitespace-only IDs fail fast instead of producing malformed /sobjects/Object/ empty-path requests (all update/delete/single-get tools) - URL-encode the fields query value in get_opportunities and get_tasks single-record GETs (matching the other get_* tools) - Reflect the Salesforce API success flag consistently across all create tools (success/created use data.success === true)
|
@greptile |
|
@cursor review |
- update/delete tools now return output.id from the trimmed ID so chained workflows never receive whitespace-padded IDs - trim relation reference IDs (AccountId, ContactId, WhoId, WhatId) in create/update bodies to avoid Salesforce reference errors from copy-pasted whitespace
|
@greptile |
|
@cursor review |
Last remaining untrimmed relation reference ID — update_contact now trims AccountId like the other create/update tools.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e4cb146. Configure here.
Summary
getInstanceUrl+extractErrorMessagehelpers (dropped ~40 lines of inlined idToken decode per file); every CRUD tool now usesextractErrorMessageconsistently and the opportunity tools gained loggersget_dashboard/refresh_dashboardnow read name/metadata fromdashboardMetadata.attributes(previously alwaysnull);refresh_dashboardreturnsstatus/statusUrldefensively across both documented response shapes; dropped the no-oplist_dashboardsfolderName filterupdate_caseorigin/contact/account andupdate_taskwho/what fields end-to-end (params → body → block subBlocks)billing*/revenue/employees and contactmailing*/department subBlocks; convertedincludeDetailsto a Yes/No dropdown; moved optional fields to advanced modeTask.Statusoptional, regenerated integration docsType of Change
Testing
Tested manually — typecheck clean (0 Salesforce errors), biome lint clean, docs regenerated. Validated every tool + the block against the live Salesforce REST/Analytics API docs via parallel subagent audits. Fully backwards-compatible: no tool IDs or input params removed (except a no-op filter), output removals are always-null phantom fields, new required/advanced flags are UI-only.
Checklist