export type LeadSyncStatus = | "pending" | "sent" | "synced" | "failed" | "skipped" export type IngestLeadInput = { host: string tenantSlug?: string tenantName?: string tenantDomains?: string[] source?: string idempotencyKey: string name: string firstName?: string lastName?: string email: string phone: string company?: string service?: string intent?: string page?: string url?: string message: string employeeCount?: string machineType?: string machineCount?: string serviceTextConsent?: boolean marketingTextConsent?: boolean consentVersion?: string consentCapturedAt?: string consentSourcePage?: string } export type IngestLeadResult = { inserted: boolean leadId: string idempotencyKey: string tenantId: string } function getConvexUrl() { return ( process.env.CONVEX_URL || process.env.NEXT_PUBLIC_CONVEX_URL || "" ).replace(/\/+$/, "") } async function callConvex(path: string, args: Record) { const convexUrl = getConvexUrl() if (!convexUrl) { throw new Error("CONVEX_URL is not configured") } const endpoint = `${convexUrl}/api/mutation` const response = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json", }, cache: "no-store", body: JSON.stringify({ path, args, format: "json", }), }) const body = await response.json().catch(() => null) if (!response.ok || body?.status === "error") { const message = body?.errorMessage || `Convex call failed (${response.status})` throw new Error(message) } return body?.value } export function isConvexConfigured() { return getConvexUrl().length > 0 } export async function ingestLead( input: IngestLeadInput ): Promise { const value = await callConvex("leads:ingestLead", input) return value as IngestLeadResult } export async function updateLeadSyncStatus(input: { leadId: string usesendStatus?: LeadSyncStatus ghlStatus?: LeadSyncStatus error?: string }) { return await callConvex("leads:updateLeadSyncStatus", input) }