Skip to main content

bpm_engine_core/
external_task.rs

1//! External Task domain: state and DTO for Worker protocol (fetch-and-lock / complete / fail).
2
3use std::collections::HashMap;
4
5/// External task lifecycle (plan §3).
6#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
7#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
8pub enum ExternalTaskState {
9    Ready,
10    Locked,
11    Completed,
12    Failed,
13}
14
15impl ExternalTaskState {
16    pub fn as_str(&self) -> &'static str {
17        match self {
18            ExternalTaskState::Ready => "READY",
19            ExternalTaskState::Locked => "LOCKED",
20            ExternalTaskState::Completed => "COMPLETED",
21            ExternalTaskState::Failed => "FAILED",
22        }
23    }
24}
25
26/// External task DTO for API and store (plan §5).
27#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
28pub struct ExternalTask {
29    pub task_id: String,
30    pub token_id: String,
31    pub process_instance_id: String,
32    pub task_type: String,
33    pub state: ExternalTaskState,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub lock_owner: Option<String>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub lock_expire_at: Option<String>,
38    pub retries: i32,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub error_message: Option<String>,
41    #[serde(default)]
42    pub variables: HashMap<String, String>,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub created_at: Option<String>,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub updated_at: Option<String>,
47}