@thewhateverapp/notifications
v0.1.5
Published
Shared notification service for TheWhateverApp with direct MongoDB writes and Redis pub/sub
Maintainers
Readme
@thewhatever/notifications
Shared notification service for TheWhateverApp. Provides direct MongoDB writes with Redis pub/sub broadcasting for real-time SSE notifications.
Features
- ✅ Direct MongoDB writes (no HTTP overhead)
- ✅ Redis pub/sub for multi-pod SSE broadcasting
- ✅ Type-safe notification creation
- ✅ Helper methods for common notification types
- ✅ Read/unread status tracking
- ✅ Unread count management
Installation
pnpm add @thewhatever/notificationsUsage
Initialize (once at app startup)
import { NotificationService } from '@thewhatever/notifications';
await NotificationService.initialize({
mongoUri: process.env.MONGODB_URI!,
redisUrl: process.env.REDIS_URL, // Optional - for multi-pod SSE
dbName: 'thewhatever', // Optional - defaults to 'thewhatever'
});Create notifications
// Generic notification
await NotificationService.createNotification({
userId: 'user123',
type: 'deploy_started',
title: 'Deployment Started',
message: 'Your app is being deployed...',
link: '/dashboard',
metadata: { tileId: 'tile456' },
});
// Helper methods for common types
await NotificationService.notifyDeployStarted({
userId: 'user123',
tileId: 'tile456',
tileTitle: 'My Awesome App',
});
await NotificationService.notifyDeploySuccess({
userId: 'user123',
tileId: 'tile456',
tileTitle: 'My Awesome App',
tileUrl: 'https://tile.pages.dev',
pageUrl: 'https://page.pages.dev',
});
await NotificationService.notifyDeployFailed({
userId: 'user123',
tileId: 'tile456',
tileTitle: 'My Awesome App',
errorMessage: 'Build failed',
});Query notifications
// Get user's notifications (paginated)
const { notifications, total } = await NotificationService.getUserNotifications(
'user123',
{
limit: 20,
skip: 0,
unreadOnly: false,
}
);
// Get unread count
const unreadCount = await NotificationService.getUnreadCount('user123');Mark as read
// Mark single notification as read
await NotificationService.markAsRead('notificationId', 'user123');
// Mark all as read
await NotificationService.markAllAsRead('user123');Cleanup (on shutdown)
await NotificationService.close();Redis Pub/Sub Channels
The service publishes to the following Redis channels for SSE broadcasting:
notifications:{userId}- New notification eventsnotifications:unread:{userId}- Unread count updates
SSE endpoints should subscribe to these channels to receive real-time updates.
Architecture
┌─────────────────────────────────────────────────┐
│ Backend Service (platform-api, agent-service) │
│ ┌────────────────────────────────────────────┐ │
│ │ NotificationService.createNotification() │ │
│ └──────────────┬─────────────────────────────┘ │
└─────────────────┼───────────────────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ MongoDB │ │ Redis │
│ (persist) │ │ (pub/sub) │
└─────────────┘ └──────┬──────┘
│
│ Subscribe
▼
┌─────────────┐
│ Web App │
│ SSE Stream │
└─────────────┘TypeScript Types
type NotificationType =
| 'deploy_started'
| 'deploy_success'
| 'deploy_failed'
| 'build_started'
| 'build_completed'
| 'app_published'
| 'app_updated';
interface NotificationInput {
userId: string;
type: NotificationType;
title: string;
message: string;
link?: string;
metadata?: Record<string, any>;
}
interface Notification extends NotificationInput {
_id: string;
createdAt: Date;
read: boolean;
readAt?: Date;
}License
Proprietary
