import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import path from "node:path"; import test from "node:test"; const leadDiscoveryPath = path.join(process.cwd(), "convex", "leadDiscovery.ts"); const leadDiscoverySource = readFileSync(leadDiscoveryPath, "utf8"); function hasPattern(source: string, pattern: RegExp) { return pattern.test(source); } function extractExportSource(name: string) { const marker = `export const ${name} = `; const declarationIndex = leadDiscoverySource.indexOf(marker); assert.notEqual(declarationIndex, -1, `Expected declaration for ${name}`); const openBraceIndex = leadDiscoverySource.indexOf("{", declarationIndex); let depth = 0; let end = -1; for (let index = openBraceIndex; index < leadDiscoverySource.length; index++) { const char = leadDiscoverySource[index]; if (char === "{") { depth += 1; } else if (char === "}") { depth -= 1; if (depth === 0) { end = index; break; } } } assert.notEqual(end, -1, `Expected balanced braces for ${name}`); return leadDiscoverySource.slice(openBraceIndex, end + 1); } test("startCampaignRun checks active campaign runs via by_type_and_status", () => { const source = extractExportSource("startCampaignRun"); assert.equal( hasPattern( source, /withIndex\(\s*"by_type_and_status"\s*,\s*\(q\)\s*=>[\s\S]*?q\.eq\("type",\s*"campaign"\)\.eq\("status",\s*"running"\),?[\s\S]*?\)/, ), true, "Campaign starts should only consider running campaign-type runs as blockers", ); }); test("persistDiscoveredLeads does not schedule website enrichment jobs directly", () => { const source = extractExportSource("persistDiscoveredLeads"); assert.equal( source.includes("ctx.scheduler.runAfter"), false, "Lead persistence must not call runAfter", ); }); test("persistDiscoveredLeads backfills missing emails on duplicate re-runs only", () => { const source = extractExportSource("persistDiscoveredLeads"); assert.match(source, /getUsableContactEmail\(candidate\)/); assert.match(source, /duplicateLeadForEmailBackfill/); assert.match(source, /ctx\.db\.patch\(\s*duplicateLeadForEmailBackfill\._id/); assert.match(source, /normalizedEmail:\s*usableEmail\.email/); assert.match(source, /email:\s*usableEmail\.email/); assert.match(source, /contactStatus\s*=\s*"new"/); assert.match(source, /contactStatus\s*!==\s*"do_not_contact"/); assert.match(source, /blacklistStatus\s*!==\s*"blocked"/); assert.match(source, /duplicateByEmailRows\.length\s*===\s*0/); assert.doesNotMatch(source, /internal\.websiteEnrichment\.queueLeadEnrichment/); assert.doesNotMatch(source, /internal\.pageSpeed\.queueLeadPageSpeedAudit/); }); test("processCampaignRun uses Local Business Data and does not schedule website enrichment", () => { const source = extractExportSource("processCampaignRun"); const persistIndex = source.indexOf( "internal.leadDiscovery.persistDiscoveredLeads", ); const queueCall = source.indexOf("internal.websiteEnrichment.queueLeadEnrichment"); assert.notEqual(persistIndex, -1, "processCampaignRun should persist discovered leads"); assert.equal( queueCall, -1, "Campaign discovery must not schedule website enrichment in the SaaS flow", ); assert.equal( source.includes("GOOGLE_GEOCODING_API_KEY") || source.includes("GOOGLE_PLACES_API_KEY"), false, "Campaign discovery should no longer require Google lead-discovery keys", ); assert.match( source, /LOCAL_BUSINESS_DATA_API_KEY/, "Campaign discovery should read the Local Business Data API key", ); assert.match( source, /local_business_data/, "Campaign discovery should record Local Business Data as the source", ); });