From 529a62db4064d0b7419e53002d90fbfdb259d2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Ch=C3=A1vez?= Date: Sun, 15 Mar 2026 23:13:52 -0600 Subject: [PATCH 1/6] Expand PREGENERATED_RESPONSE to all company sizes Remove the MICRO-only restriction on bespoke welcome messages so that all company sizes use the PREGENERATED_RESPONSE path when the suggestedFollowups beta is enabled. This makes the WELCOME_EVENT backend fallback unnecessary for new App versions. getBespokeWelcomeMessage now accepts companySize and tailors the welcome phrasing: MEDIUM/LARGE companies hear about approval workflows and the Expensify Card, SMALL/MEDIUM_SMALL about categories and workflows, and MICRO (default) about receipts and quick setup. Co-Authored-By: Claude Opus 4.6 --- src/libs/ReportUtils.ts | 43 +++++++++++++++++++++++-------- tests/unit/ReportUtilsTest.ts | 48 ++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a0830fa94c51a..ed0df3e435952 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11629,15 +11629,38 @@ type PrepareOnboardingOnyxDataParams = { betas?: OnyxEntry; }; -function getBespokeWelcomeMessage(userReportedIntegration?: OnboardingAccounting): string { +function getBespokeWelcomeMessage(companySize: OnboardingCompanySize | undefined, userReportedIntegration?: OnboardingAccounting): string { // Use markdown (not HTML) because buildOptimisticAddCommentReportAction -> getParsedComment // escapes HTML entities before parsing, so raw HTML tags would render as literal text. - let message = - "# Your free trial has started! Let's get you set up.\n" + - "šŸ‘‹ Hey there! I'm your Expensify setup specialist. " + - 'For a small team like yours, the fastest way to get value is to set up a few expense categories, ' + - 'invite your team members, and have them start snapping receipts right away. ' + - "I'm here to walk you through each step — just ask!"; + let message: string; + switch (companySize) { + case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM: + case CONST.ONBOARDING_COMPANY_SIZE.LARGE: + message = + "# Your free trial has started! Let's get you set up.\n" + + "šŸ‘‹ Hey there! I'm your Expensify setup specialist. " + + 'For an organization your size, the fastest path to value is setting up approval workflows, ' + + 'connecting your accounting software, and rolling out the Expensify Card to your team. ' + + "I'm here to walk you through each step — just ask!"; + break; + case CONST.ONBOARDING_COMPANY_SIZE.SMALL: + case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL: + message = + "# Your free trial has started! Let's get you set up.\n" + + "šŸ‘‹ Hey there! I'm your Expensify setup specialist. " + + 'For a growing team like yours, the fastest way to get value is to set up expense categories, ' + + 'configure approval workflows, and invite your team members. ' + + "I'm here to walk you through each step — just ask!"; + break; + default: + message = + "# Your free trial has started! Let's get you set up.\n" + + "šŸ‘‹ Hey there! I'm your Expensify setup specialist. " + + 'For a small team like yours, the fastest way to get value is to set up a few expense categories, ' + + 'invite your team members, and have them start snapping receipts right away. ' + + "I'm here to walk you through each step — just ask!"; + break; + } if (userReportedIntegration && userReportedIntegration !== 'other') { const friendlyName = CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration as keyof typeof CONST.ONBOARDING_ACCOUNTING_MAPPING]; @@ -11744,14 +11767,14 @@ function prepareOnboardingOnyxData({ reportComment: textComment.commentText, }; - // When the user is MICRO and using followups, generate a bespoke welcome message from Concierge. + // When using followups instead of tasks, generate a bespoke welcome message from Concierge. // The frontend displays it optimistically; the server uses it to generate suggested followups. let bespokeWelcomeMessage: string | undefined; let optimisticConciergeReportActionID: string | undefined; let bespokeAction: OptimisticReportAction | undefined; - if (shouldUseFollowupsInsteadOfTasks && companySize === CONST.ONBOARDING_COMPANY_SIZE.MICRO) { - bespokeWelcomeMessage = getBespokeWelcomeMessage(userReportedIntegration); + if (shouldUseFollowupsInsteadOfTasks) { + bespokeWelcomeMessage = getBespokeWelcomeMessage(companySize, userReportedIntegration); optimisticConciergeReportActionID = rand64(); bespokeAction = buildOptimisticAddCommentReportAction({ text: bespokeWelcomeMessage, diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index ac34e40dec9e7..fc6702c8624db 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -571,13 +571,59 @@ describe('ReportUtils', () => { companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, }); expect(result?.guidedSetupData).toHaveLength(0); - // MICRO company size with suggestedFollowups beta adds a bespoke Concierge welcome action optimistically + // suggestedFollowups beta adds a bespoke Concierge welcome action optimistically for all company sizes const reportActionsEntries = result?.optimisticData.filter((i) => i.key === `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`); expect(reportActionsEntries).toHaveLength(1); expect(result?.bespokeWelcomeMessage).toBeDefined(); expect(result?.optimisticConciergeReportActionID).toBeDefined(); }); + it('should generate bespoke welcome message for non-MICRO company sizes with suggestedFollowups beta', async () => { + const adminsChatReportID = '1'; + await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'}); + await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]); + await waitForBatchedUpdates(); + + const result = prepareOnboardingOnyxData({ + introSelected: undefined, + engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM, + onboardingMessage: { + message: 'This is a test', + tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}], + }, + adminsChatReportID, + selectedInterestedFeatures: ['areCompanyCardsEnabled'], + companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, + }); + expect(result?.guidedSetupData).toHaveLength(0); + expect(result?.bespokeWelcomeMessage).toBeDefined(); + expect(result?.bespokeWelcomeMessage).toContain('growing team'); + expect(result?.optimisticConciergeReportActionID).toBeDefined(); + }); + + it('should generate bespoke welcome message for LARGE company sizes with suggestedFollowups beta', async () => { + const adminsChatReportID = '1'; + await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'}); + await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]); + await waitForBatchedUpdates(); + + const result = prepareOnboardingOnyxData({ + introSelected: undefined, + engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM, + onboardingMessage: { + message: 'This is a test', + tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}], + }, + adminsChatReportID, + selectedInterestedFeatures: ['areCompanyCardsEnabled'], + companySize: CONST.ONBOARDING_COMPANY_SIZE.LARGE, + }); + expect(result?.guidedSetupData).toHaveLength(0); + expect(result?.bespokeWelcomeMessage).toBeDefined(); + expect(result?.bespokeWelcomeMessage).toContain('organization your size'); + expect(result?.optimisticConciergeReportActionID).toBeDefined(); + }); + it('should add guidedSetupData when posting into admin room WITHOUT suggestedFollowups beta', async () => { const adminsChatReportID = '1'; // Not having `+` in the email allows for `isPostingTasksInAdminsRoom` flow From 56c74664c121361dc6051ac16e7a3dc94c60284f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Ch=C3=A1vez?= Date: Mon, 16 Mar 2026 12:53:50 -0600 Subject: [PATCH 2/6] Update PolicyTest to expect bespoke Concierge welcome message for all company sizes The PR removed the MICRO-only guard from prepareOnboardingOnyxData, so now all company sizes get a bespoke welcome message when shouldUseFollowupsInsteadOfTasks is true. Update the expected signoff message count from 0 to 1. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/actions/PolicyTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index 92d6c8b33b535..9a52f3aceabb6 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -188,7 +188,7 @@ describe('actions/Policy', () => { // After filtering, two actions are added to the list =- signoff message (+1) and default create action (+1) const expectedReportActionsOfTypeCreatedCount = 1; - const expectedSignOffMessagesCount = 0; + const expectedSignOffMessagesCount = 1; expect(adminReportActions.length).toBe(expectedManageTeamDefaultTasksCount + expectedReportActionsOfTypeCreatedCount + expectedSignOffMessagesCount); let reportActionsOfTypeCreatedCount = 0; From a1183b9bb9535674eacd86c8039c0d70e3a302aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Ch=C3=A1vez?= Date: Mon, 16 Mar 2026 14:04:57 -0600 Subject: [PATCH 3/6] Add test coverage for getBespokeWelcomeMessage company size and integration suffix paths Cover MEDIUM_SMALL, MEDIUM company sizes and the userReportedIntegration suffix path in prepareOnboardingOnyxData to satisfy Codecov requirements. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/unit/ReportUtilsTest.ts | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index fc6702c8624db..d425282139b54 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -624,6 +624,75 @@ describe('ReportUtils', () => { expect(result?.optimisticConciergeReportActionID).toBeDefined(); }); + it('should generate bespoke welcome message for MEDIUM_SMALL company sizes with suggestedFollowups beta', async () => { + const adminsChatReportID = '1'; + await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'}); + await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]); + await waitForBatchedUpdates(); + + const result = prepareOnboardingOnyxData({ + introSelected: undefined, + engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM, + onboardingMessage: { + message: 'This is a test', + tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}], + }, + adminsChatReportID, + selectedInterestedFeatures: ['areCompanyCardsEnabled'], + companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL, + }); + expect(result?.guidedSetupData).toHaveLength(0); + expect(result?.bespokeWelcomeMessage).toBeDefined(); + expect(result?.bespokeWelcomeMessage).toContain('growing team'); + expect(result?.optimisticConciergeReportActionID).toBeDefined(); + }); + + it('should generate bespoke welcome message for MEDIUM company sizes with suggestedFollowups beta', async () => { + const adminsChatReportID = '1'; + await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'}); + await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]); + await waitForBatchedUpdates(); + + const result = prepareOnboardingOnyxData({ + introSelected: undefined, + engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM, + onboardingMessage: { + message: 'This is a test', + tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}], + }, + adminsChatReportID, + selectedInterestedFeatures: ['areCompanyCardsEnabled'], + companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM, + }); + expect(result?.guidedSetupData).toHaveLength(0); + expect(result?.bespokeWelcomeMessage).toBeDefined(); + expect(result?.bespokeWelcomeMessage).toContain('organization your size'); + expect(result?.optimisticConciergeReportActionID).toBeDefined(); + }); + + it('should append accounting integration suffix to bespoke welcome message', async () => { + const adminsChatReportID = '1'; + await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'}); + await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]); + await waitForBatchedUpdates(); + + const result = prepareOnboardingOnyxData({ + introSelected: undefined, + engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM, + onboardingMessage: { + message: 'This is a test', + tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}], + }, + adminsChatReportID, + selectedInterestedFeatures: ['areCompanyCardsEnabled'], + companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, + userReportedIntegration: 'quickbooksOnline', + }); + expect(result?.bespokeWelcomeMessage).toBeDefined(); + expect(result?.bespokeWelcomeMessage).toContain('QuickBooks Online'); + expect(result?.bespokeWelcomeMessage).toContain('expenses sync automatically'); + }); + it('should add guidedSetupData when posting into admin room WITHOUT suggestedFollowups beta', async () => { const adminsChatReportID = '1'; // Not having `+` in the email allows for `isPostingTasksInAdminsRoom` flow From cf802189ef73158cc33d3268ba3d5a772bc19425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Ch=C3=A1vez?= Date: Tue, 17 Mar 2026 14:32:42 -0600 Subject: [PATCH 4/6] Address review comments: extract duplicated welcome header, improve tests - Extract duplicated welcome header string into `welcomeHeader` constant in getBespokeWelcomeMessage, concatenating only the varying tail per company size - Rename test from 'non-MICRO' to 'SMALL' to match the actual company size tested - Add content assertion for MICRO/default test case ('For a small team like yours') - Remove redundant toBeDefined() checks where toContain already validates Co-Authored-By: Claude Opus 4.6 (1M context) --- src/libs/ReportUtils.ts | 17 +++++++---------- tests/unit/ReportUtilsTest.ts | 9 ++------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ed0df3e435952..ce2ee4aed6cb5 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11632,35 +11632,32 @@ type PrepareOnboardingOnyxDataParams = { function getBespokeWelcomeMessage(companySize: OnboardingCompanySize | undefined, userReportedIntegration?: OnboardingAccounting): string { // Use markdown (not HTML) because buildOptimisticAddCommentReportAction -> getParsedComment // escapes HTML entities before parsing, so raw HTML tags would render as literal text. - let message: string; + const welcomeHeader = "# Your free trial has started! Let's get you set up.\n" + "šŸ‘‹ Hey there! I'm your Expensify setup specialist. "; + + let messageTail: string; switch (companySize) { case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM: case CONST.ONBOARDING_COMPANY_SIZE.LARGE: - message = - "# Your free trial has started! Let's get you set up.\n" + - "šŸ‘‹ Hey there! I'm your Expensify setup specialist. " + + messageTail = 'For an organization your size, the fastest path to value is setting up approval workflows, ' + 'connecting your accounting software, and rolling out the Expensify Card to your team. ' + "I'm here to walk you through each step — just ask!"; break; case CONST.ONBOARDING_COMPANY_SIZE.SMALL: case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL: - message = - "# Your free trial has started! Let's get you set up.\n" + - "šŸ‘‹ Hey there! I'm your Expensify setup specialist. " + + messageTail = 'For a growing team like yours, the fastest way to get value is to set up expense categories, ' + 'configure approval workflows, and invite your team members. ' + "I'm here to walk you through each step — just ask!"; break; default: - message = - "# Your free trial has started! Let's get you set up.\n" + - "šŸ‘‹ Hey there! I'm your Expensify setup specialist. " + + messageTail = 'For a small team like yours, the fastest way to get value is to set up a few expense categories, ' + 'invite your team members, and have them start snapping receipts right away. ' + "I'm here to walk you through each step — just ask!"; break; } + let message = welcomeHeader + messageTail; if (userReportedIntegration && userReportedIntegration !== 'other') { const friendlyName = CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration as keyof typeof CONST.ONBOARDING_ACCOUNTING_MAPPING]; diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index d425282139b54..f8699b431e2e9 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -574,11 +574,11 @@ describe('ReportUtils', () => { // suggestedFollowups beta adds a bespoke Concierge welcome action optimistically for all company sizes const reportActionsEntries = result?.optimisticData.filter((i) => i.key === `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`); expect(reportActionsEntries).toHaveLength(1); - expect(result?.bespokeWelcomeMessage).toBeDefined(); + expect(result?.bespokeWelcomeMessage).toContain('For a small team like yours'); expect(result?.optimisticConciergeReportActionID).toBeDefined(); }); - it('should generate bespoke welcome message for non-MICRO company sizes with suggestedFollowups beta', async () => { + it('should generate bespoke welcome message for SMALL company sizes with suggestedFollowups beta', async () => { const adminsChatReportID = '1'; await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'}); await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]); @@ -596,7 +596,6 @@ describe('ReportUtils', () => { companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, }); expect(result?.guidedSetupData).toHaveLength(0); - expect(result?.bespokeWelcomeMessage).toBeDefined(); expect(result?.bespokeWelcomeMessage).toContain('growing team'); expect(result?.optimisticConciergeReportActionID).toBeDefined(); }); @@ -619,7 +618,6 @@ describe('ReportUtils', () => { companySize: CONST.ONBOARDING_COMPANY_SIZE.LARGE, }); expect(result?.guidedSetupData).toHaveLength(0); - expect(result?.bespokeWelcomeMessage).toBeDefined(); expect(result?.bespokeWelcomeMessage).toContain('organization your size'); expect(result?.optimisticConciergeReportActionID).toBeDefined(); }); @@ -642,7 +640,6 @@ describe('ReportUtils', () => { companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL, }); expect(result?.guidedSetupData).toHaveLength(0); - expect(result?.bespokeWelcomeMessage).toBeDefined(); expect(result?.bespokeWelcomeMessage).toContain('growing team'); expect(result?.optimisticConciergeReportActionID).toBeDefined(); }); @@ -665,7 +662,6 @@ describe('ReportUtils', () => { companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM, }); expect(result?.guidedSetupData).toHaveLength(0); - expect(result?.bespokeWelcomeMessage).toBeDefined(); expect(result?.bespokeWelcomeMessage).toContain('organization your size'); expect(result?.optimisticConciergeReportActionID).toBeDefined(); }); @@ -688,7 +684,6 @@ describe('ReportUtils', () => { companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, userReportedIntegration: 'quickbooksOnline', }); - expect(result?.bespokeWelcomeMessage).toBeDefined(); expect(result?.bespokeWelcomeMessage).toContain('QuickBooks Online'); expect(result?.bespokeWelcomeMessage).toContain('expenses sync automatically'); }); From 5d195ac90ac197e7c190490081916ed09ae1f753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Ch=C3=A1vez?= Date: Tue, 17 Mar 2026 14:42:46 -0600 Subject: [PATCH 5/6] Fix ESLint no-useless-concat: merge adjacent string literals in welcomeHeader Co-Authored-By: Claude Opus 4.6 (1M context) --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ce2ee4aed6cb5..7f216aaa960b8 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11632,7 +11632,7 @@ type PrepareOnboardingOnyxDataParams = { function getBespokeWelcomeMessage(companySize: OnboardingCompanySize | undefined, userReportedIntegration?: OnboardingAccounting): string { // Use markdown (not HTML) because buildOptimisticAddCommentReportAction -> getParsedComment // escapes HTML entities before parsing, so raw HTML tags would render as literal text. - const welcomeHeader = "# Your free trial has started! Let's get you set up.\n" + "šŸ‘‹ Hey there! I'm your Expensify setup specialist. "; + const welcomeHeader = "# Your free trial has started! Let's get you set up.\nšŸ‘‹ Hey there! I'm your Expensify setup specialist. "; let messageTail: string; switch (companySize) { From 966203b2af9c878564eeab401f9e4d0221b63d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Ch=C3=A1vez?= Date: Wed, 18 Mar 2026 12:15:44 -0600 Subject: [PATCH 6/6] Remove messageTail variable, concatenate directly on message Address review feedback to simplify the switch by appending directly to message instead of using an intermediate variable. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/libs/ReportUtils.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 7f216aaa960b8..568a264b05e64 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11634,30 +11634,29 @@ function getBespokeWelcomeMessage(companySize: OnboardingCompanySize | undefined // escapes HTML entities before parsing, so raw HTML tags would render as literal text. const welcomeHeader = "# Your free trial has started! Let's get you set up.\nšŸ‘‹ Hey there! I'm your Expensify setup specialist. "; - let messageTail: string; + let message = welcomeHeader; switch (companySize) { case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM: case CONST.ONBOARDING_COMPANY_SIZE.LARGE: - messageTail = + message += 'For an organization your size, the fastest path to value is setting up approval workflows, ' + 'connecting your accounting software, and rolling out the Expensify Card to your team. ' + "I'm here to walk you through each step — just ask!"; break; case CONST.ONBOARDING_COMPANY_SIZE.SMALL: case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL: - messageTail = + message += 'For a growing team like yours, the fastest way to get value is to set up expense categories, ' + 'configure approval workflows, and invite your team members. ' + "I'm here to walk you through each step — just ask!"; break; default: - messageTail = + message += 'For a small team like yours, the fastest way to get value is to set up a few expense categories, ' + 'invite your team members, and have them start snapping receipts right away. ' + "I'm here to walk you through each step — just ask!"; break; } - let message = welcomeHeader + messageTail; if (userReportedIntegration && userReportedIntegration !== 'other') { const friendlyName = CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration as keyof typeof CONST.ONBOARDING_ACCOUNTING_MAPPING];