Implement multi-channel notification system with: - Core notification service with email, push, and in-app channels - Email templates for all notification types (welcome, plant registered, transport alerts, farm alerts, harvest ready, demand matches, weekly digest) - Push notification support with VAPID authentication - In-app notification management with read/unread tracking - Notification scheduler for recurring and scheduled notifications - API endpoints for notifications CRUD, preferences, and subscriptions - UI components (NotificationBell, NotificationList, NotificationItem, PreferencesForm) - Full notifications page with preferences management - Service worker for push notification handling
170 lines
3.6 KiB
TypeScript
170 lines
3.6 KiB
TypeScript
/**
|
|
* Notification System Types
|
|
* Multi-channel notification system for LocalGreenChain
|
|
*/
|
|
|
|
export type NotificationChannel = 'email' | 'push' | 'inApp';
|
|
export type NotificationPriority = 'low' | 'medium' | 'high' | 'urgent';
|
|
export type NotificationStatus = 'pending' | 'sent' | 'delivered' | 'failed' | 'read';
|
|
export type NotificationType =
|
|
| 'welcome'
|
|
| 'plant_registered'
|
|
| 'plant_reminder'
|
|
| 'transport_alert'
|
|
| 'farm_alert'
|
|
| 'harvest_ready'
|
|
| 'demand_match'
|
|
| 'weekly_digest'
|
|
| 'system_alert';
|
|
|
|
export interface NotificationRecipient {
|
|
userId: string;
|
|
email?: string;
|
|
pushToken?: string;
|
|
preferences?: UserNotificationPreferences;
|
|
}
|
|
|
|
export interface NotificationPayload {
|
|
type: NotificationType;
|
|
title: string;
|
|
message: string;
|
|
data?: Record<string, any>;
|
|
actionUrl?: string;
|
|
imageUrl?: string;
|
|
}
|
|
|
|
export interface Notification {
|
|
id: string;
|
|
recipientId: string;
|
|
payload: NotificationPayload;
|
|
channels: NotificationChannel[];
|
|
priority: NotificationPriority;
|
|
status: NotificationStatus;
|
|
createdAt: string;
|
|
sentAt?: string;
|
|
deliveredAt?: string;
|
|
readAt?: string;
|
|
error?: string;
|
|
retryCount: number;
|
|
metadata?: Record<string, any>;
|
|
}
|
|
|
|
export interface UserNotificationPreferences {
|
|
userId: string;
|
|
email: boolean;
|
|
push: boolean;
|
|
inApp: boolean;
|
|
plantReminders: boolean;
|
|
transportAlerts: boolean;
|
|
farmAlerts: boolean;
|
|
harvestAlerts: boolean;
|
|
demandMatches: boolean;
|
|
weeklyDigest: boolean;
|
|
quietHoursStart?: string; // HH:mm format
|
|
quietHoursEnd?: string; // HH:mm format
|
|
timezone?: string;
|
|
}
|
|
|
|
export interface EmailNotificationData {
|
|
to: string;
|
|
subject: string;
|
|
html: string;
|
|
text?: string;
|
|
from?: string;
|
|
replyTo?: string;
|
|
}
|
|
|
|
export interface PushNotificationData {
|
|
token: string;
|
|
title: string;
|
|
body: string;
|
|
icon?: string;
|
|
badge?: string;
|
|
data?: Record<string, any>;
|
|
actions?: PushAction[];
|
|
}
|
|
|
|
export interface PushAction {
|
|
action: string;
|
|
title: string;
|
|
icon?: string;
|
|
}
|
|
|
|
export interface PushSubscription {
|
|
userId: string;
|
|
endpoint: string;
|
|
keys: {
|
|
p256dh: string;
|
|
auth: string;
|
|
};
|
|
createdAt: string;
|
|
lastUsedAt?: string;
|
|
}
|
|
|
|
export interface InAppNotification {
|
|
id: string;
|
|
userId: string;
|
|
type: NotificationType;
|
|
title: string;
|
|
message: string;
|
|
actionUrl?: string;
|
|
imageUrl?: string;
|
|
read: boolean;
|
|
createdAt: string;
|
|
expiresAt?: string;
|
|
}
|
|
|
|
export interface NotificationQueue {
|
|
notifications: Notification[];
|
|
processing: boolean;
|
|
lastProcessedAt?: string;
|
|
}
|
|
|
|
export interface ScheduledNotification {
|
|
id: string;
|
|
notification: Omit<Notification, 'id' | 'createdAt' | 'status'>;
|
|
scheduledFor: string;
|
|
recurring?: {
|
|
pattern: 'daily' | 'weekly' | 'monthly';
|
|
endDate?: string;
|
|
};
|
|
status: 'scheduled' | 'sent' | 'cancelled';
|
|
}
|
|
|
|
export interface NotificationStats {
|
|
totalSent: number;
|
|
totalDelivered: number;
|
|
totalFailed: number;
|
|
byChannel: {
|
|
email: { sent: number; delivered: number; failed: number };
|
|
push: { sent: number; delivered: number; failed: number };
|
|
inApp: { sent: number; delivered: number; failed: number };
|
|
};
|
|
byType: Record<NotificationType, number>;
|
|
}
|
|
|
|
export interface NotificationConfig {
|
|
email: {
|
|
provider: 'sendgrid' | 'nodemailer' | 'smtp';
|
|
apiKey?: string;
|
|
from: string;
|
|
replyTo?: string;
|
|
smtp?: {
|
|
host: string;
|
|
port: number;
|
|
secure: boolean;
|
|
user: string;
|
|
pass: string;
|
|
};
|
|
};
|
|
push: {
|
|
vapidPublicKey: string;
|
|
vapidPrivateKey: string;
|
|
vapidSubject: string;
|
|
};
|
|
defaults: {
|
|
retryAttempts: number;
|
|
retryDelayMs: number;
|
|
batchSize: number;
|
|
};
|
|
}
|