Update Rust code for nested API schema types

Update all struct constructions in demo data and server handlers to match
the new nested sub-schemas. Fix aggregate usage handler to use
AggregateUsageTotals wrapper, ModelReference, and TokenUsage. Update
test assertions from flat field paths to nested paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-03-06 13:11:26 -05:00
parent 736d4f8ba6
commit a7083bb165
2 changed files with 204 additions and 393 deletions

View file

@ -443,7 +443,7 @@ pub async fn list_workflow_runs(
) -> Response {
let items: Vec<_> = runs::list_items()
.into_iter()
.filter(|r| r.workflow == name)
.filter(|r| r.workflow.slug == name)
.collect();
paginated_response(items, &pagination)
}
@ -508,7 +508,7 @@ pub async fn create_session_stub(
let now = "2026-03-06T16:00:00Z";
(
StatusCode::CREATED,
Json(serde_json::json!({"id": id, "title": "New session", "model": "Opus 4.6", "created_at": now, "updated_at": now})),
Json(serde_json::json!({"id": id, "title": "New session", "model": {"id": "Opus 4.6"}, "created_at": now, "updated_at": now})),
)
.into_response()
}
@ -702,357 +702,191 @@ mod runs {
vec![
RunListItem {
id: "run-1".into(),
repo: "api-server".into(),
repository: RepositoryReference { name: "api-server".into() },
title: "Add rate limiting to auth endpoints".into(),
workflow: "implement".into(),
workflow: WorkflowReference { slug: "implement".into() },
status: BoardColumn::Working,
number: None,
additions: None,
deletions: None,
checks: vec![],
elapsed_secs: Some(420.0),
elapsed_warning: Some(false),
resources: Some("4 CPU / 8 GB".into()),
comments: Some(0),
pull_request: None,
timings: Some(RunTimings { elapsed_secs: 420.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-a1b2c3d4".into(), resources: Some(SandboxResources { cpu: 4, memory: 8 }) }),
question: None,
sandbox_id: Some("sb-a1b2c3d4".into()),
created_at: ts("2026-03-06T14:30:00Z"),
},
RunListItem {
id: "run-2".into(),
repo: "web-dashboard".into(),
repository: RepositoryReference { name: "web-dashboard".into() },
title: "Migrate to React Router v7".into(),
workflow: "implement".into(),
workflow: WorkflowReference { slug: "implement".into() },
status: BoardColumn::Working,
number: None,
additions: None,
deletions: None,
checks: vec![],
elapsed_secs: Some(8100.0),
elapsed_warning: Some(false),
resources: Some("8 CPU / 16 GB".into()),
comments: Some(0),
pull_request: None,
timings: Some(RunTimings { elapsed_secs: 8100.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-e5f6g7h8".into(), resources: Some(SandboxResources { cpu: 8, memory: 16 }) }),
question: None,
sandbox_id: Some("sb-e5f6g7h8".into()),
created_at: ts("2026-03-06T12:00:00Z"),
},
RunListItem {
id: "run-3".into(),
repo: "cli-tools".into(),
repository: RepositoryReference { name: "cli-tools".into() },
title: "Fix config parsing for nested values".into(),
workflow: "fix_build".into(),
workflow: WorkflowReference { slug: "fix_build".into() },
status: BoardColumn::Working,
number: None,
additions: None,
deletions: None,
checks: vec![],
elapsed_secs: Some(2700.0),
elapsed_warning: Some(false),
resources: Some("2 CPU / 4 GB".into()),
comments: Some(0),
pull_request: None,
timings: Some(RunTimings { elapsed_secs: 2700.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-i9j0k1l2".into(), resources: Some(SandboxResources { cpu: 2, memory: 4 }) }),
question: None,
sandbox_id: Some("sb-i9j0k1l2".into()),
created_at: ts("2026-03-05T09:20:00Z"),
},
RunListItem {
id: "run-4".into(),
repo: "api-server".into(),
repository: RepositoryReference { name: "api-server".into() },
title: "Update OpenAPI spec for v3".into(),
workflow: "expand".into(),
workflow: WorkflowReference { slug: "expand".into() },
status: BoardColumn::Pending,
number: None,
additions: Some(567),
deletions: Some(234),
checks: vec![],
elapsed_secs: Some(4320.0),
elapsed_warning: Some(false),
resources: None,
comments: Some(0),
question: Some("Accept or push for another round?".into()),
sandbox_id: Some("sb-q7r8s9t0".into()),
pull_request: Some(RunPullRequest { number: 0, additions: Some(567), deletions: Some(234), comments: Some(0), checks: vec![] }),
timings: Some(RunTimings { elapsed_secs: 4320.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-q7r8s9t0".into(), resources: None }),
question: Some(RunQuestion { text: "Accept or push for another round?".into() }),
created_at: ts("2026-03-04T15:00:00Z"),
},
RunListItem {
id: "run-5".into(),
repo: "shared-types".into(),
repository: RepositoryReference { name: "shared-types".into() },
title: "Add pipeline event types".into(),
workflow: "implement".into(),
workflow: WorkflowReference { slug: "implement".into() },
status: BoardColumn::Pending,
number: None,
additions: Some(145),
deletions: Some(23),
checks: vec![],
elapsed_secs: Some(1680.0),
elapsed_warning: Some(false),
resources: None,
comments: Some(0),
question: Some("Proceed from investigation to fix?".into()),
sandbox_id: Some("sb-u1v2w3x4".into()),
pull_request: Some(RunPullRequest { number: 0, additions: Some(145), deletions: Some(23), comments: Some(0), checks: vec![] }),
timings: Some(RunTimings { elapsed_secs: 1680.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-u1v2w3x4".into(), resources: None }),
question: Some(RunQuestion { text: "Proceed from investigation to fix?".into() }),
created_at: ts("2026-03-04T10:00:00Z"),
},
RunListItem {
id: "run-6".into(),
repo: "web-dashboard".into(),
repository: RepositoryReference { name: "web-dashboard".into() },
title: "Add dark mode toggle".into(),
workflow: "implement".into(),
workflow: WorkflowReference { slug: "implement".into() },
status: BoardColumn::Review,
number: Some(889),
additions: Some(234),
deletions: Some(67),
checks: vec![
CheckRun {
name: "lint".into(),
status: CheckRunStatus::Success,
duration_secs: Some(23.0),
},
CheckRun {
name: "typecheck".into(),
status: CheckRunStatus::Success,
duration_secs: Some(72.0),
},
CheckRun {
name: "unit-tests".into(),
status: CheckRunStatus::Success,
duration_secs: Some(154.0),
},
CheckRun {
name: "integration-tests".into(),
status: CheckRunStatus::Failure,
duration_secs: Some(296.0),
},
CheckRun {
name: "e2e / chrome".into(),
status: CheckRunStatus::Failure,
duration_secs: Some(182.0),
},
CheckRun {
name: "build".into(),
status: CheckRunStatus::Success,
duration_secs: Some(105.0),
},
CheckRun {
name: "coverage".into(),
status: CheckRunStatus::Skipped,
duration_secs: None,
},
],
elapsed_secs: Some(2100.0),
elapsed_warning: Some(false),
resources: None,
comments: Some(4),
pull_request: Some(RunPullRequest {
number: 889,
additions: Some(234),
deletions: Some(67),
comments: Some(4),
checks: vec![
CheckRun { name: "lint".into(), status: CheckRunStatus::Success, duration_secs: Some(23.0) },
CheckRun { name: "typecheck".into(), status: CheckRunStatus::Success, duration_secs: Some(72.0) },
CheckRun { name: "unit-tests".into(), status: CheckRunStatus::Success, duration_secs: Some(154.0) },
CheckRun { name: "integration-tests".into(), status: CheckRunStatus::Failure, duration_secs: Some(296.0) },
CheckRun { name: "e2e / chrome".into(), status: CheckRunStatus::Failure, duration_secs: Some(182.0) },
CheckRun { name: "build".into(), status: CheckRunStatus::Success, duration_secs: Some(105.0) },
CheckRun { name: "coverage".into(), status: CheckRunStatus::Skipped, duration_secs: None },
],
}),
timings: Some(RunTimings { elapsed_secs: 2100.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-m3n4o5p6".into(), resources: None }),
question: None,
sandbox_id: Some("sb-m3n4o5p6".into()),
created_at: ts("2026-03-03T16:45:00Z"),
},
RunListItem {
id: "run-7".into(),
repo: "infrastructure".into(),
repository: RepositoryReference { name: "infrastructure".into() },
title: "Terraform module for Redis cluster".into(),
workflow: "implement".into(),
workflow: WorkflowReference { slug: "implement".into() },
status: BoardColumn::Review,
number: Some(156),
additions: Some(412),
deletions: Some(0),
checks: vec![
CheckRun {
name: "lint".into(),
status: CheckRunStatus::Success,
duration_secs: Some(18.0),
},
CheckRun {
name: "typecheck".into(),
status: CheckRunStatus::Success,
duration_secs: Some(56.0),
},
CheckRun {
name: "unit-tests".into(),
status: CheckRunStatus::Pending,
duration_secs: None,
},
CheckRun {
name: "integration-tests".into(),
status: CheckRunStatus::Queued,
duration_secs: None,
},
CheckRun {
name: "build".into(),
status: CheckRunStatus::Pending,
duration_secs: None,
},
],
elapsed_secs: Some(720.0),
elapsed_warning: Some(false),
resources: None,
comments: Some(1),
pull_request: Some(RunPullRequest {
number: 156,
additions: Some(412),
deletions: Some(0),
comments: Some(1),
checks: vec![
CheckRun { name: "lint".into(), status: CheckRunStatus::Success, duration_secs: Some(18.0) },
CheckRun { name: "typecheck".into(), status: CheckRunStatus::Success, duration_secs: Some(56.0) },
CheckRun { name: "unit-tests".into(), status: CheckRunStatus::Pending, duration_secs: None },
CheckRun { name: "integration-tests".into(), status: CheckRunStatus::Queued, duration_secs: None },
CheckRun { name: "build".into(), status: CheckRunStatus::Pending, duration_secs: None },
],
}),
timings: Some(RunTimings { elapsed_secs: 720.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-y5z6a7b8".into(), resources: None }),
question: None,
sandbox_id: Some("sb-y5z6a7b8".into()),
created_at: ts("2026-03-03T11:00:00Z"),
},
RunListItem {
id: "run-8".into(),
repo: "api-server".into(),
repository: RepositoryReference { name: "api-server".into() },
title: "Implement webhook retry logic".into(),
workflow: "implement".into(),
workflow: WorkflowReference { slug: "implement".into() },
status: BoardColumn::Merge,
number: Some(1249),
additions: Some(189),
deletions: Some(45),
checks: vec![
CheckRun {
name: "lint".into(),
status: CheckRunStatus::Success,
duration_secs: Some(21.0),
},
CheckRun {
name: "typecheck".into(),
status: CheckRunStatus::Success,
duration_secs: Some(68.0),
},
CheckRun {
name: "unit-tests".into(),
status: CheckRunStatus::Success,
duration_secs: Some(192.0),
},
CheckRun {
name: "integration-tests".into(),
status: CheckRunStatus::Success,
duration_secs: Some(334.0),
},
CheckRun {
name: "e2e / chrome".into(),
status: CheckRunStatus::Success,
duration_secs: Some(262.0),
},
CheckRun {
name: "e2e / firefox".into(),
status: CheckRunStatus::Success,
duration_secs: Some(285.0),
},
CheckRun {
name: "build".into(),
status: CheckRunStatus::Success,
duration_secs: Some(121.0),
},
CheckRun {
name: "deploy-preview".into(),
status: CheckRunStatus::Success,
duration_secs: Some(93.0),
},
CheckRun {
name: "security-scan".into(),
status: CheckRunStatus::Skipped,
duration_secs: None,
},
CheckRun {
name: "performance".into(),
status: CheckRunStatus::Success,
duration_secs: Some(138.0),
},
CheckRun {
name: "bundle-size".into(),
status: CheckRunStatus::Success,
duration_secs: Some(34.0),
},
CheckRun {
name: "accessibility".into(),
status: CheckRunStatus::Success,
duration_secs: Some(72.0),
},
],
elapsed_secs: Some(259200.0),
elapsed_warning: Some(true),
resources: None,
comments: Some(7),
pull_request: Some(RunPullRequest {
number: 1249,
additions: Some(189),
deletions: Some(45),
comments: Some(7),
checks: vec![
CheckRun { name: "lint".into(), status: CheckRunStatus::Success, duration_secs: Some(21.0) },
CheckRun { name: "typecheck".into(), status: CheckRunStatus::Success, duration_secs: Some(68.0) },
CheckRun { name: "unit-tests".into(), status: CheckRunStatus::Success, duration_secs: Some(192.0) },
CheckRun { name: "integration-tests".into(), status: CheckRunStatus::Success, duration_secs: Some(334.0) },
CheckRun { name: "e2e / chrome".into(), status: CheckRunStatus::Success, duration_secs: Some(262.0) },
CheckRun { name: "e2e / firefox".into(), status: CheckRunStatus::Success, duration_secs: Some(285.0) },
CheckRun { name: "build".into(), status: CheckRunStatus::Success, duration_secs: Some(121.0) },
CheckRun { name: "deploy-preview".into(), status: CheckRunStatus::Success, duration_secs: Some(93.0) },
CheckRun { name: "security-scan".into(), status: CheckRunStatus::Skipped, duration_secs: None },
CheckRun { name: "performance".into(), status: CheckRunStatus::Success, duration_secs: Some(138.0) },
CheckRun { name: "bundle-size".into(), status: CheckRunStatus::Success, duration_secs: Some(34.0) },
CheckRun { name: "accessibility".into(), status: CheckRunStatus::Success, duration_secs: Some(72.0) },
],
}),
timings: Some(RunTimings { elapsed_secs: 259200.0, elapsed_warning: Some(true) }),
sandbox: Some(RunSandbox { id: "sb-c9d0e1f2".into(), resources: None }),
question: None,
sandbox_id: Some("sb-c9d0e1f2".into()),
created_at: ts("2026-02-28T14:00:00Z"),
},
RunListItem {
id: "run-9".into(),
repo: "cli-tools".into(),
repository: RepositoryReference { name: "cli-tools".into() },
title: "Add --verbose flag to run command".into(),
workflow: "expand".into(),
workflow: WorkflowReference { slug: "expand".into() },
status: BoardColumn::Merge,
number: Some(430),
additions: Some(56),
deletions: Some(12),
checks: vec![
CheckRun {
name: "lint".into(),
status: CheckRunStatus::Success,
duration_secs: Some(15.0),
},
CheckRun {
name: "typecheck".into(),
status: CheckRunStatus::Success,
duration_secs: Some(48.0),
},
CheckRun {
name: "unit-tests".into(),
status: CheckRunStatus::Success,
duration_secs: Some(116.0),
},
CheckRun {
name: "build".into(),
status: CheckRunStatus::Success,
duration_secs: Some(82.0),
},
CheckRun {
name: "coverage".into(),
status: CheckRunStatus::Success,
duration_secs: Some(124.0),
},
CheckRun {
name: "bundle-size".into(),
status: CheckRunStatus::Skipped,
duration_secs: None,
},
],
elapsed_secs: Some(3900.0),
elapsed_warning: Some(false),
resources: None,
comments: Some(2),
pull_request: Some(RunPullRequest {
number: 430,
additions: Some(56),
deletions: Some(12),
comments: Some(2),
checks: vec![
CheckRun { name: "lint".into(), status: CheckRunStatus::Success, duration_secs: Some(15.0) },
CheckRun { name: "typecheck".into(), status: CheckRunStatus::Success, duration_secs: Some(48.0) },
CheckRun { name: "unit-tests".into(), status: CheckRunStatus::Success, duration_secs: Some(116.0) },
CheckRun { name: "build".into(), status: CheckRunStatus::Success, duration_secs: Some(82.0) },
CheckRun { name: "coverage".into(), status: CheckRunStatus::Success, duration_secs: Some(124.0) },
CheckRun { name: "bundle-size".into(), status: CheckRunStatus::Skipped, duration_secs: None },
],
}),
timings: Some(RunTimings { elapsed_secs: 3900.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-g3h4i5j6".into(), resources: None }),
question: None,
sandbox_id: Some("sb-g3h4i5j6".into()),
created_at: ts("2026-02-27T09:00:00Z"),
},
RunListItem {
id: "run-10".into(),
repo: "shared-types".into(),
repository: RepositoryReference { name: "shared-types".into() },
title: "Export utility type helpers".into(),
workflow: "sync_drift".into(),
workflow: WorkflowReference { slug: "sync_drift".into() },
status: BoardColumn::Merge,
number: Some(76),
additions: Some(34),
deletions: Some(8),
checks: vec![
CheckRun {
name: "lint".into(),
status: CheckRunStatus::Success,
duration_secs: Some(12.0),
},
CheckRun {
name: "typecheck".into(),
status: CheckRunStatus::Success,
duration_secs: Some(34.0),
},
CheckRun {
name: "unit-tests".into(),
status: CheckRunStatus::Success,
duration_secs: Some(75.0),
},
CheckRun {
name: "build".into(),
status: CheckRunStatus::Success,
duration_secs: Some(58.0),
},
],
elapsed_secs: Some(2880.0),
elapsed_warning: Some(false),
resources: None,
comments: Some(0),
pull_request: Some(RunPullRequest {
number: 76,
additions: Some(34),
deletions: Some(8),
comments: Some(0),
checks: vec![
CheckRun { name: "lint".into(), status: CheckRunStatus::Success, duration_secs: Some(12.0) },
CheckRun { name: "typecheck".into(), status: CheckRunStatus::Success, duration_secs: Some(34.0) },
CheckRun { name: "unit-tests".into(), status: CheckRunStatus::Success, duration_secs: Some(75.0) },
CheckRun { name: "build".into(), status: CheckRunStatus::Success, duration_secs: Some(58.0) },
],
}),
timings: Some(RunTimings { elapsed_secs: 2880.0, elapsed_warning: Some(false) }),
sandbox: Some(RunSandbox { id: "sb-k7l8m9n0".into(), resources: None }),
question: None,
sandbox_id: Some("sb-k7l8m9n0".into()),
created_at: ts("2026-02-26T08:00:00Z"),
},
]
@ -1137,36 +971,28 @@ mod runs {
RunUsage {
stages: vec![
UsageStage {
stage: "Detect Drift".into(),
model: "Opus 4.6".into(),
input_tokens: 12480,
output_tokens: 3210,
stage: UsageStageRef { id: "detect-drift".into(), name: "Detect Drift".into() },
model: ModelReference { id: "Opus 4.6".into() },
usage: TokenUsage { input_tokens: 12480, output_tokens: 3210, cost: 0.48 },
runtime_secs: 72.0,
cost: 0.48,
},
UsageStage {
stage: "Propose Changes".into(),
model: "Gemini 3.1".into(),
input_tokens: 28640,
output_tokens: 8750,
stage: UsageStageRef { id: "propose-changes".into(), name: "Propose Changes".into() },
model: ModelReference { id: "Gemini 3.1".into() },
usage: TokenUsage { input_tokens: 28640, output_tokens: 8750, cost: 0.72 },
runtime_secs: 154.0,
cost: 0.72,
},
UsageStage {
stage: "Review Changes".into(),
model: "Codex 5.3".into(),
input_tokens: 9120,
output_tokens: 2640,
stage: UsageStageRef { id: "review-changes".into(), name: "Review Changes".into() },
model: ModelReference { id: "Codex 5.3".into() },
usage: TokenUsage { input_tokens: 9120, output_tokens: 2640, cost: 0.19 },
runtime_secs: 45.0,
cost: 0.19,
},
UsageStage {
stage: "Apply Changes".into(),
model: "Opus 4.6".into(),
input_tokens: 21300,
output_tokens: 6480,
stage: UsageStageRef { id: "apply-changes".into(), name: "Apply Changes".into() },
model: ModelReference { id: "Opus 4.6".into() },
usage: TokenUsage { input_tokens: 21300, output_tokens: 6480, cost: 0.87 },
runtime_secs: 118.0,
cost: 0.87,
},
],
totals: UsageTotals {
@ -1177,25 +1003,19 @@ mod runs {
},
by_model: vec![
UsageByModel {
model: "Opus 4.6".into(),
model: ModelReference { id: "Opus 4.6".into() },
stages: 2,
input_tokens: 33780,
output_tokens: 9690,
cost: 1.35,
usage: TokenUsage { input_tokens: 33780, output_tokens: 9690, cost: 1.35 },
},
UsageByModel {
model: "Gemini 3.1".into(),
model: ModelReference { id: "Gemini 3.1".into() },
stages: 1,
input_tokens: 28640,
output_tokens: 8750,
cost: 0.72,
usage: TokenUsage { input_tokens: 28640, output_tokens: 8750, cost: 0.72 },
},
UsageByModel {
model: "Codex 5.3".into(),
model: ModelReference { id: "Codex 5.3".into() },
stages: 1,
input_tokens: 9120,
output_tokens: 2640,
cost: 0.19,
usage: TokenUsage { input_tokens: 9120, output_tokens: 2640, cost: 0.19 },
},
],
}
@ -1255,32 +1075,28 @@ mod usage {
pub fn aggregate() -> AggregateUsage {
AggregateUsage {
total_runs: 9,
total_input_tokens: 643_860,
total_output_tokens: 189_720,
total_cost: 20.34,
total_runtime_secs: 3_501.0,
totals: AggregateUsageTotals {
runs: 9,
input_tokens: 643_860,
output_tokens: 189_720,
cost: 20.34,
runtime_secs: 3_501.0,
},
by_model: vec![
UsageByModel {
model: "Opus 4.6".into(),
model: ModelReference { id: "Opus 4.6".into() },
stages: 18,
input_tokens: 304_020,
output_tokens: 87_210,
cost: 12.15,
usage: TokenUsage { input_tokens: 304_020, output_tokens: 87_210, cost: 12.15 },
},
UsageByModel {
model: "Gemini 3.1".into(),
model: ModelReference { id: "Gemini 3.1".into() },
stages: 9,
input_tokens: 257_760,
output_tokens: 78_750,
cost: 6.48,
usage: TokenUsage { input_tokens: 257_760, output_tokens: 78_750, cost: 6.48 },
},
UsageByModel {
model: "Codex 5.3".into(),
model: ModelReference { id: "Codex 5.3".into() },
stages: 9,
input_tokens: 82_080,
output_tokens: 23_760,
cost: 1.71,
usage: TokenUsage { input_tokens: 82_080, output_tokens: 23_760, cost: 1.71 },
},
],
}
@ -1296,33 +1112,29 @@ mod workflows {
name: "Fix Build".into(),
slug: "fix_build".into(),
filename: "fix_build.dot".into(),
last_run: Some("2 hours ago".into()),
last_run: Some(WorkflowLastRun { label: "2 hours ago".into() }),
schedule: None,
next_run: None,
},
WorkflowListItem {
name: "Implement Feature".into(),
slug: "implement".into(),
filename: "implement.dot".into(),
last_run: Some("4 days ago".into()),
last_run: Some(WorkflowLastRun { label: "4 days ago".into() }),
schedule: None,
next_run: None,
},
WorkflowListItem {
name: "Sync Drift".into(),
slug: "sync_drift".into(),
filename: "sync_drift.dot".into(),
last_run: Some("1 day ago".into()),
last_run: Some(WorkflowLastRun { label: "1 day ago".into() }),
schedule: None,
next_run: None,
},
WorkflowListItem {
name: "Expand Product".into(),
slug: "expand".into(),
filename: "expand.dot".into(),
last_run: Some("2 weeks ago".into()),
last_run: Some(WorkflowLastRun { label: "2 weeks ago".into() }),
schedule: None,
next_run: None,
},
]
}
@ -2212,9 +2024,8 @@ mod verifications {
fn recent_results_from_def(defs: &[RecentResultDef]) -> Vec<RecentControlResult> {
defs.iter()
.map(|r| RecentControlResult {
run_id: r.run_id.into(),
run_title: r.run_title.into(),
workflow: r.workflow.into(),
run: RunReference { id: r.run_id.into(), title: r.run_title.into() },
workflow: WorkflowReference { slug: r.workflow.into() },
result: r.result,
timestamp: r.timestamp.into(),
})
@ -2293,7 +2104,7 @@ mod verifications {
slug: ctrl.slug.into(),
description: ctrl.description.into(),
type_: ctrl.type_,
category: cat.name.into(),
category: CategoryReference { name: cat.name.into() },
},
performance: ControlPerformance {
mode: ctrl.mode,
@ -2345,9 +2156,8 @@ mod retros {
pub fn list_items() -> Vec<RetroListItem> {
vec![
RetroListItem {
run_id: "run-1".into(),
workflow_name: "implement".into(),
goal: "Add rate limiting to auth endpoints".into(),
run: RunReference { id: "run-1".into(), title: "Add rate limiting to auth endpoints".into() },
workflow: WorkflowReference { slug: "implement".into() },
timestamp: ts("2026-02-28T14:32:00Z"),
smoothness: Some(SmoothnessRating::Smooth),
stats: RetroStats {
@ -2366,9 +2176,8 @@ mod retros {
friction_point_count: 0,
},
RetroListItem {
run_id: "run-2".into(),
workflow_name: "implement".into(),
goal: "Migrate to React Router v7".into(),
run: RunReference { id: "run-2".into(), title: "Migrate to React Router v7".into() },
workflow: WorkflowReference { slug: "implement".into() },
timestamp: ts("2026-02-28T10:15:00Z"),
smoothness: Some(SmoothnessRating::Bumpy),
stats: RetroStats {
@ -2390,9 +2199,8 @@ mod retros {
friction_point_count: 2,
},
RetroListItem {
run_id: "run-6".into(),
workflow_name: "implement".into(),
goal: "Add dark mode toggle".into(),
run: RunReference { id: "run-6".into(), title: "Add dark mode toggle".into() },
workflow: WorkflowReference { slug: "implement".into() },
timestamp: ts("2026-02-27T16:45:00Z"),
smoothness: Some(SmoothnessRating::Effortless),
stats: RetroStats {
@ -2410,9 +2218,8 @@ mod retros {
friction_point_count: 0,
},
RetroListItem {
run_id: "run-3".into(),
workflow_name: "fix_build".into(),
goal: "Fix config parsing for nested values".into(),
run: RunReference { id: "run-3".into(), title: "Fix config parsing for nested values".into() },
workflow: WorkflowReference { slug: "fix_build".into() },
timestamp: ts("2026-02-27T09:20:00Z"),
smoothness: Some(SmoothnessRating::Struggled),
stats: RetroStats {
@ -2431,9 +2238,8 @@ mod retros {
friction_point_count: 3,
},
RetroListItem {
run_id: "run-8".into(),
workflow_name: "implement".into(),
goal: "Implement webhook retry logic".into(),
run: RunReference { id: "run-8".into(), title: "Implement webhook retry logic".into() },
workflow: WorkflowReference { slug: "implement".into() },
timestamp: ts("2026-02-26T11:00:00Z"),
smoothness: Some(SmoothnessRating::Smooth),
stats: RetroStats {
@ -2478,7 +2284,7 @@ mod sessions {
SessionListItem {
id: uid(S1),
title: "Add rate limiting to auth endpoints".into(),
model: "Opus 4.6".into(),
model: ModelReference { id: "Opus 4.6".into() },
last_message_preview: "Done. I've created the rate limiter and wired it up...".into(),
created_at: ts("2026-03-06T14:30:00Z"),
updated_at: ts("2026-03-06T15:45:00Z"),
@ -2486,7 +2292,7 @@ mod sessions {
SessionListItem {
id: uid(S2),
title: "Fix config parsing for nested values".into(),
model: "Sonnet 4.6".into(),
model: ModelReference { id: "Sonnet 4.6".into() },
last_message_preview: "Fixed. The parser now tracks the current section header...".into(),
created_at: ts("2026-03-06T12:30:00Z"),
updated_at: ts("2026-03-06T13:15:00Z"),
@ -2494,7 +2300,7 @@ mod sessions {
SessionListItem {
id: uid(S3),
title: "Migrate to React Router v7".into(),
model: "Opus 4.6".into(),
model: ModelReference { id: "Opus 4.6".into() },
last_message_preview: "You're on React Router 6.22. The migration to v7 involves...".into(),
created_at: ts("2026-03-05T10:00:00Z"),
updated_at: ts("2026-03-05T11:30:00Z"),
@ -2502,7 +2308,7 @@ mod sessions {
SessionListItem {
id: uid(S4),
title: "Add dark mode toggle".into(),
model: "Sonnet 4.6".into(),
model: ModelReference { id: "Sonnet 4.6".into() },
last_message_preview: "Added a dark mode toggle to the settings panel with system preference detection.".into(),
created_at: ts("2026-03-05T09:00:00Z"),
updated_at: ts("2026-03-05T09:45:00Z"),
@ -2510,7 +2316,7 @@ mod sessions {
SessionListItem {
id: uid(S5),
title: "Update OpenAPI spec for v3".into(),
model: "Opus 4.6".into(),
model: ModelReference { id: "Opus 4.6".into() },
last_message_preview: "Updated all endpoint schemas to v3 format with discriminated unions.".into(),
created_at: ts("2026-03-05T08:00:00Z"),
updated_at: ts("2026-03-05T08:30:00Z"),
@ -2518,7 +2324,7 @@ mod sessions {
SessionListItem {
id: uid(S6),
title: "Terraform module for Redis cluster".into(),
model: "Opus 4.6".into(),
model: ModelReference { id: "Opus 4.6".into() },
last_message_preview: "Created the module with 3-node cluster, automatic failover, and encryption at rest.".into(),
created_at: ts("2026-03-03T15:00:00Z"),
updated_at: ts("2026-03-03T16:00:00Z"),
@ -2526,7 +2332,7 @@ mod sessions {
SessionListItem {
id: uid(S7),
title: "Add pipeline event types".into(),
model: "Sonnet 4.6".into(),
model: ModelReference { id: "Sonnet 4.6".into() },
last_message_preview: "Added PipelineStarted, StageCompleted, and PipelineFailed event types.".into(),
created_at: ts("2026-03-01T11:00:00Z"),
updated_at: ts("2026-03-01T12:00:00Z"),
@ -2534,7 +2340,7 @@ mod sessions {
SessionListItem {
id: uid(S8),
title: "Implement webhook retry logic".into(),
model: "Opus 4.6".into(),
model: ModelReference { id: "Opus 4.6".into() },
last_message_preview: "Implemented exponential backoff with jitter, max 5 retries over 24 hours.".into(),
created_at: ts("2026-02-28T09:00:00Z"),
updated_at: ts("2026-02-28T10:00:00Z"),
@ -2546,7 +2352,7 @@ mod sessions {
let parsed = id.parse::<Uuid>().ok()?;
match parsed.as_u128() {
S1 => Some(SessionDetail {
id: uid(S1), title: "Add rate limiting to auth endpoints".into(), model: "Opus 4.6".into(), created_at: ts("2026-03-06T14:30:00Z"), updated_at: ts("2026-03-06T15:45:00Z"),
id: uid(S1), title: "Add rate limiting to auth endpoints".into(), model: ModelReference { id: "Opus 4.6".into() }, created_at: ts("2026-03-06T14:30:00Z"), updated_at: ts("2026-03-06T15:45:00Z"),
turns: vec![
SessionTurn::UserTurn(UserTurn { kind: UserTurnKind::User, content: "Add rate limiting to the auth endpoints. We're getting hit with brute force attempts on /api/auth/login and /api/auth/register. Use a sliding window approach with Redis, 10 requests per minute per IP.".into(), created_at: ts("2026-02-28T10:00:00Z") }),
SessionTurn::AssistantTurn(AssistantTurn { kind: AssistantTurnKind::Assistant, content: "I'll implement sliding window rate limiting using Redis. Let me first look at the existing auth routes and middleware setup.".into(), created_at: ts("2026-02-28T10:00:15Z") }),
@ -2565,7 +2371,7 @@ mod sessions {
],
}),
S2 => Some(SessionDetail {
id: uid(S2), title: "Fix config parsing for nested values".into(), model: "Sonnet 4.6".into(), created_at: ts("2026-03-06T12:30:00Z"), updated_at: ts("2026-03-06T13:15:00Z"),
id: uid(S2), title: "Fix config parsing for nested values".into(), model: ModelReference { id: "Sonnet 4.6".into() }, created_at: ts("2026-03-06T12:30:00Z"), updated_at: ts("2026-03-06T13:15:00Z"),
turns: vec![
SessionTurn::UserTurn(UserTurn { kind: UserTurnKind::User, content: "The CLI crashes when parsing nested TOML config values like [database.connection]. Can you debug and fix this?".into(), created_at: ts("2026-02-28T10:00:00Z") }),
SessionTurn::AssistantTurn(AssistantTurn { kind: AssistantTurnKind::Assistant, content: "Let me look at the config parser to understand how nested keys are handled.".into(), created_at: ts("2026-02-28T10:00:12Z") }),
@ -2581,7 +2387,7 @@ mod sessions {
],
}),
S3 => Some(SessionDetail {
id: uid(S3), title: "Migrate to React Router v7".into(), model: "Opus 4.6".into(), created_at: ts("2026-03-05T10:00:00Z"), updated_at: ts("2026-03-05T11:30:00Z"),
id: uid(S3), title: "Migrate to React Router v7".into(), model: ModelReference { id: "Opus 4.6".into() }, created_at: ts("2026-03-05T10:00:00Z"), updated_at: ts("2026-03-05T11:30:00Z"),
turns: vec![
SessionTurn::UserTurn(UserTurn { kind: UserTurnKind::User, content: "Help me migrate our app from React Router v6 to v7. We're using createBrowserRouter with data loaders.".into(), created_at: ts("2026-02-26T10:00:00Z") }),
SessionTurn::AssistantTurn(AssistantTurn { kind: AssistantTurnKind::Assistant, content: "I'll audit your current router setup and identify what needs to change for v7. Let me scan the codebase.".into(), created_at: ts("2026-02-26T10:00:10Z") }),

View file

@ -315,19 +315,23 @@ async fn get_aggregate_usage(
.by_model
.iter()
.map(|(model, totals)| arc_types::UsageByModel {
model: model.clone(),
model: arc_types::ModelReference { id: model.clone() },
stages: totals.stages,
input_tokens: totals.input_tokens,
output_tokens: totals.output_tokens,
cost: totals.cost,
usage: arc_types::TokenUsage {
input_tokens: totals.input_tokens,
output_tokens: totals.output_tokens,
cost: totals.cost,
},
})
.collect();
let response = arc_types::AggregateUsage {
total_runs: agg.total_runs,
total_input_tokens: by_model.iter().map(|m| m.input_tokens).sum(),
total_output_tokens: by_model.iter().map(|m| m.output_tokens).sum(),
total_cost: by_model.iter().map(|m| m.cost).sum(),
total_runtime_secs: agg.total_runtime_secs,
totals: arc_types::AggregateUsageTotals {
runs: agg.total_runs,
input_tokens: by_model.iter().map(|m| m.usage.input_tokens).sum(),
output_tokens: by_model.iter().map(|m| m.usage.output_tokens).sum(),
cost: by_model.iter().map(|m| m.usage.cost).sum(),
runtime_secs: agg.total_runtime_secs,
},
by_model,
};
(StatusCode::OK, Json(response)).into_response()
@ -377,7 +381,7 @@ async fn list_runs(
.map(|(id, managed_run)| RunStatusResponse {
id: id.clone(),
status: managed_run.status,
error: managed_run.error.clone(),
error: managed_run.error.as_ref().map(|msg| arc_types::RunError { message: msg.clone() }),
queue_position: queue_positions.get(id).copied(),
created_at: managed_run.created_at,
})
@ -458,6 +462,7 @@ async fn start_run(
queue_position: None,
created_at,
}),
)
.into_response()
}
@ -690,7 +695,7 @@ async fn get_run_status(
Json(RunStatusResponse {
id: id.clone(),
status: managed_run.status,
error: managed_run.error.clone(),
error: managed_run.error.as_ref().map(|msg| arc_types::RunError { message: msg.clone() }),
created_at: managed_run.created_at,
queue_position,
}),
@ -1506,11 +1511,11 @@ mod tests {
assert_eq!(response.status(), StatusCode::OK);
let body = body_json(response.into_body()).await;
assert_eq!(body["total_runs"].as_i64().unwrap(), 0);
assert_eq!(body["total_input_tokens"].as_i64().unwrap(), 0);
assert_eq!(body["total_output_tokens"].as_i64().unwrap(), 0);
assert_eq!(body["total_cost"].as_f64().unwrap(), 0.0);
assert_eq!(body["total_runtime_secs"].as_f64().unwrap(), 0.0);
assert_eq!(body["totals"]["runs"].as_i64().unwrap(), 0);
assert_eq!(body["totals"]["input_tokens"].as_i64().unwrap(), 0);
assert_eq!(body["totals"]["output_tokens"].as_i64().unwrap(), 0);
assert_eq!(body["totals"]["cost"].as_f64().unwrap(), 0.0);
assert_eq!(body["totals"]["runtime_secs"].as_f64().unwrap(), 0.0);
assert!(body["by_model"].as_array().unwrap().is_empty());
}
@ -1562,7 +1567,7 @@ mod tests {
assert_eq!(response.status(), StatusCode::OK);
let body = body_json(response.into_body()).await;
assert_eq!(body["total_runs"].as_i64().unwrap(), 1);
assert_eq!(body["totals"]["runs"].as_i64().unwrap(), 1);
}
#[tokio::test]