# Intel Search Across Leads

> Search all captured intel from one unified interface

**Created:** Jan 20, 2026
**Status:** Plan Ready
**Effort:** 4-6 hours
**Ongoing Cost:** $0 (uses existing Supabase)

---

## Problem

Intel is scattered across multiple tables:
- `lead_intel` - Personal info, hobbies, family
- `company_intel` - Business info, size, industry
- `lead_dossier` - Key facts, objections, what works
- `communications` - Extracted entities from messages

Sales reps can't search "who mentioned they're hiring?" or "which leads are in construction?"

---

## Solution

Unified search endpoint + UI that queries all intel sources.

### API Endpoint

```
GET /api/intel/search?q=hiring&type=all
```

**Parameters:**
- `q` - Search query (required)
- `type` - Filter: `all`, `personal`, `business`, `objections`, `facts`
- `limit` - Results per page (default 20)

**Response:**
```json
{
  "results": [
    {
      "lead_id": "uuid",
      "lead_name": "John Smith",
      "match_type": "business_intel",
      "match_field": "hiring_needs",
      "match_text": "Looking to hire 3 formworkers",
      "relevance_score": 0.95,
      "source": "call_transcript",
      "captured_at": "2026-01-18"
    }
  ],
  "total": 45,
  "query_time_ms": 120
}
```

### Search Sources

| Source | Fields Searched |
|--------|-----------------|
| lead_intel | hobbies, interests, family_status, personality_notes |
| company_intel | industry, pain_points, competitors, notes |
| lead_dossier | key_facts, objections, what_works, ai_summary |
| communications | extracted_entities, message content |

### UI Component

`IntelSearchModal.jsx` - Accessible from:
- Dashboard header (magnifying glass icon)
- Leads page header
- Command palette (Cmd+K)

**Features:**
- Real-time search as you type (debounced 300ms)
- Filter chips for intel type
- Click result → opens Lead Profile
- Recent searches saved in localStorage

---

## Database

No new tables needed. Add full-text search indexes:

```sql
-- Add GIN indexes for fast text search
CREATE INDEX IF NOT EXISTS idx_lead_intel_search
ON lead_intel USING gin(to_tsvector('english',
  COALESCE(personality_notes, '') || ' ' ||
  COALESCE(family_status, '') || ' ' ||
  COALESCE(array_to_string(hobbies, ' '), '') || ' ' ||
  COALESCE(array_to_string(interests, ' '), '')
));

CREATE INDEX IF NOT EXISTS idx_company_intel_search
ON company_intel USING gin(to_tsvector('english',
  COALESCE(industry, '') || ' ' ||
  COALESCE(notes, '') || ' ' ||
  COALESCE(pain_points::text, '')
));

CREATE INDEX IF NOT EXISTS idx_lead_dossier_search
ON lead_dossier USING gin(to_tsvector('english',
  COALESCE(ai_summary, '') || ' ' ||
  COALESCE(key_facts::text, '') || ' ' ||
  COALESCE(objections::text, '')
));
```

---

## Implementation Steps

### Phase 1: Backend (2-3 hours)
1. [ ] Create `src/routes/intel.js` with search endpoint
2. [ ] Implement full-text search across tables
3. [ ] Add relevance scoring
4. [ ] Add result highlighting

### Phase 2: Frontend (2-3 hours)
1. [ ] Create `IntelSearchModal.jsx`
2. [ ] Add search icon to Dashboard header
3. [ ] Implement debounced search
4. [ ] Add filter chips
5. [ ] Navigate to lead on result click

---

## Success Metrics

- Search returns results in <500ms
- Reps use search 5+ times/day
- Reduces time to find specific intel by 80%

---

## Future Enhancements

- Semantic search with embeddings (find "unhappy with current supplier" when searching "competitor issues")
- Save searches as smart lists
- Search within date ranges
