1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00

feat: ignore onboarding events for existing customers (#8064)

This commit is contained in:
Mateusz Kwasniewski 2024-09-03 15:24:33 +02:00 committed by GitHub
parent e70b09ae7b
commit 3d63089cb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 13 deletions

View File

@ -76,6 +76,21 @@ test('Default project should take first user created instead of project created
]); ]);
}); });
test('Ignore events for existing customers', async () => {
jest.useFakeTimers();
jest.setSystemTime(new Date(2024, 8, 2)); // day before we added metrics
const { userStore } = stores;
await userStore.insert({});
jest.setSystemTime(new Date());
await onboardingService.insert({ type: 'first-user-login' });
const { rows: instanceEvents } = await db.rawDatabase.raw(
'SELECT * FROM onboarding_events_instance',
);
expect(instanceEvents).toMatchObject([]);
});
test('Ignore system user in onboarding events', async () => { test('Ignore system user in onboarding events', async () => {
// system users are not counted towards onboarding metrics // system users are not counted towards onboarding metrics
await db.rawDatabase.raw('INSERT INTO users (is_system) VALUES (true)'); await db.rawDatabase.raw('INSERT INTO users (is_system) VALUES (true)');

View File

@ -13,7 +13,9 @@ import type {
IOnboardingStore, IOnboardingStore,
ProjectEvent, ProjectEvent,
} from './onboarding-store-type'; } from './onboarding-store-type';
import { millisecondsToSeconds } from 'date-fns'; import { isBefore, millisecondsToSeconds } from 'date-fns';
const START_ONBOARDING_TRACKING_DATE = new Date(2024, 8, 3);
export class OnboardingService { export class OnboardingService {
private flagResolver: IFlagResolver; private flagResolver: IFlagResolver;
@ -92,18 +94,28 @@ export class OnboardingService {
| { flag: string; type: ProjectEvent['type'] } | { flag: string; type: ProjectEvent['type'] }
| { type: 'first-user-login' | 'second-user-login' }, | { type: 'first-user-login' | 'second-user-login' },
): Promise<void> { ): Promise<void> {
await this.insertInstanceEvent(event); const firstInstanceUserDate = await this.userStore.getFirstUserDate();
// the time we introduced onboarding tracking
if (
firstInstanceUserDate &&
isBefore(firstInstanceUserDate, START_ONBOARDING_TRACKING_DATE)
)
return;
await this.insertInstanceEvent(event, firstInstanceUserDate);
if ('flag' in event) { if ('flag' in event) {
await this.insertProjectEvent(event); await this.insertProjectEvent(event, firstInstanceUserDate);
} }
this.eventBus.emit('onboarding-event'); this.eventBus.emit('onboarding-event');
} }
private async insertInstanceEvent(event: { private async insertInstanceEvent(
event: {
flag?: string; flag?: string;
type: InstanceEvent['type']; type: InstanceEvent['type'];
}): Promise<void> { },
const firstInstanceUserDate = await this.userStore.getFirstUserDate(); firstInstanceUserDate: Date | null,
): Promise<void> {
if (!firstInstanceUserDate) return; if (!firstInstanceUserDate) return;
const timeToEvent = millisecondsToSeconds( const timeToEvent = millisecondsToSeconds(
@ -115,10 +127,13 @@ export class OnboardingService {
}); });
} }
private async insertProjectEvent(event: { private async insertProjectEvent(
event: {
flag: string; flag: string;
type: ProjectEvent['type']; type: ProjectEvent['type'];
}): Promise<void> { },
firstInstanceUserDate: Date | null,
): Promise<void> {
const project = await this.projectReadModel.getFeatureProject( const project = await this.projectReadModel.getFeatureProject(
event.flag, event.flag,
); );
@ -126,7 +141,7 @@ export class OnboardingService {
const startDate = const startDate =
project.project === 'default' project.project === 'default'
? await this.userStore.getFirstUserDate() ? firstInstanceUserDate
: project.createdAt || null; : project.createdAt || null;
if (!startDate) return; if (!startDate) return;