Skip to content

Commit 7999558

Browse files
Steve McMillianclaude
andcommitted
feat: LLM-based contact discovery workflow - 71% success vs Apollo 0%
Breakthrough discovery after Docker testing revealed Apollo API limitations: - Apollo org enrich: 403 Forbidden (not on our plan) - Apollo-only approach: 0% success on small/municipal clubs - Thinking LLM approach: 71% success across 7 test courses New workflow: Manual LLM → Parse → Apollo→Hunter waterfall → Supabase → ClickUp - You paste LLM response into Supabase (triggers everything) - Parsing agent extracts contacts from mixed text - Enrichment: Try Apollo first, Hunter fills gaps - Only enrich what needs it (missing email/LinkedIn/verification) - Auto-sync to ClickUp for outreach automation Key findings from 7-course testing: - LLM finds 6.1 contacts/course (vs Apollo 0.2) - Sources: PGA.org, CMAA, GCSAA, vendor sites, newsletters - Vendor breakthrough: Superintendent contacts on turf supplier sites - Course intelligence: Projects, vendors, awards for personalization Documentation: - progress.md: Complete testing journey and findings - llmtoclickup_v1.md: Full workflow spec with database design - apollo_org_enrich_api.md: API reference and limitations - agent-debugging skill: Docker env fix + Apollo API limitations Next: Build Render agents for automated enrichment pipeline 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 4e76635 commit 7999558

File tree

7 files changed

+3725
-0
lines changed

7 files changed

+3725
-0
lines changed

.claude/skills/agent-debugging/DOCKER_VALIDATION.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,89 @@ sleep 10
7171

7272
---
7373

74+
### ⚠️ Common Issue: Environment Variables Not Loading
75+
76+
**Problem:** Health check shows `"apollo_api": "missing"` despite .env file existing in project.
77+
78+
**Root Cause:**
79+
- docker-compose environment section uses `${VAR}` syntax to reference shell environment variables
80+
- These variables must exist in the shell environment when docker-compose runs
81+
- .env file must be **explicitly loaded** if not in the same directory as docker-compose.yml
82+
- Docker Compose does NOT automatically load .env from parent directories
83+
84+
**Symptoms:**
85+
```bash
86+
# Health check shows APIs as "missing"
87+
curl http://localhost:8001/health | jq '.dependencies'
88+
# {"apollo_api": "missing", "hunter_api": "missing"}
89+
90+
# Container logs show: "API key not found"
91+
92+
# Python in container can't access vars:
93+
docker exec container python -c "import os; print(os.getenv('APOLLO_API_KEY'))"
94+
# None
95+
```
96+
97+
**Solution:**
98+
99+
```bash
100+
# ❌ WRONG - .env not loaded from parent directory
101+
cd docker/
102+
docker-compose -f docker-compose.apollo.yml up -d
103+
104+
# ✅ CORRECT - explicitly specify .env file path
105+
cd docker/
106+
docker-compose --env-file ../.env -f docker-compose.apollo.yml up -d
107+
108+
# Alternative: Load into shell first
109+
export $(cat ../.env | xargs)
110+
docker-compose -f docker-compose.apollo.yml up -d
111+
```
112+
113+
**Verification:**
114+
115+
```bash
116+
# 1. Check health endpoint shows APIs configured
117+
curl http://localhost:8001/health | jq '.dependencies'
118+
119+
# Expected (correct):
120+
{
121+
"apollo_api": "configured",
122+
"hunter_api": "configured",
123+
"perplexity_api": "configured"
124+
}
125+
126+
# Not (wrong):
127+
{
128+
"apollo_api": "missing",
129+
"hunter_api": "missing"
130+
}
131+
132+
# 2. Test API actually works
133+
curl -X POST http://localhost:8001/enrich-course \
134+
-H "Content-Type: application/json" \
135+
-d '{"course_name": "Test Course", "state_code": "NC", "domain": "test.com", "use_test_tables": true}'
136+
137+
# Should return results, not "API key not found" error
138+
```
139+
140+
**Project Structure Context:**
141+
```
142+
project/
143+
├── .env # Main env file
144+
├── docker/
145+
│ ├── docker-compose.yml # Needs --env-file ../.env
146+
│ ├── docker-compose.apollo.yml # Needs --env-file ../.env
147+
│ └── Dockerfile
148+
└── golf-enrichment/
149+
├── agents/
150+
└── orchestrators/
151+
```
152+
153+
**Proven:** Oct 30, 2025 - Fixed 0% success → 100% working in golf enrichment Docker testing
154+
155+
---
156+
74157
### Phase 3: Health Check (2 min)
75158

