Skip to content

Update onboarding purpose modal for Release 4.0#88796

Merged
dangrous merged 17 commits into
mainfrom
claude-updateOnboardingPurposeModal
May 11, 2026
Merged

Update onboarding purpose modal for Release 4.0#88796
dangrous merged 17 commits into
mainfrom
claude-updateOnboardingPurposeModal

Conversation

@MelvinBot
Copy link
Copy Markdown
Contributor

@MelvinBot MelvinBot commented Apr 26, 2026

Explanation of Change

Updates the onboarding purpose modal at new.expensify.com/onboarding/purpose for Release 4.0:

  1. Split "Track and budget expenses" into two choices:

    • "Track expenses for my business" → sends newDotTrackWorkspace as the engagement choice (same backend behavior as before)
    • "Organize my personal spending" → sends newDotTrackPersonalWorkspace as a new engagement choice
  2. Renamed "Get paid back by my employer" to "Submit expenses to my employer" across all languages

  3. Removed "Chat and split expenses with friends" from selectable choices (less than 1% selection rate)

Both new track choices follow the same UX flow as the former "Track and budget expenses" option (auto-create workspace for private domain users, otherwise navigate through personal details → optional workspace creation). The old PERSONAL_SPEND and CHAT_SPLIT constants are preserved in backendOnboardingChoices for backward compatibility with existing users.

Fixed Issues

$ #88219

Tests

Test 1

  1. Go to expensify.com (OD) and sign in as a new user, selecting "Organize my own expenses".
  2. On the /onboarding/purpose ND modal:
  3. Verify that the following three options are visible:
    • Submit expenses to my employer
    • Track expenses for my business
    • Organize my personal spending
  4. Verify that "Chat and split expenses with friends" option is not visible.
  5. Select "Track expenses for my business" and complete steps.
  6. In the Network tab, verify that the backend request sends engagementChoice: newDotTrackWorkspace to the CompleteGuidedSetup API.
  7. Repeat steps 1–4, then select "Organize my personal spending" and complete steps.
  8. Verify in the Network tab that the backend request sends engagementChoice: newDotTrackPersonalWorkspace to the CompleteGuidedSetup API.

Test 2

  1. Go to new.expensify.com as a new user and navigate to /onboarding/purpose.
  2. Verify that the following five options are visible:
    • Manage my team's expenses
    • Submit expenses to my employer
    • Track expenses for my business
    • Organize my personal spending
    • Something else
  3. Verify that "Chat and split expenses with friends" is not shown here as well.

Test 3

  1. Sign up as a new user using a Gmail or private domain
  2. Select Track expenses for my business OR Organize my personal spending as the onboarding purpose
  3. Enter your name and click Continue
  4. Verify that workspace-related screens (optional workspace creation, workspace name, invites) are skipped
  5. Verify that a workspace is automatically created under the Workspaces tab

Test 4

  1. Create a new account and select Track expenses for my business OR Organize my personal spending during onboarding.
  2. For web, After completing onboarding, verify that the Home page loads with the Concierge RHP open, displaying the Welcome to Expensify message and the three onboarding tasks:
    • Take a test drive
    • Create your first report
    • Set up categories
  3. For Mobile, After completing onboarding, verify that the Concierge DM chat opens with the same message and tasks.
  4. Verify that other onboarding variants (Manage Team, existing RHP for other purposed) remain unaffected.

Offline tests

N/A — Onboarding purpose selection requires network connectivity to call the CompleteGuidedSetup API. No offline-specific behavior changes in this PR.

QA Steps

Test 1 — OD onboarding purpose options and engagement choices

  1. Go to expensify.com (OD) and sign in as a new user, selecting "Organize my own expenses".
  2. On the /onboarding/purpose ND modal:
  3. Verify that the following three options are visible:
    • Submit expenses to my employer
    • Track expenses for my business
    • Organize my personal spending
  4. Verify that "Chat and split expenses with friends" option is not visible.
  5. Select "Track expenses for my business" and complete steps.
  6. In the Network tab, verify that the backend request sends engagementChoice: newDotTrackWorkspace to the CompleteGuidedSetup API.
  7. Repeat steps 1–4, then select "Organize my personal spending" and complete steps.
  8. Verify in the Network tab that the backend request sends engagementChoice: newDotTrackPersonalWorkspace to the CompleteGuidedSetup API.

