feat: add Leads tab and Hide Assessed filter in Browse

- db.py: get_enriched() accepts ai_only + lead_quality params
- main.py: /api/enriched exposes ai_only + lead_quality query params;
  new /api/export/leads endpoint produces CSV with contacts + pitch
- index.html:
  - New "Leads 🤖" tab shows all AI-assessed domains with contacts
    (quality/country/limit filters, per-row 📋 copy email, 🔍 modal,
    CSV export, pagination, auto-refreshes every 3s)
  - Browse: "Hide assessed" checkbox filters out already-processed
    domains so you can focus on fresh targets
  - Poll cycle refreshes Leads tab when active

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 18:57:15 +02:00
parent 22eae3f9b7
commit 63f961dc80
3 changed files with 188 additions and 9 deletions

View File

@@ -306,7 +306,8 @@ async def get_stats():
# ── Enrichment helpers ───────────────────────────────────────────────────────
async def get_enriched(min_score=0, cms=None, country=None, kit_digital=None, page=1, limit=100):
async def get_enriched(min_score=0, cms=None, country=None, kit_digital=None,
ai_only=False, lead_quality=None, page=1, limit=100):
offset = (page - 1) * limit
conditions = ["score >= ?"]
params: list = [min_score]
@@ -319,6 +320,11 @@ async def get_enriched(min_score=0, cms=None, country=None, kit_digital=None, pa
if kit_digital is not None:
conditions.append("kit_digital = ?")
params.append(1 if kit_digital else 0)
if ai_only:
conditions.append("ai_lead_quality IS NOT NULL")
if lead_quality:
conditions.append("ai_lead_quality = ?")
params.append(lead_quality.upper())
where = "WHERE " + " AND ".join(conditions)
async with aiosqlite.connect(SQLITE_PATH) as db:
db.row_factory = aiosqlite.Row