/** * @factory/shared — notification DTOs (PRODUCT-SPEC §14; prisma `Notification`). */ import { z } from "zod"; export const notificationChannelSchema = z.enum(["in_app", "email", "webhook"]); export type NotificationChannelInput = z.infer; export const notificationTypeSchema = z.enum([ "mention", "comment", "assignment", "page_shared", "task_assigned", "database_change", "automation", "integration", ]); export type NotificationTypeInput = z.infer; /** Create an in-app notification (server-side producers mostly; exposed for * "notify user" automation actions). */ export const createNotificationSchema = z .object({ userId: z.string().min(1), type: notificationTypeSchema, /** Display title. */ title: z.string().min(1).max(200), body: z.string().max(2000).optional(), /** Where the notification links to. */ link: z.string().max(500).optional(), /** Delivery channels (in_app is always added). */ channels: z.array(notificationChannelSchema).min(1).max(3).optional(), actorId: z.string().min(1).optional(), refType: z.string().min(1).optional(), refId: z.string().min(1).optional(), }) .strict(); export type CreateNotification = z.infer; export const markNotificationsReadSchema = z .object({ notificationIds: z.array(z.string().min(1)).min(1).max(500).optional(), /** When no ids: mark everything up to this moment as read. */ upTo: z .string() .refine((s) => Number.isFinite(Date.parse(s)), { message: "invalid ISO date" }) .optional(), }) .strict(); export type MarkNotificationsRead = z.infer;