""" Shared Pydantic models for API communication between voicebot and server components. This module contains all the shared data models used for: - HTTP API requests and responses - WebSocket message payloads - Data persistence structures """ from __future__ import annotations from typing import List, Dict, Optional, Literal from pydantic import BaseModel # ============================================================================= # Core Data Models (for persistence and API communication) # ============================================================================= class NamePasswordRecord(BaseModel): """Password hash record for reserved names""" salt: str hash: str class LobbyModel(BaseModel): """Core lobby model used across components""" id: str name: str private: bool = False class SessionModel(BaseModel): """Core session model used across components""" id: str name: str = "" lobbies: List[LobbyModel] = [] class ParticipantModel(BaseModel): """Represents a participant in a lobby/session""" name: str session_id: str # Add other participant fields as needed based on actual data structure # ============================================================================= # HTTP API Request/Response Models # ============================================================================= class AdminNamesResponse(BaseModel): """Response for admin names endpoint""" name_passwords: Dict[str, NamePasswordRecord] class AdminActionResponse(BaseModel): """Response for admin actions""" status: Literal["ok", "not_found"] name: str class AdminSetPassword(BaseModel): """Request model for setting admin password""" name: str password: str class AdminClearPassword(BaseModel): """Request model for clearing admin password""" name: str class HealthResponse(BaseModel): """Health check response""" status: str class LobbyListItem(BaseModel): """Lobby item for list responses""" id: str name: str class LobbiesResponse(BaseModel): """Response containing list of lobbies""" lobbies: List[LobbyListItem] class SessionResponse(BaseModel): """Session response model""" id: str name: str lobbies: List[LobbyModel] class LobbyCreateData(BaseModel): """Data for lobby creation""" name: str private: bool = False class LobbyCreateRequest(BaseModel): """Request for creating a lobby""" type: Literal["lobby_create"] data: LobbyCreateData class LobbyCreateResponse(BaseModel): """Response for lobby creation""" type: Literal["lobby_created"] data: LobbyModel # ============================================================================= # WebSocket Message Models # ============================================================================= class JoinStatusModel(BaseModel): """WebSocket message for join status updates""" status: str message: str = "" class UserJoinedModel(BaseModel): """WebSocket message for user joined events""" name: str session_id: str class LobbyStateModel(BaseModel): """WebSocket message for lobby state updates""" participants: List[ParticipantModel] = [] class UpdateNameModel(BaseModel): name: str protected: Optional[bool] = False class WebSocketMessageModel(BaseModel): """Base model for all WebSocket messages""" type: str data: JoinStatusModel | UserJoinedModel | LobbyStateModel | UpdateNameModel # ============================================================================= # WebRTC Signaling Models (specific to voicebot) # ============================================================================= class ICECandidateDictModel(BaseModel): """ICE candidate dictionary structure""" candidate: Optional[str] = None sdpMid: Optional[str] = None sdpMLineIndex: Optional[int] = None class AddPeerModel(BaseModel): """WebRTC add peer message""" peer_id: str peer_name: str should_create_offer: bool = False class RemovePeerModel(BaseModel): """WebRTC remove peer message""" peer_id: str peer_name: str class SessionDescriptionTypedModel(BaseModel): """WebRTC session description""" type: str sdp: str class SessionDescriptionModel(BaseModel): """WebRTC session description message""" peer_id: str peer_name: str session_description: SessionDescriptionTypedModel class IceCandidateModel(BaseModel): """WebRTC ICE candidate message""" peer_id: str peer_name: str candidate: ICECandidateDictModel # ============================================================================= # Data Persistence Models # ============================================================================= class LobbySaved(BaseModel): """Lobby model for persistence""" id: str name: str private: bool = False class SessionSaved(BaseModel): """Session model for persistence""" id: str name: str = "" lobbies: List[LobbySaved] = [] class SessionsPayload(BaseModel): """Complete sessions data for persistence""" sessions: List[SessionSaved] = [] name_passwords: Dict[str, NamePasswordRecord] = {}