Broadcast System
The Broadcast feature (/dashboard/broadcast) allows administrators to send real-time system-wide notifications to all connected users simultaneously. Messages are delivered instantly via SSE and also persisted to the database for users who are offline.
This page requires the settings.manage permission by default. Only admins can send broadcasts.
How It Works
Admin fills form β POST /api/notifications/broadcast
βββ 1. Create a Notification record for EVERY active user
βββ 2. Emit 'broadcast' event on eventBus
βββ 3. All connected SSE clients receive the event
βββ 4. NotificationContext calls refresh()
βββ 5. Each client fetches latest notifications from APIBroadcast API Endpoint
// POST /api/notifications/broadcast
// Body: { title, message, type }
// Permission: settings.manage
import { apiGuard } from '@/lib/api-guard';
import { prisma } from '@/lib/prisma';
import { eventBus } from '@/lib/events';
export async function POST(req: Request) {
const guard = await apiGuard('settings.manage');
if (guard.error) return guard.error;
const { title, message, type = 'info' } = await req.json();
// Get all users
const users = await prisma.user.findMany({ select: { id: true } });
// Create a notification for each user
await prisma.notification.createMany({
data: users.map(user => ({
userId: user.id,
title,
message,
type,
read: false,
})),
});
// Emit real-time event to all SSE clients
eventBus.emit('system-event', {
type: 'broadcast',
title,
message,
});
return Response.json({ success: true, count: users.length });
}Using the Broadcast UI
The Broadcast tool at /dashboard/broadcast provides:
- Title field β Short subject line (shown as notification title)
- Message textarea β Full broadcast message body
- Type selector β
info,warning,success, orerror(affects the notification icon/color) - Send button β Triggers the API call and shows a success count toast
- Recent broadcasts list β Shows the last N broadcast messages sent
Triggering a Broadcast Programmatically
import { notificationsApi } from '@/services/notifications/api';
await notificationsApi.broadcast({
title: 'Scheduled Maintenance',
message: 'The system will be down for maintenance at 3AM UTC for approximately 30 minutes.',
type: 'warning',
});Targeted Broadcasts
To send to a specific role or team instead of all users, filter at the database query level:
// Send only to admins and managers
const users = await prisma.user.findMany({
where: {
userRoles: {
some: {
role: { name: { in: ['admin', 'manager'] } },
},
},
},
select: { id: true },
});How Users Receive Broadcasts
Real-time (connected users)
The eventBus.emit('system-event', { type: 'broadcast', ... }) call triggers the SSE handler. All clients with an active SSE connection receive the event and immediately call refresh() on their notification state.
Offline users
When they next open the dashboard, NotificationContext fetches /api/notifications on mount. The persisted notification record appears in their notification list as unread.
Broadcast notifications appear in the Notification Center (bell icon, top nav bar). The unread count badge updates in real time for connected users and on next load for offline users.