Worked Example
Worked Example
This example models promotion.create for an ecommerce admin panel.
Validate the request payload.
final class ValidatePromotionInput implements FlowStepHandler { public function handle(FlowContext $context): FlowStepResult { $input = $context->input(); if (($input['discount_pct'] ?? 0) <= 0) { return FlowStepResult::failure('discount_pct must be positive'); } return FlowStepResult::success(); } }Simulate impact.
final class SimulatePromotionImpact implements FlowStepHandler { public function handle(FlowContext $context): FlowStepResult { return FlowStepResult::success( output: ['eligible_customers' => 1200], businessImpact: ['margin_risk_eur' => 4200], ); } }Persist and compensate.
Flow::define('promotion.create') ->withInput(['brand', 'discount_pct', 'starts_at', 'ends_at']) ->step('validate', ValidatePromotionInput::class) ->step('simulate', SimulatePromotionImpact::class) ->withDryRun(true) ->step('persist', PersistPromotion::class) ->compensateWith(ReversePromotion::class) ->register();
Worked example limit
This example focuses on orchestration. Production handlers still need authorization, domain validation, transactions where appropriate, and redaction for stored payloads.