"""WebSocket endpoint for real-time version room events.""" import uuid from fastapi import APIRouter, Query, WebSocket, WebSocketDisconnect from rehearsalhub.repositories.member import MemberRepository from rehearsalhub.db.engine import get_session from rehearsalhub.services.auth import decode_token from rehearsalhub.ws import manager router = APIRouter(tags=["websocket"]) @router.websocket("/ws/versions/{version_id}") async def version_ws( version_id: uuid.UUID, websocket: WebSocket, token: str | None = Query(None), ): """ WebSocket endpoint. Authentication via: - ?token= query parameter, or - rh_token httpOnly cookie (sent automatically by the browser) """ raw_token = token or websocket.cookies.get("rh_token") async for session in get_session(): try: if not raw_token: raise ValueError("no token") payload = decode_token(raw_token) member_id = uuid.UUID(payload["sub"]) member = await MemberRepository(session).get_by_id(member_id) if member is None: raise ValueError("member not found") except Exception: await websocket.close(code=4001) return await manager.connect(version_id, websocket) try: while True: # Echo back any client pings; clients can send {"event": "ping"} data = await websocket.receive_json() if data.get("event") == "ping": await websocket.send_json({"event": "pong"}) except WebSocketDisconnect: manager.disconnect(version_id, websocket)