[verified] build discovery runs workspace

This commit is contained in:
Marco0300
2026-09-03 22:48:28 +02:00
parent 7276e8735e
commit a99e6b26dc
6 changed files with 60 additions and 29 deletions
+9 -8
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ProspectOS · Pipeline intelligence</title>
<meta name="description" content="Prospect discovery and review dashboard">
<link rel="stylesheet" href="styles.css?v=phase-18">
<link rel="stylesheet" href="styles.css?v=phase-19">
</head>
<body>
<section class="login-screen" id="loginScreen" aria-labelledby="loginTitle">
@@ -30,6 +30,7 @@
<a class="nav-item active" href="#dashboard"><span></span> Dashboard</a>
<a class="nav-item" href="#explorer"><span></span> Prospect explorer</a>
<a class="nav-item" href="#add"><span></span> Add prospects</a>
<a class="nav-item" href="#discoveryWorkspace" data-nav="discovery"><span></span> Discovery runs</a>
<a class="nav-item" href="#jobs" data-nav="jobs"><span></span> Jobs</a>
<a class="nav-item" href="#sources" data-nav="sources"><span></span> Sources</a>
<a class="nav-item" href="#crmPipeline" data-nav="crm"><span></span> CRM pipeline</a>
@@ -46,14 +47,14 @@
<div class="content">
<section class="hero" id="dashboard"><div><p class="eyebrow">EVIDENCE-LED PROSPECTING</p><h1>Good morning, Alex <span></span></h1><p class="hero-sub">Your pipeline has <strong id="heroCount">0 prospects</strong> ready for review.</p></div><button class="button primary" data-scroll="#add"> Add prospect</button></section>
<section class="direct-discovery-section" id="discoveryWorkspace" aria-labelledby="discoveryWorkspaceTitle" data-smoke="direct-discovery">
<div class="discovery-hero panel"><div><p class="eyebrow">BUILT-IN DISCOVERY</p><h2 id="discoveryWorkspaceTitle">Find prospects from approved seed sites</h2><p class="muted">Describe the market, provide up to five public seed URLs, and let the bounded workspace job return reviewable candidates. No manual source registration required.</p></div><span class="discovery-badge">Bounded · review first</span></div>
<div class="discovery-hero panel"><div><p class="eyebrow">SOURCE INTELLIGENCE</p><h2 id="discoveryWorkspaceTitle">Discovery runs</h2><p class="muted">Build a criteria-first run across approved sources, monitor it live, and review every result with provenance before it enters your pipeline.</p></div><span class="discovery-badge">Bounded · review first</span></div>
<div class="discovery-workspace-grid">
<article class="panel direct-discovery-form-panel"><div class="panel-heading"><div><p class="eyebrow">DISCOVERY BRIEF</p><h3>Set your criteria</h3></div><span class="small-label">Max 20 pages · 50 candidates</span></div>
<form id="directDiscoveryForm"><label>Keywords or market<input id="directDiscoveryKeywords" name="keywords" required maxlength="240" placeholder="e.g. solar installers, Cape Town"></label><label>Location <span class="optional">optional</span><input id="directDiscoveryLocation" name="location" maxlength="120" placeholder="Western Cape, South Africa"></label><label>Seed URLs <span class="optional">up to 5 · one per line</span><textarea id="directDiscoverySeeds" name="seed_urls" rows="4" required placeholder="https://directory.example/&#10;https://association.example/members"></textarea></label><div class="discovery-limit-grid"><label>Page limit<select id="directDiscoveryMaxPages" name="max_pages"><option value="5">5 pages</option><option value="10" selected>10 pages</option><option value="20">20 pages</option></select></label><label>Candidate limit<select id="directDiscoveryMaxCandidates" name="max_candidates"><option value="10">10 candidates</option><option value="25" selected>25 candidates</option><option value="50">50 candidates</option></select></label></div><div class="form-footer"><p id="directDiscoveryMessage" class="form-message" role="status" aria-live="polite"></p><button class="button primary" id="directDiscoveryRunBtn" type="submit">Run discovery <span aria-hidden="true"></span></button></div></form>
<article class="panel direct-discovery-form-panel"><div class="panel-heading"><div><p class="eyebrow">RUN BUILDER</p><h3>Define your market</h3></div><span class="small-label">Max 20 pages · 50 candidates</span></div>
<form id="directDiscoveryForm"><div class="form-grid"><label>Category / keyword<input id="directDiscoveryKeywords" name="keywords" required maxlength="240" placeholder="e.g. solar installers"></label><label>City<input id="directDiscoveryCity" name="city" maxlength="80" placeholder="Cape Town"></label><label>Province / state<input id="directDiscoveryProvince" name="province" maxlength="80" placeholder="Western Cape"></label><label>Country<input id="directDiscoveryCountry" name="country" maxlength="80" placeholder="South Africa"></label></div><label>Approved sources <span class="optional">multi-select · only enabled sources can run</span><select id="directDiscoverySources" name="source_ids" multiple size="4" aria-label="Approved discovery sources"><option value="">Loading approved sources…</option></select></label><div class="discovery-limit-grid"><label>Max records<select id="directDiscoveryMaxCandidates" name="max_candidates"><option value="10">10 records</option><option value="25" selected>25 records</option><option value="50">50 records</option></select></label><label>Daily limit<input id="directDiscoveryDailyLimit" name="daily_limit" type="number" min="1" max="1000" value="100"></label><label>Schedule<select id="directDiscoverySchedule" name="schedule"><option value="now">Run now</option><option value="daily">Daily · 09:00</option><option value="weekdays">Weekdays · 09:00</option><option value="weekly">Weekly · Monday</option></select></label><label>Page limit<select id="directDiscoveryMaxPages" name="max_pages"><option value="5">5 pages</option><option value="10" selected>10 pages</option><option value="20">20 pages</option></select></label></div><details class="advanced-discovery"><summary>Advanced run options</summary><label>Public seed URLs <span class="optional">optional · up to 5, one per line</span><textarea id="directDiscoverySeeds" name="seed_urls" rows="3" placeholder="https://directory.example/"></textarea></label><label class="checkbox-label"><input type="checkbox" name="dry_run" id="directDiscoveryDryRun"> Dry run · validate the plan without creating a job</label></details><div class="form-footer"><p id="directDiscoveryMessage" class="form-message" role="status" aria-live="polite"></p><button class="button primary" id="directDiscoveryRunBtn" type="submit">Start discovery <span aria-hidden="true"></span></button></div></form>
</article>
<aside class="panel discovery-runs-panel"><div class="panel-heading"><div><p class="eyebrow">RUN HISTORY</p><h3>Discovery runs</h3></div><button class="button ghost compact" id="directDiscoveryRefreshBtn" type="button">↻ Refresh</button></div><div id="directDiscoveryRunsState" class="discovery-runs-state" aria-live="polite"><div class="detail-loading">Sign in to load discovery runs.</div></div></aside>
</div>
<div class="panel discovery-results-panel" id="directDiscoveryResultsPanel"><div class="panel-heading"><div><p class="eyebrow">RESULT STATUS</p><h3 id="directDiscoveryResultTitle">Select a run to inspect results</h3></div><span id="directDiscoveryResultStatus" class="small-label">No run selected</span></div><div id="directDiscoveryResultState" aria-live="polite"><p class="muted">Results appear here with job state, partial-result handling, and candidate provenance.</p></div></div>
<div class="panel discovery-results-panel" id="directDiscoveryResultsPanel"><div class="panel-heading"><div><p class="eyebrow">ACTIVE RUN</p><h3 id="directDiscoveryResultTitle">Select a run to inspect results</h3></div><span id="directDiscoveryResultStatus" class="small-label">No run selected</span></div><div id="directDiscoveryResultState" aria-live="polite"><p class="muted">Progress, metrics, live events, and per-source health appear here.</p></div></div>
</section>
<section class="metrics" aria-label="Dashboard metrics">
<a class="metric-card metric-link" data-dashboard-filter="all" href="#explorer"><div class="metric-icon violet"></div><div><p>Total prospects</p><h2 id="metricTotal">0</h2><span class="trend neutral">● Current workspace</span></div></a>
@@ -66,7 +67,7 @@
<section class="score-rules-section" id="scoreRules" aria-labelledby="scoreRulesTitle"><article class="panel" id="scoreRulesPanel" data-smoke="score-rules"><div class="detail-loading" aria-live="polite">Sign in to load score rules…</div></article></section>
<section class="workspace-grid" id="explorer">
<div class="explorer-panel panel"><div class="panel-heading"><div><p class="eyebrow">PIPELINE</p><h2>Prospect explorer</h2></div><button class="button ghost" id="refreshBtn">↻ Refresh</button></div>
<div class="filters"><label class="search-wrap"><span></span><input id="searchInput" type="search" placeholder="Search companies, domains, locations…" autocomplete="off"></label><select id="scoreFilter" aria-label="Filter by score"><option value="all">All scores</option><option value="high">High fit · 80+</option><option value="medium">Medium · 6079</option><option value="low">Low · under 60</option></select><select id="statusFilter" aria-label="Filter by status"><option value="all">All statuses</option><option value="review">Needs review</option><option value="reviewed">Reviewed</option><option value="suppressed">Suppressed</option></select><select id="websiteClassFilter" aria-label="Filter by website class"><option value="all">All website classes</option><option value="business_site">Business site</option><option value="social_profile">Social profile</option><option value="missing">Missing website</option></select><select id="pipelineFilter" aria-label="Filter by pipeline stage"><option value="all">All pipeline stages</option><option value="new">New</option><option value="contacted">Contacted</option><option value="qualified">Qualified</option><option value="proposal">Proposal</option><option value="negotiation">Negotiation</option><option value="won">Won</option><option value="lost">Lost</option></select></div>
<div class="filters"><label class="search-wrap"><span></span><input id="searchInput" type="search" placeholder="Search companies, domains, locations…" autocomplete="off"></label><select id="sourceFilter" aria-label="Filter by source"><option value="all">All sources</option></select><select id="geographyFilter" aria-label="Filter by geography"><option value="all">All geographies</option></select><select id="categoryFilter" aria-label="Filter by category"><option value="all">All categories</option></select><select id="websiteClassFilter" aria-label="Filter by website or domain status"><option value="all">Website / domain status</option><option value="business_site">Business site</option><option value="social_profile">Social profile</option><option value="missing">Missing website</option></select><select id="contactStatusFilter" aria-label="Filter by contact status"><option value="all">All contact status</option><option value="present">Contact present</option><option value="missing">Contact missing</option><option value="suppressed">Do not contact</option></select><select id="scoreFilter" aria-label="Filter by score"><option value="all">All scores</option><option value="high">High fit · 80+</option><option value="medium">Medium · 6079</option><option value="low">Low · under 60</option></select><select id="statusFilter" aria-label="Filter by review status"><option value="all">All review states</option><option value="review">Needs review</option><option value="reviewed">Reviewed</option><option value="suppressed">Suppressed</option></select><select id="pipelineFilter" aria-label="Filter by pipeline stage"><option value="all">All pipeline stages</option><option value="new">New</option><option value="contacted">Contacted</option><option value="qualified">Qualified</option><option value="proposal">Proposal</option><option value="negotiation">Negotiation</option><option value="won">Won</option><option value="lost">Lost</option></select></div>
<div class="saved-view-controls" data-smoke="saved-views"><form id="savedFilterForm" class="inline-form"><input id="savedFilterName" name="name" placeholder="Save current filters as…" maxlength="80" required><button class="button ghost compact" type="submit">Save view</button></form><select id="savedFilterSelect" aria-label="Load saved view"><option value="">Saved views</option></select><button class="button ghost compact" id="deleteSavedFilterBtn" type="button" disabled>Delete view</button><p id="savedFilterMessage" class="form-message" role="status" aria-live="polite"></p></div>
<section class="review-queue" data-smoke="review-queue"><div class="queue-heading"><div><p class="eyebrow">OPERATOR QUEUE</p><h3>Review queue <span class="count" id="reviewQueueCount">0</span></h3></div><span class="small-label">Human decision required</span></div><div id="reviewQueueState" class="queue-state" aria-live="polite">Loading review queue…</div><div class="bulk-actions"><label class="checkbox-label"><input id="selectAllReview" type="checkbox"> Select visible</label><span id="selectedReviewCount" class="small-label">0 selected</span><button class="button primary compact" id="bulkVerifyBtn" type="button" disabled>Verify selected</button><button class="button danger compact" id="bulkRejectBtn" type="button" disabled>Reject selected</button></div></section>
<div class="table-meta"><span id="resultCount">Showing 0 prospects</span><span class="legend"><span class="legend-dot high-dot"></span> High fit <span class="legend-dot review-dot"></span> Needs review</span><label class="page-size">Rows <select id="pageSize" aria-label="Page size"><option>10</option><option>25</option><option>50</option></select></label><button class="button ghost compact" id="nextPageBtn" type="button">Next page →</button></div>
@@ -129,7 +130,7 @@
<div class="merge-dialog" id="mergeDialog" hidden role="dialog" aria-modal="true" aria-labelledby="mergeDialogTitle">
<div class="merge-dialog-card"><div class="panel-heading"><div><p class="eyebrow">REVIEW REQUIRED</p><h2 id="mergeDialogTitle">Confirm merge</h2></div><button class="icon-button" id="cancelMergeBtn" type="button" aria-label="Close merge confirmation">×</button></div><p id="mergeDialogCopy"></p><div class="merge-warning"><strong>This action is reversible.</strong> The merge will be recorded in history and can be reversed later.</div><p id="mergeDialogMessage" class="form-message" role="alert" aria-live="polite"></p><div class="merge-dialog-actions"><button class="button ghost" id="cancelMergeBtnSecondary" type="button">Cancel</button><button class="button primary" id="confirmMergeBtn" type="button">Confirm merge</button></div></div>
</div>
<script src="config.js?v=phase-18"></script>
<script src="app.js?v=phase-18"></script>
<script src="config.js?v=phase-19"></script>
<script src="app.js?v=phase-19"></script>
</body>
</html>