import { z } from "zod"; import prisma from "~/server/utils/prisma"; // Query parameter validation schema const jobsQuerySchema = z.object({ page: z .string() .transform((val) => parseInt(val) || 1) .optional(), limit: z .string() .transform((val) => parseInt(val) || 10) .optional(), status: z.string().optional(), }); export default defineEventHandler(async (event) => { try { // Parse and validate query parameters const queryParams = getQuery(event) || {}; const params = jobsQuerySchema.parse(queryParams); // Build where clause for filtering const where = {}; if (params.status) { where.status = params.status; } // Get total count for pagination const total = await prisma.notification_queue.count({ where }); // Calculate pagination metadata const totalPages = Math.ceil(total / params.limit); // Fetch jobs with relations const jobs = await prisma.notification_queue.findMany({ where, select: { id: true, status: true, scheduled_for: true, attempts: true, max_attempts: true, last_attempt_at: true, error_message: true, created_at: true, updated_at: true, priority: true, notifications: { select: { id: true, title: true, type: true, }, }, notification_recipients: { select: { user_id: true, email: true, channel_type: true, }, }, }, orderBy: { scheduled_for: "asc", }, skip: (params.page - 1) * params.limit, take: params.limit, }); // Format jobs for response const formattedJobs = jobs.map((job) => { return { id: job.id, type: job.notifications?.type || "unknown", description: job.notifications?.title || "Job Description", status: job.status, attempts: job.attempts, maxAttempts: job.max_attempts, priority: job.priority, recipient: job.notification_recipients?.email || job.notification_recipients?.user_id, channel: job.notification_recipients?.channel_type, scheduledFor: job.scheduled_for, createdAt: job.created_at, lastAttempt: job.last_attempt_at, errorMessage: job.error_message, }; }); return { success: true, data: { jobs: formattedJobs, pagination: { page: params.page, totalPages, totalItems: total, hasMore: params.page < totalPages, }, }, }; } catch (error) { console.error("Error fetching queue jobs:", error); if (error.statusCode) { throw error; } throw createError({ statusCode: 500, statusMessage: "Failed to fetch queue jobs", data: { error: error.message, }, }); } finally { } });