# WhatsApp Polling System

## Overview

The WhatsApp inbox uses HTTP polling (no WebSockets) to keep the UI updated in real-time.
When the inbox is open with a conversation selected, there are **3 HTTP pollings + 1 local timer** running simultaneously.

---

## Polling Map

### 1. Unread Badge (WhatsappInboxButton)

| Property | Value |
|---|---|
| **Interval** | 30 seconds |
| **Endpoint** | `GET /app/whatsapp/inbox/unread-count` |
| **Component** | `WhatsappConversation/WhatsappInboxButton.vue` |
| **Always active** | Yes — runs whenever the dashboard is open, even if the inbox is closed |
| **Purpose** | Updates the unread count badge on the WhatsApp button in the sidebar menu |
| **Payload** | `{ tenant }` |
| **Response** | `{ total_unread: number }` |

---

### 2. Conversation List (WhatsappConversationsList / ConversationListV2)

| Property | Value |
|---|---|
| **Interval** | 15 seconds |
| **Endpoint** | `GET /app/whatsapp/inbox/conversations` |
| **Component V1** | `WhatsappConversation/WhatsappConversationsList.vue` |
| **Component V2** | `WhatsappInboxV2/ConversationListV2.vue` |
| **Active when** | Inbox is open AND the "Inbox" tab is selected |
| **Purpose** | Refreshes the conversation list: new conversations, updated snippets, unread counts, customer_status |
| **Payload** | `{ tenant, filter: 'all'|'unread', limit: 50 }` |
| **Response** | `{ conversations: [...], total_unread: number }` |

---

### 3. Bookings List (WhatsappBookingsList)

| Property | Value |
|---|---|
| **Interval** | 15 seconds |
| **Endpoint** | `GET /app/whatsapp/inbox/bookings` |
| **Component** | `WhatsappConversation/WhatsappBookingsList.vue` (shared by V1 and V2) |
| **Active when** | Inbox is open AND the "Bookings" tab is selected |
| **Purpose** | Refreshes bookings with their conversation data: unread counts, window status, customer_status |
| **Payload** | `{ tenant, date_range: 'today'|'tomorrow'|'week'|'past'|'all', status, only_unread }` |
| **Response** | `{ bookings: [...], total_unread: number }` |

> **Note:** Pollings #2 and #3 are mutually exclusive — only one runs at a time depending on which tab is visible.

---

### 4. Messages (WhatsappConversationSidebar / ConversationSidebarV2)

| Property | Value |
|---|---|
| **Interval** | 5 seconds |
| **Endpoint** | `GET /app/whatsapp/conversation/{conversationId}/messages` |
| **Component V1** | `WhatsappConversation/WhatsappConversationSidebar.vue` |
| **Component V2** | `WhatsappInboxV2/ConversationSidebarV2.vue` |
| **Active when** | A conversation is selected and the sidebar is visible |
| **Purpose** | Fetches new messages since `last_message_id`, also returns updated window status |
| **Payload** | `{ tenant, last_message_id }` |
| **Response** | `{ messages: [...], conversation: {...}, has_new_messages, window_open, window_expires_at }` |

---

### 5. Window Countdown Timer (local, no HTTP)

| Property | Value |
|---|---|
| **Interval** | 60 seconds |
| **Component V1** | `WhatsappConversation/WhatsappConversationSidebar.vue` |
| **Component V2** | `WhatsappInboxV2/ConversationSidebarV2.vue` |
| **Active when** | A conversation is selected |
| **Purpose** | Updates the "Window open · 23h 39m" countdown text in the sidebar |
| **HTTP call** | None — purely local calculation based on `window_expires_at` |

---

## Simultaneous Requests

### Inbox open, conversation selected (Inbox tab):

| Every 5s | Every 15s | Every 30s | Every 60s |
|---|---|---|---|
| Messages refresh | Conversation list refresh | Unread badge | Window countdown (local) |

**= 3 HTTP requests every 30 seconds** (on average)

### Inbox open, conversation selected (Bookings tab):

| Every 5s | Every 15s | Every 30s | Every 60s |
|---|---|---|---|
| Messages refresh | Bookings list refresh | Unread badge | Window countdown (local) |

### Inbox closed:

| Every 30s |
|---|
| Unread badge only |

---

## Lifecycle

All pollings are started in `mounted()` and stopped in `beforeUnmount()`.
When switching conversations, the sidebar stops the old polling and starts a new one for the new conversation.

```
Dashboard loads
  └─ WhatsappInboxButton mounted → starts unread polling (30s)

User opens inbox
  └─ ConversationsList mounted → starts list polling (15s)

User selects conversation
  └─ ConversationSidebar mounted → starts messages polling (5s) + window timer (60s)

User switches to Bookings tab
  └─ BookingsList mounted → starts bookings polling (15s)
  └─ ConversationsList still mounted but v-show=false → polling continues (could be optimized)

User closes inbox
  └─ All inbox components unmounted → all pollings stopped
  └─ InboxButton remains → unread polling continues
```

---

## Endpoints Summary

| Endpoint | Method | Used by | Interval |
|---|---|---|---|
| `/app/whatsapp/inbox/unread-count` | GET | InboxButton | 30s |
| `/app/whatsapp/inbox/conversations` | GET | ConversationsList | 15s |
| `/app/whatsapp/inbox/bookings` | GET | BookingsList | 15s |
| `/app/whatsapp/conversation/{id}/messages` | GET | Sidebar | 5s |
