diff --git a/app/actions/leads.ts b/app/actions/leads.ts index b2c378c0..65ff587a 100644 --- a/app/actions/leads.ts +++ b/app/actions/leads.ts @@ -79,7 +79,7 @@ export async function findLeadsAction(input: { } let added = 0; - let scanning = 0; + const scanning = 0; for (const candidate of found.prospects.slice(0, limit)) { const res = await researchProspect({ userId: auth.userId, @@ -87,11 +87,15 @@ export async function findLeadsAction(input: { url: candidate.url, discoveredVia: candidate.via, discoveryLabel: candidate.label, + // Finding leads for a project does not scan them. The scan exists to + // supply findings for the CrawlProof audit pitch, and firing one at + // every discovered business spends worker time on evidence nobody is + // going to cite — and points a scanner at people who only turned up in + // a search. Campaigns that do pitch an audit turn scanning back on + // explicitly. + skipScan: true, }); - if (res.status === "scanning") { - scanning += 1; - added += 1; - } else if (res.status === "researched") { + if (res.status === "researched") { added += 1; } } @@ -101,9 +105,7 @@ export async function findLeadsAction(input: { ok: true, added, scanning, - note: scanning - ? `${added} leads added — ${scanning} are scanning now. Refresh in a minute to see scores.` - : `${added} leads added.`, + note: `${added} leads added.`, }; } diff --git a/components/leads/campaign-panel.tsx b/components/leads/campaign-panel.tsx index 22a2321c..e3851403 100644 --- a/components/leads/campaign-panel.tsx +++ b/components/leads/campaign-panel.tsx @@ -76,7 +76,11 @@ export function CampaignPanel({ const [pitchIntro, setPitchIntro] = useState(""); const [pitchAsk, setPitchAsk] = useState(""); const [pitchFacts, setPitchFacts] = useState(""); - const [scanProspects, setScanProspects] = useState(true); + // Scanning is off by default now: a project-level campaign is pitching the + // project's own offer, not a CrawlProof audit, so there is nothing for a + // scan of the prospect to contribute. Selecting the audit pitch turns it + // back on, because that pitch is built from findings. + const [scanProspects, setScanProspects] = useState(false); const [senderName, setSenderName] = useState(""); const [replyTo, setReplyTo] = useState(""); diff --git a/components/leads/lead-finder.tsx b/components/leads/lead-finder.tsx index 796c0bca..c5b9c6f8 100644 --- a/components/leads/lead-finder.tsx +++ b/components/leads/lead-finder.tsx @@ -6,9 +6,14 @@ import { findLeadsAction } from "@/app/actions/leads"; /** * The "add leads" box. A search query finds businesses; a directory URL mines - * one page's outbound links. Both queue a free scan per domain, because a - * lead with no report is not a lead — every claim in the eventual email has - * to trace back to one. + * one page's outbound links. + * + * Neither scans the businesses it finds. Scanning exists to supply findings + * for the CrawlProof audit pitch, and a project pitching its own offer has no + * use for them — so firing a scan at every discovered domain would spend + * worker time on evidence nobody cites, and point a scanner at people whose + * only involvement was appearing in a search. A campaign that does pitch an + * audit turns scanning back on explicitly. */ export function LeadFinder({ projectId }: { projectId: string }) { const router = useRouter(); @@ -88,7 +93,7 @@ export function LeadFinder({ projectId }: { projectId: string }) {

{mode === "query" - ? "Finds businesses, then queues a free scan of each so the pitch can cite real findings." + ? "Finds businesses and looks up a contact address for each. It does not scan them." : "Every outbound link on that page becomes a candidate. Platforms and aggregators are filtered out."}

{note &&

{note}

}