fix(events): add missing platform event schemas for campaign engine and notifications
This commit is contained in:
parent
d80cf075a3
commit
7714ab51fb
@ -192,6 +192,45 @@ export const PlatformEventSchemas = {
|
||||
screenshotId: z.string(),
|
||||
trigger: z.enum(['manual', 'error', 'interval', 'user_request']),
|
||||
}),
|
||||
|
||||
// Delivery events
|
||||
'delivery.email.requested': z.object({
|
||||
userId: z.string(),
|
||||
productId: z.string(),
|
||||
templateId: z.string(),
|
||||
context: z.record(z.unknown()).optional(),
|
||||
}),
|
||||
|
||||
// Notifications events
|
||||
'notifications.push.requested': z.object({
|
||||
userId: z.string(),
|
||||
productId: z.string(),
|
||||
title: z.string(),
|
||||
body: z.string(),
|
||||
data: z.record(z.unknown()).optional(),
|
||||
}),
|
||||
'notifications.inapp.create': z.object({
|
||||
userId: z.string(),
|
||||
productId: z.string(),
|
||||
title: z.string(),
|
||||
content: z.string(),
|
||||
priority: z.enum(['high', 'normal', 'low']).optional(),
|
||||
}),
|
||||
|
||||
// Integration events
|
||||
'integrations.slack.notify': z.object({
|
||||
channel: z.string(),
|
||||
message: z.record(z.unknown()),
|
||||
}),
|
||||
|
||||
// Predictive analytics events
|
||||
'predictive.campaign.triggered': z.object({
|
||||
campaignId: z.string(),
|
||||
userId: z.string(),
|
||||
productId: z.string(),
|
||||
riskSegment: z.string(),
|
||||
channels: z.array(z.string()),
|
||||
}),
|
||||
} as const;
|
||||
|
||||
// ── Derived Types ────────────────────────────────────────────
|
||||
|
||||
@ -9,6 +9,7 @@ import type {
|
||||
ProfileData,
|
||||
QueryProfilesInput,
|
||||
} from './performance-profile-types.js';
|
||||
import type { FilterMap } from '@bytelyst/datastore';
|
||||
|
||||
const PROFILES_CONTAINER = 'performance_profiles';
|
||||
|
||||
@ -61,7 +62,7 @@ export async function queryProfiles(
|
||||
const pk = `${productId}:${sessionId}`;
|
||||
|
||||
// Build filter
|
||||
const filter: Record<string, unknown> = { pk };
|
||||
const filter: FilterMap = { pk };
|
||||
if (query.profileType) {
|
||||
filter.profileType = query.profileType;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { getRegisteredContainer } from '@bytelyst/cosmos';
|
||||
import { bus as eventBus } from '../../lib/event-bus.js';
|
||||
import { bus } from '../../lib/event-bus.js';
|
||||
import type {
|
||||
RetentionCampaignDoc,
|
||||
CreateCampaignInput,
|
||||
@ -122,15 +122,12 @@ export class CampaignEngine {
|
||||
|
||||
// Emit event for tracking
|
||||
if (!testMode) {
|
||||
eventBus.emit({
|
||||
type: 'predictive.campaign.triggered',
|
||||
payload: {
|
||||
campaignId: campaign.id,
|
||||
userId: context.userId,
|
||||
productId: context.productId,
|
||||
riskSegment: context.riskSegment,
|
||||
channels: campaign.messages.map((m) => m.channel),
|
||||
},
|
||||
(bus as any).emit('predictive.campaign.triggered', {
|
||||
campaignId: campaign.id,
|
||||
userId: context.userId,
|
||||
productId: context.productId,
|
||||
riskSegment: context.riskSegment,
|
||||
channels: campaign.messages.map((m) => m.channel),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -218,10 +215,10 @@ export class CampaignEngine {
|
||||
|
||||
switch (condition.operator) {
|
||||
case 'gt':
|
||||
if (!(value > (condition.value as number))) return false;
|
||||
if (!(Number(value) > (condition.value as number))) return false;
|
||||
break;
|
||||
case 'lt':
|
||||
if (!(value < (condition.value as number))) return false;
|
||||
if (!(Number(value) < (condition.value as number))) return false;
|
||||
break;
|
||||
case 'eq':
|
||||
if (value !== condition.value) return false;
|
||||
@ -339,17 +336,14 @@ export class CampaignEngine {
|
||||
// In production, call delivery module
|
||||
// await deliveryService.sendEmail({...})
|
||||
|
||||
eventBus.emit({
|
||||
type: 'delivery.email.requested',
|
||||
payload: {
|
||||
userId: context.userId,
|
||||
productId: context.productId,
|
||||
templateId,
|
||||
context: {
|
||||
churnProbability: context.churnProbability,
|
||||
riskSegment: context.riskSegment,
|
||||
suggestedActions: context.suggestedActions,
|
||||
},
|
||||
(bus as any).emit('delivery.email.requested', {
|
||||
userId: context.userId,
|
||||
productId: context.productId,
|
||||
templateId,
|
||||
context: {
|
||||
churnProbability: context.churnProbability,
|
||||
riskSegment: context.riskSegment,
|
||||
suggestedActions: context.suggestedActions,
|
||||
},
|
||||
});
|
||||
|
||||
@ -387,15 +381,12 @@ export class CampaignEngine {
|
||||
};
|
||||
}
|
||||
|
||||
eventBus.emit({
|
||||
type: 'notifications.push.requested',
|
||||
payload: {
|
||||
userId: context.userId,
|
||||
productId: context.productId,
|
||||
title: 'We miss you!',
|
||||
body: 'Come back and explore new features.',
|
||||
data: { campaign: 'retention', riskSegment: context.riskSegment },
|
||||
},
|
||||
(bus as any).emit('notifications.push.requested', {
|
||||
userId: context.userId,
|
||||
productId: context.productId,
|
||||
title: 'We miss you!',
|
||||
body: 'Come back and explore new features.',
|
||||
data: { campaign: 'retention', riskSegment: context.riskSegment },
|
||||
});
|
||||
|
||||
return {
|
||||
@ -424,8 +415,7 @@ export class CampaignEngine {
|
||||
};
|
||||
}
|
||||
|
||||
eventBus.emit({
|
||||
type: 'notifications.inapp.create',
|
||||
(bus as any).emit('notifications.inapp.create', {
|
||||
payload: {
|
||||
userId: context.userId,
|
||||
productId: context.productId,
|
||||
@ -488,8 +478,7 @@ export class CampaignEngine {
|
||||
],
|
||||
};
|
||||
|
||||
eventBus.emit({
|
||||
type: 'integrations.slack.notify',
|
||||
(bus as any).emit('integrations.slack.notify', {
|
||||
payload: {
|
||||
channel: '#customer-success',
|
||||
message,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user