Skip to main content

wfe_core/models/
lifecycle.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct LifecycleEvent {
6    pub event_time_utc: DateTime<Utc>,
7    pub workflow_instance_id: String,
8    pub workflow_definition_id: String,
9    pub version: u32,
10    pub reference: Option<String>,
11    pub event_type: LifecycleEventType,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub enum LifecycleEventType {
16    Started,
17    Resumed,
18    Suspended,
19    Completed,
20    Terminated,
21    Error { message: String },
22    StepStarted { step_id: usize, step_name: Option<String> },
23    StepCompleted { step_id: usize, step_name: Option<String> },
24}
25
26impl LifecycleEvent {
27    pub fn new(
28        workflow_instance_id: impl Into<String>,
29        workflow_definition_id: impl Into<String>,
30        version: u32,
31        event_type: LifecycleEventType,
32    ) -> Self {
33        Self {
34            event_time_utc: Utc::now(),
35            workflow_instance_id: workflow_instance_id.into(),
36            workflow_definition_id: workflow_definition_id.into(),
37            version,
38            reference: None,
39            event_type,
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use pretty_assertions::assert_eq;
48
49    #[test]
50    fn lifecycle_event_types_are_distinct() {
51        assert_ne!(LifecycleEventType::Started, LifecycleEventType::Completed);
52    }
53
54    #[test]
55    fn serde_round_trip_simple_variant() {
56        let event = LifecycleEvent::new("wf-1", "def-1", 1, LifecycleEventType::Started);
57        let json = serde_json::to_string(&event).unwrap();
58        let deserialized: LifecycleEvent = serde_json::from_str(&json).unwrap();
59        assert_eq!(event.workflow_instance_id, deserialized.workflow_instance_id);
60        assert_eq!(event.event_type, deserialized.event_type);
61    }
62
63    #[test]
64    fn serde_round_trip_error_variant() {
65        let event = LifecycleEvent::new(
66            "wf-1",
67            "def-1",
68            1,
69            LifecycleEventType::Error {
70                message: "boom".into(),
71            },
72        );
73        let json = serde_json::to_string(&event).unwrap();
74        let deserialized: LifecycleEvent = serde_json::from_str(&json).unwrap();
75        assert_eq!(
76            deserialized.event_type,
77            LifecycleEventType::Error {
78                message: "boom".into()
79            }
80        );
81    }
82
83    #[test]
84    fn serde_round_trip_step_variant() {
85        let event = LifecycleEvent::new(
86            "wf-1",
87            "def-1",
88            1,
89            LifecycleEventType::StepStarted {
90                step_id: 3,
91                step_name: Some("ProcessOrder".into()),
92            },
93        );
94        let json = serde_json::to_string(&event).unwrap();
95        let deserialized: LifecycleEvent = serde_json::from_str(&json).unwrap();
96        assert_eq!(
97            deserialized.event_type,
98            LifecycleEventType::StepStarted {
99                step_id: 3,
100                step_name: Some("ProcessOrder".into()),
101            }
102        );
103    }
104}