import { z } from "zod" import { api } from "@/convex/_generated/api" import type { Id } from "@/convex/_generated/dataModel" import { createCorsPreflight, jsonWithCors } from "@/server/cors" import { createConvexClient, ConvexConfigurationError } from "@/server/convex-client" const getMessagesSchema = z.object({ machineToken: z.string().min(1), ticketId: z.string().min(1), since: z.number().optional(), limit: z.number().optional(), }) const postMessageSchema = z.object({ machineToken: z.string().min(1), ticketId: z.string().min(1), body: z.string().min(1).max(4000), attachments: z .array( z.object({ storageId: z.string(), name: z.string(), size: z.number().optional(), type: z.string().optional(), }) ) .optional(), }) const CORS_METHODS = "POST, OPTIONS" export async function OPTIONS(request: Request) { return createCorsPreflight(request.headers.get("origin"), CORS_METHODS) } // POST /api/machines/chat/messages // action=list: Lista mensagens de um chat // action=send: Envia nova mensagem export async function POST(request: Request) { const origin = request.headers.get("origin") let client try { client = createConvexClient() } catch (error) { if (error instanceof ConvexConfigurationError) { return jsonWithCors({ error: error.message }, 500, origin, CORS_METHODS) } throw error } let raw try { raw = await request.json() } catch { return jsonWithCors({ error: "JSON invalido" }, 400, origin, CORS_METHODS) } const action = raw.action ?? "list" if (action === "list") { let payload try { payload = getMessagesSchema.parse(raw) } catch (error) { return jsonWithCors( { error: "Payload invalido", details: error instanceof Error ? error.message : String(error) }, 400, origin, CORS_METHODS ) } try { const result = await client.query(api.liveChat.listMachineMessages, { machineToken: payload.machineToken, ticketId: payload.ticketId as Id<"tickets">, since: payload.since, limit: payload.limit, }) return jsonWithCors(result, 200, origin, CORS_METHODS) } catch (error) { console.error("[machines.chat.messages] Falha ao listar mensagens", error) const details = error instanceof Error ? error.message : String(error) return jsonWithCors({ error: "Falha ao listar mensagens", details }, 500, origin, CORS_METHODS) } } if (action === "send") { let payload try { payload = postMessageSchema.parse(raw) } catch (error) { return jsonWithCors( { error: "Payload invalido", details: error instanceof Error ? error.message : String(error) }, 400, origin, CORS_METHODS ) } try { const result = await client.mutation(api.liveChat.postMachineMessage, { machineToken: payload.machineToken, ticketId: payload.ticketId as Id<"tickets">, body: payload.body, attachments: payload.attachments as | Array<{ storageId: Id<"_storage"> name: string size?: number type?: string }> | undefined, }) return jsonWithCors(result, 200, origin, CORS_METHODS) } catch (error) { console.error("[machines.chat.messages] Falha ao enviar mensagem", error) const details = error instanceof Error ? error.message : String(error) return jsonWithCors({ error: "Falha ao enviar mensagem", details }, 500, origin, CORS_METHODS) } } return jsonWithCors({ error: "Acao invalida" }, 400, origin, CORS_METHODS) }