diff --git a/web/src/padelnomics/leads/routes.py b/web/src/padelnomics/leads/routes.py index fb8cb04..c65d568 100644 --- a/web/src/padelnomics/leads/routes.py +++ b/web/src/padelnomics/leads/routes.py @@ -346,8 +346,8 @@ async def quote_request(): previous_supplier_contact, services_needed, additional_info, contact_name, contact_email, contact_phone, contact_company, stakeholder_type, - heat_score, status, credit_cost, token, created_at) - VALUES (?, 'quote', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", + heat_score, status, credit_cost, token, created_at, visible_from) + VALUES (?, 'quote', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now', '+2 hours'))""", ( user_id, form.get("court_count", 0), @@ -522,7 +522,7 @@ async def verify_quote(): credit_cost = compute_credit_cost(dict(lead)) now = utcnow_iso() await execute( - "UPDATE lead_requests SET status = 'new', verified_at = ?, credit_cost = ? WHERE id = ?", + "UPDATE lead_requests SET status = 'new', verified_at = ?, credit_cost = ?, visible_from = datetime('now', '+2 hours') WHERE id = ?", (now, credit_cost, lead["id"]), ) diff --git a/web/src/padelnomics/migrations/versions/0023_lead_visible_from.py b/web/src/padelnomics/migrations/versions/0023_lead_visible_from.py new file mode 100644 index 0000000..96fe2b3 --- /dev/null +++ b/web/src/padelnomics/migrations/versions/0023_lead_visible_from.py @@ -0,0 +1,9 @@ +"""Migration 0023: Add visible_from to lead_requests for 2-hour admin review window.""" + + +def up(conn) -> None: + conn.execute("ALTER TABLE lead_requests ADD COLUMN visible_from TEXT") + # Backfill: existing verified leads are already past review — make them visible immediately + conn.execute( + "UPDATE lead_requests SET visible_from = created_at WHERE status = 'new' AND verified_at IS NOT NULL" + ) diff --git a/web/src/padelnomics/suppliers/routes.py b/web/src/padelnomics/suppliers/routes.py index 0ae31b2..f38c442 100644 --- a/web/src/padelnomics/suppliers/routes.py +++ b/web/src/padelnomics/suppliers/routes.py @@ -513,7 +513,7 @@ async def signup_success(): async def _get_lead_feed_data(supplier, country="", heat="", timeline="", q="", limit=50): """Shared query for lead feed — used by standalone and dashboard.""" - wheres = ["lr.lead_type = 'quote'", "lr.status = 'new'", "lr.verified_at IS NOT NULL"] + wheres = ["lr.lead_type = 'quote'", "lr.status = 'new'", "lr.verified_at IS NOT NULL", "lr.visible_from <= datetime('now')"] params: list = [] if country: diff --git a/web/src/padelnomics/worker.py b/web/src/padelnomics/worker.py index b543d10..387987a 100644 --- a/web/src/padelnomics/worker.py +++ b/web/src/padelnomics/worker.py @@ -567,7 +567,7 @@ async def handle_notify_matching_suppliers(payload: dict) -> None: lang = payload.get("lang", "en") lead = await fetch_one( - "SELECT * FROM lead_requests WHERE id = ? AND status = 'new' AND verified_at IS NOT NULL", + "SELECT * FROM lead_requests WHERE id = ? AND status = 'new' AND verified_at IS NOT NULL AND visible_from <= datetime('now')", (lead_id,), ) if not lead or not lead.get("country"): @@ -652,6 +652,7 @@ async def handle_send_weekly_lead_digest(payload: dict) -> None: f"""SELECT id, heat_score, country, court_count, facility_type, timeline, credit_cost, created_at FROM lead_requests WHERE lead_type = 'quote' AND status = 'new' AND verified_at IS NOT NULL + AND visible_from <= datetime('now') AND country IN ({placeholders}) AND created_at >= datetime('now', '-7 days') AND NOT EXISTS (