import { emitNotificationCreated } from "../sse/event-bus.js"; export interface CreateNotificationParams { // eslint-disable-next-line @typescript-eslint/no-explicit-any db: { notification: { create: (args: any) => Promise<{ id: string; userId: string }> } }; userId: string; type: string; title: string; body?: string | undefined; link?: string | undefined; entityId?: string | undefined; entityType?: string | undefined; category?: string | undefined; priority?: string | undefined; senderId?: string | undefined; channel?: string | undefined; taskStatus?: string | undefined; taskAction?: string | undefined; assigneeId?: string | undefined; dueDate?: Date | undefined; sourceId?: string | undefined; /** Set to false to suppress the SSE emitNotificationCreated call. Default: true. */ emit?: boolean | undefined; } /** * Create a single in-app notification and optionally emit an SSE event. * * Handles the `exactOptionalPropertyTypes` spread pattern internally so * callers do not need to repeat the `...(val !== undefined ? { key: val } : {})` boilerplate. * * Returns the created notification's ID. */ export async function createNotification( params: CreateNotificationParams, ): Promise { const { db, userId, type, title, body, link, entityId, entityType, category, priority, senderId, channel, taskStatus, taskAction, assigneeId, dueDate, sourceId, emit = true, } = params; const notification = await db.notification.create({ data: { userId, type, title, ...(body !== undefined ? { body } : {}), ...(link !== undefined ? { link } : {}), ...(entityId !== undefined ? { entityId } : {}), ...(entityType !== undefined ? { entityType } : {}), ...(category !== undefined ? { category } : {}), ...(priority !== undefined ? { priority } : {}), ...(senderId !== undefined ? { senderId } : {}), ...(channel !== undefined ? { channel } : {}), ...(taskStatus !== undefined ? { taskStatus } : {}), ...(taskAction !== undefined ? { taskAction } : {}), ...(assigneeId !== undefined ? { assigneeId } : {}), ...(dueDate !== undefined ? { dueDate } : {}), ...(sourceId !== undefined ? { sourceId } : {}), }, }); if (emit) { emitNotificationCreated(userId, notification.id); } return notification.id; } /** * Create one notification per user ID. * * Useful for fan-out scenarios (e.g. notifying all managers). * Returns the count of notifications created. */ export async function createNotificationsForUsers( params: Omit & { userIds: string[] }, ): Promise { const { userIds, ...rest } = params; if (userIds.length === 0) return 0; await Promise.all(userIds.map((userId) => createNotification({ ...rest, userId }))); return userIds.length; }