Real-Time Communication (WebSockets)
Relevant source files
The following files were used as context for generating this wiki page:The real-time communication system is a core feature of the QA Dashboard, enabling live updates for new questions and status changes without requiring users to refresh the page. This is achieved using WebSockets, with a FastAPI backend managing connections and broadcasting events, and a Next.js frontend subscribing to and reacting to these events through a React Context.
This system ensures that all users see new questions as they are posted and see status updates (e.g., "Pending" to "Answered") in real-time, creating a dynamic and interactive experience.
Sources: README.md:6-7
Architecture Overview
The WebSocket architecture consists of a central ConnectionManager on the backend that tracks all active client connections. The frontend establishes a persistent connection via the WebSocketProvider. When an event occurs on the backend (like a new question being created), the relevant API endpoint uses the ConnectionManager to broadcast a message to all connected clients. The frontend's WebSocketProvider receives this message and updates the application's state, which in turn re-renders the UI.
The following diagram illustrates the high-level data flow for real-time updates.
Backend Implementation
The backend is built with FastAPI, which has native support for WebSockets. The implementation is centered around a connection manager and a dedicated WebSocket endpoint.
Sources: backend/api/questions.py, backend/main.py
Connection Management
A ConnectionManager class is used to manage the lifecycle of all active WebSocket connections. Although the class definition is not present in the provided files, its usage is evident in backend/api/questions.py. It is instantiated once and used to connect, disconnect, and broadcast messages to clients.
| Method | Description |
|---|---|
connect() | Adds a new client's WebSocket connection to the pool. |
disconnect() | Removes a client's connection from the pool. |
broadcast() | Sends a JSON message to all active connections. |
Sources: backend/api/questions.py:28, 70, 90, 155
WebSocket Endpoint: /questions/ws
The primary endpoint for establishing a WebSocket connection is defined at /questions/ws.
# backend/api/questions.py:68-92
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await manager.connect(websocket)
db = SessionLocal()
try:
# ... query and sort questions ...
questions = ...
await websocket.send_json(
{"type": "questions_list", "data": jsonable_encoder(questions)}
)
while True:
await websocket.receive_text()
except WebSocketDisconnect:
manager.disconnect(websocket)
# ...
When a client connects to this endpoint:
- The connection is registered with the
ConnectionManager. - The server immediately queries the database for the current list of all questions.
- The questions are sorted by status (
Escalated,Pending,Answered) and timestamp. - The full, sorted list is sent to the newly connected client in a message with
type: "questions_list". - The server then enters an idle loop, keeping the connection open to listen for client-side disconnects or to broadcast server-side events.
- If the client disconnects, the connection is removed from the manager.
Sources: backend/api/questions.py:68-92
Broadcasting Events
To ensure real-time updates, other API endpoints broadcast messages after performing key actions.
The following diagram shows the flow when a new question is created.
- On Question Creation: After a new question is saved, the
/questionsendpoint broadcasts aquestion_createdevent containing the new question's data. - On Question Update: When an admin changes a question's status via the
PATCH /questions/{id}endpoint, aquestion_updatedevent is broadcast with the updated question data.
Sources: backend/api/questions.py:60-65, backend/api/questions.py:153-158
Frontend Implementation
The frontend uses a combination of a React Context, a custom hook, and environment variables to manage the WebSocket connection and state.
Sources: web/src/context/WebSocketContext.js, web/src/app/forum/page.js, web/src/config/api.js
Configuration
The WebSocket server URL is configured in .env.local and accessed through web/src/config/api.js.
| Variable | Default Value | Description |
|---|---|---|
NEXT_PUBLIC_WS_BASE_URL | ws://localhost:8000 | The base URL for the WebSocket server. |
This is exported as WS_BASE_URL and used to initiate the connection.
Sources: web/src/config/api.js:2, README.md:112-113
WebSocket Context (WebSocketProvider)
The WebSocketProvider is a React component that wraps the entire application. It is responsible for establishing and maintaining the WebSocket connection and holding the shared state (isConnected, questions).
Key functionalities:
connect(): Creates anew WebSocket()instance pointing to${WS_BASE_URL}/questions/ws.- Reconnection Logic: If the connection is closed (
onclose), it automatically attempts to reconnect after 3 seconds. - State Management: It holds the connection status (
isConnected) and the list of questions (questions). - Message Handling: The
onmessagehandler parses incoming JSON messages and updates thequestionsstate based on the messagetype.
Sources: web/src/app/layout.js:25-27, web/src/context/WebSocketContext.js:10-70
The sequence diagram below shows the client connection and event handling process.
WebSocket Message Types
The communication between client and server relies on a set of defined message types.
| Type | Origin | Payload Description | Frontend Action |
|---|---|---|---|
questions_list | Server | An array of all existing question objects. | Replaces the entire questions state with the received array. |
question_created | Server | A single new question object. | Prepends the new question to the beginning of the questions state array. |
question_updated | Server | A single question object with updated fields (e.g., status). | Finds the corresponding question in the state array and updates its properties. |
Sources: web/src/context/WebSocketContext.js:34-47, backend/api/questions.py:62, 85, 155
UI Integration (useWebSocket hook)
Components like ForumPage use the useWebSocket hook to access the connection status and the real-time list of questions from the WebSocketContext. This decouples the UI components from the direct management of the WebSocket connection.
// web/src/app/forum/page.js:8-9
export default function ForumPage() {
const { user, token } = useAuth();
const { isConnected, connect, questions } = useWebSocket();
// ...
}
The page displays a connection status indicator and maps over the questions array to render the QuestionList. Because questions is a state variable managed by the context, the UI automatically updates whenever a new message is received from the server.
Sources: web/src/app/forum/page.js:9, 41-45, 62
Summary
The WebSocket system is a critical component for the real-time functionality of the QA Dashboard. It uses a robust client-server model where the FastAPI backend manages connections and broadcasts state changes, and the Next.js frontend subscribes to these changes via a centralized React Context. This architecture ensures that all users have a synchronized and up-to-date view of the questions and their statuses, providing a seamless and interactive experience.