/** * Message Router — list, get, respond */ import { TRPCError } from '@trpc/server'; import { z } from 'zod'; import type { ProcedureBuilder } from '../trpc.js'; import { requireMessageRepository } from './_helpers.js'; export function messageProcedures(publicProcedure: ProcedureBuilder) { return { listMessages: publicProcedure .input(z.object({ agentId: z.string().optional(), status: z.enum(['pending', 'read', 'responded']).optional(), })) .query(async ({ ctx, input }) => { const messageRepository = requireMessageRepository(ctx); let messages = await messageRepository.findByRecipient('user'); if (input.agentId) { messages = messages.filter(m => m.senderId === input.agentId); } if (input.status) { messages = messages.filter(m => m.status === input.status); } return messages; }), getMessage: publicProcedure .input(z.object({ id: z.string().min(1) })) .query(async ({ ctx, input }) => { const messageRepository = requireMessageRepository(ctx); const message = await messageRepository.findById(input.id); if (!message) { throw new TRPCError({ code: 'NOT_FOUND', message: `Message '${input.id}' not found`, }); } return message; }), respondToMessage: publicProcedure .input(z.object({ id: z.string().min(1), response: z.string().min(1), })) .mutation(async ({ ctx, input }) => { const messageRepository = requireMessageRepository(ctx); const existing = await messageRepository.findById(input.id); if (!existing) { throw new TRPCError({ code: 'NOT_FOUND', message: `Message '${input.id}' not found`, }); } const responseMessage = await messageRepository.create({ senderType: 'user', recipientType: 'agent', recipientId: existing.senderId, type: 'response', content: input.response, parentMessageId: input.id, }); await messageRepository.update(input.id, { status: 'responded' }); return responseMessage; }), }; }