import { z } from "zod"; import { describeRoute, resolver } from "hono-openapi"; import { NOTIFICATION_TYPES, notificationConfigSchema } from "~/schemas/notifications"; const notificationDestinationSchema = z.object({ id: z.number(), name: z.string(), enabled: z.boolean(), status: z.enum(["healthy", "error", "unknown"]), lastChecked: z.number().nullable(), lastError: z.string().nullable(), type: z.enum(NOTIFICATION_TYPES), config: notificationConfigSchema, createdAt: z.number(), updatedAt: z.number(), }); const listDestinationsResponse = notificationDestinationSchema.array(); export type ListDestinationsDto = z.infer; export const listDestinationsDto = describeRoute({ description: "List all notification destinations", tags: ["Notifications"], operationId: "listNotificationDestinations", responses: { 200: { description: "A list of notification destinations", content: { "application/json": { schema: resolver(listDestinationsResponse), }, }, }, }, }); export const createDestinationBody = z.object({ name: z.string(), config: notificationConfigSchema, }); const createDestinationResponse = notificationDestinationSchema; export type CreateDestinationDto = z.infer; export const createDestinationDto = describeRoute({ description: "Create a new notification destination", operationId: "createNotificationDestination", tags: ["Notifications"], responses: { 201: { description: "Notification destination created successfully", content: { "application/json": { schema: resolver(createDestinationResponse), }, }, }, }, }); const getDestinationResponse = notificationDestinationSchema; export type GetDestinationDto = z.infer; export const getDestinationDto = describeRoute({ description: "Get a notification destination by ID", operationId: "getNotificationDestination", tags: ["Notifications"], responses: { 200: { description: "Notification destination details", content: { "application/json": { schema: resolver(getDestinationResponse), }, }, }, 404: { description: "Notification destination not found", }, }, }); export const updateDestinationBody = z.object({ name: z.string().optional(), enabled: z.boolean().optional(), config: notificationConfigSchema.optional(), }); const updateDestinationResponse = notificationDestinationSchema; export type UpdateDestinationDto = z.infer; export const updateDestinationDto = describeRoute({ description: "Update a notification destination", operationId: "updateNotificationDestination", tags: ["Notifications"], responses: { 200: { description: "Notification destination updated successfully", content: { "application/json": { schema: resolver(updateDestinationResponse), }, }, }, 404: { description: "Notification destination not found", }, }, }); const deleteDestinationResponse = z.object({ message: z.string(), }); export type DeleteDestinationDto = z.infer; export const deleteDestinationDto = describeRoute({ description: "Delete a notification destination", operationId: "deleteNotificationDestination", tags: ["Notifications"], responses: { 200: { description: "Notification destination deleted successfully", content: { "application/json": { schema: resolver(deleteDestinationResponse), }, }, }, 404: { description: "Notification destination not found", }, }, }); const testDestinationResponse = z.object({ success: z.boolean(), }); export type TestDestinationDto = z.infer; export const testDestinationDto = describeRoute({ description: "Test a notification destination by sending a test message", operationId: "testNotificationDestination", tags: ["Notifications"], responses: { 200: { description: "Test notification sent successfully", content: { "application/json": { schema: resolver(testDestinationResponse), }, }, }, 404: { description: "Notification destination not found", }, 409: { description: "Cannot test disabled destination", }, 500: { description: "Failed to send test notification", }, }, }); const scheduleNotificationAssignmentSchema = z.object({ scheduleId: z.number(), destinationId: z.number(), notifyOnStart: z.boolean(), notifyOnSuccess: z.boolean(), notifyOnWarning: z.boolean(), notifyOnFailure: z.boolean(), createdAt: z.number(), destination: notificationDestinationSchema, }); const getScheduleNotificationsResponse = scheduleNotificationAssignmentSchema.array(); export type GetScheduleNotificationsDto = z.infer; export const getScheduleNotificationsDto = describeRoute({ description: "Get notification assignments for a backup schedule", operationId: "getScheduleNotifications", tags: ["Backups", "Notifications"], responses: { 200: { description: "List of notification assignments for the schedule", content: { "application/json": { schema: resolver(getScheduleNotificationsResponse), }, }, }, }, }); export const updateScheduleNotificationsBody = z.object({ assignments: z .object({ destinationId: z.number(), notifyOnStart: z.boolean(), notifyOnSuccess: z.boolean(), notifyOnWarning: z.boolean(), notifyOnFailure: z.boolean(), }) .array(), }); const updateScheduleNotificationsResponse = scheduleNotificationAssignmentSchema.array(); export type UpdateScheduleNotificationsDto = z.infer; export const updateScheduleNotificationsDto = describeRoute({ description: "Update notification assignments for a backup schedule", operationId: "updateScheduleNotifications", tags: ["Backups", "Notifications"], responses: { 200: { description: "Notification assignments updated successfully", content: { "application/json": { schema: resolver(updateScheduleNotificationsResponse), }, }, }, }, });