import { z } from "zod/v4"; /** * Notification channel declarations (v1 carry-forward, plan ยง11.2). * Defined independently of the legacy module so v2 has no legacy imports. */ export const NOTIFICATION_DELIVERY_CHANNELS = [ "in_app", "desktop", "mobile_push", ] as const; export const notificationDeliveryChannelV2Schema = z.enum( NOTIFICATION_DELIVERY_CHANNELS, ); export type NotificationDeliveryChannelV2 = z.infer< typeof notificationDeliveryChannelV2Schema >; export const NOTIFICATION_PRIORITIES = ["low", "default", "high"] as const; export const notificationPriorityV2Schema = z.enum(NOTIFICATION_PRIORITIES); export type NotificationPriorityV2 = z.infer; export const notificationChannelV2Schema = z.strictObject({ key: z .string() .trim() .regex(/^[a-z][a-z0-9-]*$/, "Channel keys are lowercase kebab-case.") .max(160), name: z.string().trim().min(1).max(120), description: z.string().trim().max(500).optional(), defaultDeliveries: z .array(notificationDeliveryChannelV2Schema) .min(1) .max(NOTIFICATION_DELIVERY_CHANNELS.length) .default(["in_app"]) .refine( (values) => new Set(values).size === values.length, "Deliveries must be unique.", ), defaultPriority: notificationPriorityV2Schema.default("default"), }); export type NotificationChannelV2 = z.infer; export const appNotificationsV2Schema = z .strictObject({ channels: z .array(notificationChannelV2Schema) .max(20) .default([]) .refine( (channels) => new Set(channels.map((channel) => channel.key)).size === channels.length, "Channel keys must be unique.", ), }) .default({ channels: [] }); export type AppNotificationsV2 = z.infer;