feat: clone a connector across profiles within a merchant#4952
feat: clone a connector across profiles within a merchant#4952kanikabansal08 wants to merge 2 commits into
Conversation
Add a "Clone connector" action on the connector preview that copies a connector's configuration into another business profile of the same merchant via POST /user/connectors/clone. - Gate behind the connector_clone_allow_list feature flag, org/merchant admin role, and non-embedded sessions - Modal shows the source connector, a destination profile picker and a required new connector label, built with Form + FormRenderer (native required validation) - Fix Modal to skip the empty description block when no description is provided (removes a phantom gap) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
XyneSpaces
left a comment
There was a problem hiding this comment.
Automated Review Summary
PR: feat: clone a connector across profiles within a merchant
Reviewer: XyneSpaces Automation
Findings
Found 3 issues requiring changes:
- Critical: Error handling silently swallows all errors in the
onSubmitcatch block - Warning: Mixpanel event lacks required metadata
- Warning: Typography module classes not used correctly for text styling
Please address the inline comments below.
| @@ -0,0 +1,236 @@ | |||
| open APIUtils | |||
There was a problem hiding this comment.
🚨 Silent error swallowing violates error handling rules. The catch block on lines 75-76 discards all errors without user notification or logging.
Fix: Replace the empty catch block with proper error handling:
catch {
| Exn.Error(exn) => {
showToast(~message="Failed to clone connector. Please try again.", ~toastType=ToastError)
logger.error(~message="Connector clone failed", ~data=exn)
}
}| @@ -0,0 +1,236 @@ | |||
| open APIUtils | |||
| open LogicUtils | |||
There was a problem hiding this comment.
Fix: Enrich the event with relevant identifiers:
mixpanelEvent(
~eventName=`processor_clone_${connectorInfo.connector_name}`,
~props=Dict.make()
->Dict.set("connector_name", connectorInfo.connector_name->JSON.Encode.string)
->Dict.set("source_profile_id", connectorInfo.profile_id->JSON.Encode.string)
->JSON.Encode.object
)| @@ -0,0 +1,236 @@ | |||
| open APIUtils | |||
| open LogicUtils | |||
| open Typography | |||
There was a problem hiding this comment.
💡 Typography module classes should be used for text styling. Lines 69, 80, 86 use {body.sm.semibold} inline instead of applying Typography module classes to the elements.
Fix: Use the Typography module pattern consistently:
// Instead of inline interpolation:
p className={`${body.sm.semibold} text-nd_gray-400`}
// Open Typography at module top and use:
p className={`${Typography.body.sm.semibold} text-nd_gray-400`}See existing patterns in sibling files for reference.
Type of Change
Description
Adds a Clone connector action on the connector preview page that copies a connector's configuration from one business profile into another profile of the same merchant, via
POST /user/connectors/clone.#CLONE_CONNECTORuser route mapping touser/connectors/clone.connector_clone_allow_listfeature flag (array of connector names) that controls which connectors expose the action.Form+FormRenderer.FieldRenderer/SubmitButton— required-field validation and submit-disabling are native.Modalno longer renders an empty description block (and its padding) when no description is provided.Screen.Recording.2026-06-09.at.4.48.47.PM.mov
Motivation and Context
Merchants with multiple profiles currently have to re-create a connector by hand in each profile. This lets them clone an existing connector's setup into another profile in a couple of clicks, while making clear which settings carry over and which need re-configuration.
How did you test it?
npm run re:build(full clean build passes).Where to test it?
Backend Dependency
Backend PR URL: depends on
POST /user/connectors/clone(ProfileConnectorWrite, org/merchant admin only).Feature Flag
Feature flag name(s):
connector_clone_allow_listChecklist
npm run re:build