Skip to content

Conversation

@utsabc
Copy link
Member

@utsabc utsabc commented Dec 18, 2025

What are the changes introduced in this PR?

This pull request simplifies the Salesforce destination integration by removing legacy HTTP-based lookup logic and consolidating all Salesforce ID lookups to use the Salesforce SDK. As a result, related code paths, parameters, and tests have been cleaned up to reflect this unified approach.

Refactor: Remove legacy HTTP lookup and workspace SOQL support checks

  • All code paths that previously checked if a workspace supported SOQL and conditionally used HTTP-based lookups have been removed. Now, all Salesforce ID lookups use the Salesforce SDK exclusively. This includes removing the isWorkspaceSupportedForSoql utility and all references to it. [1] [2] [3] [4] [5]

API and parameter cleanup

  • Functions such as getSalesforceIdFromPayload, processIdentify, processSingleMessage, getSalesforceIdForRecord, and getSalesforceIdForLead have been refactored to remove unused metadata parameters, as they are no longer needed for SOQL support checks or HTTP lookups. [1] [2] [3] [4] [5] [6]

Test suite updates

  • The test suite for Salesforce utilities has been updated to remove tests for the legacy HTTP code paths and workspace SOQL checks. Tests now focus exclusively on SDK-based logic, including handling cases such as no records found, multiple records found, and lead conversion scenarios. [1] [2] [3] [4] [5] [6] [7] [8] [9]

Minor dependency cleanup

  • Unused modules such as stats have been removed from utils.js since instrumentation for HTTP lookups is no longer needed.

These changes streamline the Salesforce integration codebase, making it easier to maintain and reducing the potential for inconsistent behavior between SDK and HTTP lookup paths.

What is the related Linear task?

Resolves INT-XXX

Please explain the objectives of your changes below

Put down any required details on the broader aspect of your changes. If there are any dependent changes, mandatorily mention them here

Any changes to existing capabilities/behaviour, mention the reason & what are the changes ?

N/A

Any new dependencies introduced with this change?

N/A

Any new generic utility introduced or modified. Please explain the changes.

N/A

Any technical or performance related pointers to consider with the change?

N/A

@coderabbitai review


Developer checklist

  • My code follows the style guidelines of this project

  • No breaking changes are being introduced.

  • All related docs linked with the PR?

  • All changes manually tested?

  • Any documentation changes needed with this change?

  • Is the PR limited to 10 file changes?

  • Is the PR limited to one linear task?

  • Are relevant unit and component test-cases added in new readability format?

Reviewer checklist

  • Is the type of change in the PR title appropriate as per the changes?

  • Verified that there are no credentials or confidential data exposed with the changes.

@utsabc utsabc requested a review from a team as a code owner December 18, 2025 07:36
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 18, 2025

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'auto_resolve_threads'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Summary by CodeRabbit

  • Refactor
    • Optimized Salesforce integration by standardizing data retrieval mechanisms and consolidating processing logic, enabling more consistent behavior across all configurations.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

The PR simplifies Salesforce SDK integration by removing workspace-based conditional branching. It eliminates the isWorkspaceSupportedForSoql check, removes metadata parameters from public function signatures, and consolidates ID lookup to always use the Salesforce SDK path, removing HTTP fallback mechanisms.

Changes

Cohort / File(s) Summary
Salesforce SDK and transform refactoring
src/v0/destinations/salesforce/transform.js, src/v0/destinations/salesforce/utils.js
Removed workspace-based conditional branching and isWorkspaceSupportedForSoql checks. Simplified function signatures by removing metadata parameter from getSalesforceIdFromPayload, processIdentify, and processSingleMessage. Consolidated ID lookup to always use Salesforce SDK path, eliminating HTTP fallback logic in getSalesforceIdForRecord and getSalesforceIdForLead. SDK initialization now unconditional using token and instanceUrl from authorizationData.
Test updates
src/v0/destinations/salesforce/utils.test.js
Updated test descriptions and assertions to reflect SDK-only path. Replaced workspace-support-based test scenarios with cases covering no results, multiple results, and error handling. Added tests for Lead vs. Contact determination based on IsConverted and useContactId flags. Removed predefined workspace fixtures in favor of in-test configuration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30–40 minutes

Areas requiring extra attention:

  • Verify all internal and external call sites have been updated to pass only { message, destination } instead of including metadata
  • Ensure the SDK-only path in getSalesforceIdForRecord and getSalesforceIdForLead handles all error scenarios and edge cases previously managed by the HTTP fallback
  • Confirm test assertions accurately validate query construction and error handling across all new scenarios (no results, multiple results, conversion flags)
  • Check that removed stats instrumentation doesn't impact observability or monitoring

Possibly related PRs

