feat(wfe-core): add models, traits, and error types
Core domain models: WorkflowInstance, ExecutionPointer, WorkflowDefinition,
WorkflowStep, Event, EventSubscription, ScheduledCommand, ExecutionError,
LifecycleEvent, PollEndpointConfig. All serde-serializable.
Provider traits: PersistenceProvider (composite of WorkflowRepository,
EventRepository, SubscriptionRepository, ScheduledCommandRepository),
DistributedLockProvider, QueueProvider, SearchIndex, LifecyclePublisher,
WorkflowMiddleware, StepMiddleware, WorkflowRegistry.
StepBody trait with StepExecutionContext for workflow step implementations.
WorkflowData marker trait (blanket impl for Serialize + DeserializeOwned).
2026-03-25 20:07:50 +00:00
|
|
|
use async_trait::async_trait;
|
|
|
|
|
|
|
|
|
|
use crate::models::{ExecutionResult, WorkflowInstance};
|
|
|
|
|
use crate::traits::step::StepExecutionContext;
|
|
|
|
|
|
|
|
|
|
/// Workflow-level middleware with default no-op implementations.
|
|
|
|
|
#[async_trait]
|
|
|
|
|
pub trait WorkflowMiddleware: Send + Sync {
|
|
|
|
|
async fn pre_workflow(&self, _instance: &WorkflowInstance) -> crate::Result<()> {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
async fn post_workflow(&self, _instance: &WorkflowInstance) -> crate::Result<()> {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Step-level middleware with default no-op implementations.
|
|
|
|
|
#[async_trait]
|
|
|
|
|
pub trait StepMiddleware: Send + Sync {
|
|
|
|
|
async fn pre_step(&self, _context: &StepExecutionContext<'_>) -> crate::Result<()> {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
async fn post_step(
|
|
|
|
|
&self,
|
|
|
|
|
_context: &StepExecutionContext<'_>,
|
|
|
|
|
_result: &ExecutionResult,
|
|
|
|
|
) -> crate::Result<()> {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
use crate::models::{ExecutionPointer, ExecutionResult, WorkflowInstance};
|
|
|
|
|
|
|
|
|
|
struct NoOpWorkflowMiddleware;
|
|
|
|
|
impl WorkflowMiddleware for NoOpWorkflowMiddleware {}
|
|
|
|
|
|
|
|
|
|
struct NoOpStepMiddleware;
|
|
|
|
|
impl StepMiddleware for NoOpStepMiddleware {}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn workflow_middleware_default_pre_workflow() {
|
|
|
|
|
let mw = NoOpWorkflowMiddleware;
|
|
|
|
|
let instance = WorkflowInstance::new("wf", 1, serde_json::json!({}));
|
|
|
|
|
mw.pre_workflow(&instance).await.unwrap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn workflow_middleware_default_post_workflow() {
|
|
|
|
|
let mw = NoOpWorkflowMiddleware;
|
|
|
|
|
let instance = WorkflowInstance::new("wf", 1, serde_json::json!({}));
|
|
|
|
|
mw.post_workflow(&instance).await.unwrap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn step_middleware_default_pre_step() {
|
|
|
|
|
use crate::models::WorkflowStep;
|
|
|
|
|
let mw = NoOpStepMiddleware;
|
|
|
|
|
let instance = WorkflowInstance::new("wf", 1, serde_json::json!({}));
|
|
|
|
|
let pointer = ExecutionPointer::new(0);
|
|
|
|
|
let step = WorkflowStep::new(0, "test_step");
|
|
|
|
|
let ctx = StepExecutionContext {
|
|
|
|
|
item: None,
|
|
|
|
|
execution_pointer: &pointer,
|
|
|
|
|
persistence_data: None,
|
|
|
|
|
step: &step,
|
|
|
|
|
workflow: &instance,
|
|
|
|
|
cancellation_token: tokio_util::sync::CancellationToken::new(),
|
2026-03-26 14:12:51 +00:00
|
|
|
host_context: None,
|
2026-04-01 14:33:27 +01:00
|
|
|
log_sink: None,
|
feat(wfe-core): add models, traits, and error types
Core domain models: WorkflowInstance, ExecutionPointer, WorkflowDefinition,
WorkflowStep, Event, EventSubscription, ScheduledCommand, ExecutionError,
LifecycleEvent, PollEndpointConfig. All serde-serializable.
Provider traits: PersistenceProvider (composite of WorkflowRepository,
EventRepository, SubscriptionRepository, ScheduledCommandRepository),
DistributedLockProvider, QueueProvider, SearchIndex, LifecyclePublisher,
WorkflowMiddleware, StepMiddleware, WorkflowRegistry.
StepBody trait with StepExecutionContext for workflow step implementations.
WorkflowData marker trait (blanket impl for Serialize + DeserializeOwned).
2026-03-25 20:07:50 +00:00
|
|
|
};
|
|
|
|
|
mw.pre_step(&ctx).await.unwrap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
|
async fn step_middleware_default_post_step() {
|
|
|
|
|
use crate::models::WorkflowStep;
|
|
|
|
|
let mw = NoOpStepMiddleware;
|
|
|
|
|
let instance = WorkflowInstance::new("wf", 1, serde_json::json!({}));
|
|
|
|
|
let pointer = ExecutionPointer::new(0);
|
|
|
|
|
let step = WorkflowStep::new(0, "test_step");
|
|
|
|
|
let ctx = StepExecutionContext {
|
|
|
|
|
item: None,
|
|
|
|
|
execution_pointer: &pointer,
|
|
|
|
|
persistence_data: None,
|
|
|
|
|
step: &step,
|
|
|
|
|
workflow: &instance,
|
|
|
|
|
cancellation_token: tokio_util::sync::CancellationToken::new(),
|
2026-03-26 14:12:51 +00:00
|
|
|
host_context: None,
|
2026-04-01 14:33:27 +01:00
|
|
|
log_sink: None,
|
feat(wfe-core): add models, traits, and error types
Core domain models: WorkflowInstance, ExecutionPointer, WorkflowDefinition,
WorkflowStep, Event, EventSubscription, ScheduledCommand, ExecutionError,
LifecycleEvent, PollEndpointConfig. All serde-serializable.
Provider traits: PersistenceProvider (composite of WorkflowRepository,
EventRepository, SubscriptionRepository, ScheduledCommandRepository),
DistributedLockProvider, QueueProvider, SearchIndex, LifecyclePublisher,
WorkflowMiddleware, StepMiddleware, WorkflowRegistry.
StepBody trait with StepExecutionContext for workflow step implementations.
WorkflowData marker trait (blanket impl for Serialize + DeserializeOwned).
2026-03-25 20:07:50 +00:00
|
|
|
};
|
|
|
|
|
let result = ExecutionResult::next();
|
|
|
|
|
mw.post_step(&ctx, &result).await.unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|