Skip to main content

a3s_flow/model/
event.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5use super::{JsonValue, RetryPolicy, WorkflowSpec};
6
7/// Event persisted as the single source of truth for a workflow run.
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9#[serde(tag = "type", rename_all = "snake_case")]
10pub enum FlowEvent {
11    RunCreated {
12        spec: WorkflowSpec,
13        input: JsonValue,
14    },
15    RunStarted,
16    RunCompleted {
17        output: JsonValue,
18    },
19    RunFailed {
20        error: String,
21    },
22    RunCancelled {
23        reason: Option<String>,
24    },
25    StepCreated {
26        step_id: String,
27        step_name: String,
28        input: JsonValue,
29        #[serde(default)]
30        retry: RetryPolicy,
31    },
32    StepStarted {
33        step_id: String,
34        attempt: u32,
35    },
36    StepCompleted {
37        step_id: String,
38        output: JsonValue,
39    },
40    StepRetrying {
41        step_id: String,
42        attempt: u32,
43        error: String,
44        retry_after: Option<DateTime<Utc>>,
45    },
46    StepFailed {
47        step_id: String,
48        attempt: u32,
49        error: String,
50    },
51    WaitCreated {
52        wait_id: String,
53        resume_at: DateTime<Utc>,
54    },
55    WaitCompleted {
56        wait_id: String,
57    },
58    HookCreated {
59        hook_id: String,
60        token: String,
61        metadata: JsonValue,
62    },
63    HookReceived {
64        hook_id: String,
65        payload: JsonValue,
66    },
67    HookDisposed {
68        hook_id: String,
69    },
70}
71
72impl FlowEvent {
73    /// Dot-separated event key for A3S-wide event routing.
74    pub fn event_key(&self) -> &'static str {
75        match self {
76            Self::RunCreated { .. } => "flow.run.created",
77            Self::RunStarted => "flow.run.started",
78            Self::RunCompleted { .. } => "flow.run.completed",
79            Self::RunFailed { .. } => "flow.run.failed",
80            Self::RunCancelled { .. } => "flow.run.cancelled",
81            Self::StepCreated { .. } => "flow.step.created",
82            Self::StepStarted { .. } => "flow.step.started",
83            Self::StepCompleted { .. } => "flow.step.completed",
84            Self::StepRetrying { .. } => "flow.step.retrying",
85            Self::StepFailed { .. } => "flow.step.failed",
86            Self::WaitCreated { .. } => "flow.wait.created",
87            Self::WaitCompleted { .. } => "flow.wait.completed",
88            Self::HookCreated { .. } => "flow.hook.created",
89            Self::HookReceived { .. } => "flow.hook.received",
90            Self::HookDisposed { .. } => "flow.hook.disposed",
91        }
92    }
93}
94
95/// Stored event with per-run sequence and timestamp.
96#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
97pub struct FlowEventEnvelope {
98    pub run_id: String,
99    pub sequence: u64,
100    pub event_id: Uuid,
101    pub timestamp: DateTime<Utc>,
102    pub event: FlowEvent,
103}