1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::time::Duration;
9use kotoba_core::prelude::*;
10use kotoba_core::types::{GraphRef_ as GraphRef, Value, TxId};
11
12#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
14pub struct WorkflowExecutionId(pub String);
15
16#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
18pub struct ActivityExecutionId(pub String);
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct WorkflowIR {
23 pub id: String,
24 pub name: String,
25 pub description: Option<String>,
26 pub version: String,
27
28 pub inputs: Vec<WorkflowParam>,
30
31 pub outputs: Vec<WorkflowParam>,
33
34 pub strategy: WorkflowStrategyOp,
36
37 #[serde(skip_serializing_if = "Vec::is_empty")]
39 pub activities: Vec<ActivityIR>,
40
41 pub timeout: Option<Duration>,
43
44 pub retry_policy: Option<RetryPolicy>,
46
47 pub metadata: HashMap<String, Value>,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct WorkflowParam {
54 pub name: String,
55 pub param_type: String,
56 pub required: bool,
57 pub default_value: Option<Value>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(tag = "op")]
63pub enum WorkflowStrategyOp {
64 Basic {
66 strategy: StrategyOp,
67 },
68
69 Seq {
71 strategies: Vec<Box<WorkflowStrategyOp>>,
72 },
73
74 Parallel {
76 branches: Vec<Box<WorkflowStrategyOp>>,
77 #[serde(default)]
78 completion_condition: CompletionCondition,
79 },
80
81 Decision {
83 conditions: Vec<DecisionBranch>,
84 default_branch: Option<Box<WorkflowStrategyOp>>,
85 },
86
87 Wait {
89 condition: WaitCondition,
90 timeout: Option<Duration>,
91 },
92
93 Saga {
95 main_flow: Box<WorkflowStrategyOp>,
96 compensation: Box<WorkflowStrategyOp>,
97 },
98
99 Activity {
101 activity_ref: String, input_mapping: HashMap<String, String>,
103 retry_policy: Option<RetryPolicy>,
104 },
105
106 SubWorkflow {
108 workflow_ref: String,
109 input_mapping: HashMap<String, String>,
110 },
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize, Default)]
115pub enum CompletionCondition {
116 #[default]
117 All,
119 Any,
121 AtLeast(u32),
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct DecisionBranch {
128 pub condition: String, pub branch: Box<WorkflowStrategyOp>,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
134#[serde(tag = "type")]
135pub enum WaitCondition {
136 Timer {
138 duration: Duration,
139 },
140 Event {
142 event_type: String,
143 filter: Option<HashMap<String, Value>>,
144 },
145 Signal {
147 signal_name: String,
148 },
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct RetryPolicy {
154 pub initial_interval: Duration,
155 pub backoff_coefficient: f64,
156 pub maximum_interval: Option<Duration>,
157 pub maximum_attempts: u32,
158 pub non_retryable_errors: Vec<String>,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct ActivityIR {
164 pub name: String,
165 pub description: Option<String>,
166 pub inputs: Vec<ActivityParam>,
167 pub outputs: Vec<ActivityParam>,
168 pub timeout: Option<Duration>,
169 pub retry_policy: Option<RetryPolicy>,
170 pub implementation: ActivityImplementation,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct WorkflowStep {
176 pub id: String,
177 pub step_type: WorkflowStepType,
178 pub body: serde_json::Value,
179}
180
181#[derive(Debug, Clone, Serialize, Deserialize)]
183pub enum WorkflowStepType {
184 HttpCall,
186 DbQuery,
188 DbRewrite,
190 Return,
192 Activity,
194 SubWorkflow,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct ActivityParam {
201 pub name: String,
202 pub param_type: String,
203 pub required: bool,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
208#[serde(tag = "type")]
209pub enum ActivityImplementation {
210 Function {
212 function_name: String,
213 },
214 Http {
216 url: String,
217 method: String,
218 headers: HashMap<String, String>,
219 },
220 Process {
222 command: String,
223 args: Vec<String>,
224 env: HashMap<String, String>,
225 },
226 GraphQL {
228 query: String,
229 endpoint: String,
230 },
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct WorkflowExecution {
236 pub id: WorkflowExecutionId,
237 pub workflow_id: String,
238 pub status: ExecutionStatus,
239 pub start_time: chrono::DateTime<chrono::Utc>,
240 pub end_time: Option<chrono::DateTime<chrono::Utc>>,
241 pub inputs: HashMap<String, serde_json::Value>,
242 pub outputs: Option<HashMap<String, serde_json::Value>>,
243 pub current_graph: GraphRef,
244 pub execution_history: Vec<ExecutionEvent>,
245 pub retry_count: u32,
246 pub timeout_at: Option<chrono::DateTime<chrono::Utc>>,
247}
248
249#[derive(Debug, Clone, Serialize, Deserialize)]
251pub enum ExecutionStatus {
252 Running,
253 Completed,
254 Failed,
255 Cancelled,
256 TimedOut,
257 Compensating,
258}
259
260#[derive(Debug, Clone, Serialize, Deserialize)]
262pub struct ExecutionEvent {
263 pub id: String,
264 pub timestamp: chrono::DateTime<chrono::Utc>,
265 pub event_type: ExecutionEventType,
266 pub payload: HashMap<String, serde_json::Value>,
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize)]
271pub enum ExecutionEventType {
272 Started,
273 ActivityScheduled,
274 ActivityStarted,
275 ActivityCompleted,
276 ActivityFailed,
277 DecisionMade,
278 TimerScheduled,
279 TimerFired,
280 SignalReceived,
281 WorkflowCompleted,
282 WorkflowFailed,
283 WorkflowCancelled,
284 CompensationStarted,
285 CompensationCompleted,
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize)]
290pub struct SagaPattern {
291 pub name: String,
292 pub description: Option<String>,
293 pub main_activities: Vec<String>, pub compensation_activities: Vec<String>, pub timeout: Option<Duration>,
296}
297
298#[derive(Debug, Clone)]
300pub struct WorkflowResult {
301 pub execution_id: WorkflowExecutionId,
302 pub status: ExecutionStatus,
303 pub outputs: Option<HashMap<String, Value>>,
304 pub error: Option<String>,
305 pub execution_time: Duration,
306}
307
308#[derive(Debug, Clone)]
310pub struct ActivityResult {
311 pub activity_id: ActivityExecutionId,
312 pub status: ActivityStatus,
313 pub outputs: Option<HashMap<String, Value>>,
314 pub error: Option<String>,
315 pub execution_time: Duration,
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize)]
320pub enum ActivityStatus {
321 Scheduled,
322 Started,
323 Completed,
324 Failed,
325 Cancelled,
326 TimedOut,
327}
328
329