# `PgFlow.Flow.Step`
[🔗](https://github.com/agoodway/pgflow/blob/v0.1.0/lib/pgflow/flow/step.ex#L1)

Represents a single step in a flow definition.

A step is the basic unit of work in a PgFlow workflow. Each step has:
- A unique slug identifier
- A type (`:single` or `:map`)
- Optional dependencies on other steps
- Optional retry configuration (max_attempts, base_delay, timeout)
- Optional start delay

## Step Types

- `:single` - Executes once with the flow's input data
- `:map` - Executes multiple times, once for each item in an array from a dependency

## Examples

    # Simple step with no dependencies
    %PgFlow.Flow.Step{
      slug: :fetch_user,
      step_type: :single
    }

    # Step with dependencies and custom retry settings
    %PgFlow.Flow.Step{
      slug: :send_email,
      step_type: :single,
      depends_on: [:fetch_user, :prepare_template],
      max_attempts: 5,
      base_delay: 2000
    }

    # Map step that processes an array
    %PgFlow.Flow.Step{
      slug: :process_items,
      step_type: :map,
      depends_on: [:fetch_items]
    }

# `step_type`

```elixir
@type step_type() :: :single | :map
```

# `t`

```elixir
@type t() :: %PgFlow.Flow.Step{
  base_delay: pos_integer() | nil,
  depends_on: [atom()],
  max_attempts: pos_integer() | nil,
  slug: atom(),
  start_delay: pos_integer() | nil,
  step_type: step_type(),
  timeout: pos_integer() | nil
}
```

# `from_tuple`

```elixir
@spec from_tuple(atom() | {atom(), keyword()}) :: t()
```

Converts a step tuple from the DSL into a Step struct.

Accepts tuples in the format:
- `{name, opts}` - Step with options
- `name` - Step with just a slug (converted to tuple internally)

## Options

- `:depends_on` - List of step slugs this step depends on (default: `[]`)
- `:step_type` - Either `:single` or `:map` (default: `:single`)
- `:max_attempts` - Maximum retry attempts (default: flow default)
- `:base_delay` - Base delay in milliseconds for exponential backoff (default: flow default)
- `:timeout` - Timeout in milliseconds (default: flow default)
- `:start_delay` - Delay in milliseconds before starting (default: `nil`)

## Examples

    iex> PgFlow.Flow.Step.from_tuple(:fetch_user)
    %PgFlow.Flow.Step{slug: :fetch_user, step_type: :single, depends_on: []}

    iex> PgFlow.Flow.Step.from_tuple({:send_email, depends_on: [:fetch_user]})
    %PgFlow.Flow.Step{
      slug: :send_email,
      step_type: :single,
      depends_on: [:fetch_user]
    }

    iex> PgFlow.Flow.Step.from_tuple({:process_items, step_type: :map, depends_on: [:fetch_items]})
    %PgFlow.Flow.Step{
      slug: :process_items,
      step_type: :map,
      depends_on: [:fetch_items]
    }

# `slug_to_string`

```elixir
@spec slug_to_string(atom()) :: String.t()
```

Converts a step slug (atom) to a string for database storage.

## Examples

    iex> PgFlow.Flow.Step.slug_to_string(:fetch_user)
    "fetch_user"

    iex> PgFlow.Flow.Step.slug_to_string(:send_email)
    "send_email"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
