# 01 - Visitor WebSocket Presence Foundation

Welcome to **Milestone 2, Step 2.1**: Visitor & Agent WebSocket Presence Foundation (`WS /ws/session/{sessionId}` and `WS /ws/agent`).

---

## 1. What is a WebSocket?

A **WebSocket** is a persistent, full-duplex communication protocol that operates over a single TCP connection (`ws://` or `wss://`).

Unlike HTTP REST requests (where the client sends a request and receives a single response), a WebSocket connection stays open continuously until closed by either the client or the server, enabling low-latency, bidirectional real-time communication.

---

## 2. REST vs. WebSocket in Universal Chatbot

In this architecture, REST and WebSocket serve distinct, complementary responsibilities:

| Protocol | Endpoint | Purpose in Milestone 2 |
|---|---|---|
| **HTTP REST** | `POST /api/v1/message`<br>`POST /api/v1/handoff/*` | **State & Transports:** Initiates sessions, submits visitor/agent messages, accepts/ends chats. |
| **Visitor WS** | `WS /ws/session/{sessionId}` | **Visitor Real-Time Channel:** Tracks presence state (`active_sessions`), receives status changes (`IN_CHAT`, `ENDED`), and receives live agent replies. |
| **Agent WS** | `WS /ws/agent` | **Agent Feed:** Receives live broadcasts (`visitor_connected`, `visitor_disconnected`, `user_message`, `agent_message`, `chat_ended`). |

---

## 3. Connection Lifecycle & `active_sessions` Store

The backend maintains an in-memory session registry (`active_sessions` in `app/services/presence.py`):

```text
  [Widget Client]                             [FastAPI Backend]                              [Agent Dashboard]
         │                                            │                                              │
         │ 1. Open WS /ws/session/{sessionId}         │                                              │
         ├───────────────────────────────────────────►│                                              │
         │                                            │ 2. Validate session in MongoDB               │
         │                                            │ 3. Store in active_sessions dict              │
         │                                            │ 4. Broadcast visitor_connected ─────────────►│ (Chime sound + Ringing card)
         │                                            │                                              │
         │ 5. Connection Active                       │                                              │
         │◄══════════════════════════════════════════►│                                              │
         │                                            │                                              │
         │ 6. Tab Closed / Page Reload                │                                              │
         ├───────────────────────────────────────────►│ (WebSocketDisconnect event)                   │
         │                                            │ 7. Remove from active_sessions:               │
         │                                            │    broadcast visitor_disconnected ───────────►│ (Card removed)
```

---

## 4. Presence Data Model in Memory

The `active_sessions` dictionary stores comprehensive visitor metadata:

```python
{
    "sessionId": "sess_1234567890ab",
    "siteId": "site_demo_123",
    "status": "RINGING",       # "RINGING" | "IN_CHAT" | "ENDED"
    "endedBy": "agent",        # "visitor" | "agent" (set when chat ends)
    "user": {
        "id": "usr_123",
        "name": "Alice Visitor",
        "email": "alice@example.com"
    },
    "ipAddress": "127.0.0.1",
    "country": "Local / Demo",
    "connectedAt": "2026-08-14T14:00:00+00:00",
    "websocket": <WebSocket object>
}
```

---

## 5. In-Memory Store Rationale

- **Phase 1 Scale:** For single-instance FastAPI deployments, storing active connections in Python memory (`active_sessions = {}`) provides zero-latency reads/writes without external database roundtrips.
- **Horizontal Scaling:** When scaling horizontally across multiple server nodes in later phases, Redis Pub/Sub will replace the local in-memory registry.
