Skip to main content

a3s_flow/model/
event.rs

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