pub struct ApprovalConfig { /* private fields */ }Expand description
Configuration for a human approval step.
When the workflow reaches an approval step, the run transitions to
AwaitingApproval and waits for a human to approve or reject via
the API.
A gate can carry an SLA: with_deadline arms a timer
persisted alongside the step, and on_timeout says what
happens when it fires. The timer lives in the database, so it survives an API
or worker restart.
A gate can also require several approvers:
requiring takes the Approvers the handler computed
in Rust, from its typed input and earlier step outputs. They decide how many
distinct approvals the gate needs and which groups may vote. A config
without approvers is resolved by one approval from anyone allowed to answer
the gate.
§Examples
use ironflow_engine::config::{ApprovalConfig, Approvers};
let config = ApprovalConfig::new("Deploy to production?");
assert_eq!(config.message(), "Deploy to production?");
assert!(config.timeout_seconds().is_none());
let payment = ApprovalConfig::new("Release the payment?")
.requiring(Approvers::at_least(2).from_groups(["finance"]).because("amount > 10k"));
assert_eq!(payment.approvers().map(Approvers::required), Some(2));Implementations§
Source§impl ApprovalConfig
impl ApprovalConfig
Sourcepub fn new(message: &str) -> Self
pub fn new(message: &str) -> Self
Create a new approval config with the given message.
§Examples
use ironflow_engine::config::ApprovalConfig;
let config = ApprovalConfig::new("Approve this deployment?");
assert_eq!(config.message(), "Approve this deployment?");Sourcepub fn with_timeout_seconds(self, seconds: u64) -> Self
pub fn with_timeout_seconds(self, seconds: u64) -> Self
Set an auto-reject timeout in seconds.
If no approval or rejection is received within this duration, the run is automatically rejected (marked as Failed).
This is the legacy spelling of with_deadline_secs
with an implicit EscalationPolicy::AutoReject. It is now actually
enforced by the escalator; a config that sets both keeps the explicit
deadline.
§Examples
use ironflow_engine::config::{ApprovalConfig, EscalationPolicy};
let config = ApprovalConfig::new("Approve?")
.with_timeout_seconds(3600);
assert_eq!(config.timeout_seconds(), Some(3600));
assert_eq!(config.effective_deadline_secs(), Some(3600));
assert_eq!(config.effective_policy(), EscalationPolicy::AutoReject);Sourcepub fn with_deadline(self, deadline: Duration) -> Self
pub fn with_deadline(self, deadline: Duration) -> Self
Set the SLA deadline of this gate.
Sub-second precision is dropped: the deadline is stored in whole seconds.
§Panics
Panics if deadline rounds down to zero seconds.
§Examples
use std::time::Duration;
use ironflow_engine::config::ApprovalConfig;
let config = ApprovalConfig::new("Approve?")
.with_deadline(Duration::from_secs(1800));
assert_eq!(config.deadline(), Some(Duration::from_secs(1800)));Sourcepub fn with_deadline_secs(self, secs: u64) -> Self
pub fn with_deadline_secs(self, secs: u64) -> Self
Set the SLA deadline of this gate, in seconds.
§Panics
Panics if secs is zero: a gate that expires the instant it opens can
never be approved by a human.
§Examples
use ironflow_engine::config::ApprovalConfig;
let config = ApprovalConfig::new("Approve?").with_deadline_secs(1800);
assert_eq!(config.deadline_secs(), Some(1800));Sourcepub fn on_timeout(self, policy: EscalationPolicy) -> Self
pub fn on_timeout(self, policy: EscalationPolicy) -> Self
Set the policy applied when the deadline fires.
§Examples
use ironflow_engine::config::{ApprovalConfig, EscalationPolicy};
let config = ApprovalConfig::new("Approve?")
.with_deadline_secs(3600)
.on_timeout(EscalationPolicy::AutoApprove);
assert_eq!(config.effective_policy(), EscalationPolicy::AutoApprove);Sourcepub fn assigned_to(self, assignee: Assignee) -> Self
pub fn assigned_to(self, assignee: Assignee) -> Self
Assign the gate to a user or group.
§Panics
Panics if the assignee name is empty or only whitespace.
§Examples
use ironflow_engine::config::ApprovalConfig;
use ironflow_store::entities::Assignee;
let config = ApprovalConfig::new("Approve?").assigned_to(Assignee::group("release-managers"));
assert_eq!(config.assignee(), Some(&Assignee::group("release-managers")));Sourcepub fn requiring(self, approvers: Approvers) -> Self
pub fn requiring(self, approvers: Approvers) -> Self
Require the given approvers. A later call replaces an earlier one.
The engine records them on the gate when it opens, as an
ApprovalRequirement; that record
stays the source of truth on replay and resume.
§Examples
use ironflow_engine::config::{ApprovalConfig, Approvers};
let config = ApprovalConfig::new("Approve?")
.requiring(Approvers::at_least(3).from_groups(["finance", "board"]));
assert_eq!(config.approvers().map(Approvers::required), Some(3));Sourcepub fn approvers(&self) -> Option<&Approvers>
pub fn approvers(&self) -> Option<&Approvers>
The approvers this gate requires, if any were set.
§Examples
use ironflow_engine::config::ApprovalConfig;
assert!(ApprovalConfig::new("Approve?").approvers().is_none());Sourcepub fn timeout_seconds(&self) -> Option<u64>
pub fn timeout_seconds(&self) -> Option<u64>
Optional auto-reject timeout in seconds.
Sourcepub fn deadline(&self) -> Option<Duration>
pub fn deadline(&self) -> Option<Duration>
The configured SLA deadline, if any.
§Examples
use std::time::Duration;
use ironflow_engine::config::ApprovalConfig;
let config = ApprovalConfig::new("Approve?").with_deadline_secs(60);
assert_eq!(config.deadline(), Some(Duration::from_secs(60)));Sourcepub fn deadline_secs(&self) -> Option<u64>
pub fn deadline_secs(&self) -> Option<u64>
The configured SLA deadline in seconds, if any.
Sourcepub fn on_timeout_policy(&self) -> Option<&EscalationPolicy>
pub fn on_timeout_policy(&self) -> Option<&EscalationPolicy>
The configured escalation policy, if any.
Sourcepub fn effective_deadline_secs(&self) -> Option<u64>
pub fn effective_deadline_secs(&self) -> Option<u64>
The deadline actually enforced, in seconds.
with_deadline_secs wins; the legacy
with_timeout_seconds is honoured as a
fallback so configs written before escalation existed finally behave the
way their documentation always promised.
§Examples
use ironflow_engine::config::ApprovalConfig;
let legacy = ApprovalConfig::new("Approve?").with_timeout_seconds(7200);
assert_eq!(legacy.effective_deadline_secs(), Some(7200));
let both = legacy.with_deadline_secs(60);
assert_eq!(both.effective_deadline_secs(), Some(60));
assert_eq!(ApprovalConfig::new("Approve?").effective_deadline_secs(), None);Sourcepub fn effective_policy(&self) -> EscalationPolicy
pub fn effective_policy(&self) -> EscalationPolicy
The policy applied when the deadline fires. Defaults to
EscalationPolicy::AutoReject, matching the documented meaning of
timeout_seconds.
§Examples
use ironflow_engine::config::{ApprovalConfig, EscalationPolicy};
let config = ApprovalConfig::new("Approve?").with_deadline_secs(60);
assert_eq!(config.effective_policy(), EscalationPolicy::AutoReject);