fix: Maps-Vault-Sync sofort nach Google Maps, nicht erst nach Anymailfinder
- Google Maps Ergebnisse werden direkt nach der Suche in LeadVault gespeichert - Anymailfinder-Fehler führen nicht mehr zum Datenverlust - Bessere Fehlermeldungen: echter Fehlertext statt hardcoded Message - Anymailfinder-Fehlermeldung auf Deutsch Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,7 +74,7 @@ async function runMapsEnrich(
|
|||||||
data: { totalLeads: places.length },
|
data: { totalLeads: places.length },
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. Store raw Google Maps results immediately
|
// 2. Store raw Google Maps results + immediately sink to LeadVault
|
||||||
for (const place of places) {
|
for (const place of places) {
|
||||||
await prisma.leadResult.create({
|
await prisma.leadResult.create({
|
||||||
data: {
|
data: {
|
||||||
@@ -91,10 +91,24 @@ async function runMapsEnrich(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sink Google Maps results to vault immediately (before enrichment)
|
||||||
|
// so they're available even if Anymailfinder fails
|
||||||
|
await sinkLeadsToVault(
|
||||||
|
places.map(p => ({
|
||||||
|
domain: p.domain,
|
||||||
|
companyName: p.name || null,
|
||||||
|
phone: p.phone,
|
||||||
|
address: p.address,
|
||||||
|
})),
|
||||||
|
"maps",
|
||||||
|
params.queries.join(", "),
|
||||||
|
jobId,
|
||||||
|
);
|
||||||
|
|
||||||
// 3. Optionally enrich with Anymailfinder
|
// 3. Optionally enrich with Anymailfinder
|
||||||
if (params.enrichEmails && places.length > 0) {
|
if (params.enrichEmails && places.length > 0) {
|
||||||
const anymailKey = await getApiKey("anymailfinder");
|
const anymailKey = await getApiKey("anymailfinder");
|
||||||
if (!anymailKey) throw new Error("Anymailfinder key missing");
|
if (!anymailKey) throw new Error("Anymailfinder API-Key fehlt — bitte in den Einstellungen eintragen");
|
||||||
const domains = places.filter(p => p.domain).map(p => p.domain!);
|
const domains = places.filter(p => p.domain).map(p => p.domain!);
|
||||||
|
|
||||||
// Map domain → placeId for updating results
|
// Map domain → placeId for updating results
|
||||||
@@ -142,35 +156,29 @@ async function runMapsEnrich(
|
|||||||
where: { id: jobId },
|
where: { id: jobId },
|
||||||
data: { status: "complete", emailsFound, totalLeads: places.length },
|
data: { status: "complete", emailsFound, totalLeads: places.length },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update vault entries with enrichment results
|
||||||
|
await sinkLeadsToVault(
|
||||||
|
enrichResults
|
||||||
|
.filter(r => r.email)
|
||||||
|
.map(r => ({
|
||||||
|
domain: r.domain,
|
||||||
|
contactName: r.person_full_name || null,
|
||||||
|
contactTitle: r.person_job_title || null,
|
||||||
|
email: r.email || null,
|
||||||
|
linkedinUrl: r.person_linkedin_url || null,
|
||||||
|
emailConfidence: r.valid_email ? 1.0 : r.email_status === "risky" ? 0.5 : 0,
|
||||||
|
})),
|
||||||
|
"maps",
|
||||||
|
params.queries.join(", "),
|
||||||
|
jobId,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
await prisma.job.update({
|
await prisma.job.update({
|
||||||
where: { id: jobId },
|
where: { id: jobId },
|
||||||
data: { status: "complete", totalLeads: places.length },
|
data: { status: "complete", totalLeads: places.length },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync to LeadVault
|
|
||||||
const finalResults = await prisma.leadResult.findMany({ where: { jobId } });
|
|
||||||
await sinkLeadsToVault(
|
|
||||||
finalResults.map(r => {
|
|
||||||
let src: { phone?: string; address?: string } = {};
|
|
||||||
try { src = JSON.parse(r.source || "{}"); } catch { /* ignore */ }
|
|
||||||
return {
|
|
||||||
domain: r.domain,
|
|
||||||
companyName: r.companyName,
|
|
||||||
contactName: r.contactName,
|
|
||||||
contactTitle: r.contactTitle,
|
|
||||||
email: r.email,
|
|
||||||
linkedinUrl: r.linkedinUrl,
|
|
||||||
emailConfidence: r.confidence,
|
|
||||||
phone: src.phone || null,
|
|
||||||
address: src.address || null,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
"maps",
|
|
||||||
params.queries.join(", "),
|
|
||||||
jobId,
|
|
||||||
);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const message = err instanceof Error ? err.message : String(err);
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
await prisma.job.update({
|
await prisma.job.update({
|
||||||
|
|||||||
@@ -121,14 +121,14 @@ export default function MapsPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/jobs/${id}/status`);
|
const res = await fetch(`/api/jobs/${id}/status`);
|
||||||
const data = await res.json() as {
|
const data = await res.json() as {
|
||||||
status: string; totalLeads: number; emailsFound: number; results: ResultRow[];
|
status: string; totalLeads: number; emailsFound: number; results: ResultRow[]; error?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (data.totalLeads > 0 && data.emailsFound === 0 && enrichEmails) {
|
if (data.totalLeads > 0 && data.emailsFound === 0 && enrichEmails) {
|
||||||
phase = "Enriching with Anymailfinder...";
|
phase = "Anreicherung mit Anymailfinder...";
|
||||||
}
|
}
|
||||||
if (data.emailsFound > 0) {
|
if (data.emailsFound > 0) {
|
||||||
phase = `Found ${data.emailsFound} emails so far...`;
|
phase = `${data.emailsFound} E-Mails gefunden...`;
|
||||||
}
|
}
|
||||||
|
|
||||||
setProgress({
|
setProgress({
|
||||||
@@ -146,12 +146,13 @@ export default function MapsPage() {
|
|||||||
if (data.status === "complete") {
|
if (data.status === "complete") {
|
||||||
setStage("done");
|
setStage("done");
|
||||||
const msg = enrichEmails
|
const msg = enrichEmails
|
||||||
? `Done! ${data.totalLeads} companies found, ${data.emailsFound} emails enriched`
|
? `Fertig! ${data.totalLeads} Unternehmen gefunden, ${data.emailsFound} E-Mails angereichert`
|
||||||
: `Done! ${data.totalLeads} companies found`;
|
: `Fertig! ${data.totalLeads} Unternehmen gefunden`;
|
||||||
toast.success(msg);
|
toast.success(msg);
|
||||||
} else {
|
} else {
|
||||||
setStage("failed");
|
setStage("failed");
|
||||||
toast.error("Job failed. Check your Google Maps API key in Settings.");
|
const errMsg = data.error || "Unbekannter Fehler";
|
||||||
|
toast.error(`Job fehlgeschlagen: ${errMsg}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user