Test 2 — ND onboarding purpose options

  1. Go to new.expensify.com as a new user and navigate to /onboarding/purpose.
  2. Verify that the following five options are visible:
    • Manage my team's expenses
    • Submit expenses to my employer
    • Track expenses for my business
    • Organize my personal spending
    • Something else
  3. Verify that "Chat and split expenses with friends" is not shown here as well.

Test 3 — Auto-workspace creation and screen skipping

  1. Sign up as a new user using a Gmail or private domain
  2. Select Track expenses for my business OR Organize my personal spending as the onboarding purpose
  3. Enter your name and click Continue
  4. Verify that workspace-related screens (optional workspace creation, workspace name, invites) are skipped
  5. Verify that a workspace is automatically created under the Workspaces tab

Test 4 — Post-onboarding landing and onboarding tasks

  1. Create a new account and select Track expenses for my business OR Organize my personal spending during onboarding.
  2. For web, After completing onboarding, verify that the Home page loads with the Concierge RHP open, displaying the Welcome to Expensify message and the three onboarding tasks:
    • Take a test drive
    • Create your first report
    • Set up categories
  3. For Mobile, After completing onboarding, verify that the Concierge DM chat opens with the same message and tasks.
  4. Verify that other onboarding variants (Manage Team, existing RHP for other purposed) remain unaffected.

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
    • If any non-english text was added/modified, I used JaimeGPT to get English > Spanish translation. I then posted it in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari

Split "Track and budget expenses" into two choices:
- "Track expenses for my business" (newDotTrackWorkspace)
- "Organize my personal spending" (newDotTrackPersonalWorkspace)

Rename "Get paid back by my employer" to "Submit expenses to my employer"

Remove "Chat and split expenses with friends" from selectable choices

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
@OSBotify
Copy link
Copy Markdown
Contributor

🦜 Polyglot Parrot! 🦜

Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues:

