mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-07 03:00:29 +00:00
Remove NodeOutcomeRecord alias; embed CatalogRecord in RunSummary
NodeOutcomeRecord was a duplicate alias for Outcome<Option<StageUsage>> which fabro-workflow already calls Outcome. Inline the type instead. RunSummary duplicated CatalogRecord's four fields. Use #[serde(flatten)] to embed CatalogRecord directly, eliminating the duplication. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7bc0b5db3a
commit
22115a180b
6 changed files with 24 additions and 32 deletions
|
|
@ -15,9 +15,6 @@ pub use runtime::RuntimeState;
|
|||
pub use slate::{SlateRunStore, SlateStore};
|
||||
pub use types::{CatalogRecord, EventEnvelope, EventPayload, NodeVisitRef, RunSummary};
|
||||
|
||||
use fabro_types::{Outcome, StageUsage};
|
||||
|
||||
pub type NodeOutcomeRecord = Outcome<Option<StageUsage>>;
|
||||
pub type StoreHandle = Arc<SlateStore>;
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -6,13 +6,11 @@ use chrono::{DateTime, Utc};
|
|||
use serde::de::DeserializeOwned;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::{
|
||||
CatalogRecord, EventEnvelope, NodeOutcomeRecord, NodeVisitRef, Result, RunSummary, StoreError,
|
||||
};
|
||||
use crate::{CatalogRecord, EventEnvelope, NodeVisitRef, Result, RunSummary, StoreError};
|
||||
use fabro_types::{
|
||||
Checkpoint, Conclusion, FailureSignature, NodeStatusRecord, Outcome, PullRequestRecord, Retro,
|
||||
RunId, RunRecord, RunStatus, RunStatusRecord, SandboxRecord, StageStatus, StartRecord,
|
||||
StatusReason,
|
||||
RunId, RunRecord, RunStatus, RunStatusRecord, SandboxRecord, StageStatus, StageUsage,
|
||||
StartRecord, StatusReason,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
|
@ -39,7 +37,7 @@ pub struct NodeState {
|
|||
pub prompt: Option<String>,
|
||||
pub response: Option<String>,
|
||||
pub status: Option<NodeStatusRecord>,
|
||||
pub outcome: Option<NodeOutcomeRecord>,
|
||||
pub outcome: Option<Outcome<Option<StageUsage>>>,
|
||||
pub provider_used: Option<serde_json::Value>,
|
||||
pub diff: Option<String>,
|
||||
pub script_invocation: Option<serde_json::Value>,
|
||||
|
|
@ -309,10 +307,7 @@ impl RunState {
|
|||
(!goal.is_empty()).then(|| goal.to_string())
|
||||
});
|
||||
RunSummary {
|
||||
run_id: catalog.run_id,
|
||||
created_at: catalog.created_at,
|
||||
db_prefix: catalog.db_prefix.clone(),
|
||||
run_dir: catalog.run_dir.clone(),
|
||||
catalog: catalog.clone(),
|
||||
workflow_name,
|
||||
workflow_slug: self.run.as_ref().and_then(|run| run.workflow_slug.clone()),
|
||||
goal,
|
||||
|
|
@ -564,7 +559,7 @@ fn stage_visit(
|
|||
|
||||
fn stage_outcome_from_properties(
|
||||
properties: &serde_json::Map<String, Value>,
|
||||
) -> Result<NodeOutcomeRecord> {
|
||||
) -> Result<Outcome<Option<StageUsage>>> {
|
||||
let status = StageStatus::from_str(&required_string(properties, "status")?)
|
||||
.map_err(|err| StoreError::InvalidEvent(format!("invalid stage status: {err}")))?;
|
||||
Ok(Outcome {
|
||||
|
|
@ -582,7 +577,7 @@ fn stage_outcome_from_properties(
|
|||
}
|
||||
|
||||
fn node_status_from_outcome(
|
||||
outcome: &NodeOutcomeRecord,
|
||||
outcome: &Outcome<Option<StageUsage>>,
|
||||
timestamp: DateTime<Utc>,
|
||||
) -> NodeStatusRecord {
|
||||
NodeStatusRecord {
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ impl SlateStore {
|
|||
let summary = summary?;
|
||||
summaries.push(summary);
|
||||
}
|
||||
summaries.sort_by(|a, b| b.created_at.cmp(&a.created_at));
|
||||
summaries.sort_by(|a, b| b.catalog.created_at.cmp(&a.catalog.created_at));
|
||||
Ok(summaries)
|
||||
}
|
||||
|
||||
|
|
@ -656,7 +656,7 @@ mod tests {
|
|||
|
||||
let summary = store.list_runs(&ListRunsQuery::default()).await.unwrap();
|
||||
assert_eq!(summary.len(), 1);
|
||||
assert_eq!(summary[0].run_id, test_run_id("run-1"));
|
||||
assert_eq!(summary[0].catalog.run_id, test_run_id("run-1"));
|
||||
assert_eq!(summary[0].workflow_name, Some("night-sky".to_string()));
|
||||
assert_eq!(summary[0].goal, Some("map the constellations".to_string()));
|
||||
assert_eq!(summary[0].status, Some(RunStatus::Succeeded));
|
||||
|
|
@ -2020,7 +2020,7 @@ mod tests {
|
|||
|
||||
let all = store.list_runs(&ListRunsQuery::default()).await.unwrap();
|
||||
assert_eq!(all.len(), 2);
|
||||
assert_eq!(all[0].run_id, test_run_id("run-late"));
|
||||
assert_eq!(all[0].catalog.run_id, test_run_id("run-late"));
|
||||
assert_eq!(all[0].workflow_name, Some("night-sky".to_string()));
|
||||
assert_eq!(all[0].goal, Some("map the constellations".to_string()));
|
||||
assert_eq!(
|
||||
|
|
@ -2040,6 +2040,6 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
assert_eq!(filtered.len(), 1);
|
||||
assert_eq!(filtered[0].run_id, test_run_id("run-late"));
|
||||
assert_eq!(filtered[0].catalog.run_id, test_run_id("run-late"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,8 @@ pub struct CatalogRecord {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RunSummary {
|
||||
pub run_id: RunId,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub db_prefix: String,
|
||||
pub run_dir: Option<String>,
|
||||
#[serde(flatten)]
|
||||
pub catalog: CatalogRecord,
|
||||
pub workflow_name: Option<String>,
|
||||
pub workflow_slug: Option<String>,
|
||||
pub goal: Option<String>,
|
||||
|
|
|
|||
|
|
@ -185,9 +185,9 @@ pub async fn find_run_id_by_prefix_or_store(
|
|||
let current_repo_root = canonical_repo_root(repo)?;
|
||||
let mut matches = Vec::new();
|
||||
for summary in fabro_store.list_runs(&ListRunsQuery::default()).await? {
|
||||
if summary.run_id.to_string() == prefix {
|
||||
if summary.catalog.run_id.to_string() == prefix {
|
||||
if summary.host_repo_path.is_none() {
|
||||
return Ok(summary.run_id);
|
||||
return Ok(summary.catalog.run_id);
|
||||
}
|
||||
|
||||
let Some(host_repo_path) = summary.host_repo_path.as_deref() else {
|
||||
|
|
@ -200,7 +200,7 @@ pub async fn find_run_id_by_prefix_or_store(
|
|||
continue;
|
||||
};
|
||||
if host_repo_root == current_repo_root {
|
||||
return Ok(summary.run_id);
|
||||
return Ok(summary.catalog.run_id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
@ -214,8 +214,10 @@ pub async fn find_run_id_by_prefix_or_store(
|
|||
let Ok(host_repo_root) = canonical_repo_root(&host_repo) else {
|
||||
continue;
|
||||
};
|
||||
if host_repo_root == current_repo_root && summary.run_id.to_string().starts_with(prefix) {
|
||||
matches.push(summary.run_id);
|
||||
if host_repo_root == current_repo_root
|
||||
&& summary.catalog.run_id.to_string().starts_with(prefix)
|
||||
{
|
||||
matches.push(summary.catalog.run_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ pub async fn scan_runs_combined(store: &SlateStore, base: &Path) -> Result<Vec<R
|
|||
let Some(run_info) = run_info_from_summary(&summary) else {
|
||||
continue;
|
||||
};
|
||||
runs_by_id.insert(summary.run_id, run_info);
|
||||
runs_by_id.insert(summary.catalog.run_id, run_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ pub async fn scan_runs_combined(store: &SlateStore, base: &Path) -> Result<Vec<R
|
|||
}
|
||||
|
||||
fn run_info_from_summary(summary: &fabro_store::RunSummary) -> Option<RunInfo> {
|
||||
let run_dir = summary.run_dir.as_deref()?;
|
||||
let run_dir = summary.catalog.run_dir.as_deref()?;
|
||||
let path = PathBuf::from(run_dir);
|
||||
if !path.exists() {
|
||||
return None;
|
||||
|
|
@ -153,7 +153,7 @@ fn run_info_from_summary(summary: &fabro_store::RunSummary) -> Option<RunInfo> {
|
|||
let dir_name = path
|
||||
.file_name()
|
||||
.map(|name| name.to_string_lossy().to_string())?;
|
||||
let start_time_dt = summary.created_at;
|
||||
let start_time_dt = summary.catalog.created_at;
|
||||
let start_time = summary.start_time.unwrap_or(start_time_dt);
|
||||
let end_time = if summary.status.is_some_and(RunStatus::is_terminal) {
|
||||
summary.duration_ms.and_then(|duration_ms| {
|
||||
|
|
@ -164,7 +164,7 @@ fn run_info_from_summary(summary: &fabro_store::RunSummary) -> Option<RunInfo> {
|
|||
};
|
||||
|
||||
Some(RunInfo {
|
||||
run_id: summary.run_id,
|
||||
run_id: summary.catalog.run_id,
|
||||
dir_name,
|
||||
workflow_name: summary
|
||||
.workflow_name
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue