# `ExGram.FSM.Flow`
[🔗](https://github.com/rockneurotiko/ex_gram_fsm/blob/v0.1.0/lib/ex_gram/fsm/flow.ex#L1)

Behaviour and DSL for declaring a named FSM conversation flow.

Each flow is an independent module that bundles a name, optional default state,
and state/transition declarations. Register flows with
`use ExGram.FSM, flows: [MyBot.RegistrationFlow, MyBot.SettingsFlow]`.

## Usage

    defmodule MyBot.RegistrationFlow do
      use ExGram.FSM.Flow, name: :registration

      defstates do
        state :get_name,  to: [:get_email]
        state :get_email, to: [:confirm, :get_name]
        state :confirm,   to: []
      end

      # Optional: define the starting state when start_flow/2 is called.
      # If not defined, flow starts with state: nil (you must set it manually).
      def default_state, do: :get_name
    end

## Callbacks

| Callback | Returns | Description |
|----------|---------|-------------|
| `flow_name/0` | `atom()` | The unique flow name atom |
| `default_state/0` | `atom() \| nil` | Initial state when flow starts (override if needed) |
| `states/0` | `[atom()]` | All valid state atoms |
| `transitions/0` | `%{atom() => [atom()]} \| :any` | Allowed transitions |

## Notes

- `flow_name/0` is generated from the `:name` option and cannot be overridden.
- `default_state/0` defaults to `nil`; override with your own `def default_state, do: :get_name`.
- `states/0` and `transitions/0` are generated by the `defstates` block (same as `ExGram.FSM.States`).
- The `:name` option is required. A `CompileError` is raised if omitted.

# `default_state`

```elixir
@callback default_state() :: atom() | nil
```

Returns the initial state atom when `start_flow/2` is called, or `nil` to
start with no state set (you must call `transition/2` or `set_state/2` manually).

# `flow_name`

```elixir
@callback flow_name() :: atom()
```

Returns the unique name atom for this flow.

# `states`

```elixir
@callback states() :: [atom()]
```

Returns all valid state atoms declared in the `defstates` block.

# `transitions`

```elixir
@callback transitions() :: %{required(atom()) =&gt; [atom()]} | :any
```

Returns the allowed transitions map, or `:any` if all transitions are allowed.

When returning a map, keys are source states and values are lists of allowed
target states. Transitions not in the map are invalid.

---

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