Button erscheint in der Ergebnis-Headerzeile sobald vorhandene Leads
dabei sind. Löscht diese aus dem Leadspeicher und zeigt Bilanz-Toast.
Verschwindet nach Ausführung. Checkbox vor der Suche entfernt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Suchergebnis-Filter als Tabs: [Alle (46)] [Nur neue (X)] — beide klickbar
- Checkbox "Nur neue Leads speichern" erscheint vor der Suche
- Bei aktivierter Option: nach Abschluss werden vorhandene Leads
automatisch aus dem Leadspeicher gelöscht, Toast zeigt Bilanz
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maps-Ergebnisse ohne Domain werden vor Speicherung herausgefiltert.
sinkLeadsToVault überspringt Leads ohne Domain komplett.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Anymailfinder-Fehler (z.B. 402) markiert Job nicht mehr als failed.
Maps- und SERP-Jobs schließen als complete ab und liefern die gefundenen
Unternehmen ohne Kontaktdaten — SERP-Supplement triggert danach normal.
- maps-enrich: Anymailfinder in eigenem try-catch, Fehler → complete
- serp-enrich: SERP-Rohdaten zuerst speichern, dann Enrichment versuchen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wenn Google Maps weniger Leads findet als angefragt, wird automatisch
eine optimierte Suchanfrage via GPT-4.1 generiert und als SERP-Job
gestartet, um die Lücke zu füllen. Die KI-Query wird im LoadingCard
angezeigt. Fallback auf Original-Query wenn kein OpenAI-Key konfiguriert.
- lib/services/openai.ts: GPT-4.1 Query-Generator
- app/api/search/supplement: neuer Endpoint (GPT + SERP-Job)
- LoadingCard: ruft /api/search/supplement statt direkt SERP
- apiKey.ts + .env.local.example: openai Key-Support
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Progressbar geht nie mehr rückwärts (Math.min-Cap entfernt)
- E-Mails-suchen-Phase wird immer kurz angezeigt bevor Fertig
- SERP-Supplement startet automatisch wenn Maps < Zielanzahl liefert
- Suchergebnisse bleiben nach Abschluss sichtbar (kein Redirect)
- Dedup in leadVault strikt nach Domain (verhindert Duplikate)
- isNew-Flag pro Result (Batch-Query gegen bestehende Vault-Domains)
- Nur-neue-Filter + vorhanden-Badge in Suchergebnissen
- Einzeln und Bulk löschen aus Suchergebnissen + Leadspeicher
- Fehlermeldung zeigt echten API-Fehler (z.B. 402 Anymailfinder)
- SERP-Supplement aus /api/search entfernt (LoadingCard übernimmt)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Always use Google Maps (max 60 per call)
- If count > 60: fire SERP job in background for additional results
- Dedup handled automatically by LeadVault domain upsert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
- GET /api/leads/search-terms: distinct Suchbegriffe aus DB
- Filter-Bar: Suchbegriff-Chips (amber), klickbar zum Filtern
- Tabelle: Suchbegriff-Spalte mit Chip — Klick filtert direkt
- Mehrere Suchbegriffe gleichzeitig filterbar (OR-Logik)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wenn current=0 und total>0: Shimmer-Animation statt leerer Balken
- Bouncing Dots + "Warte auf Anymailfinder-Server..." Text
- Hinweis "dauert ca. 1–3 Min. für X Domains"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CSV: UTF-8 BOM + \r\n Zeilenenden → Umlaute in Excel korrekt
- CSV: deutsche Spaltennamen, Tags als kommagetrennte Liste
- Excel (.xlsx): nativer Export via xlsx-Library mit Spaltenbreiten
- Export-Dropdown: CSV und Excel jeweils für aktuelle Ansicht und nur mit E-Mail
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Prisma-Schema: Lead + LeadEvent Modelle (Migration 20260320)
- lib/services/leadVault.ts: sinkLeadsToVault mit Deduplizierung
- Auto-Sync: alle 4 Pipelines schreiben Leads in LeadVault
- GET /api/leads: Filter, Sortierung, Pagination (Server-side)
- PATCH/DELETE /api/leads/[id]: Status, Priorität, Tags, Notizen
- POST /api/leads/bulk: Bulk-Aktionen für mehrere Leads
- GET /api/leads/stats: Statistiken + 7-Tage-Sparkline
- POST /api/leads/quick-serp: SERP-Capture ohne Enrichment
- GET /api/leads/export: CSV-Export mit allen Feldern
- app/leadvault/page.tsx: vollständige UI mit Stats, Quick SERP,
Filter-Leiste, sortierbare Tabelle, Bulk-Aktionen, Side Panel
- Sidebar: LeadVault-Eintrag mit Live-Badge (neue Leads)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Neuer getApiKey() Helper: prüft zuerst ENV-Vars, dann DB
- Alle Job-Routes nutzen getApiKey() statt direktem DB-Lookup
- Credentials-Status berücksichtigt ENV-Vars (Sidebar-Haken)
- .env.local.example: Platzhalter für alle 4 API Keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nur noch eine Kategorie gleichzeitig wählbar (Array → einzelner Wert)
- ceo-Label: "CEO / Owner / President / Founder" mit Empfohlen-Badge
- API-Aufruf sendet [category] statt categories[]
- Überflüssige Validierungen entfernt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Alle Seiten (AirScale, LinkedIn, SERP, Ergebnisse, Einstellungen) auf Deutsch
- Gemeinsame Komponenten übersetzt: StatusBadge, ResultsTable-Spalten, FileDropZone, ExportButtons
- Sidebar API-Status-Label und TopBar-Breadcrumbs auf Deutsch
- Alle Toast-Nachrichten und Fehlermeldungen auf Deutsch
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New Maps page with keyword + region chips, German city presets, query preview, enrichment toggle
- Google Maps Places API (New) service with pagination and deduplication
- maps-enrich job route: Maps search → store raw leads → optional Anymailfinder bulk enrichment
- Settings: Google Maps API key credential card with Places API instructions
- Sidebar: MapPin nav item + googlemaps credential status indicator
- Results: maps job type with MapPin icon (text-green-400)
- Credentials API: added googlemaps to SERVICES array and test endpoint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>