feat : big update
CI / Verify (push) Successful in 3m14s
CI / Build immutable images and deploy (push) Successful in 4m0s

This commit is contained in:
2026-10-01 18:37:15 +07:00 Unverified
parent c5037154cb
commit 0022625edb
76 changed files with 18671 additions and 29 deletions
@@ -0,0 +1,20 @@
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); }
}