122 lines
5.4 KiB
Markdown
122 lines
5.4 KiB
Markdown
# PRD: WhatsApp Lead Management for go-crm
|
|
|
|
---
|
|
|
|
## Problem Statement
|
|
|
|
Clients using the go-crm platform need to connect their personal WhatsApp number to capture leads. Currently, there is no way for clients to:
|
|
1. Authenticate their WhatsApp account via QR code
|
|
2. Automatically capture incoming WhatsApp messages (1:1 chats, not groups) as leads in the CRM
|
|
3. Manage these leads (CRUD operations) through the platform
|
|
|
|
---
|
|
|
|
## Solution
|
|
|
|
Add a "Leads" feature to go-crm that allows clients to:
|
|
1. Connect their WhatsApp via QR code scanning from the client list
|
|
2. Automatically sync incoming WhatsApp messages (not group chats) as leads in the CRM
|
|
3. View, edit, and manage these leads through existing CRUD operations
|
|
|
|
---
|
|
|
|
## User Stories
|
|
|
|
1. As a client, I want to see a "QR Connect" button next to my client name in the client list, so that I can initiate WhatsApp connection
|
|
2. As a client, I want to scan a QR code with my WhatsApp app to authenticate, so that my WhatsApp gets connected to my CRM account
|
|
3. As a client, I want to see my connected WhatsApp phone number displayed in the client list, so that I know I'm connected
|
|
4. As a client, I want my incoming WhatsApp messages (not groups) to automatically appear as leads in the CRM, so that I can manage them
|
|
5. As a client, I want my existing WhatsApp contacts to sync as leads when I first connect, so that I have my historical data in the CRM
|
|
6. As a client, I want to view all my leads in a dedicated "/leads" page, so that I can see my potential customers
|
|
7. As a client, I want to search and filter my leads by name or phone number, so that I can find specific contacts quickly
|
|
8. As a client, I want to edit lead details (name, phone, birth date, Instagram) from the Leads page, so that I can keep information up to date
|
|
9. As a client, I want to delete a lead, so that I can remove spam or unwanted contacts
|
|
10. As a client, I want my lead's phone number to be normalized (with country code), so that data is consistent
|
|
11. As a client, I want the system to skip group messages from WhatsApp, so that I only get 1:1 chat leads
|
|
12. As a client, if I reconnect my WhatsApp, I want the session to be reused, so that I don't need to scan QR every time
|
|
13. As a client, if the WhatsApp background process crashes, I want it to automatically restart, so that I don't lose messages
|
|
14. As a client, if I receive a message from an existing lead phone number, I want the system to update the existing record (not create duplicates), so that my data stays accurate
|
|
15. As a client, I want my leads to display the phone number I connected with as my own, so that I know which WhatsApp is linked
|
|
|
|
---
|
|
|
|
## Implementation Decisions
|
|
|
|
### Architecture
|
|
|
|
- Go wraps Node.js whatsapp-web.js as a subprocess (spawn-and-keep after connection)
|
|
- IPC via stdout JSON lines + HTMX polling for frontend
|
|
- Per-client WhatsApp session folder (`.wwebjs_auth/{client_id}/`)
|
|
|
|
### Database Schema (clients table)
|
|
|
|
- `whatsapp_number TEXT` — normalized phone number (e.g., `+5521...`)
|
|
- `whatsapp_connected INTEGER DEFAULT 0` — connection status (0=false, 1=true)
|
|
|
|
### Route Structure
|
|
|
|
- `GET /leads` — list all leads for the logged-in client's account
|
|
- `GET /leads/connect?client_id={id}` — QR code display page for connection
|
|
- `GET /leads/qr?client_id={id}` — polling endpoint for QR/status (returns current QR string or status)
|
|
|
|
### Node.js Script (whatsapp-leads.js)
|
|
|
|
- Spawned per-client with per-client session folder
|
|
- Filters group chats (only processes 1:1 messages)
|
|
- Upserts on duplicate phone number
|
|
- Syncs historical chats + new incoming messages
|
|
- Calls Go's existing `POST /customers` endpoint with internal secret header
|
|
|
|
### Process Lifecycle
|
|
|
|
- Ephemeral spawn for QR connection flow (spawns, waits for READY, then keeps running)
|
|
- Auto-restart if Node.js process exits unexpectedly
|
|
|
|
### UI Flow
|
|
|
|
- Client list (`/clients`) shows "Connect" button if `whatsapp_number IS NULL`, otherwise displays connected phone number
|
|
- Leads page (`/leads`) shows table of leads with edit/delete actions
|
|
|
|
### Authentication
|
|
|
|
- Node.js → Go uses shared internal secret header (`X-Internal-Secret`) to bypass session auth
|
|
|
|
---
|
|
|
|
## Testing Decisions
|
|
|
|
### Test Philosophy
|
|
|
|
- Tests should verify behavior through public interfaces, not implementation details
|
|
- Good tests read like specifications: "client can connect WhatsApp" tells you exactly what capability exists
|
|
- Tests should survive internal refactors — if renaming an internal function breaks tests, those tests were testing implementation
|
|
|
|
### Modules to Test
|
|
|
|
- Database: Client WhatsApp columns (insert/query)
|
|
- Handler: Leads page rendering, connection status display
|
|
- Node.js script: JSON output to stdout, group message filtering
|
|
|
|
### Prior Art
|
|
|
|
- No existing tests in go-crm to follow; will create new `handlers_test.go` alongside implementation
|
|
|
|
---
|
|
|
|
## Out of Scope
|
|
|
|
- Sending messages back to WhatsApp from the CRM (only receiving/syncing)
|
|
- WhatsApp profile pictures/avatars
|
|
- Multiple WhatsApp numbers per client (one per client)
|
|
- Group management features
|
|
- Message notifications/push to mobile
|
|
- WhatsApp Web client session restoration across Go server restarts (requires systemd/supervisor)
|
|
|
|
---
|
|
|
|
## Further Notes
|
|
|
|
- Phone numbers are stored normalized (with country code) as received from WhatsApp
|
|
- Historical chat sync happens on first connection (all existing 1:1 chats become leads)
|
|
- New messages sync in real-time while the Node.js process runs
|
|
- If WhatsApp session expires/disconnects, client must reconnect via QR |