feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > BeautyLeads — Cosmetics B2B Intelligence< / title >
< script src = "https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer > < / script >
< style >
2026-05-04 19:44:34 +02:00
:root{
--bg:#0f0f13;--surface:#18181f;--card:#1e1e28;--border:#2a2a38;
--text:#e2e0f0;--muted:#7c7a96;--accent:#e879a0;--accent2:#c026d3;
--success:#34d399;--warn:#f97316;--danger:#f43f5e;--info:#818cf8;
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--text);font-family:'Segoe UI',system-ui,sans-serif;font-size:13px;min-height:100vh}
a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}
input,select,textarea{background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:5px 8px;font-size:12px;outline:none}
input:focus,select:focus,textarea:focus{border-color:var(--accent)}
button{cursor:pointer;border:none;border-radius:6px;padding:6px 14px;font-size:12px;font-weight:600;transition:opacity .15s}
2026-05-04 19:44:34 +02:00
button:hover{opacity:.85}button:disabled{opacity:.4;cursor:default}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
.btn-primary{background:var(--accent);color:#fff}
2026-05-04 19:44:34 +02:00
.btn-ok{background:#16a34a;color:#fff}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
.btn-secondary{background:var(--surface);color:var(--text);border:1px solid var(--border)}
.btn-danger{background:var(--danger);color:#fff}
.btn-sm{padding:4px 10px;font-size:11px}
.card{background:var(--card);border:1px solid var(--border);border-radius:10px;padding:16px}
.header{background:var(--surface);border-bottom:1px solid var(--border);padding:10px 24px;display:flex;align-items:center;gap:16px}
2026-05-04 19:44:34 +02:00
.logo{font-size:18px;font-weight:700;background:linear-gradient(135deg,var(--accent),var(--accent2));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.logo-sub{color:var(--muted);font-weight:400;font-size:12px;-webkit-text-fill-color:var(--muted)}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
.tabs{display:flex;gap:2px;margin-left:auto}
.tab-btn{background:none;border:none;color:var(--muted);padding:8px 16px;border-radius:8px;font-size:13px;font-weight:500;cursor:pointer;transition:all .15s}
.tab-btn:hover{color:var(--text);background:var(--card)}
.tab-btn.active{color:var(--accent);background:var(--card)}
2026-05-04 19:44:34 +02:00
.stat-row{display:flex;gap:10px;flex-wrap:wrap;padding:14px 24px}
.stat-box{background:var(--card);border:1px solid var(--border);border-radius:8px;padding:10px 16px;min-width:100px;text-align:center}
.stat-val{font-size:20px;font-weight:700;line-height:1.1}
.stat-lbl{font-size:10px;color:var(--muted);margin-top:2px;text-transform:uppercase;letter-spacing:.04em}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
2026-05-04 19:44:34 +02:00
.filter-bar{padding:0 24px 10px;display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.filter-label{color:var(--muted);font-size:11px;white-space:nowrap}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
.tbl-wrap{padding:0 24px 24px;overflow-x:auto}
table{width:100%;border-collapse:collapse}
2026-05-04 19:44:34 +02:00
th{background:var(--surface);color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.05em;padding:8px 10px;text-align:left;border-bottom:1px solid var(--border);white-space:nowrap;position:sticky;top:0;z-index:1}
td{padding:7px 10px;border-bottom:1px solid var(--border);vertical-align:middle}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
tr:hover td{background:rgba(232,121,160,.04)}
2026-05-04 19:44:34 +02:00
.badge{display:inline-block;padding:2px 8px;border-radius:20px;font-size:10px;font-weight:700;letter-spacing:.04em;white-space:nowrap}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
.badge-hot{background:rgba(244,63,94,.18);color:var(--danger)}
.badge-warm{background:rgba(249,115,22,.18);color:var(--warn)}
.badge-cold{background:rgba(129,140,248,.18);color:var(--info)}
.badge-nr{background:rgba(100,116,139,.15);color:var(--muted)}
.badge-live{background:rgba(52,211,153,.15);color:var(--success)}
.badge-dead{background:rgba(244,63,94,.15);color:var(--danger)}
.badge-error{background:rgba(249,115,22,.15);color:var(--warn)}
.badge-parked{background:rgba(251,191,36,.15);color:#fbbf24}
.badge-redirect{background:rgba(148,163,184,.15);color:#94a3b8}
2026-05-04 19:44:34 +02:00
.chip{display:inline-block;background:rgba(232,121,160,.1);color:var(--accent);border:1px solid rgba(232,121,160,.2);border-radius:10px;padding:1px 6px;font-size:10px;margin:1px 1px 1px 0}
.chip-match{background:rgba(52,211,153,.1);color:var(--success);border-color:rgba(52,211,153,.25)}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
2026-05-04 19:44:34 +02:00
.detail-row>td{background:#16161e;padding:14px 18px;border-bottom:2px solid var(--border)}
.detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.detail-box{background:var(--surface);border-radius:8px;padding:10px 14px}
.detail-box h4{color:var(--muted);font-size:10px;text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px}
.detail-box p{font-size:12px;line-height:1.55}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
2026-05-04 19:44:34 +02:00
.val-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-bottom:16px}
.esb{background:var(--card);border:1px solid var(--border);border-radius:8px;padding:12px;text-align:center}
.ev{font-size:20px;font-weight:700}.el{font-size:10px;color:var(--muted);margin-top:2px}
.bulk-bar{padding:0 24px 8px;display:flex;gap:8px;align-items:center;flex-wrap:wrap;
background:rgba(232,121,160,.06);border-top:1px solid rgba(232,121,160,.15);
border-bottom:1px solid rgba(232,121,160,.15);margin-bottom:4px;min-height:40px}
.toast-wrap{position:fixed;bottom:20px;right:20px;z-index:999;display:flex;flex-direction:column;gap:8px}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
.toast{background:var(--card);border:1px solid var(--border);border-radius:8px;padding:10px 16px;font-size:12px;min-width:240px;max-width:380px;animation:slideIn .2s ease}
.toast.success{border-color:rgba(52,211,153,.4);color:var(--success)}
.toast.error{border-color:rgba(244,63,94,.4);color:var(--danger)}
.toast.info{border-color:rgba(129,140,248,.4);color:var(--info)}
2026-05-04 19:44:34 +02:00
@keyframes slideIn{from{transform:translateX(20px);opacity:0}to{transform:translateX(0);opacity:1}}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
2026-05-04 19:44:34 +02:00
.page-info{color:var(--muted);font-size:11px}
.empty-state{padding:48px;text-align:center;color:var(--muted)}
.loading-state{padding:24px;text-align:center;color:var(--muted);font-size:12px}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
input[type=checkbox]{width:14px;height:14px;accent-color:var(--accent);cursor:pointer}
2026-05-04 19:44:34 +02:00
textarea{width:100%;resize:vertical;font-family:monospace;font-size:12px}
.section-pad{padding:0 24px}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / style >
< / head >
< body x-data = "app()" x-init = "init()" >
<!-- Header -->
< div class = "header" >
2026-05-04 19:44:34 +02:00
< div >
< span class = "logo" > BeautyLeads< / span >
< span class = "logo-sub" style = "display:block;font-size:11px;margin-top:1px" > Cosmetics B2B Intelligence< / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
< div class = "tabs" >
2026-05-04 19:44:34 +02:00
< button class = "tab-btn" :class = "{active:tab==='browse'}" @ click = "tab='browse';loadDomains()" > Browse< / button >
< button class = "tab-btn" :class = "{active:tab==='validator'}" @ click = "tab='validator';loadValStatus()" > Validator< / button >
< button class = "tab-btn" :class = "{active:tab==='pipeline'}" @ click = "tab='pipeline';loadLeads()" > B2B Pipeline< / button >
< button class = "tab-btn" :class = "{active:tab==='prescreen'}" @ click = "tab='prescreen'" > Pre-screen< / button >
< button class = "tab-btn" :class = "{active:tab==='export'}" @ click = "tab='export'" > Export< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
< / div >
2026-05-04 19:44:34 +02:00
<!-- Stats -->
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div class = "stat-row" >
< div class = "stat-box" > < div class = "stat-val" x-text = "(stats.total_domains||0).toLocaleString()" > < / div > < div class = "stat-lbl" > Total Domains< / div > < / div >
2026-05-04 19:44:34 +02:00
< div class = "stat-box" > < div class = "stat-val" style = "color:var(--success)" x-text = "(stats.beauty_live||0).toLocaleString()" > < / div > < div class = "stat-lbl" > Beauty Live< / div > < / div >
< div class = "stat-box" > < div class = "stat-val" style = "color:var(--danger)" x-text = "(aiSt.hot||0).toLocaleString()" > < / div > < div class = "stat-lbl" > HOT Leads< / div > < / div >
< div class = "stat-box" > < div class = "stat-val" style = "color:var(--warn)" x-text = "(aiSt.warm||0).toLocaleString()" > < / div > < div class = "stat-lbl" > WARM Leads< / div > < / div >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div class = "stat-box" > < div class = "stat-val" x-text = "(aiSt.total||0).toLocaleString()" > < / div > < div class = "stat-lbl" > Assessed< / div > < / div >
< div class = "stat-box" > < div class = "stat-val" :style = "aiSt.pending>0?'color:var(--warn)':''" x-text = "(aiSt.pending||0).toLocaleString()" > < / div > < div class = "stat-lbl" > In Queue< / div > < / div >
< / div >
2026-05-04 19:44:34 +02:00
<!-- ══════════════════════ BROWSE ══════════════════════ -->
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div x-show = "tab==='browse'" >
2026-05-04 19:44:34 +02:00
<!-- Filters -->
< div class = "filter-bar" style = "padding-top:4px" >
< input x-model = "f.keyword" placeholder = "Keyword in domain/title…" style = "width:170px" @ keyup . enter = "goSearch()" >
< input x-model = "f.tld" placeholder = "TLD (es, ro, fr…)" style = "width:110px" @ keyup . enter = "goSearch()" >
< select x-model = "f.prescreen_status" @ change = "goSearch()" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< option value = "live" > Live< / option >
2026-05-04 19:44:34 +02:00
< option value = "" > All Statuses< / option >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< option value = "error" > Error (4xx/5xx)< / option >
< option value = "redirect" > Redirect< / option >
< option value = "parked" > Parked< / option >
< option value = "dead" > Dead< / option >
< option value = "none" > Not checked< / option >
< / select >
2026-05-04 19:44:34 +02:00
< select x-model = "f.niche" @ change = "goSearch()" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< option value = "beauty_cosmetics" > Beauty & Cosmetics< / option >
< option value = "" > All Niches< / option >
< option value = "fashion_retail" > Fashion Retail< / option >
< option value = "medical_health" > Medical / Health< / option >
< / select >
2026-05-04 19:44:34 +02:00
< select x-model = "f.site_type" @ change = "goSearch()" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< option value = "ecommerce" > E-commerce< / option >
< option value = "" > All Types< / option >
< option value = "corporate" > Corporate< / option >
2026-05-04 19:44:34 +02:00
< option value = "landing_page" > Landing Page< / option >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / select >
2026-05-04 19:44:34 +02:00
< input x-model = "f.country" placeholder = "Country (ES, FR…)" style = "width:100px" @ keyup . enter = "goSearch()" >
< select x-model = "f.limit" @ change = "goSearch()" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< option value = "50" > 50< / option >
< option value = "100" selected > 100< / option >
< option value = "200" > 200< / option >
2026-05-04 19:44:34 +02:00
< option value = "500" > 500< / option >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / select >
2026-05-04 19:44:34 +02:00
< button class = "btn-primary" @ click = "goSearch()" > Search< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< button class = "btn-secondary" @ click = "resetFilters()" > Reset< / button >
2026-05-04 19:44:34 +02:00
< span class = "page-info" style = "margin-left:auto" x-text = "domainsTotal.toLocaleString()+' results · page '+f.page" > < / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
2026-05-04 19:44:34 +02:00
<!-- Bulk bar (visible when items selected) -->
< div class = "bulk-bar" x-show = "selected.length>0" >
< span style = "color:var(--accent);font-weight:600;font-size:12px" x-text = "selected.length+' selected'" > < / span >
< button class = "btn-ok btn-sm" @ click = "prescreenSelected()" > Pre-screen Selected< / button >
< button class = "btn-primary btn-sm" @ click = "assessSelected()" > B2B Assess Selected< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< button class = "btn-secondary btn-sm" @ click = "selected=[]" > Clear< / button >
< / div >
2026-05-04 19:44:34 +02:00
<!-- Table -->
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div class = "tbl-wrap" >
2026-05-04 19:44:34 +02:00
< div class = "loading-state" x-show = "loading" > Loading…< / div >
< div class = "empty-state" x-show = "!loading && domains.length===0" >
No domains found. Try adjusting filters, running the Validator, or Pre-screening first.
< / div >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< table x-show = "!loading && domains.length>0" >
< thead >
< tr >
2026-05-04 19:44:34 +02:00
< th style = "width:30px" >
< input type = "checkbox" @ change = "toggleAll($event)" :checked = "selected.length===domains.length && domains.length>0" >
< / th >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< th > Domain< / th >
< th > Status< / th >
< th > Country< / th >
< th > Title< / th >
< th > Niche< / th >
< th > Type< / th >
< th > B2B< / th >
2026-05-04 19:44:34 +02:00
< th style = "width:130px" > < / th >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / tr >
< / thead >
< tbody >
< template x-for = "row in domains" :key = "row.domain" >
< tr >
< td > < input type = "checkbox" :value = "row.domain" x-model = "selected" > < / td >
2026-05-04 19:44:34 +02:00
< td style = "white-space:nowrap" >
< a :href = "'https://'+row.domain" target = "_blank" x-text = "row.domain" @ click . stop > < / a >
< / td >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< td >
2026-05-04 19:44:34 +02:00
< span x-show = "row.prescreen_status" class = "badge" :class = "statusBadge(row.prescreen_status)" x-text = "row.prescreen_status" > < / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< span x-show = "!row.prescreen_status" style = "color:var(--muted)" > —< / span >
< / td >
< td x-text = "row.ip_country||'—'" > < / td >
2026-05-04 19:44:34 +02:00
< td style = "max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" :title = "row.page_title||''" x-text = "row.page_title||'—'" > < / td >
< td x-text = "(row.niche||'—').replace('_',' ')" > < / td >
< td x-text = "(row.site_type||'—').replace('_',' ')" > < / td >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< td >
2026-05-04 19:44:34 +02:00
< span x-show = "row.beauty_lead_quality" class = "badge" :class = "qualityBadge(row.beauty_lead_quality)" x-text = "row.beauty_lead_quality" > < / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< span x-show = "!row.beauty_lead_quality" style = "color:var(--muted)" > —< / span >
< / td >
2026-05-04 19:44:34 +02:00
< td style = "white-space:nowrap;display:flex;gap:4px" >
< button class = "btn-secondary btn-sm" @ click = "prescreenOne(row.domain)" title = "HTTP check + niche classify" > Screen< / button >
< button class = "btn-primary btn-sm" @ click = "assessOne(row.domain)" title = "Beauty B2B AI assessment" > Assess< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / td >
< / tr >
< / template >
< / tbody >
< / table >
< / div >
2026-05-04 19:44:34 +02:00
<!-- Pagination -->
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div class = "filter-bar" x-show = "!loading && domains.length>0" >
< button class = "btn-secondary btn-sm" @ click = "f.page=Math.max(1,f.page-1);loadDomains()" :disabled = "f.page<=1" > ← Prev< / button >
2026-05-04 19:44:34 +02:00
< span class = "page-info" x-text = "'Page '+f.page+' of '+Math.max(1,Math.ceil(domainsTotal/parseInt(f.limit)))" > < / span >
< button class = "btn-secondary btn-sm" @ click = "f.page++;loadDomains()" :disabled = "f.page>=Math.ceil(domainsTotal/parseInt(f.limit))" > Next →< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
< / div >
2026-05-04 19:44:34 +02:00
<!-- ══════════════════════ VALIDATOR ══════════════════════ -->
< div x-show = "tab==='validator'" class = "section-pad" style = "padding-top:16px" >
< p style = "color:var(--muted);font-size:12px;margin-bottom:14px" >
Bulk HTTP validator — checks all domains in the dataset and tags them live / dead / error / parked / redirect.
Run this first, then Pre-screen to classify niches, then Browse to find beauty leads.
< / p >
< div class = "val-grid" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div class = "esb" > < div class = "ev" x-text = "(valSt.processed||0).toLocaleString()" > < / div > < div class = "el" > Checked< / div > < / div >
2026-05-04 19:44:34 +02:00
< div class = "esb" > < div class = "ev" style = "color:var(--success)" x-text = "(valSt.live||0).toLocaleString()" > < / div > < div class = "el" > Live< / div > < / div >
< div class = "esb" > < div class = "ev" style = "color:var(--danger)" x-text = "(valSt.dead||0).toLocaleString()" > < / div > < div class = "el" > Dead< / div > < / div >
< div class = "esb" > < div class = "ev" style = "color:var(--warn)" x-text = "(valSt.error||0).toLocaleString()" > < / div > < div class = "el" > Error< / div > < / div >
< div class = "esb" > < div class = "ev" style = "color:#fbbf24" x-text = "(valSt.parked||0).toLocaleString()" > < / div > < div class = "el" > Parked< / div > < / div >
< div class = "esb" > < div class = "ev" style = "color:var(--info)" x-text = "(valSt.rate||0)+'/s'" > < / div > < div class = "el" > Rate< / div > < / div >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
2026-05-04 19:44:34 +02:00
< div x-show = "valSt.processed>0||valSt.running" style = "font-size:11px;color:var(--muted);margin-bottom:12px" >
Offset: < span x-text = "valSt.offset" > < / span > · Skipped: < span x-text = "valSt.skipped" > < / span >
< span x-show = "valSt.tld_filter" > · TLD filter: < span x-text = "valSt.tld_filter" > < / span > < / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
2026-05-04 19:44:34 +02:00
< div style = "display:flex;gap:10px;align-items:center;flex-wrap:wrap" >
< input x-model = "valTld" placeholder = "TLD filter (es, ro…)" style = "width:150px" >
< label style = "display:flex;align-items:center;gap:6px;color:var(--muted);font-size:12px" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< input type = "checkbox" x-model = "valRescan" > Rescan dead
< / label >
2026-05-04 19:44:34 +02:00
< button class = "btn-primary" @ click = "startValidator()" :disabled = "valSt.running" > Start Validator< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< button class = "btn-danger" @ click = "stopValidator()" :disabled = "!valSt.running" > Stop< / button >
2026-05-04 19:44:34 +02:00
< span x-show = "valSt.running" style = "color:var(--success);font-size:11px" > ● Running< / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< span x-show = "!valSt.running && valSt.processed>0" style = "color:var(--muted);font-size:11px" > ● Stopped< / span >
< / div >
< / div >
2026-05-04 19:44:34 +02:00
<!-- ══════════════════════ B2B PIPELINE ══════════════════════ -->
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div x-show = "tab==='pipeline'" >
2026-05-04 19:44:34 +02:00
< div class = "filter-bar" style = "padding-top:4px" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< select x-model = "pf.quality" @ change = "loadLeads()" >
< option value = "" > All Qualities< / option >
2026-05-04 19:44:34 +02:00
< option value = "HOT" > 🔥 HOT< / option >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< option value = "WARM" > WARM< / option >
< option value = "COLD" > COLD< / option >
< / select >
2026-05-04 19:44:34 +02:00
< input x-model = "pf.country" placeholder = "Country (ES, FR…)" style = "width:110px" @ keyup . enter = "loadLeads()" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< select x-model = "pf.limit" @ change = "loadLeads()" >
< option value = "50" > 50< / option >
< option value = "100" selected > 100< / option >
< option value = "200" > 200< / option >
< / select >
2026-05-04 19:44:34 +02:00
< button class = "btn-primary" @ click = "loadLeads()" > Filter< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< button class = "btn-secondary" @ click = "pf={quality:'',country:'',page:1,limit:'100'};loadLeads()" > Reset< / button >
2026-05-04 19:44:34 +02:00
< span class = "page-info" style = "margin-left:auto" x-text = "leadsTotal.toLocaleString()+' leads · page '+pf.page" > < / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
< div class = "tbl-wrap" >
2026-05-04 19:44:34 +02:00
< div class = "loading-state" x-show = "loadingLeads" > Loading…< / div >
< div class = "empty-state" x-show = "!loadingLeads && leads.length===0" >
No B2B assessments yet. Go to Browse → select domains → B2B Assess Selected.
< / div >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< table x-show = "!loadingLeads && leads.length>0" >
< thead >
< tr >
< th > Domain< / th >
< th > Quality< / th >
< th > Business< / th >
< th > Country< / th >
< th > Categories< / th >
< th > Portfolio Match< / th >
< th > Contact< / th >
2026-05-04 19:44:34 +02:00
< th style = "width:80px" > < / th >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / tr >
< / thead >
< tbody >
< template x-for = "row in leads" :key = "row.domain" >
2026-05-04 19:44:34 +02:00
<!-- Main row -->
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< tr @ click = "toggleLead(row.domain)" style = "cursor:pointer" >
< td > < a :href = "'https://'+row.domain" target = "_blank" @ click . stop x-text = "row.domain" > < / a > < / td >
2026-05-04 19:44:34 +02:00
< td > < span class = "badge" :class = "qualityBadge(row.beauty_lead_quality)" x-text = "row.beauty_lead_quality||'—'" > < / span > < / td >
< td style = "max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" x-text = "(row._beauty||{}).business_name||(row.page_title||'—')" > < / td >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< td x-text = "(row._beauty||{}).country_fiscal||(row.ip_country||'—')" > < / td >
2026-05-04 19:44:34 +02:00
< td style = "max-width:160px" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< template x-for = "cat in ((row._beauty||{}).categories||[]).slice(0,3)" :key = "cat" >
< span class = "chip" x-text = "cat" > < / span >
< / template >
< / td >
2026-05-04 19:44:34 +02:00
< td style = "max-width:200px" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< template x-if = "((row._beauty||{}).dist_matches||[]).length>0" >
2026-05-04 19:44:34 +02:00
< div >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< template x-for = "b in ((row._beauty||{}).dist_matches||[]).slice(0,4)" :key = "b" >
< span class = "chip chip-match" x-text = "b" > < / span >
< / template >
2026-05-04 19:44:34 +02:00
< span x-show = "((row._beauty||{}).dist_matches||[]).length>4" class = "chip" x-text = "'+'+(((row._beauty||{}).dist_matches||[]).length-4)" > < / span >
< / div >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / template >
< span x-show = "!((row._beauty||{}).dist_matches||[]).length" style = "color:var(--muted)" > —< / span >
< / td >
2026-05-04 19:44:34 +02:00
< td style = "font-size:11px;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
x-text="(row._beauty||{}).contact_email||row.emails||'—'">< / td >
< td @ click . stop style = "white-space:nowrap;display:flex;gap:4px" >
< button class = "btn-secondary btn-sm" @ click = "copyOutreach(row)" > Copy email< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / td >
< / tr >
2026-05-04 19:44:34 +02:00
<!-- Expanded detail -->
< tr class = "detail-row" x-show = "expandedLead===row.domain" @ click = "expandedLead=null" style = "cursor:pointer" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< td colspan = "8" >
2026-05-04 19:44:34 +02:00
< div class = "detail-grid" @ click . stop >
< div class = "detail-box" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< h4 > B2B Proposal< / h4 >
< p x-text = "(row._beauty||{}).b2b_proposal||'—'" > < / p >
< / div >
2026-05-04 19:44:34 +02:00
< div class = "detail-box" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< h4 > Lead Reasoning< / h4 >
< p x-text = "(row._beauty||{}).lead_reasoning||'—'" > < / p >
< / div >
2026-05-04 19:44:34 +02:00
< div class = "detail-box" style = "grid-column:1/-1" >
< h4 style = "display:flex;align-items:center;gap:8px" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
Outreach Email
2026-05-04 19:44:34 +02:00
< button class = "btn-secondary btn-sm" @ click = "copyText((row._beauty||{}).outreach_email||'')" > Copy< / button >
< span style = "color:var(--muted);font-size:10px" x-text = "'Subject: '+((row._beauty||{}).outreach_subject||'')" > < / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / h4 >
2026-05-04 19:44:34 +02:00
< p style = "white-space:pre-wrap;font-size:11px;color:var(--text);margin-top:6px;line-height:1.6" x-text = "(row._beauty||{}).outreach_email||'—'" > < / p >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
2026-05-04 19:44:34 +02:00
< div class = "detail-box" >
< h4 > Brands Detected on Site< / h4 >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< p style = "font-size:11px" >
2026-05-04 19:44:34 +02:00
< template x-for = "b in ((row._beauty||{}).detected_brands||[]).slice(0,30)" :key = "b" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< span class = "chip" x-text = "b" > < / span >
< / template >
2026-05-04 19:44:34 +02:00
< span x-show = "!((row._beauty||{}).detected_brands||[]).length" style = "color:var(--muted)" > None detected in scraped text< / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / p >
< / div >
2026-05-04 19:44:34 +02:00
< div class = "detail-box" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< h4 > Contact Details< / h4 >
2026-05-04 19:44:34 +02:00
< p style = "font-size:12px;line-height:1.7" >
< template x-if = "(row._beauty||{}).contact_email" >
< span > Email: < a :href = "'mailto:'+(row._beauty||{}).contact_email" x-text = "(row._beauty||{}).contact_email" > < / a > < br > < / span >
< / template >
< template x-if = "(row._beauty||{}).contact_phone" >
< span > Phone: < span x-text = "(row._beauty||{}).contact_phone" > < / span > < br > < / span >
< / template >
< template x-if = "row.emails" >
< span style = "color:var(--muted);font-size:11px" > On-site: < span x-text = "row.emails" > < / span > < / span >
< / template >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / p >
< / div >
< / div >
< / td >
< / tr >
< / template >
< / tbody >
< / table >
< / div >
< div class = "filter-bar" x-show = "!loadingLeads && leads.length>0" >
< button class = "btn-secondary btn-sm" @ click = "pf.page=Math.max(1,pf.page-1);loadLeads()" :disabled = "pf.page<=1" > ← Prev< / button >
2026-05-04 19:44:34 +02:00
< span class = "page-info" x-text = "'Page '+pf.page+' of '+Math.max(1,Math.ceil(leadsTotal/parseInt(pf.limit)))" > < / span >
< button class = "btn-secondary btn-sm" @ click = "pf.page++;loadLeads()" :disabled = "pf.page>=Math.ceil(leadsTotal/parseInt(pf.limit))" > Next →< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
< / div >
2026-05-04 19:44:34 +02:00
<!-- ══════════════════════ PRE - SCREEN ══════════════════════ -->
< div x-show = "tab==='prescreen'" class = "section-pad" style = "padding-top:16px" >
< p style = "color:var(--muted);font-size:12px;margin-bottom:12px" >
< strong style = "color:var(--text)" > Phase 1< / strong > — HTTP check: marks domains live / dead / parked / redirect / error.< br >
< strong style = "color:var(--text)" > Phase 2< / strong > — DeepSeek classifies niche (beauty_cosmetics, fashion_retail…) and site type (ecommerce, corporate…).< br >
Paste up to 200 domains, one per line. Results saved automatically — then use Browse to filter by beauty + ecommerce.
< / p >
< textarea x-model = "prescreenInput" rows = "12" placeholder = "domain1.com domain2.es domain3.fr …" > < / textarea >
< div style = "display:flex;gap:10px;margin-top:10px;align-items:center;flex-wrap:wrap" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< button class = "btn-primary" @ click = "runPrescreen()" :disabled = "prescreenRunning" >
< span x-show = "!prescreenRunning" > Run Pre-screen< / span >
< span x-show = "prescreenRunning" > Running…< / span >
< / button >
2026-05-04 19:44:34 +02:00
< span x-show = "prescreenResult" style = "font-size:12px" x-text = "prescreenResult" > < / span >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
< / div >
2026-05-04 19:44:34 +02:00
<!-- ══════════════════════ EXPORT ══════════════════════ -->
< div x-show = "tab==='export'" class = "section-pad" style = "padding-top:24px" >
< div class = "card" style = "max-width:460px" >
< h3 style = "margin-bottom:16px;font-size:14px;color:var(--accent)" > Export Beauty B2B Leads< / h3 >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< div style = "display:flex;flex-direction:column;gap:12px" >
< div style = "display:flex;gap:8px;align-items:center" >
2026-05-04 19:44:34 +02:00
< label class = "filter-label" style = "width:65px" > Quality< / label >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< select x-model = "exportQuality" style = "flex:1" >
< option value = "" > All< / option >
< option value = "HOT" > HOT only< / option >
< option value = "WARM" > WARM only< / option >
2026-05-04 19:44:34 +02:00
< option value = "COLD" > COLD only< / option >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / select >
< / div >
< div style = "display:flex;gap:8px;align-items:center" >
2026-05-04 19:44:34 +02:00
< label class = "filter-label" style = "width:65px" > Country< / label >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< input x-model = "exportCountry" placeholder = "ES, FR, DE …" style = "flex:1" >
< / div >
2026-05-04 19:44:34 +02:00
< button class = "btn-primary" @ click = "doExport()" > Download CSV< / button >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / div >
2026-05-04 19:44:34 +02:00
< p style = "margin-top:14px;font-size:11px;color:var(--muted);line-height:1.6" >
Columns: domain · quality · business name · fiscal country · active countries ·
categories · detected brands · portfolio matches · contact email · phone ·
B2B proposal · outreach subject · outreach email
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< / p >
< / div >
< / div >
<!-- Toasts -->
2026-05-04 19:44:34 +02:00
< div class = "toast-wrap" >
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
< template x-for = "t in toasts" :key = "t.id" >
< div class = "toast" :class = "t.type" x-text = "t.msg" > < / div >
< / template >
< / div >
< script >
function app() {
return {
tab: 'browse',
2026-05-04 19:44:34 +02:00
loading: false, loadingLeads: false,
domains: [], domainsTotal: 0,
leads: [], leadsTotal: 0,
selected: [], expandedLead: null,
stats: {}, aiSt: {hot:0,warm:0,total:0,pending:0,running:0,done:0,failed:0},
valSt: {running:false,processed:0,live:0,dead:0,error:0,parked:0,redirect:0,skipped:0,offset:0,rate:0},
valTld: '', valRescan: false,
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
toasts: [],
2026-05-04 19:44:34 +02:00
prescreenInput: '', prescreenRunning: false, prescreenResult: '',
exportQuality: '', exportCountry: '',
f: {keyword:'', tld:'', prescreen_status:'live', niche:'beauty_cosmetics',
site_type:'ecommerce', country:'', limit:'100', page:1},
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
pf: {quality:'', country:'', limit:'100', page:1},
async init() {
2026-05-04 19:44:34 +02:00
await Promise.all([this.loadStats(), this.loadAiStatus(), this.loadValStatus()]);
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
await this.loadDomains();
setInterval(async () => {
2026-05-04 19:44:34 +02:00
this.loadStats();
this.loadAiStatus();
if (this.tab==='validator') this.loadValStatus();
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
}, 4000);
},
async loadStats() {
try {
const d = await fetch('/api/stats').then(r=>r.json());
this.stats = d;
2026-05-04 19:44:34 +02:00
// Count beauty live in background
fetch('/api/enriched?prescreen_status=live& niche=beauty_cosmetics& limit=1')
.then(r=>r.json()).then(d=>{ this.stats = {...this.stats, beauty_live: d.total||0}; })
.catch(()=>{});
} catch(e){}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
async loadAiStatus() {
try {
2026-05-04 19:44:34 +02:00
const [st, hot, warm] = await Promise.all([
fetch('/api/beauty/status').then(r=>r.json()),
fetch('/api/beauty/leads?quality=HOT& limit=1').then(r=>r.json()).catch(()=>({total:0})),
fetch('/api/beauty/leads?quality=WARM& limit=1').then(r=>r.json()).catch(()=>({total:0})),
]);
this.aiSt = {...st, hot: hot.total||0, warm: warm.total||0};
} catch(e){}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
async loadValStatus() {
2026-05-04 19:44:34 +02:00
try { this.valSt = await fetch('/api/validator/status').then(r=>r.json()); } catch(e){}
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
2026-05-04 19:44:34 +02:00
goSearch() { this.f.page=1; this.loadDomains(); },
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
async loadDomains() {
this.loading = true;
try {
2026-05-04 19:44:34 +02:00
const p = new URLSearchParams({page: this.f.page, limit: this.f.limit});
if (this.f.keyword) p.set('keyword', this.f.keyword.trim());
if (this.f.tld) p.set('tld', this.f.tld.trim());
if (this.f.prescreen_status) p.set('prescreen_status', this.f.prescreen_status);
if (this.f.niche) p.set('niche', this.f.niche);
if (this.f.site_type) p.set('site_type', this.f.site_type);
if (this.f.country) p.set('country', this.f.country.trim().toUpperCase());
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
const d = await fetch('/api/enriched?' + p).then(r=>r.json());
2026-05-04 19:44:34 +02:00
this.domains = d.results || [];
this.domainsTotal = d.total || 0;
} catch(e) { this.notify('Failed to load: '+e.message, 'error'); }
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
finally { this.loading = false; }
},
async loadLeads() {
this.loadingLeads = true;
try {
2026-05-04 19:44:34 +02:00
const p = new URLSearchParams({page: this.pf.page, limit: this.pf.limit});
if (this.pf.quality) p.set('quality', this.pf.quality);
if (this.pf.country) p.set('country', this.pf.country.trim().toUpperCase());
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
const d = await fetch('/api/beauty/leads?' + p).then(r=>r.json());
this.leads = d.results || [];
this.leadsTotal = d.total || 0;
2026-05-04 19:44:34 +02:00
} catch(e) { this.notify('Failed: '+e.message, 'error'); }
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
finally { this.loadingLeads = false; }
},
resetFilters() {
2026-05-04 19:44:34 +02:00
this.f = {keyword:'', tld:'', prescreen_status:'live', niche:'beauty_cosmetics',
site_type:'ecommerce', country:'', limit:'100', page:1};
this.selected = [];
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
this.loadDomains();
},
toggleAll(e) {
this.selected = e.target.checked ? this.domains.map(r=>r.domain) : [];
},
2026-05-04 19:44:34 +02:00
async prescreenSelected() {
if (!this.selected.length) return;
this.notify(`Pre-screening ${this.selected.length} domains…`, 'info');
try {
const chunks = [];
for (let i=0; i< this.selected.length ; i + = 200 ) chunks . push ( this . selected . slice ( i , i + 200 ) ) ;
let totals = {live:0,dead:0,parked:0,redirect:0,classified:0};
for (const chunk of chunks) {
const d = await fetch('/api/prescreen/batch', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({domains: chunk}),
}).then(r=>r.json());
totals.live += d.live||0; totals.dead += d.dead||0;
totals.parked += d.parked||0; totals.redirect += d.redirect||0;
totals.classified += d.classified||0;
}
this.notify(`✅ ${totals.live} live · ☠ ${totals.dead} dead · 🅿 ${totals.parked} parked · 🏷 ${totals.classified} classified`, 'success');
this.selected = [];
await this.loadDomains();
} catch(e) { this.notify('Pre-screen failed: '+e.message, 'error'); }
},
async assessSelected() {
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
if (!this.selected.length) return;
try {
const d = await fetch('/api/beauty/assess/batch', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({domains: this.selected}),
}).then(r=>r.json());
this.notify(`Queued ${d.queued} domains for B2B assessment`, 'success');
this.selected = [];
} catch(e) { this.notify('Queue failed: '+e.message, 'error'); }
},
2026-05-04 19:44:34 +02:00
async prescreenOne(domain) {
this.notify(`Pre-screening ${domain}…`, 'info');
try {
const d = await fetch('/api/prescreen/batch', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({domains:[domain]}),
}).then(r=>r.json());
this.notify(`${domain}: ${d.live?'live':'dead/parked'}, classified: ${d.classified}`, 'success');
await this.loadDomains();
} catch(e) { this.notify('Failed: '+e.message, 'error'); }
},
async assessOne(domain) {
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
try {
await fetch('/api/beauty/assess/batch', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({domains:[domain]}),
});
2026-05-04 19:44:34 +02:00
this.notify(`${domain} queued for B2B assessment`, 'success');
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
} catch(e) { this.notify('Failed: '+e.message, 'error'); }
},
toggleLead(domain) {
2026-05-04 19:44:34 +02:00
this.expandedLead = this.expandedLead===domain ? null : domain;
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
2026-05-04 19:44:34 +02:00
copyOutreach(row) {
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
const b = row._beauty || {};
2026-05-04 19:44:34 +02:00
const text = ['Subject: '+(b.outreach_subject||''), '', b.outreach_email||''].join('\n').trim();
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
this.copyText(text);
},
copyText(text) {
2026-05-04 19:44:34 +02:00
navigator.clipboard.writeText(text)
.then(()=> this.notify('Copied!', 'success'))
.catch(()=> this.notify('Copy failed', 'error'));
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
async runPrescreen() {
const lines = this.prescreenInput.split('\n').map(l=>l.trim()).filter(Boolean);
2026-05-04 19:44:34 +02:00
if (!lines.length) { this.notify('No domains entered', 'error'); return; }
if (lines.length > 200) { this.notify('Max 200 per batch', 'error'); return; }
this.prescreenRunning = true; this.prescreenResult = '';
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
try {
const d = await fetch('/api/prescreen/batch', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({domains: lines}),
}).then(r=>r.json());
this.prescreenResult = `✅ ${d.live} live · ☠ ${d.dead} dead · 🅿 ${d.parked} parked · ↗ ${d.redirect} redirect · 🏷 ${d.classified} classified`;
this.notify(this.prescreenResult, 'success');
2026-05-04 19:44:34 +02:00
} catch(e) { this.notify('Failed: '+e.message, 'error'); }
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
finally { this.prescreenRunning = false; }
},
async startValidator() {
const p = new URLSearchParams();
if (this.valTld) p.set('tld', this.valTld);
if (this.valRescan) p.set('rescan_dead', 'true');
try {
2026-05-04 19:44:34 +02:00
this.valSt = await fetch('/api/validator/start?'+p, {method:'POST'}).then(r=>r.json());
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
this.notify('Validator started', 'success');
} catch(e) { this.notify('Failed: '+e.message, 'error'); }
},
async stopValidator() {
await fetch('/api/validator/stop', {method:'POST'});
2026-05-04 19:44:34 +02:00
this.notify('Stop requested', 'info');
await this.loadValStatus();
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
2026-05-04 19:44:34 +02:00
doExport() {
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
const p = new URLSearchParams();
2026-05-04 19:44:34 +02:00
if (this.exportQuality) p.set('quality', this.exportQuality);
if (this.exportCountry) p.set('country', this.exportCountry);
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
window.open('/api/beauty/export?' + p, '_blank');
},
qualityBadge(q) {
2026-05-04 19:44:34 +02:00
return {HOT:'badge-hot', WARM:'badge-warm', COLD:'badge-cold', NOT_RELEVANT:'badge-nr'}[q]||'badge-nr';
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
statusBadge(s) {
2026-05-04 19:44:34 +02:00
return {live:'badge-live', dead:'badge-dead', error:'badge-error', parked:'badge-parked', redirect:'badge-redirect'}[s]||'badge-nr';
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
notify(msg, type='info') {
2026-05-04 19:44:34 +02:00
const id = Date.now()+Math.random();
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
this.toasts.push({id, msg, type});
2026-05-04 19:44:34 +02:00
setTimeout(()=>{ this.toasts=this.toasts.filter(t=>t.id!==id); }, 4500);
feat: BeautyLeads B2B cosmetics frontend on port 7788
New service (app/beauty_main.py) sharing the same /data volume:
- Separate FastAPI app running on port 7788
- beauty_ai.py: brand universe scan (~650 brands), portfolio match
detection against OUR_BRANDS, Gemini B2B assessment prompt in Spanish
returning quality/categories/dist_matches/outreach_email
- beauty_queue table + beauty_lead_quality/beauty_assessment columns
in enriched_domains (with migrations)
- Endpoints: /api/beauty/assess/batch, /api/beauty/leads,
/api/beauty/status, /api/beauty/export, /api/beauty/reset
- Static frontend: Browse (beauty/ecommerce pre-filtered, no CMS/SSL/KD
columns), Validator, B2B Pipeline (brand chips, expandable outreach),
Pre-screen, Export CSV
- docker-compose: second 'beauty' service with shared data volume
- Dockerfile: expose 7788 alongside 6677
Also: add 'error' prescreen_status handling + UI (orange stat box,
filter option) for 4xx/5xx HTTP responses
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:10 +02:00
},
};
}
< / script >
< / body >
< / html >