fix: search race condition + brand detection + contacts + reassess

- loadDomains(): add generation counter so stale auto-advance fetches
  cannot overwrite a newer user-triggered search result; snapshot filter
  state before the first await so URL reflects what was requested; add
  HTTP status check so backend errors surface as toasts rather than
  silent empty results; auto-advance now calls loadDomains() without
  await so the counter increments correctly per page advance

- beauty_ai: word-boundary regex for short brands (≤5 chars) to stop
  'ref' matching 'reference'/'refresh'/'prefer' etc.; merge phones,
  whatsapp and social_links from site_analyzer directly into result
  (more reliable than AI extraction); add contact_whatsapp and
  contact_social fields to AI JSON schema

- db: add requeue_beauty() for re-assessing already-assessed domains

- beauty_main: /api/beauty/reassess/batch endpoint using requeue_beauty

- index.html: Re-assess Selected bulk button, per-row ↺ button in
  Browse and Pipeline, WhatsApp + social links in Pipeline contact panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-07 11:06:58 +02:00
parent be0fbb502c
commit d9ece58e12
4 changed files with 141 additions and 27 deletions

View File

@@ -22,7 +22,7 @@ load_dotenv()
from app.db import (
SQLITE_PATH, init_db, get_stats, get_domains, get_enriched,
build_duckdb_index, index_status,
queue_beauty, get_beauty_queue_status, save_beauty_assessment, get_beauty_leads,
queue_beauty, requeue_beauty, get_beauty_queue_status, save_beauty_assessment, get_beauty_leads,
save_prescreen_results,
)
from app.validator import start_validator, stop_validator, get_validator_status
@@ -277,6 +277,17 @@ async def beauty_assess_batch(body: dict):
return {"queued": len(domains_list)}
@app.post("/api/beauty/reassess/batch")
async def beauty_reassess_batch(body: dict):
"""Re-queue domains for fresh assessment, resetting any existing result."""
domains_list = body.get("domains", [])
if not domains_list:
return JSONResponse({"error": "no domains provided"}, status_code=400)
await requeue_beauty(domains_list)
_start_beauty_worker()
return {"requeued": len(domains_list)}
@app.post("/api/beauty/worker/restart")
async def beauty_worker_restart():
_start_beauty_worker()