import { NextResponse } from 'next/server'; import { scheduleDisconnectRoomChat } from '@/lib/chzzk/chat-session'; import { getRoom, getRoomViewerCount, removeRoomViewer, toPublicRoom, } from '@/lib/rooms/store'; export const runtime = 'nodejs'; type Params = { params: Promise<{ roomId: string }> }; /** * 탭/창 종료·페이지 이탈 시 호출. * 마지막 시청자면 치지직 채팅 웹소켓을 유예 후 끊는다 (빠른 재입장 대비). */ export async function POST(request: Request, { params }: Params) { const { roomId } = await params; const room = getRoom(roomId); if (!room) { return NextResponse.json({ ok: true, emptied: true }); } let clientId = ''; const contentType = request.headers.get('content-type') || ''; try { if (contentType.includes('application/json')) { const body = (await request.json()) as { clientId?: string }; clientId = body.clientId?.trim() || ''; } else { const text = await request.text(); if (text.startsWith('{')) { const body = JSON.parse(text) as { clientId?: string }; clientId = body.clientId?.trim() || ''; } else { clientId = new URLSearchParams(text).get('clientId')?.trim() || ''; } } } catch { clientId = ''; } if (!clientId) { return NextResponse.json({ ok: true, viewers: getRoomViewerCount(roomId) }); } const { viewers, emptied } = removeRoomViewer(roomId, clientId); if (emptied) { scheduleDisconnectRoomChat(roomId); } return NextResponse.json({ ok: true, viewers, emptied, room: toPublicRoom(getRoom(roomId) ?? room), }); }