import { authorizeTicket } from "@/lib/commission/tickets"; import { getRedisClient, redisEventChannel } from "@/lib/redis/client"; import { errorResponse, HttpError, readJson, requireSameOrigin } from "@/lib/security/http"; import { limitRequest } from "@/lib/security/rate-limit"; export async function POST(request: Request, context: RouteContext<"/api/commission/tickets/[id]/typing">) { try { requireSameOrigin(request); const { id } = await context.params; const { ticket, user } = await authorizeTicket(id); if (ticket.status !== "open") throw new HttpError(409, "ticket-closed"); await limitRequest("commission-typing", user.id, 30); const body = await readJson(request, 128); if (!body || typeof body !== "object" || !("active" in body) || typeof body.active !== "boolean") throw new HttpError(400, "invalid-typing-state"); await (await getRedisClient()).publish(redisEventChannel(`commission:ticket:${id}`), `typing:${JSON.stringify({ userId: user.id, name: user.name, active: body.active })}`); return new Response(null, { status: 204 }); } catch (cause) { return errorResponse(cause); } }