import type { GooglePlaceCandidate } from "./lead-discovery-google"; type AgentRunLike = { status: string; updatedAt?: number; }; type LeadDiscoveryCounterInput = { leadsFound: number; leadsCreated: number; errors: number; }; type LeadDiscoveryContactInput = { websiteDomain?: string | null; phone?: string | null; }; type LeadDiscoveryLeadRecordInput = { campaignId: TCampaignId; runId: TRunId; niche: string; postalCode: string; candidate: GooglePlaceCandidate; now: number; }; function optionalString(value: string | null) { return value && value.trim().length > 0 ? value : undefined; } function optionalNumber(value: number | null) { return typeof value === "number" && Number.isFinite(value) ? value : undefined; } export const PENDING_AGENT_RUN_GRACE_MS = 10 * 60 * 1000; export function isStalePendingAgentRun(run: AgentRunLike, now: number) { const updatedAt = typeof run.updatedAt === "number" ? run.updatedAt : 0; return ( run.status === "pending" && updatedAt > 0 && now - updatedAt > PENDING_AGENT_RUN_GRACE_MS ); } export function canStartAgentRun(runs: AgentRunLike[], now = Date.now()) { return !runs.some((run) => { if (run.status === "running") { return true; } return run.status === "pending" && !isStalePendingAgentRun(run, now); }); } export function buildLeadDiscoveryCounters(input: LeadDiscoveryCounterInput) { return { leadsFound: input.leadsFound, leadsCreated: input.leadsCreated, auditsCreated: 0, outreachPrepared: 0, errors: input.errors, }; } export function getLeadDiscoveryContactStatus( input: LeadDiscoveryContactInput, ) { if (input.websiteDomain || input.phone) { return "new"; } return "missing_contact"; } export function buildLeadDiscoveryLeadRecord< TCampaignId extends string, TRunId extends string, >(input: LeadDiscoveryLeadRecordInput) { const lead: { campaignId: TCampaignId; discoveryRunId: TRunId; companyName: string; niche: string; address: string; postalCode: string; googlePlaceId: string; googleMapsUrl?: string; googlePrimaryType?: string; googleTypes: string[]; googleRating?: number; googleUserRatingCount?: number; googleBusinessStatus?: string; sourceProvider: "google_places"; sourceFetchedAt: number; websiteUrl?: string; websiteDomain?: string; phone?: string; priority: "medium"; contactStatus: "new" | "missing_contact"; duplicateStatus: "unique"; blacklistStatus: "clear"; createdAt: number; updatedAt: number; } = { campaignId: input.campaignId, discoveryRunId: input.runId, companyName: input.candidate.businessName, niche: input.niche, address: input.candidate.address, postalCode: input.postalCode, googlePlaceId: input.candidate.placeId, googleTypes: input.candidate.googleTypes, sourceProvider: input.candidate.sourceProvider, sourceFetchedAt: input.candidate.sourceFetchedAt, priority: "medium", contactStatus: getLeadDiscoveryContactStatus({ websiteDomain: input.candidate.websiteDomain, phone: input.candidate.phone, }), duplicateStatus: "unique", blacklistStatus: "clear", createdAt: input.now, updatedAt: input.now, }; const googleMapsUrl = optionalString(input.candidate.googleMapsUrl); const googlePrimaryType = optionalString(input.candidate.googlePrimaryType); const googleRating = optionalNumber(input.candidate.rating); const googleUserRatingCount = optionalNumber(input.candidate.userRatingCount); const googleBusinessStatus = optionalString(input.candidate.businessStatus); const websiteUrl = optionalString(input.candidate.websiteUrl); const websiteDomain = optionalString(input.candidate.websiteDomain); const phone = optionalString(input.candidate.phone); if (googleMapsUrl !== undefined) { lead.googleMapsUrl = googleMapsUrl; } if (googlePrimaryType !== undefined) { lead.googlePrimaryType = googlePrimaryType; } if (googleRating !== undefined) { lead.googleRating = googleRating; } if (googleUserRatingCount !== undefined) { lead.googleUserRatingCount = googleUserRatingCount; } if (googleBusinessStatus !== undefined) { lead.googleBusinessStatus = googleBusinessStatus; } if (websiteUrl !== undefined) { lead.websiteUrl = websiteUrl; } if (websiteDomain !== undefined) { lead.websiteDomain = websiteDomain; } if (phone !== undefined) { lead.phone = phone; } return lead; }