@lead-routing/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/index.js +1916 -0
  2. package/dist/prisma/migrations/20260101000000_init/migration.sql +276 -0
  3. package/dist/prisma/migrations/20260223000000_add_routing_log_dismissed/migration.sql +2 -0
  4. package/dist/prisma/migrations/20260224000000_add_org_notification_webhook/migration.sql +2 -0
  5. package/dist/prisma/migrations/20260227000000_self_hosted_schema_updates/migration.sql +68 -0
  6. package/dist/prisma/schema.prisma +315 -0
  7. package/dist/sfdc-package/force-app/main/default/applications/Lead_Router_Setup.app-meta.xml +12 -0
  8. package/dist/sfdc-package/force-app/main/default/classes/AccountTriggerTest.cls +58 -0
  9. package/dist/sfdc-package/force-app/main/default/classes/AccountTriggerTest.cls-meta.xml +5 -0
  10. package/dist/sfdc-package/force-app/main/default/classes/ContactTriggerTest.cls +62 -0
  11. package/dist/sfdc-package/force-app/main/default/classes/ContactTriggerTest.cls-meta.xml +5 -0
  12. package/dist/sfdc-package/force-app/main/default/classes/LeadTriggerTest.cls +95 -0
  13. package/dist/sfdc-package/force-app/main/default/classes/LeadTriggerTest.cls-meta.xml +5 -0
  14. package/dist/sfdc-package/force-app/main/default/classes/OnboardingController.cls +183 -0
  15. package/dist/sfdc-package/force-app/main/default/classes/OnboardingController.cls-meta.xml +5 -0
  16. package/dist/sfdc-package/force-app/main/default/classes/RoutingEngineCallout.cls +96 -0
  17. package/dist/sfdc-package/force-app/main/default/classes/RoutingEngineCallout.cls-meta.xml +5 -0
  18. package/dist/sfdc-package/force-app/main/default/classes/RoutingEngineMock.cls +28 -0
  19. package/dist/sfdc-package/force-app/main/default/classes/RoutingEngineMock.cls-meta.xml +5 -0
  20. package/dist/sfdc-package/force-app/main/default/classes/RoutingPayloadBuilder.cls +50 -0
  21. package/dist/sfdc-package/force-app/main/default/classes/RoutingPayloadBuilder.cls-meta.xml +5 -0
  22. package/dist/sfdc-package/force-app/main/default/lwc/onboardingWizard/onboardingWizard.html +230 -0
  23. package/dist/sfdc-package/force-app/main/default/lwc/onboardingWizard/onboardingWizard.js +222 -0
  24. package/dist/sfdc-package/force-app/main/default/lwc/onboardingWizard/onboardingWizard.js-meta.xml +11 -0
  25. package/dist/sfdc-package/force-app/main/default/namedCredentials/RoutingEngine.namedCredential-meta.xml +10 -0
  26. package/dist/sfdc-package/force-app/main/default/objects/Routing_Error_Log__c/Routing_Error_Log__c.object-meta.xml +21 -0
  27. package/dist/sfdc-package/force-app/main/default/objects/Routing_Error_Log__c/fields/Created_At__c.field-meta.xml +6 -0
  28. package/dist/sfdc-package/force-app/main/default/objects/Routing_Error_Log__c/fields/Payload__c.field-meta.xml +8 -0
  29. package/dist/sfdc-package/force-app/main/default/objects/Routing_Error_Log__c/fields/Response_Body__c.field-meta.xml +8 -0
  30. package/dist/sfdc-package/force-app/main/default/objects/Routing_Error_Log__c/fields/Status_Code__c.field-meta.xml +9 -0
  31. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/Routing_Settings__c.object-meta.xml +8 -0
  32. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Account_Insert_Enabled__c.field-meta.xml +7 -0
  33. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Account_Routing_Enabled__c.field-meta.xml +7 -0
  34. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Account_Update_Enabled__c.field-meta.xml +7 -0
  35. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/App_Url__c.field-meta.xml +8 -0
  36. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Contact_Insert_Enabled__c.field-meta.xml +7 -0
  37. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Contact_Routing_Enabled__c.field-meta.xml +7 -0
  38. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Contact_Update_Enabled__c.field-meta.xml +7 -0
  39. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Engine_Endpoint__c.field-meta.xml +8 -0
  40. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Lead_Insert_Enabled__c.field-meta.xml +7 -0
  41. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Lead_Routing_Enabled__c.field-meta.xml +7 -0
  42. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Lead_Update_Enabled__c.field-meta.xml +7 -0
  43. package/dist/sfdc-package/force-app/main/default/objects/Routing_Settings__c/fields/Webhook_Secret__c.field-meta.xml +8 -0
  44. package/dist/sfdc-package/force-app/main/default/permissionsets/LeadRouterAdmin.permissionset-meta.xml +14 -0
  45. package/dist/sfdc-package/force-app/main/default/remoteSiteSettings/LeadRouterEngine.remoteSite-meta.xml +7 -0
  46. package/dist/sfdc-package/force-app/main/default/tabs/Lead_Router_Setup.tab-meta.xml +7 -0
  47. package/dist/sfdc-package/force-app/main/default/triggers/AccountTrigger.trigger +28 -0
  48. package/dist/sfdc-package/force-app/main/default/triggers/AccountTrigger.trigger-meta.xml +5 -0
  49. package/dist/sfdc-package/force-app/main/default/triggers/ContactTrigger.trigger +28 -0
  50. package/dist/sfdc-package/force-app/main/default/triggers/ContactTrigger.trigger-meta.xml +5 -0
  51. package/dist/sfdc-package/force-app/main/default/triggers/LeadTrigger.trigger +28 -0
  52. package/dist/sfdc-package/force-app/main/default/triggers/LeadTrigger.trigger-meta.xml +5 -0
  53. package/dist/sfdc-package/sfdx-project.json +14 -0
  54. package/package.json +41 -0
