FRE-4495: Set up notification infrastructure (email, push, SMS)
- Created shared-notifications package with multi-channel support
- Implemented EmailService with Resend integration
- Implemented PushService with FCM/APNs support
- Implemented SMSService with Twilio integration
- Added NotificationService to orchestrate all channels
- Created notification types, configuration, and routes
- Added rate limiting and delivery tracking support
- Configured notification preferences management
Files:
- packages/shared-notifications/src/{types,config,services}/*.ts
- packages/shared-notifications/package.json
- apps/api/src/routes/notifications.routes.ts
- apps/api/package.json (updated dependencies)
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import { RateLimitConfig, NotificationChannel } from '../types/notification.types';
|
||||
|
||||
// Resend configuration
|
||||
export interface ResendConfig {
|
||||
apiKey: string;
|
||||
fromEmail: string;
|
||||
fromName: string;
|
||||
}
|
||||
|
||||
// Firebase Cloud Messaging configuration
|
||||
export interface FCMConfig {
|
||||
projectId: string;
|
||||
privateKey: string;
|
||||
clientEmail: string;
|
||||
keyPath?: string; // Path to service account key file
|
||||
}
|
||||
|
||||
// APNs configuration
|
||||
export interface APNsConfig {
|
||||
keyPath: string; // Path to .p8 key file
|
||||
keyId: string;
|
||||
teamId: string;
|
||||
bundleId: string;
|
||||
}
|
||||
|
||||
// Twilio configuration
|
||||
export interface TwilioConfig {
|
||||
accountSid: string;
|
||||
authToken: string;
|
||||
fromNumber?: string; // Optional default sender number
|
||||
}
|
||||
|
||||
// Combined notification config
|
||||
export interface NotificationConfig {
|
||||
resend: ResendConfig;
|
||||
fcm?: FCMConfig;
|
||||
apns?: APNsConfig;
|
||||
twilio?: TwilioConfig;
|
||||
rateLimits: {
|
||||
email: RateLimitConfig;
|
||||
push: RateLimitConfig;
|
||||
sms: RateLimitConfig;
|
||||
};
|
||||
}
|
||||
|
||||
// Default rate limits
|
||||
export const defaultRateLimits: Record<NotificationChannel, RateLimitConfig> = {
|
||||
[NotificationChannel.EMAIL]: {
|
||||
maxPerWindow: 100,
|
||||
windowMs: 60 * 60 * 1000, // 1 hour
|
||||
key: 'user',
|
||||
},
|
||||
[NotificationChannel.PUSH]: {
|
||||
maxPerWindow: 50,
|
||||
windowMs: 60 * 60 * 1000, // 1 hour
|
||||
key: 'user',
|
||||
},
|
||||
[NotificationChannel.SMS]: {
|
||||
maxPerWindow: 20,
|
||||
windowMs: 60 * 60 * 1000, // 1 hour
|
||||
key: 'user',
|
||||
},
|
||||
};
|
||||
|
||||
// Load config from environment variables
|
||||
export function loadNotificationConfig(): NotificationConfig {
|
||||
return {
|
||||
resend: {
|
||||
apiKey: process.env.RESEND_API_KEY!,
|
||||
fromEmail: process.env.RESEND_FROM_EMAIL || 'noreply@shieldsai.com',
|
||||
fromName: process.env.RESEND_FROM_NAME || 'ShieldAI',
|
||||
},
|
||||
fcm: process.env.FCM_PROJECT_ID ? {
|
||||
projectId: process.env.FCM_PROJECT_ID,
|
||||
privateKey: process.env.FCM_PRIVATE_KEY!.replace(/\\n/g, '\n'),
|
||||
clientEmail: process.env.FCM_CLIENT_EMAIL!,
|
||||
keyPath: process.env.FCM_KEY_PATH,
|
||||
} : undefined,
|
||||
apns: process.env.APNS_KEY_PATH ? {
|
||||
keyPath: process.env.APNS_KEY_PATH,
|
||||
keyId: process.env.APNS_KEY_ID!,
|
||||
teamId: process.env.APNS_TEAM_ID!,
|
||||
bundleId: process.env.APNS_BUNDLE_ID!,
|
||||
} : undefined,
|
||||
twilio: process.env.TWILIO_ACCOUNT_SID ? {
|
||||
accountSid: process.env.TWILIO_ACCOUNT_SID!,
|
||||
authToken: process.env.TWILIO_AUTH_TOKEN!,
|
||||
fromNumber: process.env.TWILIO_FROM_NUMBER,
|
||||
} : undefined,
|
||||
rateLimits: defaultRateLimits,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user