# Plan: Send to Similar Leads

## Goal
After sending a Smart Reply, prompt user to send personalized versions to similar leads in one tap.

---

## User Flow

```
1. User opens Smart Reply for "John Smith" (Concreter, Warm)
2. User sends AI-generated message
3. Popup appears:

   ┌─────────────────────────────────────────┐
   │  ✨ Send to similar leads?              │
   │                                         │
   │  3 other Concreters waiting on reply:   │
   │                                         │
   │  ☑ Sarah Jones (72) - 2 days waiting    │
   │  ☑ Mike Brown (58) - 3 days waiting     │
   │  ☑ Dave Wilson (45) - 5 days waiting    │
   │                                         │
   │  AI will personalize each message       │
   │                                         │
   │  [Send to 3]  [Skip]                    │
   └─────────────────────────────────────────┘

4. User taps "Send to 3"
5. AI generates personalized version for each lead
6. All 3 sent, confirmation shown
```

---

## Matching Criteria

Find similar leads where:
- Same `lead_type` (client/worker) as original
- Same or similar `trade` (if available)
- Status = 'active' or 'contacted'
- Last message was OUTBOUND (we're waiting on them)
- Last contact > 24 hours ago
- NOT the lead we just messaged
- Limit to 5 suggestions

**Scoring for ranking:**
- Higher lead score = higher priority
- More days waiting = higher priority
- Same trade = bonus

---

## Implementation

### Backend: New Endpoint

**POST /api/ai/draft-similar**
```javascript
// Request
{
  leadId: "uuid",           // Original lead
  originalMessage: "...",   // What we sent
  prompt: "follow up",      // Original prompt
  tone: "friendly"
}

// Response
{
  success: true,
  similarLeads: [
    {
      id: "uuid",
      name: "Sarah Jones",
      company: "ABC Concrete",
      score: 72,
      trade: "Concreter",
      daysSinceContact: 2,
      personalizedMessage: "Hey Sarah, just checking in..."
    },
    // ... up to 5
  ]
}
```

### Backend: Bulk Send Endpoint

**POST /api/sms/send-batch-personalized**
```javascript
// Request
{
  leads: [
    { leadId: "uuid", message: "personalized msg 1" },
    { leadId: "uuid", message: "personalized msg 2" },
  ]
}

// Response
{
  success: true,
  sent: 3,
  failed: 0
}
```

### Frontend: SimilarLeadsPrompt Component

New component that appears after successful send:

```jsx
// admin/src/components/SimilarLeadsPrompt.jsx

export default function SimilarLeadsPrompt({
  originalLead,
  originalMessage,
  prompt,
  tone,
  onSend,
  onSkip
}) {
  const [similarLeads, setSimilarLeads] = useState([]);
  const [selected, setSelected] = useState([]);
  const [loading, setLoading] = useState(true);
  const [sending, setSending] = useState(false);

  useEffect(() => {
    // Fetch similar leads with personalized messages
    fetchSimilarLeads();
  }, []);

  // ... render checkboxes, send button
}
```

### Frontend: Integration in AIMessageWriter

After successful send in `handleSendMessage`:
```javascript
// Show similar leads prompt
setShowSimilarPrompt(true);
setSentMessage(message);
```

---

## Files to Modify

### Backend
1. **src/routes/ai.js** - Add `/draft-similar` endpoint
2. **src/routes/sms.js** - Add `/send-batch-personalized` endpoint
3. **src/services/ai.js** - Add `findSimilarLeads()` and `generatePersonalizedBatch()`

### Frontend
1. **admin/src/components/SimilarLeadsPrompt.jsx** - New component
2. **admin/src/components/AIMessageWriter.jsx** - Show prompt after send
3. **admin/src/api/client.js** - Add API methods

---

## Step-by-Step Execution

### Step 1: Backend - Find Similar Leads ✅
- [x] Add `findSimilarLeads(lead, limit)` to ai.js service
- [x] Query leads with matching criteria
- [x] Return ranked list

### Step 2: Backend - Generate Personalized Messages ✅
- [x] Add `generatePersonalizedBatch(leads, originalPrompt, tone)`
- [x] Use GPT to create variations for each lead
- [x] Include lead name, company, context

### Step 3: Backend - Draft Similar Endpoint ✅
- [x] Add `POST /api/ai/draft-similar`
- [x] Combine find + generate
- [x] Return leads with messages

### Step 4: Backend - Batch Send Endpoint ✅
- [x] Add `POST /api/sms/send-batch`
- [x] Loop through leads, send each
- [x] Track success/failure

### Step 5: Frontend - SimilarLeadsPrompt Component ✅
- [x] Create new component
- [x] Fetch similar leads on mount
- [x] Checkbox selection UI
- [x] Send button with loading state
- [x] Success/skip callbacks

### Step 6: Frontend - Integrate in AIMessageWriter ✅
- [x] Add state for showing prompt
- [x] After successful send, show SimilarLeadsPrompt
- [x] Handle send/skip

### Step 7: Test
- [ ] Send message to one lead
- [ ] Verify similar leads appear
- [ ] Send to selected leads
- [ ] Verify all messages sent correctly
- [ ] Check each message is personalized

---

## Edge Cases

1. **No similar leads found** - Don't show prompt, just close
2. **All similar leads contacted recently** - Don't show prompt
3. **Rate limit** - Show warning if too many messages
4. **One fails** - Show partial success: "Sent 2/3, 1 failed"

---

## UI/UX Details

**Prompt appears:**
- Bottom sheet on mobile
- Modal on desktop
- Auto-dismiss after 10 seconds if no interaction

**Checkboxes:**
- All selected by default
- Tap to deselect
- Show lead score as colored badge

**Personalization preview:**
- Tap lead row to expand and see their personalized message
- Edit option before sending

---

## Success Metrics

- % of users who use "Send to Similar"
- Avg leads reached per session
- Response rate from batch sends vs individual

---

## 0.1% Quality Check

- [x] Would best CRM do this? YES - Outreach, Apollo have similar
- [x] Is there friction? Minimal - one tap after natural send
- [x] Could AI make it smarter? YES - AI personalizes each message
- [x] One click when could be zero? User still confirms (intentional)

---

## Status: DEPLOYED ✅

**Deployed:** Jan 18, 2026
**Commit:** 0b53def (includes LeadProfile fix)

All implementation steps complete.

**Bug fix applied:** LeadProfile.jsx was closing the modal on `onSend` before SimilarLeadsPrompt could appear. Fixed by moving `loadLead()` to `onClose` callback only.

Ready for user testing.