@@ -0,0 +1,230 @@
1
+ <template>
2
+ <div class="slds-card slds-p-around_large" style="max-width: 640px; margin: 0 auto;">
3
+
4
+ <!-- Loading state while connectedCallback initialises -->
5
+ <template lwc:if={isLoading}>
6
+ <div class="slds-align_absolute-center slds-p-around_large">
7
+ <lightning-spinner alternative-text="Loading Lead Router Setup…" size="medium"></lightning-spinner>
8
+ </div>
9
+ </template>
10
+
11
+ <!-- Error state (App URL not configured, or Apex error) -->
12
+ <template lwc:elseif={initError}>
13
+ <div class="slds-align_absolute-center slds-p-around_large">
14
+ <div class="slds-notify slds-notify_alert slds-theme_error" role="alert">
15
+ <span class="slds-assistive-text">Error</span>
16
+ <lightning-icon icon-name="utility:error" size="x-small" variant="inverse" class="slds-m-right_x-small"></lightning-icon>
17
+ {initError}
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <!-- Main wizard content -->
23
+ <template lwc:else>
24
+
25
+ <!-- Header -->
26
+ <div class="slds-align_absolute-center slds-m-bottom_large">
27
+ <div>
28
+ <h1 class="slds-text-heading_large slds-text-align_center">Lead Router Setup</h1>
29
+ <p class="slds-text-color_weak slds-text-align_center slds-m-top_x-small">
30
+ Connect your Salesforce org to the routing engine in 4 steps.
31
+ </p>
32
+ </div>
33
+ </div>
34
+
35
+ <!-- Progress indicator -->
36
+ <div class="slds-progress slds-progress_shade slds-m-bottom_large">
37
+ <ol class="slds-progress__list">
38
+ <template for:each={steps} for:item="step">
39
+ <li key={step.index}
40
+ class={step.cssClass}
41
+ aria-label={step.label}>
42
+ <button class="slds-progress__marker" title={step.label}>
43
+ <span class="slds-assistive-text">{step.label}</span>
44
+ </button>
45
+ </li>
46
+ </template>
47
+ </ol>
48
+ <div class="slds-progress-bar slds-progress-bar_x-small" aria-valuemin="0" aria-valuemax="100" aria-valuenow={progressPercent} role="progressbar">
49
+ <span class="slds-progress-bar__value" style={progressStyle}></span>
50
+ </div>
51
+ </div>
52
+
53
+ <!-- ─── Step 1: Connect Your Org ──────────────────────────────────────── -->
54
+ <template if:true={isStep1}>
55
+ <div class="slds-card__body">
56
+ <div class="slds-align_absolute-center slds-m-bottom_medium">
57
+ <lightning-icon icon-name="utility:connected_apps" size="large" class="slds-m-bottom_small"></lightning-icon>
58
+ </div>
59
+ <h2 class="slds-text-heading_medium slds-text-align_center slds-m-bottom_small">Step 1: Connect Your Org</h2>
60
+ <p class="slds-text-color_weak slds-text-align_center slds-m-bottom_large">
61
+ Authorise Lead Router to access your Salesforce org via OAuth.
62
+ </p>
63
+
64
+ <template if:false={isConnected}>
65
+ <div class="slds-align_absolute-center">
66
+ <lightning-button
67
+ variant="brand"
68
+ label="Connect to Lead Router"
69
+ icon-name="utility:salesforce1"
70
+ onclick={handleConnect}>
71
+ </lightning-button>
72
+ </div>
73
+ <template if:true={isPolling}>
74
+ <div class="slds-align_absolute-center slds-m-top_medium">
75
+ <lightning-spinner alternative-text="Waiting for connection..." size="small"></lightning-spinner>
76
+ <p class="slds-m-top_small slds-text-color_weak">Waiting for authorisation…</p>
77
+ </div>
78
+ </template>
79
+ </template>
80
+
81
+ <template if:true={isConnected}>
82
+ <div class="slds-notify slds-notify_alert slds-theme_success slds-m-bottom_medium" role="alert">
83
+ <span class="slds-assistive-text">success</span>
84
+ <span class="slds-icon_container slds-icon-utility-success slds-m-right_x-small">
85
+ <lightning-icon icon-name="utility:success" size="x-small" variant="inverse"></lightning-icon>
86
+ </span>
87
+ Org connected successfully!
88
+ </div>
89
+ <div class="slds-align_absolute-center">
90
+ <lightning-button variant="brand" label="Next: Activate Objects" onclick={goToStep2}></lightning-button>
91
+ </div>
92
+ </template>
93
+ </div>
94
+ </template>
95
+
96
+ <!-- ─── Step 2: Activate Objects & Triggers ───────────────────────────── -->
97
+ <template if:true={isStep2}>
98
+ <div class="slds-card__body">
99
+ <h2 class="slds-text-heading_medium slds-text-align_center slds-m-bottom_small">Step 2: Activate Objects &amp; Triggers</h2>
100
+ <p class="slds-text-color_weak slds-text-align_center slds-m-bottom_large">
101
+ Select which objects and events should trigger routing.
102
+ </p>
103
+
104
+ <div class="slds-grid slds-gutters slds-wrap">
105
+ <!-- Lead -->
106
+ <div class="slds-col slds-size_1-of-3">
107
+ <div class="slds-card slds-p-around_medium">
108
+ <p class="slds-text-heading_small slds-m-bottom_small">Lead</p>
109
+ <lightning-input type="toggle" label="Enable Lead Routing"
110
+ checked={leadEnabled} onchange={handleLeadEnabledChange}></lightning-input>
111
+ <template if:true={leadEnabled}>
112
+ <lightning-input type="checkbox" label="On Insert"
113
+ checked={leadInsert} onchange={handleLeadInsertChange}
114
+ class="slds-m-top_x-small"></lightning-input>
115
+ <lightning-input type="checkbox" label="On Update"
116
+ checked={leadUpdate} onchange={handleLeadUpdateChange}
117
+ class="slds-m-top_x-small"></lightning-input>
118
+ </template>
119
+ </div>
120
+ </div>
121
+ <!-- Contact -->
122
+ <div class="slds-col slds-size_1-of-3">
123
+ <div class="slds-card slds-p-around_medium">
124
+ <p class="slds-text-heading_small slds-m-bottom_small">Contact</p>
125
+ <lightning-input type="toggle" label="Enable Contact Routing"
126
+ checked={contactEnabled} onchange={handleContactEnabledChange}></lightning-input>
127
+ <template if:true={contactEnabled}>
128
+ <lightning-input type="checkbox" label="On Insert"
129
+ checked={contactInsert} onchange={handleContactInsertChange}
130
+ class="slds-m-top_x-small"></lightning-input>
131
+ <lightning-input type="checkbox" label="On Update"
132
+ checked={contactUpdate} onchange={handleContactUpdateChange}
133
+ class="slds-m-top_x-small"></lightning-input>
134
+ </template>
135
+ </div>
136
+ </div>
137
+ <!-- Account -->
138
+ <div class="slds-col slds-size_1-of-3">
139
+ <div class="slds-card slds-p-around_medium">
140
+ <p class="slds-text-heading_small slds-m-bottom_small">Account</p>
141
+ <lightning-input type="toggle" label="Enable Account Routing"
142
+ checked={accountEnabled} onchange={handleAccountEnabledChange}></lightning-input>
143
+ <template if:true={accountEnabled}>
144
+ <lightning-input type="checkbox" label="On Insert"
145
+ checked={accountInsert} onchange={handleAccountInsertChange}
146
+ class="slds-m-top_x-small"></lightning-input>
147
+ <lightning-input type="checkbox" label="On Update"
148
+ checked={accountUpdate} onchange={handleAccountUpdateChange}
149
+ class="slds-m-top_x-small"></lightning-input>
150
+ </template>
151
+ </div>
152
+ </div>
153
+ </div>
154
+
155
+ <div class="slds-align_absolute-center slds-m-top_large slds-grid slds-gutters">
156
+ <div class="slds-col">
157
+ <lightning-button variant="neutral" label="Send Test Event"
158
+ icon-name="utility:send" onclick={handleTestEvent}
159
+ disabled={isSaving}></lightning-button>
160
+ </div>
161
+ <div class="slds-col">
162
+ <lightning-button variant="brand" label="Save &amp; Next"
163
+ onclick={handleSaveSettings} disabled={isSaving}>
164
+ </lightning-button>
165
+ </div>
166
+ </div>
167
+
168
+ <template if:true={step2Message}>
169
+ <p class={step2MessageClass}>{step2Message}</p>
170
+ </template>
171
+ </div>
172
+ </template>
173
+
174
+ <!-- ─── Step 3: Sync Field Schema ─────────────────────────────────────── -->
175
+ <template if:true={isStep3}>
176
+ <div class="slds-card__body">
177
+ <div class="slds-align_absolute-center slds-m-bottom_medium">
178
+ <lightning-icon icon-name="utility:sync" size="large"></lightning-icon>
179
+ </div>
180
+ <h2 class="slds-text-heading_medium slds-text-align_center slds-m-bottom_small">Step 3: Sync Field Schema</h2>
181
+ <p class="slds-text-color_weak slds-text-align_center slds-m-bottom_large">
182
+ Pull your Salesforce field definitions into Lead Router so you can build routing conditions.
183
+ </p>
184
+
185
+ <div class="slds-align_absolute-center">
186
+ <lightning-button variant="brand" label="Sync Fields"
187
+ icon-name="utility:refresh" onclick={handleSyncFields}
188
+ disabled={isSyncing}></lightning-button>
189
+ </div>
190
+
191
+ <template if:true={isSyncing}>
192
+ <div class="slds-align_absolute-center slds-m-top_medium">
193
+ <lightning-spinner alternative-text="Syncing..." size="small"></lightning-spinner>
194
+ </div>
195
+ </template>
196
+
197
+ <template for:each={syncResults} for:item="result">
198
+ <div key={result.object} class="slds-notify slds-notify_alert slds-theme_success slds-m-top_small" role="status">
199
+ <lightning-icon icon-name="utility:check" size="x-small" variant="inverse" class="slds-m-right_x-small"></lightning-icon>
200
+ {result.object}: {result.synced} fields synced
201
+ </div>
202
+ </template>
203
+
204
+ <template if:true={allSynced}>
205
+ <div class="slds-align_absolute-center slds-m-top_large">
206
+ <lightning-button variant="brand" label="Next: Finish Setup" onclick={goToStep4}></lightning-button>
207
+ </div>
208
+ </template>
209
+ </div>
210
+ </template>
211
+
212
+ <!-- ─── Step 4: Done ──────────────────────────────────────────────────── -->
213
+ <template if:true={isStep4}>
214
+ <div class="slds-card__body slds-align_absolute-center">
215
+ <lightning-icon icon-name="utility:success" size="xx-large" variant="success"
216
+ class="slds-m-bottom_medium"></lightning-icon>
217
+ <h2 class="slds-text-heading_large slds-text-align_center slds-m-bottom_small">You&apos;re all set!</h2>
218
+ <p class="slds-text-color_weak slds-text-align_center slds-m-bottom_large">
219
+ Lead Router is connected and ready to route records.
220
+ Go to the dashboard to build your routing rules.
221
+ </p>
222
+ <lightning-button variant="brand" label="Open Lead Router →"
223
+ icon-name="utility:new_window" onclick={handleOpenApp}></lightning-button>
224
+ </div>
225
+ </template>
226
+
227
+ </template><!-- end lwc:else (main content) -->
228
+
229
+ </div>
230
+ </template>
@@ -0,0 +1,222 @@
1
+ import { LightningElement, track } from 'lwc';
2
+ import { ShowToastEvent } from 'lightning/platformShowToastEvent';
3
+ import getAppUrl from '@salesforce/apex/OnboardingController.getAppUrl';
4
+ import getOrgId from '@salesforce/apex/OnboardingController.getOrgId';
5
+ import saveRoutingSettings from '@salesforce/apex/OnboardingController.saveRoutingSettings';
6
+ import checkConnectionStatus from '@salesforce/apex/OnboardingController.checkConnectionStatus';
7
+ import sendTestEvent from '@salesforce/apex/OnboardingController.sendTestEvent';
8
+ import syncFieldSchema from '@salesforce/apex/OnboardingController.syncFieldSchema';
9
+ import markOnboardingDone from '@salesforce/apex/OnboardingController.markOnboardingDone';
10
+
11
+ const POLL_INTERVAL_MS = 3000;
12
+ const POLL_MAX_ATTEMPTS = 40; // 2 minutes
13
+
14
+ export default class OnboardingWizard extends LightningElement {
15
+
16
+ // ─── Init state ───────────────────────────────────────────────────────────
17
+
18
+ @track isLoading = true;
19
+ @track initError = null;
20
+ _appUrl = null;
21
+ _sfdcOrgId = null;
22
+
23
+ async connectedCallback() {
24
+ try {
25
+ const [appUrl, orgId] = await Promise.all([getAppUrl(), getOrgId()]);
26
+ if (!appUrl) {
27
+ this.initError = 'Lead Router App URL not configured. Run: lead-routing sfdc deploy';
28
+ return;
29
+ }
30
+ this._appUrl = appUrl;
31
+ this._sfdcOrgId = orgId;
32
+ } catch (e) {
33
+ this.initError = this._errorMsg(e);
34
+ } finally {
35
+ this.isLoading = false;
36
+ }
37
+ }
38
+
39
+ // ─── Step state ───────────────────────────────────────────────────────────
40
+
41
+ @track currentStep = 1;
42
+
43
+ get isStep1() { return this.currentStep === 1; }
44
+ get isStep2() { return this.currentStep === 2; }
45
+ get isStep3() { return this.currentStep === 3; }
46
+ get isStep4() { return this.currentStep === 4; }
47
+
48
+ get steps() {
49
+ return [1, 2, 3, 4].map(i => ({
50
+ index: i,
51
+ label: ['Connect Org', 'Activate Objects', 'Sync Fields', 'Done'][i - 1],
52
+ cssClass: [
53
+ 'slds-progress__item',
54
+ i < this.currentStep ? 'slds-is-completed' : '',
55
+ i === this.currentStep ? 'slds-is-active' : ''
56
+ ].filter(Boolean).join(' ')
57
+ }));
58
+ }
59
+
60
+ get progressPercent() { return Math.round(((this.currentStep - 1) / 3) * 100); }
61
+ get progressStyle() { return `width: ${this.progressPercent}%`; }
62
+
63
+ // ─── Step 1: Connection ───────────────────────────────────────────────────
64
+
65
+ @track isConnected = false;
66
+ @track isPolling = false;
67
+ _pollTimer = null;
68
+ _pollCount = 0;
69
+
70
+ handleConnect() {
71
+ const authUrl = `${this._appUrl}/api/auth/sfdc/login`;
72
+ window.open(authUrl, '_blank', 'width=600,height=700');
73
+ this.isPolling = true;
74
+ this._pollCount = 0;
75
+ this._pollTimer = setInterval(() => this._pollConnectionStatus(), POLL_INTERVAL_MS);
76
+ }
77
+
78
+ async _pollConnectionStatus() {
79
+ this._pollCount++;
80
+ if (this._pollCount > POLL_MAX_ATTEMPTS) {
81
+ clearInterval(this._pollTimer);
82
+ this.isPolling = false;
83
+ this._showError('Connection timed out. Please try again.');
84
+ return;
85
+ }
86
+
87
+ try {
88
+ const status = await checkConnectionStatus({ sfdcOrgId: this._sfdcOrgId });
89
+ if (status === true) {
90
+ clearInterval(this._pollTimer);
91
+ this.isPolling = false;
92
+ this.isConnected = true;
93
+ }
94
+ } catch (e) {
95
+ // Ignore polling errors — keep retrying
96
+ }
97
+ }
98
+
99
+ goToStep2() { this.currentStep = 2; }
100
+
101
+ // ─── Step 2: Object / Event settings ─────────────────────────────────────
102
+
103
+ @track leadEnabled = true;
104
+ @track leadInsert = true;
105
+ @track leadUpdate = false;
106
+ @track contactEnabled = false;
107
+ @track contactInsert = false;
108
+ @track contactUpdate = false;
109
+ @track accountEnabled = false;
110
+ @track accountInsert = false;
111
+ @track accountUpdate = false;
112
+
113
+ @track isSaving = false;
114
+ @track step2Message = '';
115
+ @track step2MessageClass = 'slds-text-align_center slds-m-top_small';
116
+
117
+ handleLeadEnabledChange(e) { this.leadEnabled = e.detail.checked; }
118
+ handleLeadInsertChange(e) { this.leadInsert = e.detail.checked; }
119
+ handleLeadUpdateChange(e) { this.leadUpdate = e.detail.checked; }
120
+ handleContactEnabledChange(e) { this.contactEnabled = e.detail.checked; }
121
+ handleContactInsertChange(e) { this.contactInsert = e.detail.checked; }
122
+ handleContactUpdateChange(e) { this.contactUpdate = e.detail.checked; }
123
+ handleAccountEnabledChange(e) { this.accountEnabled = e.detail.checked; }
124
+ handleAccountInsertChange(e) { this.accountInsert = e.detail.checked; }
125
+ handleAccountUpdateChange(e) { this.accountUpdate = e.detail.checked; }
126
+
127
+ async handleTestEvent() {
128
+ this.isSaving = true;
129
+ this.step2Message = '';
130
+ try {
131
+ await sendTestEvent();
132
+ this.step2Message = '✓ Test event sent — check routing history in Lead Router.';
133
+ this.step2MessageClass = 'slds-text-align_center slds-m-top_small slds-text-color_success';
134
+ } catch (e) {
135
+ this.step2Message = 'Test event failed: ' + this._errorMsg(e);
136
+ this.step2MessageClass = 'slds-text-align_center slds-m-top_small slds-text-color_error';
137
+ } finally {
138
+ this.isSaving = false;
139
+ }
140
+ }
141
+
142
+ async handleSaveSettings() {
143
+ this.isSaving = true;
144
+ try {
145
+ await saveRoutingSettings({
146
+ leadEnabled: this.leadEnabled,
147
+ leadInsert: this.leadInsert,
148
+ leadUpdate: this.leadUpdate,
149
+ contactEnabled: this.contactEnabled,
150
+ contactInsert: this.contactInsert,
151
+ contactUpdate: this.contactUpdate,
152
+ accountEnabled: this.accountEnabled,
153
+ accountInsert: this.accountInsert,
154
+ accountUpdate: this.accountUpdate
155
+ });
156
+ this.currentStep = 3;
157
+ } catch (e) {
158
+ this._showError('Failed to save settings: ' + this._errorMsg(e));
159
+ } finally {
160
+ this.isSaving = false;
161
+ }
162
+ }
163
+
164
+ // ─── Step 3: Sync fields ──────────────────────────────────────────────────
165
+
166
+ @track isSyncing = false;
167
+ @track syncResults = [];
168
+
169
+ get allSynced() { return this.syncResults.length > 0; }
170
+
171
+ async handleSyncFields() {
172
+ this.isSyncing = true;
173
+ this.syncResults = [];
174
+
175
+ const objects = [];
176
+ if (this.leadEnabled) objects.push('LEAD');
177
+ if (this.contactEnabled) objects.push('CONTACT');
178
+ if (this.accountEnabled) objects.push('ACCOUNT');
179
+
180
+ try {
181
+ for (const obj of objects) {
182
+ // eslint-disable-next-line no-await-in-loop
183
+ const synced = await syncFieldSchema({ objectType: obj });
184
+ this.syncResults = [...this.syncResults, { object: obj, synced }];
185
+ }
186
+ } catch (e) {
187
+ this._showError('Sync failed: ' + this._errorMsg(e));
188
+ } finally {
189
+ this.isSyncing = false;
190
+ }
191
+ }
192
+
193
+ goToStep4() { this.currentStep = 4; this._completeOnboarding(); }
194
+
195
+ async _completeOnboarding() {
196
+ try {
197
+ await markOnboardingDone();
198
+ } catch (e) {
199
+ // Non-fatal — onboarding flag is cosmetic
200
+ }
201
+ }
202
+
203
+ // ─── Step 4: Done ─────────────────────────────────────────────────────────
204
+
205
+ handleOpenApp() {
206
+ window.open(this._appUrl, '_blank');
207
+ }
208
+
209
+ // ─── Utilities ────────────────────────────────────────────────────────────
210
+
211
+ _showError(msg) {
212
+ this.dispatchEvent(new ShowToastEvent({
213
+ title: 'Error',
214
+ message: msg,
215
+ variant: 'error'
216
+ }));
217
+ }
218
+
219
+ _errorMsg(err) {
220
+ return (err && err.body && err.body.message) ? err.body.message : String(err);
221
+ }
222
+ }
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <apiVersion>59.0</apiVersion>
4
+ <isExposed>true</isExposed>
5
+ <targets>
6
+ <target>lightning__AppPage</target>
7
+ <target>lightning__Tab</target>
8
+ </targets>
9
+ <masterLabel>Lead Router Onboarding Wizard</masterLabel>
10
+ <description>Post-install setup wizard for connecting Salesforce to the Lead Router engine.</description>
11
+ </LightningComponentBundle>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <label>Routing Engine</label>
4
+ <endpoint>https://engine.openedgeai.tech</endpoint>
5
+ <principalType>Anonymous</principalType>
6
+ <protocol>NoAuthentication</protocol>
7
+ <allowMergeFieldsInBody>false</allowMergeFieldsInBody>
8
+ <allowMergeFieldsInHeader>false</allowMergeFieldsInHeader>
9
+ <generateAuthorizationHeader>false</generateAuthorizationHeader>
10
+ </NamedCredential>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <description>Records callout failures from Apex triggers to the routing engine.</description>
4
+ <enableActivities>false</enableActivities>
5
+ <enableBulkApi>true</enableBulkApi>
6
+ <enableFeeds>false</enableFeeds>
7
+ <enableHistory>false</enableHistory>
8
+ <enableReports>true</enableReports>
9
+ <enableSearch>false</enableSearch>
10
+ <enableSharing>true</enableSharing>
11
+ <enableStreamingApi>true</enableStreamingApi>
12
+ <label>Routing Error Log</label>
13
+ <nameField>
14
+ <displayFormat>ERR-{0000000}</displayFormat>
15
+ <label>Error Log Name</label>
16
+ <type>AutoNumber</type>
17
+ </nameField>
18
+ <pluralLabel>Routing Error Logs</pluralLabel>
19
+ <sharingModel>ReadWrite</sharingModel>
20
+ <deploymentStatus>Deployed</deploymentStatus>
21
+ </CustomObject>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Created_At__c</fullName>
4
+ <label>Created At</label>
5
+ <type>DateTime</type>
6
+ </CustomField>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Payload__c</fullName>
4
+ <label>Payload</label>
5
+ <length>131072</length>
6
+ <type>LongTextArea</type>
7
+ <visibleLines>5</visibleLines>
8
+ </CustomField>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Response_Body__c</fullName>
4
+ <label>Response Body</label>
5
+ <length>32768</length>
6
+ <type>LongTextArea</type>
7
+ <visibleLines>5</visibleLines>
8
+ </CustomField>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Status_Code__c</fullName>
4
+ <label>Status Code</label>
5
+ <precision>5</precision>
6
+ <scale>0</scale>
7
+ <type>Number</type>
8
+ <unique>false</unique>
9
+ </CustomField>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <customSettingsType>Hierarchy</customSettingsType>
4
+ <description>Controls which objects and events are routed by the Lead Router engine.</description>
5
+ <enableFeeds>false</enableFeeds>
6
+ <label>Routing Settings</label>
7
+ <visibility>Public</visibility>
8
+ </CustomObject>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Account_Insert_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Account Insert Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Account_Routing_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Account Routing Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Account_Update_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Account Update Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>App_Url__c</fullName>
4
+ <label>App URL</label>
5
+ <length>255</length>
6
+ <type>Text</type>
7
+ <unique>false</unique>
8
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Contact_Insert_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Contact Insert Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Contact_Routing_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Contact Routing Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Contact_Update_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Contact Update Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Engine_Endpoint__c</fullName>
4
+ <label>Engine Endpoint</label>
5
+ <length>255</length>
6
+ <type>Text</type>
7
+ <unique>false</unique>
8
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Lead_Insert_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Lead Insert Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Lead_Routing_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Lead Routing Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <fullName>Lead_Update_Enabled__c</fullName>
4
+ <defaultValue>false</defaultValue>
5
+ <label>Lead Update Enabled</label>
6
+ <type>Checkbox</type>
7
+ </CustomField>