rebuild source discovery workflows
CI / compose (push) Failing after 5m46s

This commit is contained in:
Marco0300
2026-09-04 20:52:37 +02:00
parent 3a9b553440
commit 6aefbdc1f3
18 changed files with 853 additions and 106 deletions
+6 -9
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-34">
<link rel="stylesheet" href="styles.css?v=phase-35">
</head>
<body>
<section class="login-screen" id="loginScreen" aria-labelledby="loginTitle">
@@ -58,7 +58,7 @@
<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">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>
<form id="directDiscoveryForm"><div class="form-grid"><label>Category<input id="directDiscoveryCategory" name="category" required maxlength="120" placeholder="e.g. Renewable energy"></label><label>Keywords<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><label>Language<input id="directDiscoveryLanguage" name="language" maxlength="24" placeholder="en"></label></div><label>Enabled sources <span class="optional">Select one or more approved sources</span><select id="directDiscoverySources" name="source_ids" multiple size="4" aria-describedby="directDiscoverySourceHelp"><option value="" disabled>Loading enabled sources…</option></select></label><p id="directDiscoverySourceHelp" class="small-label">No enabled sources are available. Configure, test, and enable a source first.</p><div class="discovery-limit-grid"><label>Max results<select id="directDiscoveryMaxResults" name="max_results"><option value="10">10 results</option><option value="25" selected>25 results</option><option value="50">50 results</option></select></label><label>Max pages<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>Daily limit<input id="directDiscoveryDailyLimit" name="daily_limit" type="number" min="1" max="1000" value="100"></label></div><details class="advanced-discovery" open><summary>Website analysis</summary><label>Analysis priorities<input id="directDiscoveryPriorities" name="priorities" maxlength="240" placeholder="service fit, contacts, local presence"></label><label>Include websites <span class="optional">optional · one domain or URL per line</span><textarea id="directDiscoveryIncludeWebsites" name="include_websites" rows="2" placeholder="https://example.com"></textarea></label><label>Exclude websites <span class="optional">optional · one domain or URL per line</span><textarea id="directDiscoveryExcludeWebsites" name="exclude_websites" rows="2" placeholder="https://excluded.example"></textarea></label></details><label class="checkbox-label"><input id="directDiscoveryDryRun" name="dry_run" type="checkbox" checked> Dry run validate criteria and source readiness without creating a job</label><div class="form-footer"><p id="directDiscoveryMessage" class="form-message" role="status" aria-live="polite">Choose enabled sources to start. Nothing runs until you submit.</p><button class="button primary" id="directDiscoveryRunBtn" type="submit">Start discovery run</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>
@@ -86,7 +86,7 @@
<section class="jobs-section" id="jobs" aria-labelledby="jobsTitle">
<div class="jobs-header panel">
<div><p class="eyebrow">OPERATIONS</p><h2 id="jobsTitle">Job monitor</h2><p class="muted">Track authenticated workspace jobs and their progress. No job data is shown until the API responds.</p></div>
<div class="jobs-actions"><button class="button ghost" id="jobsRefreshBtn" type="button">↻ Refresh</button><button class="button primary" id="startDemoJobBtn" type="button"> Start demo job</button></div>
<div class="jobs-actions"><button class="button ghost" id="jobsRefreshBtn" type="button">↻ Refresh</button></div>
</div>
<div id="jobsMessage" class="jobs-message" role="status" aria-live="polite"></div>
<div class="job-counts" id="jobCounts" aria-label="Job status counts">
@@ -101,10 +101,7 @@
<div class="sources-header panel"><div><p class="eyebrow">GOVERNANCE · SOURCE REGISTRY</p><h2 id="sourcesTitle">Sources</h2><p class="muted">One operational view of every registered integration. Configure, test, and enable sources only after their terms, owner, limits, and health are reviewable.</p></div><button class="button ghost" id="sourcesRefreshBtn" type="button">↻ Refresh registry</button></div>
<div class="source-safety" role="note"><strong>Discovery is disabled by default.</strong> No live source is enabled in this workspace. Enable a source only after its terms, owner, rate limit, and health have been reviewed.</div>
<div id="sourcesMessage" class="sources-message" role="status" aria-live="polite"></div>
<div class="sources-grid">
<article class="panel source-config-panel"><div class="panel-heading"><div><p class="eyebrow">SOURCE SETUP</p><h3>Add a governed source</h3></div><span class="small-label">Manual or CSV only</span></div><p class="source-setup-copy">Bring in operator-controlled records without activating an external integration. New sources start disabled and remain review-only until explicitly enabled.</p><form id="sourceForm"><div class="form-grid"><label>Source name<input name="name" required placeholder="Partner list / manual import"></label><label>Source type<select name="source_type" id="sourceType"><option value="manual">Manual records</option><option value="csv">CSV import</option></select></label><label>Source URL <span class="optional">optional reference</span><input name="url" type="url" placeholder="https://…"></label><label>Terms URL <span class="optional">required for enablement</span><input name="terms_url" type="url" placeholder="https://…/terms"></label><label>Owner<input name="owner" required placeholder="Team or accountable person"></label><label>Rate limit<input name="rate_limit" required placeholder="e.g. 60 records/hour"></label></div><label class="source-csv-field" id="sourceCsvField" hidden>CSV content<textarea name="csv_content" id="sourceCsvContent" rows="4" placeholder="Paste CSV content; it is sent only when you save this source."></textarea></label><div class="form-footer"><p id="sourceFormMessage" class="form-message" role="status"></p><button class="button primary" type="submit">Register source</button></div></form></article>
<article class="panel discovery-panel"><div class="panel-heading"><div><p class="eyebrow">DISCOVERY</p><h3>Query a source</h3></div><span class="small-label">No automatic runs</span></div><form id="discoveryForm"><label>Source<select name="source_id" id="discoverySource" required><option value="">Select a source</option></select></label><label>Query<input name="query" required placeholder="e.g. renewable energy firms in Cape Town"></label><label class="checkbox-label"><input type="checkbox" name="dry_run" id="discoveryDryRun" checked> Dry run (preview only)</label><div class="form-footer"><p id="discoveryMessage" class="form-message" role="status"></p><div class="discovery-actions"><button class="button ghost" id="discoveryDryRunBtn" type="submit">Validate query</button><button class="button primary" id="discoveryRunBtn" type="button">Run discovery</button></div></div></form></article>
</div>
<div class="sources-grid"><article class="panel source-config-panel"><div class="panel-heading"><div><p class="eyebrow">SOURCE CONFIGURATION</p><h3>Add a governed source</h3></div><span class="small-label">Registry only · starts disabled</span></div><p class="source-setup-copy">Register source ownership, terms, quotas, and provider settings here. Discovery criteria belong in Discovery runs, never in a source record.</p><form id="sourceForm"><div class="form-grid"><label>Source name<input id="sourceName" name="name" required maxlength="120" placeholder="Partner directory"></label><label>Source type<select name="source_type" id="sourceType"><option value="manual">Manual records</option><option value="csv">CSV import</option><option value="provider">Configured provider</option></select></label><label>Owner<input id="sourceOwner" name="owner" required maxlength="120" placeholder="Accountable team or person"></label><label>Terms URL<input id="sourceTermsUrl" name="terms_url" type="url" required placeholder="https://provider.example/terms"></label><label>Terms status<select id="sourceTermsStatus" name="terms_status" required><option value="pending">Pending review</option><option value="approved">Approved</option><option value="rejected">Rejected</option></select></label><label>Rate limit<input id="sourceRateLimit" name="rate_limit" required maxlength="80" placeholder="e.g. 60 requests/hour"></label><label>Daily quota<input id="sourceDailyQuota" name="daily_quota" type="number" min="1" max="100000" required value="100"></label><label>Provider settings <span class="optional">non-query configuration only</span><textarea id="sourceProviderSettings" name="provider_settings" rows="3" placeholder='{"region":"za"}'></textarea></label></div><label class="source-csv-field" id="sourceCsvField" hidden>CSV content<textarea name="csv_content" id="sourceCsvContent" rows="4" placeholder="Paste CSV content for this registry source."></textarea></label><div class="form-footer"><p id="sourceFormMessage" class="form-message" role="status" aria-live="polite">Save configuration before testing. Enable remains unavailable until terms, owner, limits, and a successful test are recorded.</p><div class="source-form-actions"><button class="button primary" id="sourceSaveBtn" type="submit">Save configuration</button><button class="button ghost" id="sourceTestBtn" type="button" disabled title="Save a source before testing.">Test source</button><button class="button ghost" id="sourceEnableBtn" type="button" disabled title="Save and test a source before enabling.">Enable source</button></div></div><p id="sourceStatus" class="small-label" aria-live="polite">Unsaved source · disabled</p></form></article></div>
<div class="sources-list panel"><div class="panel-heading"><div><p class="eyebrow">REGISTRY STATUS</p><h3>Configured &amp; available integrations</h3><p class="muted source-registry-caption">Configured sources are shown alongside optional adapters so unavailable capability is never mistaken for an active source.</p></div><span id="sourcesUpdatedAt" class="small-label">Not loaded</span></div><div id="sourcesList" class="sources-list-body"><div class="source-empty">Sign in to load sources from the workspace.</div></div></div>
<div class="source-records panel"><div class="panel-heading"><div><p class="eyebrow">RECENT OUTPUT</p><h3>Recent source records</h3></div></div><div id="sourceRecordsList" class="source-records-body"><div class="source-empty">No records loaded.</div></div></div>
</section>
@@ -138,7 +135,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-34"></script>
<script src="app.js?v=phase-34"></script>
<script src="config.js?v=phase-35"></script>
<script src="app.js?v=phase-35"></script>
</body>
</html>