Files
FrenoCorp/packages/shared-analytics/src/services/mixpanel.service.ts

117 lines
2.4 KiB
TypeScript

import { Analytics } from '@segment/analytics-node';
import { analyticsEnv, EventType, eventPropertiesSchema } from '../config/analytics.config';
// Mixpanel service
export class MixpanelService {
private client: Analytics;
constructor() {
this.client = new Analytics({
apiKey: analyticsEnv.MIXPANEL_TOKEN,
});
}
/**
* Track an event in Mixpanel
*/
async track(
event: EventType,
distinctId: string,
properties?: Record<string, any>
): Promise<void> {
const validatedProperties = eventPropertiesSchema.parse(properties);
this.client.track({
event,
distinctId,
properties: {
...validatedProperties,
...properties,
},
});
}
/**
* Identify a user
*/
async identify(userId: string, traits?: Record<string, any>): Promise<void> {
this.client.identify({
distinctId: userId,
traits,
});
}
/**
* Group users by subscription tier
*/
async group(groupId: string, groupKey: string, traits?: Record<string, any>): Promise<void> {
this.client.group({
groupKey,
groupId,
traits,
});
}
/**
* Track user sign-up
*/
async userSignedUp(userId: string, plan?: string, referrer?: string): Promise<void> {
await this.track(EventType.USER_SIGNED_UP, userId, {
plan,
referrer,
timestamp: new Date(),
});
}
/**
* Track subscription upgrade
*/
async userUpgraded(userId: string, fromTier: string, toTier: string, mrr: number): Promise<void> {
await this.track(EventType.USER_UPGRADED, userId, {
fromTier,
toTier,
mrr,
timestamp: new Date(),
});
}
/**
* Track exposure detection
*/
async exposureDetected(
userId: string,
exposureType: string,
severity: string,
source: string
): Promise<void> {
await this.track(EventType.EXPOSURE_DETECTED, userId, {
exposureType,
severity,
source,
timestamp: new Date(),
});
}
/**
* Track spam detection
*/
async spamBlocked(userId: string, phoneNumber: string, confidence: number, method: string): Promise<void> {
await this.track(EventType.SPAM_BLOCKED, userId, {
phoneNumber,
confidence,
method,
timestamp: new Date(),
});
}
/**
* Flush pending events
*/
async flush(): Promise<void> {
await this.client.flush();
}
}
// Export instance
export const mixpanelService = new MixpanelService();