use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::time::{SystemTime, UNIX_EPOCH};
use super::strategy::{StrategyMap, StrategyStep};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionJournal {
pub strategy: StrategyMap,
pub steps: Vec<StepRecord>,
}
impl ExecutionJournal {
pub fn new(strategy: StrategyMap) -> Self {
Self {
strategy,
steps: Vec::new(),
}
}
pub fn record_step(&mut self, record: StepRecord) {
self.steps.push(record);
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum StepStatus {
Pending,
Running,
Completed,
Failed,
Skipped,
PausedForApproval,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StepRecord {
pub step_id: String,
pub title: String,
pub agent: String,
pub status: StepStatus,
pub output_key: Option<String>,
pub output: Option<JsonValue>,
pub error: Option<String>,
pub recorded_at_ms: u64,
}
impl StepRecord {
pub fn from_step(
step: &StrategyStep,
status: StepStatus,
output: Option<JsonValue>,
error: Option<String>,
) -> Self {
Self::with_timestamp(step, status, output, error, current_timestamp_ms())
}
pub fn with_timestamp(
step: &StrategyStep,
status: StepStatus,
output: Option<JsonValue>,
error: Option<String>,
recorded_at_ms: u64,
) -> Self {
Self {
step_id: step.step_id.clone(),
title: step.description.clone(),
agent: step.assigned_agent.clone(),
status,
output_key: step.output_key.clone(),
output,
error,
recorded_at_ms,
}
}
}
pub fn current_timestamp_ms() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_millis() as u64)
.unwrap_or(0)
}