diff --git a/src/libs/Fullstory/index.ts b/src/libs/Fullstory/index.ts index 28269674089f..ead801b1257d 100644 --- a/src/libs/Fullstory/index.ts +++ b/src/libs/Fullstory/index.ts @@ -143,6 +143,8 @@ const FS: Fullstory = { properties: { // eslint-disable-next-line @typescript-eslint/naming-convention -- FullStory schema uses external snake_case keys. nps_response_date: 'date', + // eslint-disable-next-line @typescript-eslint/naming-convention -- FullStory schema uses external snake_case keys. + nudged_date: 'date', }, }, }); diff --git a/src/libs/Fullstory/types.ts b/src/libs/Fullstory/types.ts index 5443594eddb8..16783adbe8d8 100644 --- a/src/libs/Fullstory/types.ts +++ b/src/libs/Fullstory/types.ts @@ -29,6 +29,7 @@ type FullstoryUserVars = { paid_member?: boolean; nps_score?: number; nps_response_date?: Date; + nudged_date?: Date; auth_method?: 'email' | 'google' | 'apple'; reg_method?: 'Google signup' | 'email/phone signup'; login_status?: 'success' | 'failure'; diff --git a/src/libs/Fullstory/utils.ts b/src/libs/Fullstory/utils.ts index 96e4be977d7d..a75a1393e178 100644 --- a/src/libs/Fullstory/utils.ts +++ b/src/libs/Fullstory/utils.ts @@ -204,6 +204,7 @@ function buildFullstoryUserVars({ paid_member: userMetadata?.paidMember, nps_score: userMetadata?.npsScore, nps_response_date: getUTCDate(userMetadata?.npsResponseDate), + nudged_date: getUTCDate(userMetadata?.nudgedDate), } satisfies FullstoryUserVars, (_key, value) => value !== undefined, ); @@ -228,9 +229,10 @@ function buildPageViewedEvent(screenName: string, currentPath: string, entryPoin } /* eslint-disable @typescript-eslint/naming-convention -- The comparable snapshot preserves FullStory's external snake_case field names. */ -type ComparableFullstoryUserVars = Omit & { +type ComparableFullstoryUserVars = Omit & { free_trial_end_date?: string; nps_response_date?: string; + nudged_date?: string; }; function getComparableFullstoryUserVars(userVars: FullstoryUserVars): ComparableFullstoryUserVars { @@ -238,6 +240,7 @@ function getComparableFullstoryUserVars(userVars: FullstoryUserVars): Comparable ...userVars, free_trial_end_date: userVars.free_trial_end_date?.toISOString(), nps_response_date: userVars.nps_response_date?.toISOString(), + nudged_date: userVars.nudged_date?.toISOString(), }; } /* eslint-enable @typescript-eslint/naming-convention */ diff --git a/src/types/onyx/UserMetadata.ts b/src/types/onyx/UserMetadata.ts index f8ee216a6f6a..0acc50e39cbd 100644 --- a/src/types/onyx/UserMetadata.ts +++ b/src/types/onyx/UserMetadata.ts @@ -25,6 +25,9 @@ type UserMetadata = { /** When the user gave their most recent NPS score, in ISO 8601 */ npsResponseDate?: string; + + /** When the user was nudged to New Expensify, as a UTC `YYYY-MM-DD HH:MM:SS` timestamp. Only set for nudged users */ + nudgedDate?: string; }; export default UserMetadata; diff --git a/tests/unit/FullstoryUtilsTest.ts b/tests/unit/FullstoryUtilsTest.ts index 6c12fa5626ec..036029cf6012 100644 --- a/tests/unit/FullstoryUtilsTest.ts +++ b/tests/unit/FullstoryUtilsTest.ts @@ -42,6 +42,7 @@ describe('FullstoryUtils', () => { paidMember: true, npsScore: 9, npsResponseDate: '2026-05-03 09:30:00', + nudgedDate: '2026-06-16 10:26:36', }, }); @@ -64,6 +65,7 @@ describe('FullstoryUtils', () => { expect(userVars.days_till_trial_end).toBeGreaterThan(0); expect(userVars.free_trial_end_date?.toISOString()).toBe('2099-05-31T23:59:59.000Z'); expect(userVars.nps_response_date?.toISOString()).toBe('2026-05-03T09:30:00.000Z'); + expect(userVars.nudged_date?.toISOString()).toBe('2026-06-16T10:26:36.000Z'); }); it('builds page viewed event metadata', () => {