- Apply Stitch design system to leadspeicher, suche, TopBar, globals.css
- Add Energieversorger queue campaign (Netzbetreiber, Fernwärme, Industriepark)
with BW + Bayern priority, tracks usage per term+location combo
- Remove TopBar right-side actions (Leads finden, bell, settings)
- Remove mode tabs from manual search, rename KI button
- Fix Google Fonts @import order (move to <link> in layout.tsx)
- Add cursor-pointer globally via globals.css
- Responsive fixes for campaign buttons and KI button
- Fix .dockerignore to exclude .env from image build
- Add stadtwerke-cities API + city data (50 cities per Bundesland)
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>
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>
- 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>
- 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>