Suggested reviewers

  • chandumlg
  • achettyiitr

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: enable soql by default' is partially related to the changeset. While the PR does consolidate SOQL usage, the actual changes remove workspace-specific SOQL checks and make SDK-based lookups mandatory (removing HTTP fallback), rather than enabling SOQL for the first time. The title could be more precise about this consolidation.
Description check ✅ Passed The PR description comprehensively addresses the template requirements. It explains the changes (removing HTTP lookups, consolidating to SDK), provides related Linear task reference (INT-XXX), details refactored functions and test updates, and includes both checklists. All template sections are addressed.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat.enable-soql-default

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/v0/destinations/salesforce/utils.js (3)

323-325: Potential SOQL injection vulnerability via unescaped identifier value.

The identifierValue is directly interpolated into the SOQL query string without escaping single quotes. If identifierValue contains a single quote (e.g., O'Brien), the query will be malformed and could potentially be exploited.

Consider escaping single quotes by replacing ' with \' before interpolation:

Suggested fix
+const escapeSoqlValue = (value) => String(value).replace(/'/g, "\\'");
+
 async function getSalesforceIdForRecordUsingSdk(
   salesforceSdk,
   objectType,
   identifierType,
   identifierValue,
 ) {
   let queryResponse;
   try {
+    const escapedValue = escapeSoqlValue(identifierValue);
     queryResponse = await salesforceSdk.query(
-      `SELECT Id FROM ${objectType} WHERE ${identifierType} = '${identifierValue}'`,
+      `SELECT Id FROM ${objectType} WHERE ${identifierType} = '${escapedValue}'`,
     );

395-397: Same SOQL injection risk with email parameter.

The email value is interpolated directly without escaping. Emails with special characters (though rare) or malicious input could break or exploit the query.

Suggested fix
 async function getSalesforceIdForLeadUsingSdk(salesforceSdk, email, destination) {
   let queryResponse;
   try {
+    const escapedEmail = String(email).replace(/'/g, "\\'");
     queryResponse = await salesforceSdk.query(
-      `SELECT Id, IsConverted, ConvertedContactId, IsDeleted FROM Lead WHERE Email = '${email}'`,
+      `SELECT Id, IsConverted, ConvertedContactId, IsDeleted FROM Lead WHERE Email = '${escapedEmail}'`,
     );

248-253: isWorkspaceSupportedForSoql is unused production code and should be removed.

The function is exported at line 547 but is not called from any production code. It only appears in the definition and export, with no usages elsewhere in the codebase outside of test files. Since workspace-based SOQL checks are being removed per the PR summary, remove this function and its associated test cases. Also remove the DEST_SALESFORCE_SOQL_SUPPORTED_WORKSPACE_IDS environment variable dependency if it's no longer needed elsewhere.

src/v0/destinations/salesforce/utils.test.js (1)

573-589: This test demonstrates the SOQL injection issue.

The test shows that a value containing a single quote (test'value) produces a malformed query: 'test'value'. This would likely cause a SOQL syntax error at runtime. Once the escaping fix is applied in utils.js, this test should be updated to expect the escaped value:

-      expect(mockSalesforceSdk.query).toHaveBeenCalledWith(
-        "SELECT Id FROM Account WHERE External_ID__c = 'test'value'",
-      );
+      expect(mockSalesforceSdk.query).toHaveBeenCalledWith(
+        "SELECT Id FROM Account WHERE External_ID__c = 'test\\'value'",
+      );
🧹 Nitpick comments (2)
src/v0/destinations/salesforce/utils.test.js (1)

41-76: Tests for isWorkspaceSupportedForSoql may be testing dead code.

If isWorkspaceSupportedForSoql is removed from utils.js as suggested, these tests should also be removed. If the function is kept for backward compatibility, consider adding a comment explaining why.

src/v0/destinations/salesforce/utils.js (1)

265-305: HTTP-based lookup functions are exported but not used by their public entry points.

getSalesforceIdForRecordUsingHttp and getSalesforceIdForLeadUsingHttp are defined and exported but the public entry points (getSalesforceIdForRecord, getSalesforceIdForLead) now exclusively call their SDK-based counterparts. Consider documenting these functions if they're intentionally maintained for backward compatibility or external SDK consumers. Otherwise, evaluate removing them to reduce maintenance burden and improve code clarity.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56203fb and 14cda92.

📒 Files selected for processing (3)
  • src/v0/destinations/salesforce/transform.js (6 hunks)
  • src/v0/destinations/salesforce/utils.js (2 hunks)
  • src/v0/destinations/salesforce/utils.test.js (7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.js

⚙️ CodeRabbit configuration file

Focus on ESLint errors (max 3) and warnings (max 5).

Files:

  • src/v0/destinations/salesforce/utils.test.js
  • src/v0/destinations/salesforce/utils.js
  • src/v0/destinations/salesforce/transform.js
🧠 Learnings (2)
📚 Learning: 2025-12-12T12:38:43.404Z
Learnt from: maheshkutty
Repo: rudderlabs/rudder-transformer PR: 4855
File: src/cdk/v2/destinations/zoho/utils.ts:412-433
Timestamp: 2025-12-12T12:38:43.404Z
Learning: In the Zoho destination (src/cdk/v2/destinations/zoho/), identifier values in `message.identifiers` will not contain object data types; they are expected to be scalar values (string, number, boolean) or arrays of scalars, so additional type guards against objects are not needed.

Applied to files:

  • src/v0/destinations/salesforce/transform.js
📚 Learning: 2025-12-05T08:37:16.001Z
Learnt from: maheshkutty
Repo: rudderlabs/rudder-transformer PR: 4846
File: src/cdk/v2/destinations/zoho/transformRecordV2.ts:286-286
Timestamp: 2025-12-05T08:37:16.001Z
Learning: In src/cdk/v2/destinations/zoho/transformRecordV2.ts, the `identifiers` property is optional in the Message type (identifiers?: Record<string, unknown>), so checking both `!identifiers` and `isEmptyObject(identifiers)` is necessary to handle the case where identifiers is undefined before passing it to isEmptyObject.

Applied to files:

  • src/v0/destinations/salesforce/transform.js
🧬 Code graph analysis (2)
src/v0/destinations/salesforce/utils.test.js (1)
src/v0/destinations/salesforce/transform.js (3)
  • stateInfo (217-217)
  • stateInfo (260-263)
  • destination (194-194)
src/v0/destinations/salesforce/utils.js (1)
src/v0/destinations/salesforce/transform.js (4)
  • stateInfo (217-217)
  • stateInfo (260-263)
  • email (176-176)
  • destination (194-194)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Build Transformer Docker Image - PR / Build Transformer Docker Image AMD64
  • GitHub Check: Build Transformer Docker Image - PR / Build Transformer Docker Image ARM64
  • GitHub Check: Build User Transformer Docker Image - PR / Build Transformer Docker Image ARM64
  • GitHub Check: Build User Transformer Docker Image - PR / Build Transformer Docker Image AMD64
  • GitHub Check: Code Coverage
  • GitHub Check: check-health
  • GitHub Check: Check for formatting & lint errors
  • GitHub Check: test_and_publish
  • GitHub Check: UT Tests
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (10)
src/v0/destinations/salesforce/utils.js (2)

371-383: SDK-only delegation looks correct.

The simplified function signature accepting { objectType, identifierType, identifierValue, stateInfo } and delegating to getSalesforceIdForRecordUsingSdk is clean and appropriate for the SDK-only flow.


531-533: SDK-only flow for lead lookup is correctly implemented.

The function now exclusively uses getSalesforceIdForLeadUsingSdk, properly passing the SDK instance from stateInfo. The simplified signature aligns with the PR objective.

src/v0/destinations/salesforce/transform.js (4)

254-263: SDK initialization change looks correct.

The unconditional initialization of SalesforceSDK.Salesforce with token and instanceUrl from authorizationData properly implements the SDK-only flow. The stateInfo object cleanly bundles authInfo and salesforceSdk for downstream functions.


284-299: Good error handling for SDK initialization in router path.

The try-catch block around SDK creation properly handles initialization failures and returns appropriate error responses. This matches the pattern used for authorization errors above.


119-119: Function signatures consistently updated.

The simplified signatures removing metadata parameter are consistently applied across getSalesforceIdFromPayload, processIdentify, and processSingleMessage. This aligns with the SDK-only approach where metadata is no longer needed for workspace checks.

Also applies to: 193-193, 240-240


156-161: Verify stateInfo is passed correctly to getSalesforceIdForRecord.

The call passes stateInfo as a property in the options object, which matches the updated function signature in utils.js. This looks correct.

src/v0/destinations/salesforce/utils.test.js (4)

608-631: SDK-only test correctly verifies behavior.

The test properly verifies that getSalesforceIdForRecord uses the SDK to query Salesforce and that handleHttpRequest is not called. This aligns with the PR objective of SDK-only lookups.


633-674: Good coverage for no-records and multiple-records scenarios.

These tests properly verify the SDK-only behavior for edge cases: returning undefined when no record is found and throwing NetworkInstrumentationError when multiple records are found. The assertions confirm the SDK is called appropriately.


1387-1419: Lead lookup SDK-only test is comprehensive.

The test verifies that getSalesforceIdForLead uses the SDK with the correct SOQL query and that HTTP is not called. The expected query format and return structure are properly validated.


1421-1456: Good test coverage for lead conversion and multiple leads scenarios.

Tests properly cover:

  • Lead converted with useContactId: true returning Contact type
  • No lead found returning undefined
  • Multiple leads throwing NetworkInstrumentationError

These align with the SDK-based behavior expected after the refactor.

Also applies to: 1458-1500

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants