fix(pipeline): fix mark-failed CSS bug + add per-extractor run buttons

- Redirect pipeline_mark_stale to pipeline_dashboard (full page) instead
  of pipeline_extractions (partial), fixing the broken CSS on form submit
- pipeline_trigger_extract accepts optional 'extractor' POST field;
  validates against workflows.toml names to prevent injection, passes
  as payload to enqueue("run_extraction")
- handle_run_extraction dispatches to per-extractor CLI entry point
  (extract-overpass, extract-eurostat, etc.) when extractor is set,
  falls back to umbrella 'extract' command otherwise
- pipeline_overview.html: add Run button to each workflow card header,
  posting extractor name with CSRF token to pipeline_trigger_extract

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-27 11:37:39 +01:00
parent 120f974970
commit fa7604301a
3 changed files with 36 additions and 7 deletions

View File

@@ -515,7 +515,7 @@ async def pipeline_mark_stale(run_id: int):
await flash(f"Run #{run_id} marked as failed.", "success")
else:
await flash(f"Run #{run_id} could not be updated (not in 'running' state).", "warning")
return redirect(url_for("pipeline.pipeline_extractions"))
return redirect(url_for("pipeline.pipeline_dashboard"))
# ── Trigger extraction ────────────────────────────────────────────────────────
@@ -525,11 +525,23 @@ async def pipeline_mark_stale(run_id: int):
@role_required("admin")
@csrf_protect
async def pipeline_trigger_extract():
"""Enqueue a full pipeline extraction run."""
"""Enqueue an extraction run — all extractors, or a single named one."""
from ..worker import enqueue
await enqueue("run_extraction")
await flash("Extraction run queued. Check the task queue for progress.", "success")
form = await request.form
extractor = (form.get("extractor") or "").strip()
if extractor:
valid_names = {wf["name"] for wf in await asyncio.to_thread(_load_workflows)}
if extractor not in valid_names:
await flash(f"Unknown extractor '{extractor}'.", "warning")
return redirect(url_for("pipeline.pipeline_dashboard"))
await enqueue("run_extraction", {"extractor": extractor})
await flash(f"Extractor '{extractor}' queued. Check the task queue for progress.", "success")
else:
await enqueue("run_extraction")
await flash("Extraction run queued. Check the task queue for progress.", "success")
return redirect(url_for("pipeline.pipeline_dashboard"))