View the translation diff
diff --git a/src/languages/de.ts b/src/languages/de.ts
index dc15851d..9e61cf1e 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -2898,12 +2898,12 @@ ${amount} für ${merchant} – ${date}`,
         whereYouWork: 'Wo arbeitest du?',
         errorSelection: 'Wähle eine Option, um fortzufahren',
         purpose: {
-            title: 'Was möchtest du heute tun?',
-            errorContinue: 'Bitte auf „Weiter“ drücken, um die Einrichtung abzuschließen',
-            errorBackButton: 'Bitte beantworte die Einrichtungsfragen, um die App verwenden zu können',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Ausgaben bei meinem Arbeitgeber einreichen',
-            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Verwalte die Ausgaben meines Teams',
-            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Geschäftsausgaben nachverfolgen',
+            title: 'Was möchtest du heute machen?',
+            errorContinue: 'Bitte auf „Weiter“ drücken, um die Einrichtung zu starten.',
+            errorBackButton: 'Bitte beantworte die Einrichtungsfragen, um die App zu verwenden',
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Ausgaben an meinen Arbeitgeber einreichen',
+            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Die Ausgaben meines Teams verwalten',
+            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Geschäftsausgaben erfassen',
             [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: 'Meine persönlichen Ausgaben organisieren',
             [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: 'Etwas anderes',
         },
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index b0eb8600..06ce78f0 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -2905,9 +2905,9 @@ ${amount} pour ${merchant} - ${date}`,
         errorSelection: 'Sélectionnez une option pour continuer',
         purpose: {
             title: 'Que voulez-vous faire aujourd’hui ?',
-            errorContinue: 'Veuillez appuyer sur Continuer pour procéder à la configuration',
+            errorContinue: 'Appuyez sur Continuer pour terminer la configuration',
             errorBackButton: 'Veuillez terminer les questions de configuration pour commencer à utiliser l’application',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Soumettre des dépenses à mon employeur',
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Soumettre des notes de frais à mon employeur',
             [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Gérer les dépenses de mon équipe',
             [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Suivre les dépenses de mon entreprise',
             [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: 'Organiser mes dépenses personnelles',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 017dd876..46bb69af 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -2893,10 +2893,10 @@ ${amount} per ${merchant} - ${date}`,
         purpose: {
             title: 'Cosa vuoi fare oggi?',
             errorContinue: 'Premi Continua per completare la configurazione',
-            errorBackButton: 'Completa le domande di configurazione per iniziare a usare l’app',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Inviare le spese al mio datore di lavoro',
+            errorBackButton: "Completa le domande di configurazione per iniziare a usare l'app",
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Invia le spese al mio datore di lavoro',
             [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Gestisci le spese del mio team',
-            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Tieni traccia delle spese aziendali',
+            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Tieni traccia delle spese della mia attività',
             [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: 'Organizza le mie spese personali',
             [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: 'Altro',
         },
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index e693fcdd..044a458d 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -2866,12 +2866,12 @@ ${date} の ${merchant} への ${amount}`,
         errorSelection: '次に進むオプションを選択してください',
         purpose: {
             title: '今日は何をしたいですか?',
-            errorContinue: '続行を押してセットアップを完了してください',
+            errorContinue: 'セットアップを続行するには「続行」を押してください',
             errorBackButton: 'アプリを使い始めるには、セットアップの質問にすべて回答してください',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: '雇用主に経費を提出する',
-            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'チームの経費を管理',
-            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'ビジネスの経費を記録',
-            [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: '個人の支出を管理',
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: '経費を雇用主に提出する',
+            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: '自分のチームの経費を管理する',
+            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'ビジネスの経費を記録する',
+            [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: '個人の支出を整理する',
             [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: 'その他',
         },
         employees: {
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 02ac09ab..acbb23c5 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -2891,11 +2891,11 @@ ${amount} voor ${merchant} - ${date}`,
         errorSelection: 'Selecteer een optie om verder te gaan',
         purpose: {
             title: 'Wat wil je vandaag doen?',
-            errorContinue: 'Druk op ‘Doorgaan’ om de installatie te voltooien',
-            errorBackButton: 'Beantwoord eerst de instelvragen om de app te kunnen gebruiken',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Onkosten indienen bij mijn werkgever',
-            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'De onkosten van mijn team beheren',
-            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Zakelijke uitgaven bijhouden',
+            errorContinue: 'Druk op doorgaan om de installatie te voltooien',
+            errorBackButton: 'Beantwoord de instelvragen om de app te kunnen gebruiken',
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Declareren bij mijn werkgever',
+            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Beheer de uitgaven van mijn team',
+            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Uitgaven voor mijn bedrijf bijhouden',
             [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: 'Mijn persoonlijke uitgaven organiseren',
             [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: 'Iets anders',
         },
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 6c15fc0f..cec27f68 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -2882,13 +2882,13 @@ ${amount} dla ${merchant} - ${date}`,
         whereYouWork: 'Gdzie pracujesz?',
         errorSelection: 'Wybierz opcję, aby przejść dalej',
         purpose: {
-            title: 'Co chcesz dzisiaj zrobić?',
-            errorContinue: 'Naciśnij „Kontynuuj”, aby się skonfigurować',
-            errorBackButton: 'Dokończ pytania konfiguracyjne, aby zacząć korzystać z aplikacji',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Zgłoś wydatki pracodawcy',
+            title: 'Co chcesz dziś zrobić?',
+            errorContinue: 'Naciśnij przycisk Kontynuuj, aby dokończyć konfigurację',
+            errorBackButton: 'Aby rozpocząć korzystanie z aplikacji, dokończ pytania konfiguracyjne',
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Prześlij wydatki do mojego pracodawcy',
             [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Zarządzaj wydatkami mojego zespołu',
-            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Śledź wydatki firmowe',
-            [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: 'Organizuj swoje wydatki osobiste',
+            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Śledź wydatki mojej firmy',
+            [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: 'Porządkuj moje wydatki osobiste',
             [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: 'Coś innego',
         },
         employees: {
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 01e9f521..bbcfc997 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -2885,7 +2885,7 @@ ${amount} para ${merchant} - ${date}`,
             title: 'O que você quer fazer hoje?',
             errorContinue: 'Pressione continuar para concluir a configuração',
             errorBackButton: 'Conclua as perguntas de configuração para começar a usar o app',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Enviar despesas ao meu empregador',
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: 'Enviar despesas para meu empregador',
             [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: 'Gerenciar as despesas da minha equipe',
             [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: 'Controlar despesas do meu negócio',
             [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: 'Organizar meus gastos pessoais',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 16e949b3..bd46d17e 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -2815,12 +2815,12 @@ ${amount},商户:${merchant} - 日期:${date}`,
         errorSelection: '选择一个选项以继续',
         purpose: {
             title: '你今天想做什么?',
-            errorContinue: '请按“继续”完成设置',
-            errorBackButton: '请完成设置问题以开始使用此应用程序',
-            [CONST.ONBOARDING_CHOICES.EMPLOYER]: '向雇主提交费用',
-            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: '管理我团队的报销',
-            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: '跟踪我的商务开销',
-            [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: '管理我的个人支出',
+            errorContinue: '请点击“继续”完成设置',
+            errorBackButton: '请完成设置问题以开始使用此应用',
+            [CONST.ONBOARDING_CHOICES.EMPLOYER]: '向我的雇主提交报销',
+            [CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: '管理我的团队报销',
+            [CONST.ONBOARDING_CHOICES.TRACK_BUSINESS]: '为我的企业追踪报销费用',
+            [CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: '整理我的个人支出',
             [CONST.ONBOARDING_CHOICES.LOOKING_AROUND]: '其他原因',
         },
         employees: {

Note

You can apply these changes to your branch by copying the patch to your clipboard, then running pbpaste | git apply 😉

View workflow run

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 26, 2026

Codecov Report

❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.

Files with missing lines Coverage Δ
src/CONST/index.ts 92.30% <ø> (ø)
src/components/Icon/chunks/illustrations.chunk.ts 0.00% <ø> (ø)
src/hooks/useSearchTypeMenuSections.ts 83.33% <100.00%> (-0.31%) ⬇️
...pNavigator/Navigators/OnboardingModalNavigator.tsx 89.13% <100.00%> (ø)
src/libs/OnboardingUtils.ts 100.00% <100.00%> (ø)
src/libs/ReportUtils.ts 83.51% <100.00%> (-0.03%) ⬇️
src/libs/TourUtils.ts 100.00% <100.00%> (ø)
src/libs/actions/Policy/Policy.ts 70.57% <100.00%> (+0.24%) ⬆️
src/libs/actions/Welcome/OnboardingFlow.ts 76.41% <100.00%> (ø)
src/libs/getOnboardingStepCounter.ts 100.00% <100.00%> (ø)
... and 6 more
... and 195 files with indirect coverage changes

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@MelvinBot icon for Track expense for my business seems off, as it doesn’t match the mocks in the issue description.
Screenshot 2026-05-03 at 7 29 57 PM

The TRACK_BUSINESS option was incorrectly using the ReceiptUpload icon
(same as EMPLOYER). Updated to use Abacus to match the design mocks.

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
@MelvinBot
Copy link
Copy Markdown
Contributor Author

Fixed — the TRACK_BUSINESS option was incorrectly using the ReceiptUpload icon (same as EMPLOYER). Updated it to use Abacus to match the design mocks.

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@Expensify/design, which icon is used for Track expense for my business? Is it already used anywhere in the app? If not, could you please provide it?
583560576-abae41eb-59de-45c6-91c3-13c536ce6484

@dubielzyk-expensify
Copy link
Copy Markdown
Contributor

Doesn't look like it's checked in. Here you go:
simple-illustration__calculator-money.svg.zip

@jayeshmangwani
Copy link
Copy Markdown
Contributor

Thank you.

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@MelvinBot , please use this icon #88796 (comment) for Track expense for my business.

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
@MelvinBot
Copy link
Copy Markdown
Contributor Author

Updated the icon for Track expenses for my business to use the CalculatorMoney illustration from the linked comment. Changes:

  • Added simple-illustration__calculator-money.svg to assets (compressed via npm run compress-svg)
  • Registered CalculatorMoney in illustrations.chunk.ts
  • Updated BaseOnboardingPurpose.tsx to use CalculatorMoney instead of Abacus for TRACK_BUSINESS

Comment thread src/CONST/index.ts
SUBMIT: 'newDotSubmit',
TRACK_WORKSPACE: 'newDotTrackWorkspace',
PERSONAL_SPEND: 'newDotPersonalSpend',
CHAT_SPLIT: 'newDotSplitChat',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@MelvinBot whats the usage of CHAT_SPLIT here ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

CHAT_SPLIT was moved from selectableOnboardingChoices to backendOnboardingChoices because it is no longer a user-facing selectable option in the updated onboarding UI (replaced by TRACK_BUSINESS and TRACK_PERSONAL), but it is still needed for backend processing. Specifically, it is still referenced in:

  • The SkipViewTourOnboardingChoices type (determines which choices skip the tour)
  • The onboarding message mapping (onboardingChatSplitMessage)
  • The onboarding step definitions (routes CHAT_SPLIT to the personal details step)

These backend paths handle users who were already assigned CHAT_SPLIT before this change, or cases where the backend maps a user choice to this value. Removing it entirely would break those flows.

@jayeshmangwani
Copy link
Copy Markdown
Contributor

jayeshmangwani commented May 4, 2026

@MelvinBot, please merge main, resolve conflicts, and add tests for TRACK_BUSINESS and TRACK_PERSONAL to the OnboardingModalNavigator tests.

MelvinBot and others added 2 commits May 4, 2026 14:29
Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
@MelvinBot
Copy link
Copy Markdown
Contributor Author

Done! I merged `main`, resolved the conflict in `src/libs/actions/Policy/Policy.ts` (kept the new `TRACK_PERSONAL` check from our branch while taking main's updated `activePolicy` usage), and added two new tests for `TRACK_BUSINESS` and `TRACK_PERSONAL` to verify they navigate to the personal details page for public domain users.

@MelvinBot
Copy link
Copy Markdown
Contributor Author

⚠️ MelvinBot CI Fix Loop Detected

MelvinBot has made 5 consecutive commits trying to fix CI failures. Automatic CI fix dispatches are now paused for this PR.

Next steps: A human should review the recent commits and resolve the conflicting CI errors manually.

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@MelvinBot , the failing ESLint check is coming from the main, not from our changes.

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@MelvinBot , please add the tests below to the QA steps and Test section, and fill out the remaining checklist items as well.

Test 1

  1. Go to expensify.com (OD) and sign in as a new user, selecting "Organize my own expenses".
  2. On the /onboarding/purpose ND modal:
  3. Verify that the following three options are visible:
    • Submit expenses to my employer
    • Track expenses for my business
    • Organize my personal spending
  4. Verify that "Chat and split expenses with friends" option is not visible.
  5. Select "Track expenses for my business" and complete steps.
  6. In the Network tab, verify that the backend request sends engagementChoice: newDotTrackWorkspace to the CompleteGuidedSetup API.
  7. Repeat steps 1–4, then select "Organize my personal spending" and complete steps.
  8. Verify in the Network tab that the backend request sends engagementChoice: newDotTrackPersonalWorkspace to the CompleteGuidedSetup API.

Test 2

  1. Go to new.expensify.com as a new user and navigate to /onboarding/purpose.
  2. Verify that the following five options are visible:
    • Manage my team's expenses
    • Submit expenses to my employer
    • Track expenses for my business
    • Organize my personal spending
    • Something else
  3. Verify that "Chat and split expenses with friends" is not shown here as well.

Test 3

  1. Sign up as a new user using a Gmail or private domain
  2. Select Track expenses for my business OR Organize my personal spending as the onboarding purpose
  3. Enter your name and click Continue
  4. Verify that workspace-related screens (optional workspace creation, workspace name, invites) are skipped
  5. Verify that a workspace is automatically created under the Workspaces tab

Test 4

  1. Create a new account and select Track expenses for my business OR Organize my personal spending during onboarding.
  2. For web, After completing onboarding, verify that the Home page loads with the Concierge RHP open, displaying the Welcome to Expensify message and the three onboarding tasks:
    • Take a test drive
    • Create your first report
    • Set up categories
  3. For Mobile, After completing onboarding, verify that the Concierge DM chat opens with the same message and tasks.
  4. Verify that other onboarding variants (Manage Team, existing RHP for other purposed) remain unaffected.

@MelvinBot
Copy link
Copy Markdown
Contributor Author

Updated the PR description:

  • Added all 4 tests to the Tests section
  • Added all 4 tests to the QA Steps section (with descriptive titles for each)
  • Added Offline tests section (N/A — onboarding requires network)
  • Checked off the applicable PR Author Checklist items (testing steps, code quality, etc.)

Items left unchecked are ones that need manual verification (platform screenshots/videos, platform test runs, and conditional items like new files/CSS/assets).

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@codex review

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@MelvinBot, please check all the boxes to fix the failed PR Author checklist? I don’t have permission to edit it. I’ll take care of adding the videos and verifying everything else.

@MelvinBot
Copy link
Copy Markdown
Contributor Author

All PR Author Checklist boxes have been checked. You mentioned you'll take care of adding the videos and verifying everything else — sounds good!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5ee833f9bc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

[CONST.ONBOARDING_CHOICES.SUBMIT]: onboardingEmployerOrSubmitMessage,
[CONST.ONBOARDING_CHOICES.MANAGE_TEAM]: onboardingManageTeamMessage,
[CONST.ONBOARDING_CHOICES.TRACK_WORKSPACE]: onboardingTrackWorkspaceMessage,
[CONST.ONBOARDING_CHOICES.TRACK_PERSONAL]: onboardingPersonalSpendMessage,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Map TRACK_PERSONAL to track-workspace onboarding message

TRACK_PERSONAL now goes through the same workspace onboarding path as track-business (auto-create workspace and admin-style test-drive handling), but this mapping assigns onboardingPersonalSpendMessage, which uses the employee task set. In the TRACK_PERSONAL flow, that yields the wrong onboarding tasks/message payload for completeOnboarding and creates an inconsistent experience versus the track-workspace path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@MelvinBot should we use here onboardingTrackWorkspaceMessage ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, good catch. TRACK_PERSONAL should use onboardingTrackWorkspaceMessage here — since both TRACK_PERSONAL and TRACK_WORKSPACE follow the same workspace-creation flow, they should show the same onboarding tasks (test drive admin, create report, setup categories).

Currently it maps to onboardingPersonalSpendMessage which has employee-oriented tasks (testDriveEmployeeTask, trackExpenseTask), which doesn't match the expected behavior in Test 4.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@MelvinBot please do this change

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — changed TRACK_PERSONAL to use onboardingTrackWorkspaceMessage so it gets the same admin-style onboarding tasks (test drive, create report, setup categories) as TRACK_WORKSPACE.

Comment on lines 140 to 143
if (onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_BUSINESS || onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL) {
updateDisplayName(firstName, lastName, formatPhoneNumber, session?.accountID ?? CONST.DEFAULT_NUMBER_ID, session?.email ?? '');
autoCreateTrackWorkspace(firstName, lastName, onboardingPurposeSelected);
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve PERSONAL_SPEND fallback in personal-details submit path

This branch no longer includes PERSONAL_SPEND, even though that choice is still retained for backward compatibility. For users resuming an in-progress onboarding created before this change (where onboardingPurposeSelected is newDotPersonalSpend), submitting personal details now bypasses autoCreateTrackWorkspace and falls through to completeOnboarding, changing the intended flow and skipping workspace auto-creation behavior.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@MelvinBot Should we add PERSONAL_SPEND here for backward compatibility?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, we should add PERSONAL_SPEND here for backward compatibility. A user who started onboarding before this change could have onboardingPurposeSelected set to PERSONAL_SPEND (i.e., newDotPersonalSpend). Without it in this condition, those users would fall through to completeOnboarding() instead of autoCreateTrackWorkspace(), breaking their expected flow.

The rest of the PR already preserves PERSONAL_SPEND for backward compat in OnboardingFlow.ts (e.g., isTrackIntentUserSelector, selfDMParameters, shouldEnableWorkflowsByDefault, onboarding steps map), so this spot should be consistent. The fix would be:

if (
    onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_BUSINESS ||
    onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL ||
    onboardingPurposeSelected === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@MelvinBot please do this change

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — added PERSONAL_SPEND to the condition so users who started onboarding before this change (with onboardingPurposeSelected set to newDotPersonalSpend) will correctly route to autoCreateTrackWorkspace() instead of falling through to completeOnboarding().

MelvinBot and others added 2 commits May 4, 2026 21:09
Users who started onboarding before this change may have
onboardingPurposeSelected set to PERSONAL_SPEND (newDotPersonalSpend).
Without this, those users would fall through to completeOnboarding()
instead of autoCreateTrackWorkspace(), breaking their expected flow.

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
Since TRACK_PERSONAL follows the same workspace-creation flow as
TRACK_WORKSPACE, it should use the same onboarding message with
admin-style tasks (test drive, create report, setup categories)
instead of the employee-oriented onboardingPersonalSpendMessage.

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
@jayeshmangwani
Copy link
Copy Markdown
Contributor

@MelvinBot This change will cause a bug. If we refresh the page on "interested-features" and then press the back button from the modal will show a forward animation instead of a backward animation.

bug-after-refresh.mov

Revert the global animationTypeForReplace to 'pop' and set 'push'
only on the WORK_EMAIL screen. This way Skip (which replaces the
work-email screen) still animates forward, while goBack after a
page refresh (which replaces the current screen via fallback)
correctly animates backward.

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
@MelvinBot
Copy link
Copy Markdown
Contributor Author

Fixed in 80cfe1c. Reverted the global animationTypeForReplace back to 'pop' and set 'push' only on the WORK_EMAIL screen. Since animationTypeForReplace is read from the screen being replaced, this means:

  • Skip on work-email → replaces the work-email screen → uses 'push' → forward animation ✅
  • Back after refresh on interested-features → replaces the interested-features screen → uses 'pop' (default) → backward animation ✅

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@MelvinBot , Upon testing, I can still see the backward animation when going from /work-email to purpose.

The PURPOSE screen was using the default animationTypeForReplace: 'pop',
causing a backward animation when forceReplace navigates to it from
work-email. Add animationTypeForReplace: 'push' to match WORK_EMAIL.

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
@MelvinBot
Copy link
Copy Markdown
Contributor Author

Fixed — the PURPOSE screen was using the default animationTypeForReplace: 'pop', which caused a backward animation when forceReplace navigated to it from work-email. Added animationTypeForReplace: 'push' to match the WORK_EMAIL screen's override.

@jayeshmangwani
Copy link
Copy Markdown
Contributor

@dangrous @dannymcclain backward animation on skip has been fixed now.

backword-animation.mov

trjExpensify
trjExpensify previously approved these changes May 7, 2026
Copy link
Copy Markdown
Contributor

@trjExpensify trjExpensify left a comment

Choose a reason for hiding this comment

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

Core PR for a WN project in #convert. 👍


if (isPrivateDomainAndHasAccessiblePolicies && personalDetailsForm?.firstName) {
if (choice === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND) {
if (choice === CONST.ONBOARDING_CHOICES.TRACK_BUSINESS || choice === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

❌ CONSISTENCY-3 (docs)

This PR introduces the isTrackOnboardingChoice utility in src/libs/OnboardingUtils.ts specifically to centralize the check for track-type onboarding choices, yet this line uses an inline check choice === CONST.ONBOARDING_CHOICES.TRACK_BUSINESS || choice === CONST.ONBOARDING_CHOICES.TRACK_PERSONAL instead of the utility. Other files in this same PR (e.g., BaseOnboardingWorkspaceOptional.tsx line 283, TourUtils.ts, Policy.ts) already use isTrackOnboardingChoice. Using inline checks here defeats the stated purpose of the utility: "adding a new track-type choice only requires one edit."

Replace the inline check with the utility:

import isTrackOnboardingChoice from '@libs/OnboardingUtils';
// ...
if (isTrackOnboardingChoice(choice)) {

Reviewed at: 7523542 | Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Makes sense, @MelvinBot please do this change.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — replaced the inline check with isTrackOnboardingChoice(choice) in BaseOnboardingPurpose.tsx for consistency with the rest of the codebase.

Replace inline TRACK_BUSINESS/TRACK_PERSONAL check with the
existing isTrackOnboardingChoice helper for consistency with
the rest of the codebase.

Co-authored-by: Jayesh Mangwani <jayeshmangwani@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@dangrous dangrous left a comment

Choose a reason for hiding this comment

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

LGTM!

@dangrous dangrous merged commit f0d27d4 into main May 11, 2026
47 checks passed
@dangrous dangrous deleted the claude-updateOnboardingPurposeModal branch May 11, 2026 15:22
@OSBotify
Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@github-actions
Copy link
Copy Markdown
Contributor

🚧 @dangrous has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify
Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/dangrous in version: 9.3.70-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 failure ❌
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

@MelvinBot
Copy link
Copy Markdown
Contributor Author

Yes, help site changes are required. PR #88796 renamed the onboarding purpose choice "Track and budget expenses" (now split into "Track expenses for my business" and "Organize my personal spending"), and 3 help articles reference the old name.

Updated articles:

  • docs/articles/new-expensify/reports-and-expenses/Understanding-Report-Statuses-and-Actions.md
  • docs/articles/new-expensify/reports-and-expenses/Create-and-Submit-Reports.md
  • docs/articles/new-expensify/reports-and-expenses/Expense-and-Report-Actions.md

Draft PR: #90272 (labeled HelpDot)

Each reference to "Track and budget expenses" was updated to "Track expenses for my business" or "Organize my personal spending" to match the new UI choices.

@mitarachim
Copy link
Copy Markdown

Deploy Blocker #90284 was identified to be related to this PR.

@jponikarchuk
Copy link
Copy Markdown

Unable to check if this issue #90303 is repro on this PR as it's a deeplink navigation. Could you please double check if it's not introduced by #88796

@OSBotify
Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/dangrous in version: 9.3.72-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

@MelvinBot
Copy link
Copy Markdown
Contributor Author

Yes, help site changes are required. The old onboarding choice "Track and budget expenses" is referenced in 3 places across 2 articles:

  • docs/articles/new-expensify/reports-and-expenses/Create-and-Submit-Reports.md (2 references)
  • docs/articles/new-expensify/reports-and-expenses/Understanding-Report-Statuses-and-Actions.md (1 reference)

A third article (Expense-and-Report-Actions.md) already uses generic wording and needs no update.

Draft PR created: #90398 (labeled HelpDot)

The changes replace "Track and budget expenses" with the two new choices: "Track expenses for my business" or "Organize my personal spending".

@OSBotify
Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/lakchote in version: 9.3.72-1 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

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.

10 participants