# Project Memory - API Notes

## Last Updated: 2026-05-29

---

## Chat Workspace API

### GET /api/chat-workspace
Returns all data needed for the chat workspace SPA.
- **Auth**: Required (via Filament session)
- **Role filtering**:
  - Admin: sees all conversations
  - Supervisor: sees team conversations only
  - Agent: sees own conversations only
- **Response**: `{ chats, contacts, agents, teams, currentUser, stats }`
- **Optimization**: Eager loads `contact`, `assignee`, `latestMessage`

### POST /api/conversations/{id}/messages
Send a message in a conversation.
- **Body**: `{ body: "message text" }`
- **Auth**: Checked via ConversationPolicy (reply)
- **Response**: Created message object

### POST /api/conversations/{id}/transfer
Transfer conversation to another agent.
- **Body**: `{ agent_id: 123 }`
- **Auth**: Checked via ConversationPolicy (transfer, transferTo)
- **Validation**: Agent must exist; can't transfer to same agent
- **Response**: Updated conversation

### POST /api/conversations/{id}/close
Close a conversation.
- **Auth**: Checked via ConversationPolicy (close)
- **Response**: Updated conversation with status=closed

### POST /api/conversations/{id}/mark-read
Mark a conversation as read (reset unread_count to 0).
- **Auth**: Required
- **Action**: Sets `unread_count = 0`, `last_read_at = now()`
- **Response**: `{ success: true }`

### POST /api/webhooks/whatsapp
WhatsApp webhook endpoint for incoming messages.
- **Verification**: Uses WHATSAPP_APP_SECRET for signature verification
- **Processing**: Dispatched to `ProcessIncomingMessageJob` via queue
- **Dedup**: Searches existing conversation by contact_id before creating new

---

## Webhook Processing Flow
1. WhatsApp sends POST to `/api/webhooks/whatsapp`
2. Controller verifies signature (HMAC-SHA1)
3. Dispatches `ProcessIncomingMessageJob` to `webhooks` queue
4. Job finds/creates Contact, finds/reopens Conversation, creates Message
5. Frontend polls `/api/chat-workspace` every 15s for updates
