Module: Operandi::Dsl::StepsDsl::ClassMethods

Defined in:
lib/operandi/dsl/steps_dsl.rb

Instance Method Summary collapse

Instance Method Details

#remove_step(name) ⇒ Object

Remove a step from the service

Parameters:

  • name (Symbol)

    the step name to remove



79
80
81
82
83
84
# File 'lib/operandi/dsl/steps_dsl.rb', line 79

def remove_step(name)
  step_operations << { action: :remove, name: name }

  # Clear memoized steps since we're modifying them
  @steps = nil
end

#step(name, opts = {}) ⇒ Object

Define a step for the service

Examples:

Define a simple step

step :validate_input

Define a conditional step

step :send_notification, if: :should_notify?
step :skip_validation, unless: :production?

Define a step that always runs

step :cleanup, always: true

Define step ordering

step :log_start, before: :validate_input
step :log_end, after: :process_data

Define a step with proc condition

step :premium_feature, if: -> { user.premium? && feature_enabled? }

Parameters:

  • name (Symbol)

    the step name (must correspond to a private method)

  • opts (Hash) (defaults to: {})

    options for configuring the step

Options Hash (opts):

  • :if (Symbol, Proc)

    Condition to determine if step should run

  • :unless (Symbol, Proc)

    Condition to skip step (returns truthy to skip)

  • :always (Boolean) — default: false

    Run step even after errors/warnings

  • :before (Symbol)

    Insert this step before the specified step

  • :after (Symbol)

    Insert this step after the specified step



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/operandi/dsl/steps_dsl.rb', line 41

def step(name, opts = {}) # rubocop:disable Metrics/MethodLength
  Validation.validate_symbol_name!(name, :step, self)
  Validation.validate_reserved_name!(name, :step, self)
  Validation.validate_name_conflicts!(name, :step, self)
  validate_step_opts!(name, opts)

  # Build current steps to check for duplicates and find insertion targets
  current = steps
  if current.key?(name)
    raise Operandi::Error,
          "Step `#{name}` is already defined in service #{self}. Each step must have a unique name."
  end

  if (target = opts[:before] || opts[:after]) && !current.key?(target)
    available = current.keys.join(", ")
    raise Operandi::Error,
          "Cannot find target step `#{target}` in service #{self}. Available steps: [#{available}]"
  end

  step_obj = Settings::Step.new(name, self, opts)

  if opts[:before] || opts[:after]
    step_operations << { action: :insert,
                         name: name,
                         step: step_obj,
                         before: opts[:before],
                         after: opts[:after], }
  else
    step_operations << { action: :add, name: name, step: step_obj }
  end

  # Clear memoized steps since we're modifying them
  @steps = nil
end

#step_operationsArray

Get the list of step operations to be applied

Returns:

  • (Array)

    list of operations



96
97
98
# File 'lib/operandi/dsl/steps_dsl.rb', line 96

def step_operations
  @step_operations ||= []
end

#stepsHash

Get all steps including inherited ones

Returns:

  • (Hash)

    all steps defined for this service



89
90
91
# File 'lib/operandi/dsl/steps_dsl.rb', line 89

def steps
  @steps ||= build_steps
end

#validate_steps!Object

Validate that the service has steps defined Called before executing the service

Raises:



104
105
106
107
108
109
# File 'lib/operandi/dsl/steps_dsl.rb', line 104

def validate_steps!
  return unless steps.empty?

  raise Operandi::NoStepsError,
        "Service #{self} has no steps defined. Define at least one step or implement a `run` method."
end