76159
```bash

.claude/skills/agent-debugging/EXAMPLES.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,3 +1925,40 @@ SUCCESS: 80% (4/5 courses)
19251925
**Framework:** Agent Debugging Skill - 5-Phase Methodology
19261926
**Next:** Docker validation → Production deployment
19271927
**Files:** All documentation in `teams/golf-enrichment/testing/`
1928+
1929+
1930+
---
1931+
1932+
## Apollo API Plan Limitations (Oct 30, 2025)
1933+
1934+
### Organization Enrich Endpoints - Not Available on Basic Plan
1935+
1936+
**Error Received:**
1937+
```json
1938+
{
1939+
"error": "api/v1/organizations/enrich is not accessible with this api_key",
1940+
"error_code": "API_INACCESSIBLE"
1941+
}
1942+
```
1943+
1944+
**Status Code:** `403 Forbidden`
1945+
1946+
**Tested Endpoints:**
1947+
- ❌ `GET /api/v1/organizations/enrich` → 403
1948+
- ❌ `POST /api/v1/organizations/bulk_enrich` → 403
1949+
1950+
**Test Date:** Oct 30, 2025
1951+
1952+
**Conclusion:** Organization enrichment requires higher-tier Apollo plan
1953+
1954+
**Impact:**
1955+
- Cannot get organization IDs for more accurate people search
1956+
- Stuck with domain/name string matching (lower accuracy)
1957+
- Small clubs have 0-5% success rate with domain matching
1958+
1959+
**Workaround:** Use web scraping approach (PGA.org, club websites, vendor sites)
1960+
1961+
**Reference:** See `golf-enrichment/docs/apollo_org_enrich_api.md` for full API documentation
1962+
1963+
---
1964+
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
{
2+
"test_name": "NC 20 Course Batch Test - 80-90% Target",
3+
"created_at": "2025-10-30",
4+
"total_courses": 20,
5+
"batches": 4,
6+
"target_success_rate": "80-90%",
7+
8+
"batch_1_tier_a": [
9+
{
10+
"course_name": "Alamance Country Club",
11+
"state_code": "NC",
12+
"domain": "alamancecountryclub.com",
13+
"city": "Burlington"
14+
},
15+
{
16+
"course_name": "Anderson Creek Golf Club",
17+
"state_code": "NC",
18+
"domain": "andersoncreekgolf.com",
19+
"city": "Spring Lake"
20+
},
21+
{
22+
"course_name": "Asheboro Country Club",
23+
"state_code": "NC",
24+
"domain": "asheborocc.com",
25+
"city": "Asheboro"
26+
},
27+
{
28+
"course_name": "Asheville Municipal Golf Course",
29+
"state_code": "NC",
30+
"domain": "ashevillegc.com",
31+
"city": "Asheville"
32+
},
33+
{
34+
"course_name": "Ayden Golf & Country Club",
35+
"state_code": "NC",
36+
"domain": "aydengolf.com",
37+
"city": "Ayden"
38+
}
39+
],
40+
41+
"batch_2_tier_a": [
42+
{
43+
"course_name": "Bald Head Island Club",
44+
"state_code": "NC",
45+
"domain": "bhiclub.net",
46+
"city": "Southport"
47+
},
48+
{
49+
"course_name": "Bald Mountain Golf Course At Rumbling Bald Resort",
50+
"state_code": "NC",
51+
"domain": "rumblingbald.com",
52+
"city": "Lake Lure"
53+
},
54+
{
55+
"course_name": "Ballantyne Country Club",
56+
"state_code": "NC",
57+
"domain": "ballantyneclub.com",
58+
"city": "Charlotte"
59+
},
60+
{
61+
"course_name": "Balsam Mountain Preserve",
62+
"state_code": "NC",
63+
"domain": "balsammountainpreserve.com",
64+
"city": "Sylva"
65+
},
66+
{
67+
"course_name": "Baywood Golf Club",
68+
"state_code": "NC",
69+
"domain": "baywoodgc.com",
70+
"city": "Fayetteville"
71+
}
72+
],
73+
74+
"batch_3_tier_b": [
75+
{
76+
"course_name": "Beacon Ridge Golf & CC",
77+
"state_code": "NC",
78+
"domain": "beaconridgecc.com",
79+
"city": "West End"
80+
},
81+
{
82+
"course_name": "Bear Lake Golf Club",
83+
"state_code": "NC",
84+
"domain": "bearlakereserve.com",
85+
"city": "Tuckasegee"
86+
},
87+
{
88+
"course_name": "Bear Trail Golf Club",
89+
"state_code": "NC",
90+
"domain": "beartrailgolf.com",
91+
"city": "Jacksonville"
92+
},
93+
{
94+
"course_name": "Beechwood Country Club",
95+
"state_code": "NC",
96+
"domain": "beechwoodcc.com",
97+
"city": "Ahoskie"
98+
},
99+
{
100+
"course_name": "Bentwinds Golf & Country Club",
101+
"state_code": "NC",
102+
"domain": "bentwinds.org",
103+
"city": "Fuquay Varina"
104+
}
105+
],
106+
107+
"batch_4_tier_b": [
108+
{
109+
"course_name": "Bermuda Run Country Club West Course",
110+
"state_code": "NC",
111+
"domain": "bermudaruncc.com",
112+
"city": "Advance"
113+
},
114+
{
115+
"course_name": "Birchwood Country Club",
116+
"state_code": "NC",
117+
"domain": "birchwoodcc.net",
118+
"city": "Nashville"
119+
},
120+
{
121+
"course_name": "Alamance Country Club",
122+
"state_code": "NC",
123+
"domain": "alamancecountryclub.com",
124+
"city": "Burlington"
125+
},
126+
{
127+
"course_name": "Anderson Creek Golf Club",
128+
"state_code": "NC",
129+
"domain": "andersoncreekgolf.com",
130+
"city": "Spring Lake"
131+
},
132+
{
133+
"course_name": "Asheboro Country Club",
134+
"state_code": "NC",
135+
"domain": "asheborocc.com",
136+
"city": "Asheboro"
137+
}
138+
],
139+
140+
"notes": {
141+
"tier_a_description": "Batches 1-2: First 10 courses alphabetically",
142+
"tier_b_description": "Batches 3-4: Next 10 courses alphabetically",
143+
"test_tables": "Uses use_test_tables=true for safety",
144+
"batch_size": "5 courses per batch for manageable testing"
145+
}
146+
}

0 commit comments

Comments
 (0)