research canvas: collapsible sidebar + live topology-run logs (#6)
ci / gates (push) Successful in 6s
ci / frontend (push) Failing after 21s
ci / rust (push) Successful in 4m12s
ci / e2e (push) Skipped
ci / publish (push) Skipped

This commit was merged in pull request #6.
This commit is contained in:
2026-07-15 17:01:48 +00:00
parent 13ead5cb9f
commit 1d69866bcf
7 changed files with 433 additions and 2 deletions
+25
View File
@@ -167,6 +167,31 @@ pub async fn active_runs_for_research_topic(
Ok(row.n.unwrap_or(0))
}
/// Live-run panel companion to `active_runs_for_research_topic`: return
/// the actual run ids (queued + running) so the UI can subscribe to
/// their SSE event streams. Ordered newest first — the freshest run is
/// the one the user just kicked off.
pub async fn active_run_ids_for_research_topic(
pool: &PgPool,
research_topic_id: Uuid,
) -> Result<Vec<Uuid>, DbError> {
use sqlx::Row;
// Dynamic query (not `sqlx::query!`) so cm-db builds air-gapped
// without a fresh `cargo sqlx prepare` round-trip. Schema shape is
// identical to `active_runs_for_research_topic` above.
let rows: Vec<sqlx::postgres::PgRow> = sqlx::query(
"SELECT id
FROM topology_runs
WHERE research_topic_id = $1
AND status IN ('queued', 'running')
ORDER BY created_at DESC",
)
.bind(research_topic_id)
.fetch_all(pool)
.await?;
Ok(rows.into_iter().map(|r| r.get::<Uuid, _>("id")).collect())
}
/// The research topic this run belongs to, if any. Used by the topology
/// worker's `freeze_research_outcome` post-hook to snapshot the run's
/// final synthesis into `research_outcomes`.