///|
pub(all) struct RunHistoryInput {
bundles : Array[@workflow.AnalysisRunBundle]
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct RunHistoryEntry {
run_id : @domain.RunId
status : @workflow.AnalysisRunStatus
symbol : @domain.Symbol
timeframe : @domain.Timeframe
adapter : String
model : String
review_count : Int
blocking_review_count : Int
replay_available : Bool
export_item_count : Int
safety_ok : Bool
chart_path : String?
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct RunHistoryIndex {
total_count : Int
completed_count : Int
awaiting_market_data_count : Int
blocking_review_count : Int
replayable_count : Int
safety_issue_count : Int
entries : Array[RunHistoryEntry]
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn run_history_input(
bundles : Array[@workflow.AnalysisRunBundle],
) -> RunHistoryInput {
{ bundles, }
}
///|
fn run_history_entry(bundle : @workflow.AnalysisRunBundle) -> RunHistoryEntry {
let view = @app.operator_run_view(bundle)
let safety_report = @safety.prepare_safety_report(bundle)
{
run_id: view.run_id,
status: view.status,
symbol: view.symbol,
timeframe: view.timeframe,
adapter: view.adapter,
model: view.model,
review_count: view.review_count,
blocking_review_count: view.blocking_review_count,
replay_available: view.replay_available,
export_item_count: view.export_item_count,
safety_ok: safety_report.ok,
chart_path: view.chart_path,
}
}
///|
fn completed_count(entries : Array[RunHistoryEntry]) -> Int {
entries.fold(init=0, fn(count, entry) {
if entry.status is Completed {
count + 1
} else {
count
}
})
}
///|
fn awaiting_market_data_count(entries : Array[RunHistoryEntry]) -> Int {
entries.fold(init=0, fn(count, entry) {
if entry.status is AwaitingMarketData {
count + 1
} else {
count
}
})
}
///|
fn blocking_review_count(entries : Array[RunHistoryEntry]) -> Int {
entries.fold(init=0, fn(count, entry) { count + entry.blocking_review_count })
}
///|
fn replayable_count(entries : Array[RunHistoryEntry]) -> Int {
entries.fold(init=0, fn(count, entry) {
if entry.replay_available {
count + 1
} else {
count
}
})
}
///|
fn safety_issue_count(entries : Array[RunHistoryEntry]) -> Int {
entries.fold(init=0, fn(count, entry) {
if entry.safety_ok {
count
} else {
count + 1
}
})
}
///|
pub fn render_run_history(input : RunHistoryInput) -> RunHistoryIndex {
let entries = input.bundles.map(fn(bundle) { run_history_entry(bundle) })
{
total_count: entries.length(),
completed_count: completed_count(entries),
awaiting_market_data_count: awaiting_market_data_count(entries),
blocking_review_count: blocking_review_count(entries),
replayable_count: replayable_count(entries),
safety_issue_count: safety_issue_count(entries),
entries,
}
}