79 lines
2.5 KiB
TypeScript
Raw Normal View History

/**
* Notifications Schema
*
* Zod schemas and types for in-app notifications.
*/
import { z } from "zod";
import { NOTIFICATION_TYPE, NOTIFICATION_SOURCE } from "./contract.js";
// =============================================================================
// Schemas
// =============================================================================
export const notificationSchema = z.object({
id: z.string().uuid(),
userId: z.string().uuid(),
type: z.nativeEnum(NOTIFICATION_TYPE),
title: z.string(),
message: z.string().nullable(),
actionUrl: z.string().nullable(),
actionLabel: z.string().nullable(),
source: z.nativeEnum(NOTIFICATION_SOURCE),
sourceId: z.string().nullable(),
read: z.boolean(),
readAt: z.string().datetime().nullable(),
dismissed: z.boolean(),
createdAt: z.string().datetime(),
expiresAt: z.string().datetime(),
});
export type Notification = z.infer<typeof notificationSchema>;
export const createNotificationRequestSchema = z.object({
userId: z.string().uuid(),
type: z.nativeEnum(NOTIFICATION_TYPE),
title: z.string().optional(),
message: z.string().optional(),
actionUrl: z.string().optional(),
actionLabel: z.string().optional(),
source: z.nativeEnum(NOTIFICATION_SOURCE).optional(),
sourceId: z.string().optional(),
});
export type CreateNotificationRequest = z.infer<typeof createNotificationRequestSchema>;
export const notificationListResponseSchema = z.object({
notifications: z.array(notificationSchema),
unreadCount: z.number(),
total: z.number(),
});
export type NotificationListResponse = z.infer<typeof notificationListResponseSchema>;
export const notificationUnreadCountResponseSchema = z.object({
count: z.number(),
});
export type NotificationUnreadCountResponse = z.infer<typeof notificationUnreadCountResponseSchema>;
/**
* Schema for notification query parameters
*/
export const notificationQuerySchema = z.object({
limit: z.coerce.number().int().min(1).max(100).optional().default(20),
offset: z.coerce.number().int().nonnegative().optional().default(0),
includeRead: z.coerce.boolean().optional().default(true),
});
export type NotificationQuery = z.infer<typeof notificationQuerySchema>;
// =============================================================================
// Route Param Schemas (BFF)
// =============================================================================
export const notificationIdParamSchema = z.object({
id: z.string().uuid(),
});
export type NotificationIdParam = z.infer<typeof notificationIdParamSchema>;