Files
lead-scraper/prisma/schema.prisma
Timo Uttenweiler 042fbeb672 feat: LeadVault - zentrale Lead-Datenbank mit CRM-Funktionen
- 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>
2026-03-20 17:33:12 +01:00

98 lines
2.2 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
}
model ApiCredential {
id String @id @default(cuid())
service String @unique
value String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Job {
id String @id @default(cuid())
type String
status String @default("pending")
config String @default("{}")
totalLeads Int @default(0)
emailsFound Int @default(0)
error String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
results LeadResult[]
}
model LeadResult {
id String @id @default(cuid())
jobId String
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade)
companyName String?
domain String?
contactName String?
contactTitle String?
email String?
confidence Float?
linkedinUrl String?
source String?
createdAt DateTime @default(now())
}
model Lead {
id String @id @default(cuid())
domain String?
companyName String?
contactName String?
contactTitle String?
email String?
linkedinUrl String?
phone String?
sourceTab String
sourceTerm String?
sourceJobId String?
serpTitle String?
serpSnippet String?
serpRank Int?
serpUrl String?
emailConfidence Float?
status String @default("new")
priority String @default("normal")
notes String?
tags String?
country String?
headcount String?
industry String?
capturedAt DateTime @default(now())
contactedAt DateTime?
updatedAt DateTime @updatedAt
events LeadEvent[]
@@index([domain])
@@index([status])
@@index([sourceTab])
@@index([capturedAt])
@@index([email])
}
model LeadEvent {
id String @id @default(cuid())
leadId String
lead Lead @relation(fields: [leadId], references: [id], onDelete: Cascade)
event String
at DateTime @default(now())
@@index([leadId])
}