This is page 2 of 9. Use http://codebase.md/m-gonzalo/cosa-sai?lines=false&page={x} to view the full context.
# Directory Structure
```
├── .gitignore
├── bun.lock
├── Dockerfile
├── package.json
├── prompts
│ └── default.txt
├── README.md
├── smithery.yaml
├── src
│ ├── db.ts
│ ├── gemini.ts
│ ├── index.ts
│ ├── logger.ts
│ └── types.ts
├── test
│ ├── docs
│ │ ├── ash-docs
│ │ │ ├── ash_admin.md
│ │ │ ├── ash_appsignal.md
│ │ │ ├── ash_archival.md
│ │ │ ├── ash_authentication_phoenix.md
│ │ │ ├── ash_authentication.md
│ │ │ ├── ash_cloak.md
│ │ │ ├── ash_csv.md
│ │ │ ├── ash_cubdb.md
│ │ │ ├── ash_double_entry.md
│ │ │ ├── ash_graphql.md
│ │ │ ├── ash_json_api.md
│ │ │ ├── ash_money.md
│ │ │ ├── ash_oban.md
│ │ │ ├── ash_phoenix.md
│ │ │ ├── ash_postgres.md
│ │ │ ├── ash_rbac.md
│ │ │ ├── ash_sqlite.md
│ │ │ ├── ash_state_machine.md
│ │ │ └── ash.md
│ │ ├── bun-elysia-docs
│ │ │ ├── bun.sh.md
│ │ │ └── elysiajs.com.md
│ │ ├── javascript-docs
│ │ │ └── sample.md
│ │ └── phoenix-docs
│ │ └── phx-docs.md
│ └── prompts
│ ├── ash-framework.txt
│ ├── bun-elysia.txt
│ ├── javascript.txt
│ └── phoenix.txt
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/test/docs/ash-docs/ash_double_entry.md:
--------------------------------------------------------------------------------
```markdown
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry "View Source") API Reference ash\_double\_entry v1.0.10
## [](api-reference.html#modules)Modules
[AshDoubleEntry.Account](AshDoubleEntry.Account.html)
An extension for creating a double entry ledger account. See the getting started guide for more.
[AshDoubleEntry.Account.Info](AshDoubleEntry.Account.Info.html)
Introspection helpers for [`AshDoubleEntry.Account`](AshDoubleEntry.Account.html)
[AshDoubleEntry.Balance](AshDoubleEntry.Balance.html)
An extension for creating a double entry ledger balance. See the getting started guide for more.
[AshDoubleEntry.Balance.Info](AshDoubleEntry.Balance.Info.html)
Introspection helpers for [`AshDoubleEntry.Balance`](AshDoubleEntry.Balance.html)
[AshDoubleEntry.Transfer](AshDoubleEntry.Transfer.html)
An extension for creating a double entry ledger transfer. See the getting started guide for more.
[AshDoubleEntry.Transfer.Info](AshDoubleEntry.Transfer.Info.html)
Introspection helpers for [`AshDoubleEntry.Transfer`](AshDoubleEntry.Transfer.html)
[AshDoubleEntry.ULID](AshDoubleEntry.ULID.html)
An Ash type for ULID strings.
## [](api-reference.html#mix-tasks)Mix Tasks
[mix ash\_double\_entry.install](Mix.Tasks.AshDoubleEntry.Install.html)
Installs AshDoubleEntry
[Next Page → Home](readme.html)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/account.ex#L1 "View Source") AshDoubleEntry.Account (ash\_double\_entry v1.0.10)
An extension for creating a double entry ledger account. See the getting started guide for more.
# [](AshDoubleEntry.Account.html#summary)Summary
## [Functions](AshDoubleEntry.Account.html#functions)
[account(body)](AshDoubleEntry.Account.html#account/1)
# [](AshDoubleEntry.Account.html#functions)Functions
[](AshDoubleEntry.Account.html#account/1)
# account(body)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/account.ex#L39)(macro)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L1 "View Source") AshDoubleEntry.Account.Info (ash\_double\_entry v1.0.10)
Introspection helpers for [`AshDoubleEntry.Account`](AshDoubleEntry.Account.html)
# [](AshDoubleEntry.Account.Info.html#summary)Summary
## [Functions](AshDoubleEntry.Account.Info.html#functions)
[account\_balance\_resource(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_balance_resource/1)
The resource used for balances
[account\_balance\_resource!(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_balance_resource!/1)
The resource used for balances
[account\_open\_action\_accept(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_open_action_accept/1)
A list of extra attributes to be accepted by the open action. The `identifier` and `currency` attributes are always accepted.
[account\_open\_action\_accept!(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_open_action_accept!/1)
A list of extra attributes to be accepted by the open action. The `identifier` and `currency` attributes are always accepted.
[account\_options(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_options/1)
account DSL options
[account\_pre\_check\_identities\_with(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_pre_check_identities_with/1)
A domain to use to precheck generated identities. Required by certain data layers.
[account\_pre\_check\_identities\_with!(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_pre_check_identities_with!/1)
A domain to use to precheck generated identities. Required by certain data layers.
[account\_transfer\_resource(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_transfer_resource/1)
The resource used for transfers
[account\_transfer\_resource!(dsl\_or\_extended)](AshDoubleEntry.Account.Info.html#account_transfer_resource!/1)
The resource used for transfers
# [](AshDoubleEntry.Account.Info.html#functions)Functions
[](AshDoubleEntry.Account.Info.html#account_balance_resource/1)
# account\_balance\_resource(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_balance_resource(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
The resource used for balances
[](AshDoubleEntry.Account.Info.html#account_balance_resource!/1)
# account\_balance\_resource!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_balance_resource!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
The resource used for balances
[](AshDoubleEntry.Account.Info.html#account_open_action_accept/1)
# account\_open\_action\_accept(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_open_action_accept(dsl_or_extended :: module() | map()) ::
{:ok, [atom()]} | :error
```
A list of extra attributes to be accepted by the open action. The `identifier` and `currency` attributes are always accepted.
[](AshDoubleEntry.Account.Info.html#account_open_action_accept!/1)
# account\_open\_action\_accept!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_open_action_accept!(dsl_or_extended :: module() | map()) ::
[atom()] | no_return()
```
A list of extra attributes to be accepted by the open action. The `identifier` and `currency` attributes are always accepted.
[](AshDoubleEntry.Account.Info.html#account_options/1)
# account\_options(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_options(dsl_or_extended :: module() | map()) :: %{
required(atom()) => any()
}
```
account DSL options
Returns a map containing the and any configured or default values.
[](AshDoubleEntry.Account.Info.html#account_pre_check_identities_with/1)
# account\_pre\_check\_identities\_with(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_pre_check_identities_with(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
A domain to use to precheck generated identities. Required by certain data layers.
[](AshDoubleEntry.Account.Info.html#account_pre_check_identities_with!/1)
# account\_pre\_check\_identities\_with!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_pre_check_identities_with!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
A domain to use to precheck generated identities. Required by certain data layers.
[](AshDoubleEntry.Account.Info.html#account_transfer_resource/1)
# account\_transfer\_resource(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_transfer_resource(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
The resource used for transfers
[](AshDoubleEntry.Account.Info.html#account_transfer_resource!/1)
# account\_transfer\_resource!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/account/info.ex#L3)
```
@spec account_transfer_resource!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
The resource used for transfers
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/balance.ex#L1 "View Source") AshDoubleEntry.Balance (ash\_double\_entry v1.0.10)
An extension for creating a double entry ledger balance. See the getting started guide for more.
# [](AshDoubleEntry.Balance.html#summary)Summary
## [Functions](AshDoubleEntry.Balance.html#functions)
[balance(body)](AshDoubleEntry.Balance.html#balance/1)
# [](AshDoubleEntry.Balance.html#functions)Functions
[](AshDoubleEntry.Balance.html#balance/1)
# balance(body)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/balance.ex#L42)(macro)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L1 "View Source") AshDoubleEntry.Balance.Info (ash\_double\_entry v1.0.10)
Introspection helpers for [`AshDoubleEntry.Balance`](AshDoubleEntry.Balance.html)
# [](AshDoubleEntry.Balance.Info.html#summary)Summary
## [Functions](AshDoubleEntry.Balance.Info.html#functions)
[balance\_account\_resource(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_account_resource/1)
The resource used for accounts
[balance\_account\_resource!(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_account_resource!/1)
The resource used for accounts
[balance\_data\_layer\_can\_add\_money?(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_data_layer_can_add_money?/1)
Whether or not the data layer supports adding money.
[balance\_money\_composite\_type?(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_money_composite_type?/1)
Whether the balance is stored as a composite type.
[balance\_options(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_options/1)
balance DSL options
[balance\_pre\_check\_identities\_with(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_pre_check_identities_with/1)
A domain to use to precheck generated identities. Required by certain data layers.
[balance\_pre\_check\_identities\_with!(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_pre_check_identities_with!/1)
A domain to use to precheck generated identities. Required by certain data layers.
[balance\_transfer\_resource(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_transfer_resource/1)
The resource used for transfers
[balance\_transfer\_resource!(dsl\_or\_extended)](AshDoubleEntry.Balance.Info.html#balance_transfer_resource!/1)
The resource used for transfers
# [](AshDoubleEntry.Balance.Info.html#functions)Functions
[](AshDoubleEntry.Balance.Info.html#balance_account_resource/1)
# balance\_account\_resource(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_account_resource(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
The resource used for accounts
[](AshDoubleEntry.Balance.Info.html#balance_account_resource!/1)
# balance\_account\_resource!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_account_resource!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
The resource used for accounts
[](AshDoubleEntry.Balance.Info.html#balance_data_layer_can_add_money?/1)
# balance\_data\_layer\_can\_add\_money?(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_data_layer_can_add_money?(dsl_or_extended :: module() | map()) ::
boolean()
```
Whether or not the data layer supports adding money.
[](AshDoubleEntry.Balance.Info.html#balance_money_composite_type?/1)
# balance\_money\_composite\_type?(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_money_composite_type?(dsl_or_extended :: module() | map()) :: boolean()
```
Whether the balance is stored as a composite type.
[](AshDoubleEntry.Balance.Info.html#balance_options/1)
# balance\_options(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_options(dsl_or_extended :: module() | map()) :: %{
required(atom()) => any()
}
```
balance DSL options
Returns a map containing the and any configured or default values.
[](AshDoubleEntry.Balance.Info.html#balance_pre_check_identities_with/1)
# balance\_pre\_check\_identities\_with(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_pre_check_identities_with(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
A domain to use to precheck generated identities. Required by certain data layers.
[](AshDoubleEntry.Balance.Info.html#balance_pre_check_identities_with!/1)
# balance\_pre\_check\_identities\_with!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_pre_check_identities_with!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
A domain to use to precheck generated identities. Required by certain data layers.
[](AshDoubleEntry.Balance.Info.html#balance_transfer_resource/1)
# balance\_transfer\_resource(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_transfer_resource(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
The resource used for transfers
[](AshDoubleEntry.Balance.Info.html#balance_transfer_resource!/1)
# balance\_transfer\_resource!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/balance/info.ex#L3)
```
@spec balance_transfer_resource!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
The resource used for transfers
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/transfer.ex#L1 "View Source") AshDoubleEntry.Transfer (ash\_double\_entry v1.0.10)
An extension for creating a double entry ledger transfer. See the getting started guide for more.
# [](AshDoubleEntry.Transfer.html#summary)Summary
## [Functions](AshDoubleEntry.Transfer.html#functions)
[transfer(body)](AshDoubleEntry.Transfer.html#transfer/1)
# [](AshDoubleEntry.Transfer.html#functions)Functions
[](AshDoubleEntry.Transfer.html#transfer/1)
# transfer(body)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/transfer.ex#L42)(macro)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L1 "View Source") AshDoubleEntry.Transfer.Info (ash\_double\_entry v1.0.10)
Introspection helpers for [`AshDoubleEntry.Transfer`](AshDoubleEntry.Transfer.html)
# [](AshDoubleEntry.Transfer.Info.html#summary)Summary
## [Functions](AshDoubleEntry.Transfer.Info.html#functions)
[transfer\_account\_resource(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_account_resource/1)
The resource to use for account balances
[transfer\_account\_resource!(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_account_resource!/1)
The resource to use for account balances
[transfer\_balance\_resource(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_balance_resource/1)
The resource being used for balances
[transfer\_balance\_resource!(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_balance_resource!/1)
The resource being used for balances
[transfer\_create\_accept(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_create_accept/1)
Additional attributes to accept when creating a transfer
[transfer\_create\_accept!(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_create_accept!/1)
Additional attributes to accept when creating a transfer
[transfer\_destroy\_balances?(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_destroy_balances?/1)
Whether or not balances must be manually destroyed. See the getting started guide for more.
[transfer\_options(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_options/1)
transfer DSL options
[transfer\_pre\_check\_identities\_with(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_pre_check_identities_with/1)
A domain to use to precheck generated identities. Required by certain data layers.
[transfer\_pre\_check\_identities\_with!(dsl\_or\_extended)](AshDoubleEntry.Transfer.Info.html#transfer_pre_check_identities_with!/1)
A domain to use to precheck generated identities. Required by certain data layers.
# [](AshDoubleEntry.Transfer.Info.html#functions)Functions
[](AshDoubleEntry.Transfer.Info.html#transfer_account_resource/1)
# transfer\_account\_resource(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_account_resource(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
The resource to use for account balances
[](AshDoubleEntry.Transfer.Info.html#transfer_account_resource!/1)
# transfer\_account\_resource!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_account_resource!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
The resource to use for account balances
[](AshDoubleEntry.Transfer.Info.html#transfer_balance_resource/1)
# transfer\_balance\_resource(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_balance_resource(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
The resource being used for balances
[](AshDoubleEntry.Transfer.Info.html#transfer_balance_resource!/1)
# transfer\_balance\_resource!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_balance_resource!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
The resource being used for balances
[](AshDoubleEntry.Transfer.Info.html#transfer_create_accept/1)
# transfer\_create\_accept(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_create_accept(dsl_or_extended :: module() | map()) ::
{:ok, [atom()]} | :error
```
Additional attributes to accept when creating a transfer
[](AshDoubleEntry.Transfer.Info.html#transfer_create_accept!/1)
# transfer\_create\_accept!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_create_accept!(dsl_or_extended :: module() | map()) ::
[atom()] | no_return()
```
Additional attributes to accept when creating a transfer
[](AshDoubleEntry.Transfer.Info.html#transfer_destroy_balances?/1)
# transfer\_destroy\_balances?(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_destroy_balances?(dsl_or_extended :: module() | map()) :: boolean()
```
Whether or not balances must be manually destroyed. See the getting started guide for more.
[](AshDoubleEntry.Transfer.Info.html#transfer_options/1)
# transfer\_options(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_options(dsl_or_extended :: module() | map()) :: %{
required(atom()) => any()
}
```
transfer DSL options
Returns a map containing the and any configured or default values.
[](AshDoubleEntry.Transfer.Info.html#transfer_pre_check_identities_with/1)
# transfer\_pre\_check\_identities\_with(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_pre_check_identities_with(dsl_or_extended :: module() | map()) ::
{:ok, module()} | :error
```
A domain to use to precheck generated identities. Required by certain data layers.
[](AshDoubleEntry.Transfer.Info.html#transfer_pre_check_identities_with!/1)
# transfer\_pre\_check\_identities\_with!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/transfer/info.ex#L3)
```
@spec transfer_pre_check_identities_with!(dsl_or_extended :: module() | map()) ::
module() | no_return()
```
A domain to use to precheck generated identities. Required by certain data layers.
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L1 "View Source") AshDoubleEntry.ULID (ash\_double\_entry v1.0.10)
An Ash type for ULID strings.
# [](AshDoubleEntry.ULID.html#summary)Summary
## [Types](AshDoubleEntry.ULID.html#types)
[t()](AshDoubleEntry.ULID.html#t:t/0)
A hex-encoded ULID string.
## [Functions](AshDoubleEntry.ULID.html#functions)
[bingenerate(timestamp \\\\ System.system\_time(:millisecond))](AshDoubleEntry.ULID.html#bingenerate/1)
Generates a binary ULID.
[bingenerate\_last(timestamp \\\\ System.system\_time(:millisecond))](AshDoubleEntry.ULID.html#bingenerate_last/1)
Generates a binary ULID.
[cast\_input(value, constraints)](AshDoubleEntry.ULID.html#cast_input/2)
Casts a string to ULID.
[cast\_stored(bytes, constraints)](AshDoubleEntry.ULID.html#cast_stored/2)
Converts a binary ULID into a Crockford Base32 encoded string.
[dump\_to\_native(encoded, \_)](AshDoubleEntry.ULID.html#dump_to_native/2)
Converts a Crockford Base32 encoded ULID into a binary.
[generate(timestamp \\\\ System.system\_time(:millisecond))](AshDoubleEntry.ULID.html#generate/1)
Generates a Crockford Base32 encoded ULID.
[generate\_last(timestamp \\\\ System.system\_time(:millisecond))](AshDoubleEntry.ULID.html#generate_last/1)
Generates a Crockford Base32 encoded ULID, guaranteed to sort equal to or after any other ULID generated for the same timestamp.
[handle\_change?()](AshDoubleEntry.ULID.html#handle_change?/0)
[prepare\_change?()](AshDoubleEntry.ULID.html#prepare_change?/0)
[storage\_type()](AshDoubleEntry.ULID.html#storage_type/0)
The underlying schema type.
# [](AshDoubleEntry.ULID.html#types)Types
[](AshDoubleEntry.ULID.html#t:t/0)
# t()
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L11)
```
@type t() :: <<_::208>>
```
A hex-encoded ULID string.
# [](AshDoubleEntry.ULID.html#functions)Functions
[](AshDoubleEntry.ULID.html#bingenerate/1)
# bingenerate(timestamp \\\\ System.system\_time(:millisecond))
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L118)
Generates a binary ULID.
If a value is provided for `timestamp`, the generated ULID will be for the provided timestamp. Otherwise, a ULID will be generated for the current time.
Arguments:
- `timestamp`: A Unix timestamp with millisecond precision.
[](AshDoubleEntry.ULID.html#bingenerate_last/1)
# bingenerate\_last(timestamp \\\\ System.system\_time(:millisecond))
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L134)
Generates a binary ULID.
Do not use this for storage, only for generating comparators, i.e "balance as of a given ulid".
If a value is provided for `timestamp`, the generated ULID will be for the provided timestamp. Otherwise, a ULID will be generated for the current time.
Arguments:
- `timestamp`: A Unix timestamp with millisecond precision.
[](AshDoubleEntry.ULID.html#cast_input/2)
# cast\_input(value, constraints)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L21)
Casts a string to ULID.
[](AshDoubleEntry.ULID.html#cast_stored/2)
# cast\_stored(bytes, constraints)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L50)
Converts a binary ULID into a Crockford Base32 encoded string.
[](AshDoubleEntry.ULID.html#dump_to_native/2)
# dump\_to\_native(encoded, \_)
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L43)
Converts a Crockford Base32 encoded ULID into a binary.
[](AshDoubleEntry.ULID.html#generate/1)
# generate(timestamp \\\\ System.system\_time(:millisecond))
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L70)
Generates a Crockford Base32 encoded ULID.
If a value is provided for `timestamp`, the generated ULID will be for the provided timestamp. Otherwise, a ULID will be generated for the current time.
Arguments:
- `timestamp`: A Unix timestamp with millisecond precision.
[](AshDoubleEntry.ULID.html#generate_last/1)
# generate\_last(timestamp \\\\ System.system\_time(:millisecond))
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L95)
Generates a Crockford Base32 encoded ULID, guaranteed to sort equal to or after any other ULID generated for the same timestamp.
Do not use this for storage, only for generating comparators, i.e "balance as of a given ulid".
If a value is provided for `timestamp`, the generated ULID will be for the provided timestamp. Otherwise, a ULID will be generated for the current time.
Arguments:
- `timestamp`: A Unix timestamp with millisecond precision.
[](AshDoubleEntry.ULID.html#handle_change?/0)
# handle\_change?()
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L1)
[](AshDoubleEntry.ULID.html#prepare_change?/0)
# prepare\_change?()
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L1)
[](AshDoubleEntry.ULID.html#storage_type/0)
# storage\_type()
[](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/ulid.ex#L16)
The underlying schema type.
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/documentation/dsls/DSL-AshDoubleEntry.Account.md#L1 "View Source") AshDoubleEntry.Account
An extension for creating a double entry ledger account. See the getting started guide for more.
## [](dsl-ashdoubleentry-account.html#account)account
### [](dsl-ashdoubleentry-account.html#options)Options
NameTypeDefaultDocs[`transfer_resource`](dsl-ashdoubleentry-account.html#account-transfer_resource)`module`The resource used for transfers[`balance_resource`](dsl-ashdoubleentry-account.html#account-balance_resource)`module`The resource used for balances[`open_action_accept`](dsl-ashdoubleentry-account.html#account-open_action_accept)`list(atom)``[]`A list of extra attributes to be accepted by the open action. The `identifier` and `currency` attributes are always accepted.[`pre_check_identities_with`](dsl-ashdoubleentry-account.html#account-pre_check_identities_with)`module`A domain to use to precheck generated identities. Required by certain data layers.
[← Previous Page Get Started](getting-started-with-ash-double-entry.html)
[Next Page → AshDoubleEntry.Balance](dsl-ashdoubleentry-balance.html)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) ([current file](https://preview.hex.pm/preview/ash_double_entry/1.0.10/show/documentation/dsls/DSL-AshDoubleEntry.Account.md)) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/documentation/dsls/DSL-AshDoubleEntry.Balance.md#L1 "View Source") AshDoubleEntry.Balance
An extension for creating a double entry ledger balance. See the getting started guide for more.
## [](dsl-ashdoubleentry-balance.html#balance)balance
### [](dsl-ashdoubleentry-balance.html#options)Options
NameTypeDefaultDocs[`transfer_resource`](dsl-ashdoubleentry-balance.html#balance-transfer_resource)`module`The resource used for transfers[`account_resource`](dsl-ashdoubleentry-balance.html#balance-account_resource)`module`The resource used for accounts[`pre_check_identities_with`](dsl-ashdoubleentry-balance.html#balance-pre_check_identities_with)`module`A domain to use to precheck generated identities. Required by certain data layers.[`money_composite_type?`](dsl-ashdoubleentry-balance.html#balance-money_composite_type?)`boolean``true`Whether the balance is stored as a composite type.[`data_layer_can_add_money?`](dsl-ashdoubleentry-balance.html#balance-data_layer_can_add_money?)`boolean``true`Whether or not the data layer supports adding money.
[← Previous Page AshDoubleEntry.Account](dsl-ashdoubleentry-account.html)
[Next Page → AshDoubleEntry.Transfer](dsl-ashdoubleentry-transfer.html)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) ([current file](https://preview.hex.pm/preview/ash_double_entry/1.0.10/show/documentation/dsls/DSL-AshDoubleEntry.Balance.md)) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/documentation/dsls/DSL-AshDoubleEntry.Transfer.md#L1 "View Source") AshDoubleEntry.Transfer
An extension for creating a double entry ledger transfer. See the getting started guide for more.
## [](dsl-ashdoubleentry-transfer.html#transfer)transfer
### [](dsl-ashdoubleentry-transfer.html#options)Options
NameTypeDefaultDocs[`account_resource`](dsl-ashdoubleentry-transfer.html#transfer-account_resource)`module`The resource to use for account balances[`pre_check_identities_with`](dsl-ashdoubleentry-transfer.html#transfer-pre_check_identities_with)`module`A domain to use to precheck generated identities. Required by certain data layers.[`balance_resource`](dsl-ashdoubleentry-transfer.html#transfer-balance_resource)`module`The resource being used for balances[`create_accept`](dsl-ashdoubleentry-transfer.html#transfer-create_accept)`atom | list(atom)``[]`Additional attributes to accept when creating a transfer[`destroy_balances?`](dsl-ashdoubleentry-transfer.html#transfer-destroy_balances?)`boolean``false`Whether or not balances must be manually destroyed. See the getting started guide for more.
[← Previous Page AshDoubleEntry.Balance](dsl-ashdoubleentry-balance.html)
[Next Page → Change Log](changelog.html)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) ([current file](https://preview.hex.pm/preview/ash_double_entry/1.0.10/show/documentation/dsls/DSL-AshDoubleEntry.Transfer.md)) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/documentation/tutorials/getting-started-with-ash-double-entry.md#L1 "View Source") Getting Started with Ash Double Entry
Ash Double Entry is implemented as a set of Ash resource extensions. You build the resources yourself, and the extensions add the attributes, relationships, actions and validations required for them to constitute a double entry system.
## [](getting-started-with-ash-double-entry.html#what-makes-it-special)What makes it special?
1. Account balances are updated automatically as transfers are introduced.
2. Arbitrary custom validations and behavior by virtue of modifying your own resources.
3. Transactions can be entered in the past, and all future balances are updated (and therefore validated).
## [](getting-started-with-ash-double-entry.html#setup)Setup
### [](getting-started-with-ash-double-entry.html#setup-ashmoney)Setup AshMoney
Follow the setup guide for [`AshMoney`](../ash_money/0.1.15/AshMoney.html). If you are using with `AshPostgres`, be sure to include the `:ex_money_sql` dependency in your `mix.exs`.
### [](getting-started-with-ash-double-entry.html#add-the-dependency)Add the dependency
```
{:ash_double_entry, "~> 1.0.3"}
```
### [](getting-started-with-ash-double-entry.html#define-your-account-resource)Define your account resource
#### Example
```
defmodule YourApp.Ledger.Account do
use Ash.Resource,
domain: YourApp.Ledger,
data_layer: AshPostgres.DataLayer,
extensions: [AshDoubleEntry.Account]
postgres do
table "accounts"
repo YourApp.Repo
end
account do
# configure the other resources it will interact with
transfer_resource YourApp.Ledger.Transfer
balance_resource YourApp.Ledger.Balance
# accept custom attributes in the autogenerated `open` create action
open_action_accept [:account_number]
end
attributes do
# Add custom attributes
attribute :account_number, :string do
allow_nil? false
end
end
end
```
#### What does this extension do?
- Adds the following attributes:
- `:id`, a `:uuid` primary key
- `:currency`, a `:string` representing the currency of the account.
- `:inserted_at`, a `:utc_datetime_usec` timestamp
- `:identifier`, a `:string` and a unique identifier for the account
- Adds the following actions:
- A primary read called `:read`, unless a primary read action already exists.
- A create action called `open`, that accepts `identifier`, `currency`, and the attributes in `open_action_accept`
- A read action called `:lock_accounts` that can be used to lock a list of accounts while in a transaction(for data layers that support it)
- Adds a `has_many` relationship called `balances`, referring to all related balances of an account
- Adds an aggregate called `balance`, referring to the latest balance as a `decimal` for that account
- Adds the following calculations:
- A `balance_as_of_ulid` calculation that takes an argument called `ulid`, which corresponds to a transfer id and returns the balance.
- A `balance_as_of` calculation that takes a `utc_datetime_usec` and returns the balance as of that datetime.
- Adds an identity called `unique_identifier` that ensures `identifier` is unique.
### [](getting-started-with-ash-double-entry.html#define-your-transfer-resource)Define your transfer resource
#### Example
```
defmodule YourApp.Ledger.Transfer do
use Ash.Resource,
domain: YourApp.Ledger,
data_layer: AshPostgres.DataLayer,
extensions: [AshDoubleEntry.Transfer]
postgres do
table "transfers"
repo YourApp.Repo
end
transfer do
# configure the other resources it will interact with
account_resource YourApp.Ledger.Account
balance_resource YourApp.Ledger.Balance
# you only need this if you are using `postgres`
# and so cannot add the `references` block shown below
# destroy_balances? true
end
end
```
#### What does this extension do?
- Adds the following attributes
- `:id`, a [`AshDoubleEntry.ULID`](AshDoubleEntry.ULID.html) primary key which is sortable based on the `timestamp` of the transfer.
- `:amount`, a [`AshMoney.Types.Money`](../ash_money/0.1.15/AshMoney.Types.Money.html) representing the amount and currency of the transfer
- `:timestamp`, a `:utc_datetime_usec` representing when the transfer occurred
- `:inserted_at`, a `:utc_datetime_usec` timestamp
- Adds the following relationships
- `:from_account`, a `belongs_to` relationship of the account the transfer is from
- `:to_account`, a `belongs_to` relationship of the account the transfer is to
- Adds a `:read` action called `:read_transfers` with keyset pagination enabled. Required for streaming transfers, used for validating balances.
- Adds a change that runs on all create and update actions that reifies the balances table. It inserts a balance for the transfer, and updates any affected future balances.
### [](getting-started-with-ash-double-entry.html#define-your-balance-resource)Define your balance resource
#### Example
```
defmodule YourApp.Ledger.Balance do
use Ash.Resource,
domain: YourApp.Ledger,
data_layer: AshPostgres.DataLayer,
extensions: [AshDoubleEntry.Balance]
postgres do
table "balances"
repo YourApp.Repo
references do
reference :transfer, on_delete: :delete
end
end
balance do
# configure the other resources it will interact with
transfer_resource YourApp.Ledger.Transfer
account_resource YourApp.Ledger.Account
end
actions do
read :read do
primary? true
# configure keyset pagination for streaming
pagination keyset?: true, required?: false
end
end
end
```
### [](getting-started-with-ash-double-entry.html#cascading-destroys)cascading destroys
If you are not using a data layer capable of automatic cascade deletion, you must add `destroy_balances? true` to the `transfer` resource! We do this with the `references` block in `ash_postgres` as shown above.
#### What does this extension do?
- Adds the following attributes:
- `:id`, a `:uuid` primary key
- `:balance`, the balance as a decimal of the account at the time of the related transfer
- Adds the following relationships:
- `:transfer` a `:belongs_to` relationship, pointing to the transfer that this balance is as of.
- `:account` a `:belongs_to` relationship, pointing to the account the balance is for
- Adds the following actions:
- a primary read action called `:read`, if a priamry read action doesn't exist
- configure primary read action to have keyset pagination enabled
- a create action caleld `:upsert_balance`, which will create or update the relevant balance, by `transfer_id` and `account_id`
- Adds an identity that ensures that `account_id` and `transfer_id` are unique
### [](getting-started-with-ash-double-entry.html#define-an-ash-domain-to-use-them-through)Define an Ash domain to use them through
```
defmodule YourApp.Ledger do
use Ash.Domain
resources do
resource YourApp.Ledger.Account
resource YourApp.Ledger.Balance
resource YourApp.Ledger.Transfer
end
end
```
And add the domain to your config
`config :your_app, ash_domains: [..., YourApp.Ledger]`
### [](getting-started-with-ash-double-entry.html#generate-migrations)Generate Migrations
`mix ash_postgres.generate_migrations --name add_double_entry_ledger`
### [](getting-started-with-ash-double-entry.html#run-them)Run them
`mix ash_postgres.migrate`
### [](getting-started-with-ash-double-entry.html#use-them)Use them
#### Create an account
```
YourApp.Ledger.Account
|> Ash.Changeset.for_create(:open, %{identifier: "account_one"})
|> YourApp.Ledger.create!()
```
#### Create transfers between accounts
```
YourApp.Ledger.Transfer
|> Ash.Changeset.for_create(:transfer, %{
amount: Money.new!(20, :USD),
from_account_id: account_one.id,
to_account_id: account_two.id
})
|> YourApp.Ledger.create!()
```
#### Check an account's balance
```
YourApp.Ledger.Account
|> YourApp.Ledger.get!(account_id, load: :balance_as_of)
|> Map.get(:balance_as_of)
# => Money.new!(20, :USD)
```
## [](getting-started-with-ash-double-entry.html#what-else-can-you-do)What else can you do?
There are tons of things you can do with your resources. You can add code interfaces to give yourself a nice functional api. You can add custom attributes, aggregates, calculations, relationships, validations, changes, all the great things built into [`Ash.Resource`](../ash/3.4.56/Ash.Resource.html)! See the docs for more: [AshHq](https://ash-hq.org).
[← Previous Page Home](readme.html)
[Next Page → AshDoubleEntry.Account](dsl-ashdoubleentry-account.html)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) ([current file](https://preview.hex.pm/preview/ash_double_entry/1.0.10/show/documentation/tutorials/getting-started-with-ash-double-entry.md)) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/lib/mix/tasks/ash_double_entry.install.ex#L26 "View Source") mix ash\_double\_entry.install (ash\_double\_entry v1.0.10)
Installs AshDoubleEntry
## [](Mix.Tasks.AshDoubleEntry.Install.html#module-example)Example
```
mix ash_double_entry.install --example arg
```
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_double_entry)
[ash\_double\_entry](https://github.com/ash-project/ash_double_entry)
v1.0.10
- Pages
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_double\_entry
Settings
# [View Source](https://github.com/ash-project/ash_double_entry/blob/v1.0.10/README.md#L1 "View Source") Home
 
 [](https://opensource.org/licenses/MIT) [](https://hex.pm/packages/ash_double_entry) [](../ash_double_entry.html)
# AshDoubleEntry
Welcome! This is the extension for building a double entry accounting system in [Ash](../ash.html). This extension provides the basic building blocks for you to extend as necessary.
## [](readme.html#tutorials)Tutorials
- [Getting Started with AshDoubleEntry](getting-started-with-ash-double-entry.html)
## [](readme.html#reference)Reference
- [AshDoubleEntry.Account DSL](dsl-ashdoubleentry-account.html)
- [AshDoubleEntry.Transfer DSL](dsl-ashdoubleentry-transfer.html)
- [AshDoubleEntry.Balance DSL](dsl-ashdoubleentry-balance.html)
[← Previous Page API Reference](api-reference.html)
[Next Page → Get Started](getting-started-with-ash-double-entry.html)
[Hex Package](https://hex.pm/packages/ash_double_entry/1.0.10) [Hex Preview](https://preview.hex.pm/preview/ash_double_entry/1.0.10) ([current file](https://preview.hex.pm/preview/ash_double_entry/1.0.10/show/README.md)) Search HexDocs [Download ePub version](ash_double_entry.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.36.1) for the [Elixir programming language](https://elixir-lang.org "Elixir")
```
--------------------------------------------------------------------------------
/test/docs/ash-docs/ash_state_machine.md:
--------------------------------------------------------------------------------
```markdown
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine "View Source") API Reference ash\_state\_machine v0.2.7
## [](api-reference.html#modules)Modules
[AshStateMachine](AshStateMachine.html)
Provides tools for defining and working with resource-backed state machines.
[AshStateMachine.BuiltinChanges](AshStateMachine.BuiltinChanges.html)
Changes for working with AshStateMachine resources.
[AshStateMachine.Charts](AshStateMachine.Charts.html)
Returns a mermaid flow chart of a given state machine resource.
[AshStateMachine.Checks.ValidNextState](AshStateMachine.Checks.ValidNextState.html)
A policy for pre\_flight checking if a state transition is allowed.
[AshStateMachine.Errors.InvalidInitialState](AshStateMachine.Errors.InvalidInitialState.html)
Used when an initial state is set that is not a valid initial state
[AshStateMachine.Errors.NoMatchingTransition](AshStateMachine.Errors.NoMatchingTransition.html)
Used when a state change occurs in an action with no matching transition
[AshStateMachine.Info](AshStateMachine.Info.html)
Introspection helpers for [`AshStateMachine`](AshStateMachine.html)
[AshStateMachine.Transition](AshStateMachine.Transition.html)
The configuration for an transition.
## [](api-reference.html#mix-tasks)Mix Tasks
[mix ash\_state\_machine.generate\_flow\_charts](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html)
Generates a Mermaid Flow Chart for each [`Ash.Resource`](../ash/3.4.43/Ash.Resource.html) with the [`AshStateMachine`](AshStateMachine.html) extension alongside the resource.
[Next Page → Home](readme.html)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/builtin_changes/builtin_changes.ex#L1 "View Source") AshStateMachine.BuiltinChanges (ash\_state\_machine v0.2.7)
Changes for working with AshStateMachine resources.
# [](AshStateMachine.BuiltinChanges.html#summary)Summary
## [Functions](AshStateMachine.BuiltinChanges.html#functions)
[next\_state()](AshStateMachine.BuiltinChanges.html#next_state/0)
Try and transition to the next state. Must be only one possible next state.
[transition\_state(target)](AshStateMachine.BuiltinChanges.html#transition_state/1)
Changes the state to the target state, validating the transition
# [](AshStateMachine.BuiltinChanges.html#functions)Functions
[](AshStateMachine.BuiltinChanges.html#next_state/0)
# next\_state()
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/builtin_changes/builtin_changes.ex#L16)
Try and transition to the next state. Must be only one possible next state.
[](AshStateMachine.BuiltinChanges.html#transition_state/1)
# transition\_state(target)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/builtin_changes/builtin_changes.ex#L9)
Changes the state to the target state, validating the transition
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/charts.ex#L1 "View Source") AshStateMachine.Charts (ash\_state\_machine v0.2.7)
Returns a mermaid flow chart of a given state machine resource.
# [](AshStateMachine.Charts.html#summary)Summary
## [Functions](AshStateMachine.Charts.html#functions)
[mermaid\_flowchart(resource)](AshStateMachine.Charts.html#mermaid_flowchart/1)
[mermaid\_state\_diagram(resource)](AshStateMachine.Charts.html#mermaid_state_diagram/1)
# [](AshStateMachine.Charts.html#functions)Functions
[](AshStateMachine.Charts.html#mermaid_flowchart/1)
# mermaid\_flowchart(resource)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/charts.ex#L18)
```
@spec mermaid_flowchart(Ash.Resource.t()) :: String.t()
```
[](AshStateMachine.Charts.html#mermaid_state_diagram/1)
# mermaid\_state\_diagram(resource)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/charts.ex#L7)
```
@spec mermaid_state_diagram(Ash.Resource.t()) :: String.t()
```
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L1 "View Source") AshStateMachine.Checks.ValidNextState (ash\_state\_machine v0.2.7)
A policy for pre\_flight checking if a state transition is allowed.
# [](AshStateMachine.Checks.ValidNextState.html#summary)Summary
## [Functions](AshStateMachine.Checks.ValidNextState.html#functions)
[auto\_filter(actor, authorizer, opts)](AshStateMachine.Checks.ValidNextState.html#auto_filter/3)
Callback implementation for [`Ash.Policy.Check.auto_filter/3`](../ash/3.4.43/Ash.Policy.Check.html#c:auto_filter/3).
[auto\_filter\_not(actor, authorizer, opts)](AshStateMachine.Checks.ValidNextState.html#auto_filter_not/3)
[check(actor, data, authorizer, opts)](AshStateMachine.Checks.ValidNextState.html#check/4)
Callback implementation for [`Ash.Policy.Check.check/4`](../ash/3.4.43/Ash.Policy.Check.html#c:check/4).
[describe(\_)](AshStateMachine.Checks.ValidNextState.html#describe/1)
Callback implementation for [`Ash.Policy.Check.describe/1`](../ash/3.4.43/Ash.Policy.Check.html#c:describe/1).
[eager\_evaluate?()](AshStateMachine.Checks.ValidNextState.html#eager_evaluate?/0)
Callback implementation for [`Ash.Policy.Check.eager_evaluate?/0`](../ash/3.4.43/Ash.Policy.Check.html#c:eager_evaluate?/0).
[expand\_description(actor, authorizer, opts)](AshStateMachine.Checks.ValidNextState.html#expand_description/3)
Callback implementation for [`Ash.Policy.Check.expand_description/3`](../ash/3.4.43/Ash.Policy.Check.html#c:expand_description/3).
[filter(actor, context, options)](AshStateMachine.Checks.ValidNextState.html#filter/3)
Callback implementation for [`Ash.Policy.FilterCheck.filter/3`](../ash/3.4.43/Ash.Policy.FilterCheck.html#c:filter/3).
[prefer\_expanded\_description?()](AshStateMachine.Checks.ValidNextState.html#prefer_expanded_description?/0)
Callback implementation for [`Ash.Policy.Check.prefer_expanded_description?/0`](../ash/3.4.43/Ash.Policy.Check.html#c:prefer_expanded_description?/0).
[reject(actor, authorizer, opts)](AshStateMachine.Checks.ValidNextState.html#reject/3)
Callback implementation for [`Ash.Policy.FilterCheck.reject/3`](../ash/3.4.43/Ash.Policy.FilterCheck.html#c:reject/3).
[requires\_original\_data?(\_, \_)](AshStateMachine.Checks.ValidNextState.html#requires_original_data?/2)
Callback implementation for [`Ash.Policy.Check.requires_original_data?/2`](../ash/3.4.43/Ash.Policy.Check.html#c:requires_original_data?/2).
[strict\_check(actor, authorizer, opts)](AshStateMachine.Checks.ValidNextState.html#strict_check/3)
Callback implementation for [`Ash.Policy.Check.strict_check/3`](../ash/3.4.43/Ash.Policy.Check.html#c:strict_check/3).
[strict\_check\_context(opts)](AshStateMachine.Checks.ValidNextState.html#strict_check_context/1)
[type()](AshStateMachine.Checks.ValidNextState.html#type/0)
Callback implementation for [`Ash.Policy.Check.type/0`](../ash/3.4.43/Ash.Policy.Check.html#c:type/0).
# [](AshStateMachine.Checks.ValidNextState.html#functions)Functions
[](AshStateMachine.Checks.ValidNextState.html#auto_filter/3)
# auto\_filter(actor, authorizer, opts)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.auto_filter/3`](../ash/3.4.43/Ash.Policy.Check.html#c:auto_filter/3).
[](AshStateMachine.Checks.ValidNextState.html#auto_filter_not/3)
# auto\_filter\_not(actor, authorizer, opts)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
[](AshStateMachine.Checks.ValidNextState.html#check/4)
# check(actor, data, authorizer, opts)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.check/4`](../ash/3.4.43/Ash.Policy.Check.html#c:check/4).
[](AshStateMachine.Checks.ValidNextState.html#describe/1)
# describe(\_)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L7)
Callback implementation for [`Ash.Policy.Check.describe/1`](../ash/3.4.43/Ash.Policy.Check.html#c:describe/1).
[](AshStateMachine.Checks.ValidNextState.html#eager_evaluate?/0)
# eager\_evaluate?()
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.eager_evaluate?/0`](../ash/3.4.43/Ash.Policy.Check.html#c:eager_evaluate?/0).
[](AshStateMachine.Checks.ValidNextState.html#expand_description/3)
# expand\_description(actor, authorizer, opts)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.expand_description/3`](../ash/3.4.43/Ash.Policy.Check.html#c:expand_description/3).
[](AshStateMachine.Checks.ValidNextState.html#filter/3)
# filter(actor, context, options)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L11)
Callback implementation for [`Ash.Policy.FilterCheck.filter/3`](../ash/3.4.43/Ash.Policy.FilterCheck.html#c:filter/3).
[](AshStateMachine.Checks.ValidNextState.html#prefer_expanded_description?/0)
# prefer\_expanded\_description?()
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.prefer_expanded_description?/0`](../ash/3.4.43/Ash.Policy.Check.html#c:prefer_expanded_description?/0).
[](AshStateMachine.Checks.ValidNextState.html#reject/3)
# reject(actor, authorizer, opts)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.FilterCheck.reject/3`](../ash/3.4.43/Ash.Policy.FilterCheck.html#c:reject/3).
[](AshStateMachine.Checks.ValidNextState.html#requires_original_data?/2)
# requires\_original\_data?(\_, \_)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.requires_original_data?/2`](../ash/3.4.43/Ash.Policy.Check.html#c:requires_original_data?/2).
[](AshStateMachine.Checks.ValidNextState.html#strict_check/3)
# strict\_check(actor, authorizer, opts)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.strict_check/3`](../ash/3.4.43/Ash.Policy.Check.html#c:strict_check/3).
[](AshStateMachine.Checks.ValidNextState.html#strict_check_context/1)
# strict\_check\_context(opts)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
[](AshStateMachine.Checks.ValidNextState.html#type/0)
# type()
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/checks/valid_next_state.ex#L5)
Callback implementation for [`Ash.Policy.Check.type/0`](../ash/3.4.43/Ash.Policy.Check.html#c:type/0).
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/errors/invalid_initial_state.ex#L1 "View Source") AshStateMachine.Errors.InvalidInitialState exception (ash\_state\_machine v0.2.7)
Used when an initial state is set that is not a valid initial state
# [](AshStateMachine.Errors.InvalidInitialState.html#summary)Summary
## [Functions](AshStateMachine.Errors.InvalidInitialState.html#functions)
[exception()](AshStateMachine.Errors.InvalidInitialState.html#exception/0)
# [](AshStateMachine.Errors.InvalidInitialState.html#functions)Functions
[](AshStateMachine.Errors.InvalidInitialState.html#exception/0)
# exception()
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/errors/invalid_initial_state.ex#L5)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/errors/no_matching_event.ex#L1 "View Source") AshStateMachine.Errors.NoMatchingTransition exception (ash\_state\_machine v0.2.7)
Used when a state change occurs in an action with no matching transition
# [](AshStateMachine.Errors.NoMatchingTransition.html#summary)Summary
## [Functions](AshStateMachine.Errors.NoMatchingTransition.html#functions)
[exception()](AshStateMachine.Errors.NoMatchingTransition.html#exception/0)
# [](AshStateMachine.Errors.NoMatchingTransition.html#functions)Functions
[](AshStateMachine.Errors.NoMatchingTransition.html#exception/0)
# exception()
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/errors/no_matching_event.ex#L3)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/ash_state_machine.ex#L1 "View Source") AshStateMachine (ash\_state\_machine v0.2.7)
Provides tools for defining and working with resource-backed state machines.
# [](AshStateMachine.html#summary)Summary
## [Functions](AshStateMachine.html#functions)
[possible\_next\_states(record)](AshStateMachine.html#possible_next_states/1)
A reusable helper which returns all possible next states for a record (regardless of action).
[possible\_next\_states(record, action\_name)](AshStateMachine.html#possible_next_states/2)
A reusable helper which returns all possible next states for a record given a specific action.
[state\_machine(body)](AshStateMachine.html#state_machine/1)
[transition\_state(changeset, target)](AshStateMachine.html#transition_state/2)
A utility to transition the state of a changeset, honoring the rules of the resource.
# [](AshStateMachine.html#functions)Functions
[](AshStateMachine.html#possible_next_states/1)
# possible\_next\_states(record)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/ash_state_machine.ex#L233)
```
@spec possible_next_states(Ash.Resource.record()) :: [atom()]
```
A reusable helper which returns all possible next states for a record (regardless of action).
[](AshStateMachine.html#possible_next_states/2)
# possible\_next\_states(record, action\_name)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/ash_state_machine.ex#L251)
```
@spec possible_next_states(Ash.Resource.record(), atom()) :: [atom()]
```
A reusable helper which returns all possible next states for a record given a specific action.
[](AshStateMachine.html#state_machine/1)
# state\_machine(body)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/ash_state_machine.ex#L111)(macro)
[](AshStateMachine.html#transition_state/2)
# transition\_state(changeset, target)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/ash_state_machine.ex#L129)
A utility to transition the state of a changeset, honoring the rules of the resource.
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L1 "View Source") AshStateMachine.Info (ash\_state\_machine v0.2.7)
Introspection helpers for [`AshStateMachine`](AshStateMachine.html)
# [](AshStateMachine.Info.html#summary)Summary
## [Functions](AshStateMachine.Info.html#functions)
[state\_machine\_all\_states(resource\_or\_dsl)](AshStateMachine.Info.html#state_machine_all_states/1)
[state\_machine\_default\_initial\_state(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_default_initial_state/1)
The default initial state
[state\_machine\_default\_initial\_state!(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_default_initial_state!/1)
The default initial state
[state\_machine\_deprecated\_states(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_deprecated_states/1)
A list of states that have been deprecated but are still valid. These will still be in the possible list of states, but `:*` will not include them.
[state\_machine\_deprecated\_states!(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_deprecated_states!/1)
A list of states that have been deprecated but are still valid. These will still be in the possible list of states, but `:*` will not include them.
[state\_machine\_extra\_states(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_extra_states/1)
A list of states that may be used by transitions to/from `:*`. See the docs on wildcards for more.
[state\_machine\_extra\_states!(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_extra_states!/1)
A list of states that may be used by transitions to/from `:*`. See the docs on wildcards for more.
[state\_machine\_initial\_states(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_initial_states/1)
The allowed starting states of this state machine.
[state\_machine\_initial\_states!(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_initial_states!/1)
The allowed starting states of this state machine.
[state\_machine\_options(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_options/1)
state\_machine DSL options
[state\_machine\_state\_attribute(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_state_attribute/1)
The attribute to store the state in.
[state\_machine\_state\_attribute!(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_state_attribute!/1)
The attribute to store the state in.
[state\_machine\_transitions(dsl\_or\_extended)](AshStateMachine.Info.html#state_machine_transitions/1)
state\_machine.transitions DSL entities
[state\_machine\_transitions(resource\_or\_dsl, name)](AshStateMachine.Info.html#state_machine_transitions/2)
# [](AshStateMachine.Info.html#functions)Functions
[](AshStateMachine.Info.html#state_machine_all_states/1)
# state\_machine\_all\_states(resource\_or\_dsl)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L14)
```
@spec state_machine_all_states(Ash.Resource.t() | map()) :: [atom()]
```
[](AshStateMachine.Info.html#state_machine_default_initial_state/1)
# state\_machine\_default\_initial\_state(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_default_initial_state(dsl_or_extended :: module() | map()) ::
{:ok, atom()} | :error
```
The default initial state
[](AshStateMachine.Info.html#state_machine_default_initial_state!/1)
# state\_machine\_default\_initial\_state!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_default_initial_state!(dsl_or_extended :: module() | map()) ::
atom() | no_return()
```
The default initial state
[](AshStateMachine.Info.html#state_machine_deprecated_states/1)
# state\_machine\_deprecated\_states(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_deprecated_states(dsl_or_extended :: module() | map()) ::
{:ok, [atom()]} | :error
```
A list of states that have been deprecated but are still valid. These will still be in the possible list of states, but `:*` will not include them.
[](AshStateMachine.Info.html#state_machine_deprecated_states!/1)
# state\_machine\_deprecated\_states!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_deprecated_states!(dsl_or_extended :: module() | map()) ::
[atom()] | no_return()
```
A list of states that have been deprecated but are still valid. These will still be in the possible list of states, but `:*` will not include them.
[](AshStateMachine.Info.html#state_machine_extra_states/1)
# state\_machine\_extra\_states(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_extra_states(dsl_or_extended :: module() | map()) ::
{:ok, [atom()]} | :error
```
A list of states that may be used by transitions to/from `:*`. See the docs on wildcards for more.
[](AshStateMachine.Info.html#state_machine_extra_states!/1)
# state\_machine\_extra\_states!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_extra_states!(dsl_or_extended :: module() | map()) ::
[atom()] | no_return()
```
A list of states that may be used by transitions to/from `:*`. See the docs on wildcards for more.
[](AshStateMachine.Info.html#state_machine_initial_states/1)
# state\_machine\_initial\_states(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_initial_states(dsl_or_extended :: module() | map()) ::
{:ok, [atom()]} | :error
```
The allowed starting states of this state machine.
[](AshStateMachine.Info.html#state_machine_initial_states!/1)
# state\_machine\_initial\_states!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_initial_states!(dsl_or_extended :: module() | map()) ::
[atom()] | no_return()
```
The allowed starting states of this state machine.
[](AshStateMachine.Info.html#state_machine_options/1)
# state\_machine\_options(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_options(dsl_or_extended :: module() | map()) :: %{
required(atom()) => any()
}
```
state\_machine DSL options
Returns a map containing the and any configured or default values.
[](AshStateMachine.Info.html#state_machine_state_attribute/1)
# state\_machine\_state\_attribute(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_state_attribute(dsl_or_extended :: module() | map()) ::
{:ok, atom()} | :error
```
The attribute to store the state in.
[](AshStateMachine.Info.html#state_machine_state_attribute!/1)
# state\_machine\_state\_attribute!(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_state_attribute!(dsl_or_extended :: module() | map()) ::
atom() | no_return()
```
The attribute to store the state in.
[](AshStateMachine.Info.html#state_machine_transitions/1)
# state\_machine\_transitions(dsl\_or\_extended)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L3)
```
@spec state_machine_transitions(dsl_or_extended :: module() | map()) :: [struct()]
```
state\_machine.transitions DSL entities
[](AshStateMachine.Info.html#state_machine_transitions/2)
# state\_machine\_transitions(resource\_or\_dsl, name)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/info.ex#L7)
```
@spec state_machine_transitions(Ash.Resource.t() | map(), name :: atom()) :: [
AshStateMachine.Transition.t()
]
```
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/ash_state_machine.ex#L2 "View Source") AshStateMachine.Transition (ash\_state\_machine v0.2.7)
The configuration for an transition.
# [](AshStateMachine.Transition.html#summary)Summary
## [Types](AshStateMachine.Transition.html#types)
[t()](AshStateMachine.Transition.html#t:t/0)
# [](AshStateMachine.Transition.html#types)Types
[](AshStateMachine.Transition.html#t:t/0)
# t()
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/ash_state_machine.ex#L6)
```
@type t() :: %AshStateMachine.Transition{
__identifier__: any(),
action: atom(),
from: [atom()],
to: [atom()]
}
```
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/documentation/topics/charts.md#L1 "View Source") Charts
Run [`mix ash_state_machine.generate_flow_charts`](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html) to generate flow charts for your resources. See the task documentation for more. Here is an example:
```
stateDiagram-v2
pending --> confirmed: confirm
confirmed --> on_its_way: begin_delivery
on_its_way --> arrived: package_arrived
on_its_way --> error: error
confirmed --> error: error
pending --> error: error
```
[← Previous Page What is AshStateMachine?](what-is-ash-state-machine.html)
[Next Page → Working with Ash.can?](working-with-ash-can.html)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) ([current file](https://preview.hex.pm/preview/ash_state_machine/0.2.7/show/documentation/topics/charts.md)) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/documentation/dsls/DSL-AshStateMachine.md#L1 "View Source") DSL: AshStateMachine
Provides tools for defining and working with resource-backed state machines.
## [](dsl-ashstatemachine.html#state_machine)state\_machine
### [](dsl-ashstatemachine.html#nested-dsls)Nested DSLs
- [transitions](dsl-ashstatemachine.html#state_machine-transitions)
- transition
### [](dsl-ashstatemachine.html#options)Options
NameTypeDefaultDocs[`initial_states`](dsl-ashstatemachine.html#state_machine-initial_states)`list(atom)`The allowed starting states of this state machine.[`deprecated_states`](dsl-ashstatemachine.html#state_machine-deprecated_states)`list(atom)``[]`A list of states that have been deprecated but are still valid. These will still be in the possible list of states, but `:*` will not include them.[`extra_states`](dsl-ashstatemachine.html#state_machine-extra_states)`list(atom)``[]`A list of states that may be used by transitions to/from `:*`. See the docs on wildcards for more.[`state_attribute`](dsl-ashstatemachine.html#state_machine-state_attribute)`atom``:state`The attribute to store the state in.[`default_initial_state`](dsl-ashstatemachine.html#state_machine-default_initial_state)`atom`The default initial state
## [](dsl-ashstatemachine.html#state_machine-transitions)state\_machine.transitions
### [](dsl-ashstatemachine.html#wildcards)Wildcards
Use `:*` to represent "any action" when used in place of an action, or "any state" when used in place of a state.
For example:
```
transition :*, from: :*, to: :*
```
The full list of states is derived at compile time from the transitions. Use the `extra_states` to express that certain types should be included in that list even though no transitions go to/from that state explicitly. This is necessary for cases where there are states that use `:*` and no transition explicitly leads to that transition.
### [](dsl-ashstatemachine.html#nested-dsls-1)Nested DSLs
- [transition](dsl-ashstatemachine.html#state_machine-transitions-transition)
## [](dsl-ashstatemachine.html#state_machine-transitions-transition)state\_machine.transitions.transition
```
transition action
```
### [](dsl-ashstatemachine.html#arguments)Arguments
NameTypeDefaultDocs[`action`](dsl-ashstatemachine.html#state_machine-transitions-transition-action)`atom`The corresponding action that is invoked for the transition. Use `:*` to allow any update action to perform this transition.
### [](dsl-ashstatemachine.html#options-1)Options
NameTypeDefaultDocs[`from`](dsl-ashstatemachine.html#state_machine-transitions-transition-from)`list(atom) | atom`The states in which this action may be called. If not specified, then any state is accepted. Use `:*` to refer to all states.[`to`](dsl-ashstatemachine.html#state_machine-transitions-transition-to)`list(atom) | atom`The states that this action may move to. If not specified, then any state is accepted. Use `:*` to refer to all states.
### [](dsl-ashstatemachine.html#introspection)Introspection
Target: [`AshStateMachine.Transition`](AshStateMachine.Transition.html)
[← Previous Page Working with Ash.can?](working-with-ash-can.html)
[Next Page → Change Log](changelog.html)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) ([current file](https://preview.hex.pm/preview/ash_state_machine/0.2.7/show/documentation/dsls/DSL-AshStateMachine.md)) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/documentation/tutorials/getting-started-with-ash-state-machine.md#L1 "View Source") Getting Started with State Machines
## [](getting-started-with-ash-state-machine.html#get-familiar-with-ash-resources)Get familiar with Ash resources
If you haven't already, read the [Ash Getting Started Guide](../ash/get-started.html), and familiarize yourself with Ash and Ash resources.
## [](getting-started-with-ash-state-machine.html#bring-in-the-ash_state_machine-dependency)Bring in the ash\_state\_machine dependency
```
{:ash_state_machine, "~> 0.2.7"}
```
## [](getting-started-with-ash-state-machine.html#add-the-extension-to-your-resource)Add the extension to your resource
```
use Ash.Resource,
extensions: [AshStateMachine]
```
## [](getting-started-with-ash-state-machine.html#add-initial-states-and-a-default-initial-state)Add initial states, and a default initial state
```
use Ash.Resource,
extensions: [AshStateMachine]
...
state_machine do
initial_states [:pending]
default_initial_state :pending
end
```
## [](getting-started-with-ash-state-machine.html#add-allowed-transitions)Add allowed transitions
```
state_machine do
initial_states [:pending]
default_initial_state :pending
transitions do
# `:begin` action can move state from `:pending` to `:started`/`:aborted`
transition :begin, from: :pending, to: [:started, :aborted]
end
end
```
## [](getting-started-with-ash-state-machine.html#use-transition_state-in-your-actions)Use `transition_state` in your actions
### [](getting-started-with-ash-state-machine.html#for-simple-static-state-transitions)For simple/static state transitions
```
actions do
update :begin do
# for a static state transition
change transition_state(:started)
end
end
```
### [](getting-started-with-ash-state-machine.html#for-dynamic-conditional-state-transitions)For dynamic/conditional state transitions
```
defmodule Start do
use Ash.Resource.Change
def change(changeset, _, _) do
if ready_to_start?(changeset) do
AshStateMachine.transition_state(changeset, :started)
else
AshStateMachine.transition_state(changeset, :aborted)
end
end
end
actions do
update :begin do
# for a dynamic state transition
change Start
end
end
```
## [](getting-started-with-ash-state-machine.html#declaring-a-custom-state-attribute)Declaring a custom state attribute
By default, a `:state` attribute is created on the resource that looks like this:
```
attribute :state, :atom do
allow_nil? false
default AshStateMachine.Info.state_machine_initial_default_state(dsl_state)
public? true
constraints one_of: [
AshStateMachine.Info.state_machine_all_states(dsl_state)
]
end
```
You can change the name of this attribute, without declaring an attribute yourself, like so:
```
state_machine do
initial_states([:pending])
default_initial_state(:pending)
state_attribute(:alternative_state) # <-- save state in an attribute named :alternative_state
end
```
If you need more control, you can declare the attribute yourself on the resource:
```
attributes do
attribute :alternative_state, :atom do
allow_nil? false
default :issued
public? true
constraints one_of: [:issued, :sold, :reserved, :retired]
end
end
```
Be aware that the type of this attribute needs to be `:atom` or a type created with [`Ash.Type.Enum`](../ash/3.4.43/Ash.Type.Enum.html). Both the `default` and list of values need to be correct!
## [](getting-started-with-ash-state-machine.html#making-a-resource-into-a-state-machine)Making a resource into a state machine
The concept of a state machine (in this case a "Finite State Machine"), essentially involves a single `state`, with specified transitions between states. For example, you might have an order state machine with states `[:pending, :on_its_way, :delivered]`. However, you can't go from `:pending` to `:delivered` (probably), and so you want to only allow certain transitions in certain circumstances, i.e `:pending -> :on_its_way -> :delivered`.
This extension's goal is to help you write clear and clean state machines, with all of the extensibility and power of Ash resources and actions.
[← Previous Page Home](readme.html)
[Next Page → What is AshStateMachine?](what-is-ash-state-machine.html)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) ([current file](https://preview.hex.pm/preview/ash_state_machine/0.2.7/show/documentation/tutorials/getting-started-with-ash-state-machine.md)) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/mix/generate_flow_charts.ex#L1 "View Source") mix ash\_state\_machine.generate\_flow\_charts (ash\_state\_machine v0.2.7)
Generates a Mermaid Flow Chart for each [`Ash.Resource`](../ash/3.4.43/Ash.Resource.html) with the [`AshStateMachine`](AshStateMachine.html) extension alongside the resource.
## [](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html#module-prerequisites)Prerequisites
This mix task requires the Mermaid CLI to be installed on your system.
See [https://github.com/mermaid-js/mermaid-cli](https://github.com/mermaid-js/mermaid-cli)
## [](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html#module-command-line-options)Command line options
- `--type` - generates a given type. Valid values are `"state_diagram"` and `"flow_chart"`. Defaults to `"state_diagram"`.
- `--only` - only generates the given Flow file
- `--format` - Can be set to one of either:
- `plain` - Prints just the mermaid output as text. This is the default.
- `md` - Prints the mermaid diagram in a markdown code block.
- `svg` - Generates an SVG
- `pdf` - Generates a PDF
- `png` - Generates a PNG
# [](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html#summary)Summary
## [Functions](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html#functions)
[run(argv)](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html#run/1)
Callback implementation for [`Mix.Task.run/1`](../mix/Mix.Task.html#c:run/1).
# [](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html#functions)Functions
[](Mix.Tasks.AshStateMachine.GenerateFlowCharts.html#run/1)
# run(argv)
[](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/lib/mix/generate_flow_charts.ex#L29)
Callback implementation for [`Mix.Task.run/1`](../mix/Mix.Task.html#c:run/1).
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/README.md#L1 "View Source") Home
 
 [](https://opensource.org/licenses/MIT) [](https://hex.pm/packages/ash_state_machine) [](../ash_state_machine.html)
# AshStateMachine
Welcome! This is the extension for building state machines with [Ash](../ash_state_machine.html) resources.
## [](readme.html#tutorials)Tutorials
- [Getting Started with AshStateMachine](getting-started-with-ash-state-machine.html)
## [](readme.html#topics)Topics
- [What is AshStateMachine?](what-is-ash-state-machine.html)
- [Charts](charts.html)
- [Working with `Ash.can?`](working-with-ash-can.html)
## [](readme.html#reference)Reference
- [AshStateMachine DSL](dsl-ashstatemachine.html)
[← Previous Page API Reference](api-reference.html)
[Next Page → Getting Started with State Machines](getting-started-with-ash-state-machine.html)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) ([current file](https://preview.hex.pm/preview/ash_state_machine/0.2.7/show/README.md)) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/documentation/topics/what-is-ash-state-machine.md#L1 "View Source") What is AshStateMachine?
## [](what-is-ash-state-machine.html#what-is-a-state-machine)What is a State Machine?
A state machine is a program who's purpose is to manage an internal "state". The simplest example of a state machine could be a program representing a light switch. A light switch might have two states, "on" and "off". You can transition from "on" to "off", and back.
```
classDiagram
class Switch {
state on | off
turnOn() off -> on
turnOff() on -> off
}
```
To build state machines with [`Ash.Resource`](../ash/3.4.43/Ash.Resource.html), we use [`AshStateMachine`](../ash_state_machine.html).
When we refer to "state machines" in AshStateMachine, we're referring to a specific type of state machine known as a "Finite State Machine". It is "finite", because there are a statically known list of states that the machine may be in at any time, just like the `Switch` example above.
### [](what-is-ash-state-machine.html#why-should-we-use-state-machines)Why should we use state machines?
#### Flexible
State machines are a *simple* and *powerful* way to represent complex workflows. They are flexible to modifications over time by adding new states, or new transitions between states.
#### Migrateable
State machines typically contain additional data about the state that they are in, or past states that they have been in, and this state must be migrated over time. When representing data as state machines, it becomes simple to do things like "update all `package` records that are in the `pending_shipment` state".
#### Easy to reason about for humans
State machines, when compared to things like workflows, are easy for people to reason about. We have an intuition for things like "the package is currently `on_its_way`, with a `current_location` of New York, New York", or "your package is now `out_for_delivery` with an ETA of 6PM".
#### Compatible with any storage mechanism
Since state machines are backed by simple state, you can often avoid any fancy workflow runners or complex storage mechanisms. You can store them in a database table, a json blob, a CSV file, at the end of the day its just a `:state` field and accompanying additional fields.
## [](what-is-ash-state-machine.html#what-does-ashstatemachine-do-differently-than-other-implementations)What does AshStateMachine do differently than other implementations?
AshStateMachine is an [`Ash.Resource`](../ash/Ash.Resource.html) extension, meaning it *enhances a resource* with state machine capabilities. In [`Ash`](../ash/3.4.43/Ash.html), all modifications go through [*actions*](https://hexdocs.pm/ash_state_machine/actions.html). In accordance with this, [`AshStateMachine`](AshStateMachine.html) offers a DSL for declaring *valid states and transitions*, but does not, itself, *perform* those transitions. You will use a change called `transition_state/1` in an action to move from one state to the other. For more, check out the [CookBook](../ash/readme.html#cookbook)
[← Previous Page Getting Started with State Machines](getting-started-with-ash-state-machine.html)
[Next Page → Charts](charts.html)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) ([current file](https://preview.hex.pm/preview/ash_state_machine/0.2.7/show/documentation/topics/what-is-ash-state-machine.md)) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_state_machine)
[ash\_state\_machine](https://github.com/ash-project/ash_state_machine)
v0.2.7
- GUIDES
- Modules
- Mix Tasks
<!--THE END-->
<!--THE END-->
<!--THE END-->
Search documentation of ash\_state\_machine
Settings
# [View Source](https://github.com/ash-project/ash_state_machine/blob/v0.2.7/documentation/topics/working-with-ash-can.md#L1 "View Source") Working with `Ash.can?`
Using [`Ash.can?/3`](../ash/3.4.43/Ash.html#can?/3) won't return `false` if a given state machine transition is invalid. This is because [`Ash.can?/3`](../ash/3.4.43/Ash.html#can?/3) is only concerned with policies, not changes/validations. However, many folks use [`Ash.can?/3`](../ash/3.4.43/Ash.html#can?/3) in their UI to determine whether a given button/form/etc should be shown. To help with this you can add the following to your resource:
```
policies do
policy always() do
authorize_if AshStateMachine.Checks.ValidNextState
end
end
```
This check is only used in *pre\_flight* authorization checks (i.e calling [`Ash.can?/3`](../ash/3.4.43/Ash.html#can?/3)), but it will return `true` in all cases when running real authorization checks. This is because the change is validated when you use the `transition_state/1` change and [`AshStateMachine.transition_state/2`](AshStateMachine.html#transition_state/2), and so you would be doing extra work for no reason.
[← Previous Page Charts](charts.html)
[Next Page → DSL: AshStateMachine](dsl-ashstatemachine.html)
[Hex Package](https://hex.pm/packages/ash_state_machine/0.2.7) [Hex Preview](https://preview.hex.pm/preview/ash_state_machine/0.2.7) ([current file](https://preview.hex.pm/preview/ash_state_machine/0.2.7/show/documentation/topics/working-with-ash-can.md)) Search HexDocs [Download ePub version](ash_state_machine.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
```
--------------------------------------------------------------------------------
/test/docs/ash-docs/ash_oban.md:
--------------------------------------------------------------------------------
```markdown
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban "View Source") API Reference ash\_oban v0.2.6
## [](api-reference.html#modules)Modules
[AshOban](AshOban.html)
Tools for working with AshOban triggers.
[AshOban.ActorPersister](AshOban.ActorPersister.html)
A behaviour for storing and retrieving an actor from oban job arguments
[AshOban.Changes.BuiltinChanges](AshOban.Changes.BuiltinChanges.html)
Builtin changes for [`AshOban`](AshOban.html)
[AshOban.Changes.RunObanTrigger](AshOban.Changes.RunObanTrigger.html)
Runs an oban trigger by name.
[AshOban.Checks.AshObanInteraction](AshOban.Checks.AshObanInteraction.html)
This check is true if the context `private.ash_oban?` is set to true.
[AshOban.Errors.TriggerNoLongerApplies](AshOban.Errors.TriggerNoLongerApplies.html)
Used when an invalid value is provided for an action argument
[AshOban.Info](AshOban.Info.html)
Introspection for AshOban
[AshOban.Schedule](AshOban.Schedule.html)
A configured scheduled action.
[AshOban.Test](AshOban.Test.html)
Helpers for testing ash\_oban triggers
[AshOban.Trigger](AshOban.Trigger.html)
A configured trigger.
[Next Page → Home](readme.html)
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/actor_persister.ex#L1 "View Source") AshOban.ActorPersister behaviour (ash\_oban v0.2.6)
A behaviour for storing and retrieving an actor from oban job arguments
# [](AshOban.ActorPersister.html#summary)Summary
## [Types](AshOban.ActorPersister.html#types)
[actor()](AshOban.ActorPersister.html#t:actor/0)
[actor\_json()](AshOban.ActorPersister.html#t:actor_json/0)
## [Callbacks](AshOban.ActorPersister.html#callbacks)
[lookup(actor\_json)](AshOban.ActorPersister.html#c:lookup/1)
[store(actor)](AshOban.ActorPersister.html#c:store/1)
# [](AshOban.ActorPersister.html#types)Types
[Link to this type](AshOban.ActorPersister.html#t:actor/0 "Link to this type")
# actor()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/actor_persister.ex#L6 "View Source")
```
@type actor() :: any()
```
[Link to this type](AshOban.ActorPersister.html#t:actor_json/0 "Link to this type")
# actor\_json()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/actor_persister.ex#L5 "View Source")
```
@type actor_json() :: any()
```
# [](AshOban.ActorPersister.html#callbacks)Callbacks
[Link to this callback](AshOban.ActorPersister.html#c:lookup/1 "Link to this callback")
# lookup(actor\_json)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/actor_persister.ex#L9 "View Source")
```
@callback lookup(actor_json :: actor_json() | nil) ::
{:ok, actor() | nil} | {:error, Ash.Error.t()}
```
[Link to this callback](AshOban.ActorPersister.html#c:store/1 "Link to this callback")
# store(actor)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/actor_persister.ex#L8 "View Source")
```
@callback store(actor :: actor()) :: actor_json :: actor_json()
```
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/changes/builtin_changes.ex#L1 "View Source") AshOban.Changes.BuiltinChanges (ash\_oban v0.2.6)
Builtin changes for [`AshOban`](AshOban.html)
# [](AshOban.Changes.BuiltinChanges.html#summary)Summary
## [Functions](AshOban.Changes.BuiltinChanges.html#functions)
[run\_oban\_trigger(trigger\_name, oban\_job\_opts \\\\ \[\])](AshOban.Changes.BuiltinChanges.html#run_oban_trigger/2)
# [](AshOban.Changes.BuiltinChanges.html#functions)Functions
[Link to this function](AshOban.Changes.BuiltinChanges.html#run_oban_trigger/2 "Link to this function")
# run\_oban\_trigger(trigger\_name, oban\_job\_opts \\\\ \[])
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/changes/builtin_changes.ex#L4 "View Source")
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/changes/run_oban_trigger.ex#L1 "View Source") AshOban.Changes.RunObanTrigger (ash\_oban v0.2.6)
Runs an oban trigger by name.
# [](AshOban.Changes.RunObanTrigger.html#summary)Summary
## [Functions](AshOban.Changes.RunObanTrigger.html#functions)
[change(changeset, opts, context)](AshOban.Changes.RunObanTrigger.html#change/3)
Callback implementation for [`Ash.Resource.Change.change/3`](../ash/3.4.37/Ash.Resource.Change.html#c:change/3).
# [](AshOban.Changes.RunObanTrigger.html#functions)Functions
[Link to this function](AshOban.Changes.RunObanTrigger.html#change/3 "Link to this function")
# change(changeset, opts, context)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/changes/run_oban_trigger.ex#L8 "View Source")
Callback implementation for [`Ash.Resource.Change.change/3`](../ash/3.4.37/Ash.Resource.Change.html#c:change/3).
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/checks/ash_oban_interaction.ex#L1 "View Source") AshOban.Checks.AshObanInteraction (ash\_oban v0.2.6)
This check is true if the context `private.ash_oban?` is set to true.
This context will only ever be set in code that is called internally by `ash_oban`, allowing you to create a bypass in your policies on your user/user\_token resources.
```
policies do
bypass AshObanInteraction do
authorize_if always()
end
end
```
# [](AshOban.Checks.AshObanInteraction.html#summary)Summary
## [Functions](AshOban.Checks.AshObanInteraction.html#functions)
[eager\_evaluate?()](AshOban.Checks.AshObanInteraction.html#eager_evaluate?/0)
Callback implementation for [`Ash.Policy.Check.eager_evaluate?/0`](../ash/3.4.37/Ash.Policy.Check.html#c:eager_evaluate?/0).
[prefer\_expanded\_description?()](AshOban.Checks.AshObanInteraction.html#prefer_expanded_description?/0)
Callback implementation for [`Ash.Policy.Check.prefer_expanded_description?/0`](../ash/3.4.37/Ash.Policy.Check.html#c:prefer_expanded_description?/0).
[requires\_original\_data?(\_, \_)](AshOban.Checks.AshObanInteraction.html#requires_original_data?/2)
Callback implementation for [`Ash.Policy.Check.requires_original_data?/2`](../ash/3.4.37/Ash.Policy.Check.html#c:requires_original_data?/2).
[strict\_check(actor, context, opts)](AshOban.Checks.AshObanInteraction.html#strict_check/3)
Callback implementation for [`Ash.Policy.Check.strict_check/3`](../ash/3.4.37/Ash.Policy.Check.html#c:strict_check/3).
[type()](AshOban.Checks.AshObanInteraction.html#type/0)
Callback implementation for [`Ash.Policy.Check.type/0`](../ash/3.4.37/Ash.Policy.Check.html#c:type/0).
# [](AshOban.Checks.AshObanInteraction.html#functions)Functions
[Link to this function](AshOban.Checks.AshObanInteraction.html#eager_evaluate?/0 "Link to this function")
# eager\_evaluate?()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/checks/ash_oban_interaction.ex#L17 "View Source")
Callback implementation for [`Ash.Policy.Check.eager_evaluate?/0`](../ash/3.4.37/Ash.Policy.Check.html#c:eager_evaluate?/0).
[Link to this function](AshOban.Checks.AshObanInteraction.html#prefer_expanded_description?/0 "Link to this function")
# prefer\_expanded\_description?()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/checks/ash_oban_interaction.ex#L17 "View Source")
Callback implementation for [`Ash.Policy.Check.prefer_expanded_description?/0`](../ash/3.4.37/Ash.Policy.Check.html#c:prefer_expanded_description?/0).
[Link to this function](AshOban.Checks.AshObanInteraction.html#requires_original_data?/2 "Link to this function")
# requires\_original\_data?(\_, \_)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/checks/ash_oban_interaction.ex#L17 "View Source")
Callback implementation for [`Ash.Policy.Check.requires_original_data?/2`](../ash/3.4.37/Ash.Policy.Check.html#c:requires_original_data?/2).
[Link to this function](AshOban.Checks.AshObanInteraction.html#strict_check/3 "Link to this function")
# strict\_check(actor, context, opts)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/checks/ash_oban_interaction.ex#L17 "View Source")
Callback implementation for [`Ash.Policy.Check.strict_check/3`](../ash/3.4.37/Ash.Policy.Check.html#c:strict_check/3).
[Link to this function](AshOban.Checks.AshObanInteraction.html#type/0 "Link to this function")
# type()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/checks/ash_oban_interaction.ex#L17 "View Source")
Callback implementation for [`Ash.Policy.Check.type/0`](../ash/3.4.37/Ash.Policy.Check.html#c:type/0).
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/errors/trigger_no_longer_applies.ex#L1 "View Source") AshOban.Errors.TriggerNoLongerApplies exception (ash\_oban v0.2.6)
Used when an invalid value is provided for an action argument
# [](AshOban.Errors.TriggerNoLongerApplies.html#summary)Summary
## [Functions](AshOban.Errors.TriggerNoLongerApplies.html#functions)
[exception()](AshOban.Errors.TriggerNoLongerApplies.html#exception/0)
# [](AshOban.Errors.TriggerNoLongerApplies.html#functions)Functions
[Link to this function](AshOban.Errors.TriggerNoLongerApplies.html#exception/0 "Link to this function")
# exception()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/errors/trigger_no_longer_applies.ex#L3 "View Source")
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L1 "View Source") AshOban (ash\_oban v0.2.6)
Tools for working with AshOban triggers.
# [](AshOban.html#summary)Summary
## [Types](AshOban.html#types)
[result()](AshOban.html#t:result/0)
[triggerable()](AshOban.html#t:triggerable/0)
## [Functions](AshOban.html#functions)
[authorize?()](AshOban.html#authorize?/0)
[build\_trigger(record, trigger, opts \\\\ \[\])](AshOban.html#build_trigger/3)
Builds a specific trigger for the record provided, but does not insert it into the database.
[config(domains, base, opts \\\\ \[\])](AshOban.html#config/3)
Alters your oban configuration to include the required AshOban configuration.
[do\_schedule\_and\_run\_triggers(resources\_or\_domains\_or\_otp\_apps, opts)](AshOban.html#do_schedule_and_run_triggers/2)
[lookup\_actor(actor\_json)](AshOban.html#lookup_actor/1)
[oban(body)](AshOban.html#oban/1)
[run\_trigger(record, trigger, opts \\\\ \[\])](AshOban.html#run_trigger/3)
Runs a specific trigger for the record provided.
[schedule(resource, trigger, opts \\\\ \[\])](AshOban.html#schedule/3)
Schedules all relevant jobs for the provided trigger or scheduled action
[schedule\_and\_run\_triggers(resources\_or\_domains\_or\_otp\_apps, opts \\\\ \[\])](AshOban.html#schedule_and_run_triggers/2)
Runs the schedulers for the given resource, domain, or otp\_app, or list of resources, domains, or otp\_apps.
[stacktrace(arg1)](AshOban.html#stacktrace/1)
[store\_actor(args, actor)](AshOban.html#store_actor/2)
# [](AshOban.html#types)Types
[Link to this type](AshOban.html#t:result/0 "Link to this type")
# result()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L372 "View Source")
```
@type result() :: %{
discard: non_neg_integer(),
cancelled: non_neg_integer(),
success: non_neg_integer(),
failure: non_neg_integer(),
snoozed: non_neg_integer(),
queues_not_drained: [atom()]
}
```
[Link to this type](AshOban.html#t:triggerable/0 "Link to this type")
# triggerable()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L371 "View Source")
```
@type triggerable() ::
Ash.Resource.t() | {Ash.Resource.t(), atom()} | Ash.Domain.t() | atom()
```
# [](AshOban.html#functions)Functions
[Link to this function](AshOban.html#authorize?/0 "Link to this function")
# authorize?()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L416 "View Source")
```
@spec authorize?() :: boolean()
```
[Link to this function](AshOban.html#build_trigger/3 "Link to this function")
# build\_trigger(record, trigger, opts \\\\ \[])
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L474 "View Source")
Builds a specific trigger for the record provided, but does not insert it into the database.
## [](AshOban.html#build_trigger/3-options)Options
- `:actor` - the actor to set on the job. Requires configuring an actor persister.
- `:action_arguments` - additional arguments to merge into the action invocation's arguments map. affects the uniqueness checks for the job.
- `:args` - additional arguments to merge into the job's arguments map. the action will not use these arguments, it can only be used to affect the job uniqueness checks. you likely are looking for the `:action_arguments` job.
All other options are passed through to [`Oban.Worker.new/2`](../oban/2.18.3/Oban.Worker.html#c:new/2)
[Link to this function](AshOban.html#config/3 "Link to this function")
# config(domains, base, opts \\\\ \[])
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L542 "View Source")
Alters your oban configuration to include the required AshOban configuration.
# Options
- `:require?` ([`boolean/0`](../elixir/typespecs.html#built-in-types)) - Whether to require queues and plugins to be defined in your oban config. This can be helpful to allow the ability to split queues between nodes. See [https://hexdocs.pm/oban/splitting-queues.html](../oban/splitting-queues.html) The default value is `true`.
[Link to this function](AshOban.html#do_schedule_and_run_triggers/2 "Link to this function")
# do\_schedule\_and\_run\_triggers(resources\_or\_domains\_or\_otp\_apps, opts)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L802 "View Source")
[Link to this function](AshOban.html#lookup_actor/1 "Link to this function")
# lookup\_actor(actor\_json)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L434 "View Source")
```
@spec lookup_actor(actor_json :: any()) :: any()
```
[Link to this macro](AshOban.html#oban/1 "Link to this macro")
# oban(body)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L362 "View Source") (macro)
[Link to this function](AshOban.html#run_trigger/3 "Link to this function")
# run\_trigger(record, trigger, opts \\\\ \[])
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L454 "View Source")
Runs a specific trigger for the record provided.
## [](AshOban.html#run_trigger/3-options)Options
- `:actor` - the actor to set on the job. Requires configuring an actor persister.
- `:args` - additional arguments to merge into the job's arguments map.
All other options are passed through to [`Oban.Worker.new/2`](../oban/2.18.3/Oban.Worker.html#c:new/2)
[Link to this function](AshOban.html#schedule/3 "Link to this function")
# schedule(resource, trigger, opts \\\\ \[])
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L388 "View Source")
Schedules all relevant jobs for the provided trigger or scheduled action
## [](AshOban.html#schedule/3-options)Options
`:actor` - the actor to set on the job. Requires configuring an actor persister.
[Link to this function](AshOban.html#schedule_and_run_triggers/2 "Link to this function")
# schedule\_and\_run\_triggers(resources\_or\_domains\_or\_otp\_apps, opts \\\\ \[])
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L791 "View Source")
```
@spec schedule_and_run_triggers(
triggerable() | [triggerable()],
keyword()
) :: result()
```
Runs the schedulers for the given resource, domain, or otp\_app, or list of resources, domains, or otp\_apps.
Options:
- `drain_queues?` - Defaults to false, drains the queues after scheduling. This is primarily for testing
- `queue`, `with_limit`, `with_recursion`, `with_safety`, `with_scheduled` - passed through to [`Oban.drain_queue/2`](../oban/2.18.3/Oban.html#drain_queue/2), if it is called
- `scheduled_actions?` - Defaults to false, unless a scheduled action name was explicitly provided. Schedules all applicable scheduled actions.
- `triggers?` - Defaults to true, schedules all applicable scheduled actions.
- `actor` - The actor to schedule and run the triggers with
- `oban` - The oban module to use. Defaults to [`Oban`](../oban/2.18.3/Oban.html)
If the input is:
- a list - each item is passed into [`schedule_and_run_triggers/1`](AshOban.html#schedule_and_run_triggers/1), and the results are merged together.
- an otp\_app - each domain configured in the `ash_domains` of that otp\_app is passed into [`schedule_and_run_triggers/1`](AshOban.html#schedule_and_run_triggers/1), and the results are merged together.
- a domain - each reosurce configured in that domain is passed into [`schedule_and_run_triggers/1`](AshOban.html#schedule_and_run_triggers/1), and the results are merged together.
- a tuple of {resource, :trigger\_name} - that trigger is scheduled, and the results are merged together.
- a resource - each trigger configured in that resource is scheduled, and the results are merged together.
[Link to this function](AshOban.html#stacktrace/1 "Link to this function")
# stacktrace(arg1)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L765 "View Source")
[Link to this function](AshOban.html#store_actor/2 "Link to this function")
# store\_actor(args, actor)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L421 "View Source")
```
@spec store_actor(args :: map(), actor :: any()) :: any()
```
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L1 "View Source") AshOban.Info (ash\_oban v0.2.6)
Introspection for AshOban
# [](AshOban.Info.html#summary)Summary
## [Functions](AshOban.Info.html#functions)
[oban\_domain(dsl\_or\_extended)](AshOban.Info.html#oban_domain/1)
The Domain to use when calling actions on this resource. Defaults to the resource's domain.
[oban\_domain!(dsl\_or\_extended)](AshOban.Info.html#oban_domain!/1)
The Domain to use when calling actions on this resource. Defaults to the resource's domain.
[oban\_options(dsl\_or\_extended)](AshOban.Info.html#oban_options/1)
oban DSL options
[oban\_scheduled\_action(resource, name)](AshOban.Info.html#oban_scheduled_action/2)
[oban\_scheduled\_actions(dsl\_or\_extended)](AshOban.Info.html#oban_scheduled_actions/1)
oban.scheduled\_actions DSL entities
[oban\_trigger(resource, name)](AshOban.Info.html#oban_trigger/2)
[oban\_triggers(dsl\_or\_extended)](AshOban.Info.html#oban_triggers/1)
oban.triggers DSL entities
[oban\_triggers\_and\_scheduled\_actions(resource)](AshOban.Info.html#oban_triggers_and_scheduled_actions/1)
[pro?()](AshOban.Info.html#pro?/0)
# [](AshOban.Info.html#functions)Functions
[Link to this function](AshOban.Info.html#oban_domain/1 "Link to this function")
# oban\_domain(dsl\_or\_extended)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L4 "View Source")
```
@spec oban_domain(dsl_or_extended :: module() | map()) :: {:ok, module()} | :error
```
The Domain to use when calling actions on this resource. Defaults to the resource's domain.
[Link to this function](AshOban.Info.html#oban_domain!/1 "Link to this function")
# oban\_domain!(dsl\_or\_extended)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L4 "View Source")
```
@spec oban_domain!(dsl_or_extended :: module() | map()) :: module() | no_return()
```
The Domain to use when calling actions on this resource. Defaults to the resource's domain.
[Link to this function](AshOban.Info.html#oban_options/1 "Link to this function")
# oban\_options(dsl\_or\_extended)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L4 "View Source")
```
@spec oban_options(dsl_or_extended :: module() | map()) :: %{
required(atom()) => any()
}
```
oban DSL options
Returns a map containing the and any configured or default values.
[Link to this function](AshOban.Info.html#oban_scheduled_action/2 "Link to this function")
# oban\_scheduled\_action(resource, name)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L18 "View Source")
```
@spec oban_scheduled_action(Ash.Resource.t() | Spark.Dsl.t(), atom()) ::
nil | AshOban.Schedule.t()
```
[Link to this function](AshOban.Info.html#oban_scheduled_actions/1 "Link to this function")
# oban\_scheduled\_actions(dsl\_or\_extended)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L4 "View Source")
```
@spec oban_scheduled_actions(dsl_or_extended :: module() | map()) :: [struct()]
```
oban.scheduled\_actions DSL entities
[Link to this function](AshOban.Info.html#oban_trigger/2 "Link to this function")
# oban\_trigger(resource, name)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L10 "View Source")
```
@spec oban_trigger(Ash.Resource.t() | Spark.Dsl.t(), atom()) ::
nil | AshOban.Trigger.t()
```
[Link to this function](AshOban.Info.html#oban_triggers/1 "Link to this function")
# oban\_triggers(dsl\_or\_extended)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L4 "View Source")
```
@spec oban_triggers(dsl_or_extended :: module() | map()) :: [struct()]
```
oban.triggers DSL entities
[Link to this function](AshOban.Info.html#oban_triggers_and_scheduled_actions/1 "Link to this function")
# oban\_triggers\_and\_scheduled\_actions(resource)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L28 "View Source")
```
@spec oban_triggers_and_scheduled_actions(Ash.Resource.t() | Spark.Dsl.t()) :: [
AshOban.Trigger.t() | AshOban.Schedule.t()
]
```
[Link to this function](AshOban.Info.html#pro?/0 "Link to this function")
# pro?()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/info.ex#L7 "View Source")
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L211 "View Source") AshOban.Schedule (ash\_oban v0.2.6)
A configured scheduled action.
# [](AshOban.Schedule.html#summary)Summary
## [Types](AshOban.Schedule.html#types)
[t()](AshOban.Schedule.html#t:t/0)
# [](AshOban.Schedule.html#types)Types
[Link to this type](AshOban.Schedule.html#t:t/0 "Link to this type")
# t()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L216 "View Source")
```
@type t() :: %AshOban.Schedule{
__identifier__: term(),
action: atom(),
action_input: map(),
cron: String.t(),
debug: term(),
debug?: boolean(),
max_attempts: non_neg_integer(),
name: atom(),
priority: non_neg_integer(),
queue: atom(),
state: :active | :paused | :deleted,
worker: module()
}
```
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/test.ex#L1 "View Source") AshOban.Test (ash\_oban v0.2.6)
Helpers for testing ash\_oban triggers
# [](AshOban.Test.html#summary)Summary
## [Functions](AshOban.Test.html#functions)
[schedule\_and\_run\_triggers(resources\_or\_domains\_or\_otp\_apps, opts \\\\ \[\])](AshOban.Test.html#schedule_and_run_triggers/2)
Calls [`AshOban.schedule_and_run_triggers/2`](AshOban.html#schedule_and_run_triggers/2) with `drain_queues?: true`.
# [](AshOban.Test.html#functions)Functions
[Link to this function](AshOban.Test.html#schedule_and_run_triggers/2 "Link to this function")
# schedule\_and\_run\_triggers(resources\_or\_domains\_or\_otp\_apps, opts \\\\ \[])
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/test.ex#L7 "View Source")
Calls [`AshOban.schedule_and_run_triggers/2`](AshOban.html#schedule_and_run_triggers/2) with `drain_queues?: true`.
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L4 "View Source") AshOban.Trigger (ash\_oban v0.2.6)
A configured trigger.
# [](AshOban.Trigger.html#summary)Summary
## [Types](AshOban.Trigger.html#types)
[t()](AshOban.Trigger.html#t:t/0)
## [Functions](AshOban.Trigger.html#functions)
[transform(trigger)](AshOban.Trigger.html#transform/1)
# [](AshOban.Trigger.html#types)Types
[Link to this type](AshOban.Trigger.html#t:t/0 "Link to this type")
# t()
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L9 "View Source")
```
@type t() :: %AshOban.Trigger{
__identifier__: atom(),
action: atom(),
action_input: map(),
debug?: boolean(),
lock_for_update?: boolean(),
log_errors?: boolean(),
log_final_error?: boolean(),
max_attempts: pos_integer(),
max_scheduler_attempts: pos_integer(),
name: atom(),
on_error: atom(),
queue: atom(),
read_action: atom(),
read_metadata: (Ash.Resource.record() -> map()),
record_limit: pos_integer(),
scheduler: module() | nil,
scheduler_cron: String.t(),
scheduler_priority: non_neg_integer(),
scheduler_queue: atom(),
state: :active | :paused | :deleted,
stream_batch_size: pos_integer(),
where: Ash.Expr.t(),
worker: module(),
worker_priority: non_neg_integer(),
worker_read_action: term()
}
```
# [](AshOban.Trigger.html#functions)Functions
[Link to this function](AshOban.Trigger.html#transform/1 "Link to this function")
# transform(trigger)
[View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/lib/ash_oban.ex#L64 "View Source")
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/documentation/dsls/DSL-AshOban.md#L1 "View Source") DSL: AshOban
Tools for working with AshOban triggers.
## [](dsl-ashoban.html#oban)oban
### [](dsl-ashoban.html#nested-dsls)Nested DSLs
- [triggers](dsl-ashoban.html#oban-triggers)
- trigger
- [scheduled\_actions](dsl-ashoban.html#oban-scheduled_actions)
- schedule
### [](dsl-ashoban.html#examples)Examples
```
oban do
triggers do
trigger :process do
action :process
where expr(processed != true)
worker_read_action(:read)
end
end
end
```
### [](dsl-ashoban.html#options)Options
NameTypeDefaultDocs[`domain`](dsl-ashoban.html#oban-domain)`module`The Domain to use when calling actions on this resource. Defaults to the resource's domain.
## [](dsl-ashoban.html#oban-triggers)oban.triggers
### [](dsl-ashoban.html#nested-dsls-1)Nested DSLs
- [trigger](dsl-ashoban.html#oban-triggers-trigger)
### [](dsl-ashoban.html#examples-1)Examples
```
triggers do
trigger :process do
action :process
where expr(processed != true)
worker_read_action(:read)
end
end
```
## [](dsl-ashoban.html#oban-triggers-trigger)oban.triggers.trigger
```
trigger name
```
### [](dsl-ashoban.html#examples-2)Examples
```
trigger :process do
action :process
where expr(processed != true)
worker_read_action(:read)
end
```
### [](dsl-ashoban.html#arguments)Arguments
NameTypeDefaultDocs[`name`](dsl-ashoban.html#oban-triggers-trigger-name)`atom`A unique identifier for this trigger.
### [](dsl-ashoban.html#options-1)Options
NameTypeDefaultDocs[`action`](dsl-ashoban.html#oban-triggers-trigger-action)`atom`The action to be triggered. Defaults to the identifier of the resource plus the name of the trigger[`action_input`](dsl-ashoban.html#oban-triggers-trigger-action_input)`map`Static inputs to supply to the update/destroy action when it is called. Any metadata produced by `read_metadata` will overwrite these values.[`scheduler_queue`](dsl-ashoban.html#oban-triggers-trigger-scheduler_queue)`atom`The queue to place the scheduler job in. The same queue as job is used by default (but with a priority of 1 so schedulers run first).[`debug?`](dsl-ashoban.html#oban-triggers-trigger-debug?)`boolean``false`If set to `true`, detailed debug logging will be enabled for this trigger. You can also set `config :ash_oban, debug_all_triggers?: true` to enable debug logging for all triggers. If the action has `transaction?: false` this is automatically false.[`lock_for_update?`](dsl-ashoban.html#oban-triggers-trigger-lock_for_update?)`boolean``true`If `true`, a transaction will be started before looking up the record, and it will be locked for update. Typically you should leave this on unless you have before/after/around transaction hooks.[`scheduler_cron`](dsl-ashoban.html#oban-triggers-trigger-scheduler_cron)`String.t | false``"* * * * *"`A crontab configuration for when the job should run. Defaults to once per minute (" \*"). Use `false` to disable the scheduler entirely.[`stream_batch_size`](dsl-ashoban.html#oban-triggers-trigger-stream_batch_size)`pos_integer`The batch size to pass when streaming records from using [`Ash.stream!/2`](../ash/3.4.37/Ash.html#stream!/2). No batch size is passed if none is provided here, so the default is used.[`queue`](dsl-ashoban.html#oban-triggers-trigger-queue)`atom`The queue to place the worker job in. The trigger name is used by default.[`record_limit`](dsl-ashoban.html#oban-triggers-trigger-record_limit)`pos_integer`If set, any given run of the scheduler will only ever schedule this many items maximum[`log_errors?`](dsl-ashoban.html#oban-triggers-trigger-log_errors?)`boolean``true`Whether or not to log errors that occur when performing an action.[`log_final_error?`](dsl-ashoban.html#oban-triggers-trigger-log_final_error?)`boolean``true`If true, logs that an error occurred on the final attempt to perform an action even if `log_errors?` is set to false.[`worker_priority`](dsl-ashoban.html#oban-triggers-trigger-worker_priority)`non_neg_integer``2`A number from 0 to 3, where 0 is the highest priority and 3 is the lowest.[`scheduler_priority`](dsl-ashoban.html#oban-triggers-trigger-scheduler_priority)`non_neg_integer``3`A number from 0 to 3, where 0 is the highest priority and 3 is the lowest.[`max_scheduler_attempts`](dsl-ashoban.html#oban-triggers-trigger-max_scheduler_attempts)`pos_integer``1`How many times to attempt scheduling of the triggered action.[`max_attempts`](dsl-ashoban.html#oban-triggers-trigger-max_attempts)`pos_integer``1`How many times to attempt the job. After all attempts have been exhausted, the scheduler may just reschedule it. Use the `on_error` action to update the record to make the scheduler no longer apply.[`read_metadata`](dsl-ashoban.html#oban-triggers-trigger-read_metadata)`(any -> any)`Takes a record, and returns metadata to be given to the update action as an argument called `metadata`.[`state`](dsl-ashoban.html#oban-triggers-trigger-state)`:active | :paused | :deleted``:active`Describes the state of the cron job. See the getting started guide for more information. The most important thing is that you *do not remove a trigger from a resource if you are using oban pro*.[`read_action`](dsl-ashoban.html#oban-triggers-trigger-read_action)`atom`The read action to use when querying records. Defaults to the primary read. This action *must* support keyset pagination.[`worker_read_action`](dsl-ashoban.html#oban-triggers-trigger-worker_read_action)`atom`The read action to use when fetching the individual records for the trigger. Defaults to `read_action`. If you customize this, ensure your action handles scenarios where the trigger is no longer relevant.[`where`](dsl-ashoban.html#oban-triggers-trigger-where)`any`The filter expression to determine if something should be triggered[`on_error`](dsl-ashoban.html#oban-triggers-trigger-on_error)`atom`An update action to call after the last attempt has failed. See the getting started guide for more.
### [](dsl-ashoban.html#introspection)Introspection
Target: [`AshOban.Trigger`](AshOban.Trigger.html)
## [](dsl-ashoban.html#oban-scheduled_actions)oban.scheduled\_actions
A section for configured scheduled actions. Supports generic and create actions.
### [](dsl-ashoban.html#nested-dsls-2)Nested DSLs
- [schedule](dsl-ashoban.html#oban-scheduled_actions-schedule)
### [](dsl-ashoban.html#examples-3)Examples
```
scheduled_actions do
schedule :import, "0 */6 * * *", action: :import
end
```
## [](dsl-ashoban.html#oban-scheduled_actions-schedule)oban.scheduled\_actions.schedule
```
schedule name, cron
```
### [](dsl-ashoban.html#arguments-1)Arguments
NameTypeDefaultDocs[`name`](dsl-ashoban.html#oban-scheduled_actions-schedule-name)`atom`A unique identifier for this scheduled action.[`cron`](dsl-ashoban.html#oban-scheduled_actions-schedule-cron)`String.t`The schedule in crontab notation
### [](dsl-ashoban.html#options-2)Options
NameTypeDefaultDocs[`action_input`](dsl-ashoban.html#oban-scheduled_actions-schedule-action_input)`map`Inputs to supply to the action when it is called.[`action`](dsl-ashoban.html#oban-scheduled_actions-schedule-action)`atom`The generic or create action to call when the schedule is triggered.[`queue`](dsl-ashoban.html#oban-scheduled_actions-schedule-queue)`atom`The queue to place the job in. Defaults to the resources short name plus the name of the scheduled action (not the action name).[`state`](dsl-ashoban.html#oban-scheduled_actions-schedule-state)`:active | :paused | :deleted``:active`Describes the state of the cron job. See the getting started guide for more information. The most important thing is that you *do not remove a scheduled action from a resource if you are using oban pro*.[`max_attempts`](dsl-ashoban.html#oban-scheduled_actions-schedule-max_attempts)`pos_integer``1`How many times to attempt the job. The action will receive a `last_oban_attempt?` argument on the last attempt, and you should handle errors accordingly.[`priority`](dsl-ashoban.html#oban-scheduled_actions-schedule-priority)`non_neg_integer``3`A number from 0 to 3, where 0 is the highest priority and 3 is the lowest.[`debug?`](dsl-ashoban.html#oban-scheduled_actions-schedule-debug?)`boolean``false`If set to `true`, detailed debug logging will be enabled for this trigger. You can also set `config :ash_oban, debug_all_triggers?: true` to enable debug logging for all triggers.
### [](dsl-ashoban.html#introspection-1)Introspection
Target: [`AshOban.Schedule`](AshOban.Schedule.html)
[← Previous Page Getting Started With Ash Oban](getting-started-with-ash-oban.html)
[Next Page → Change Log](changelog.html)
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) ([current file](https://preview.hex.pm/preview/ash_oban/0.2.6/show/documentation/dsls/DSL-AshOban.md)) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/documentation/tutorials/getting-started-with-ash-oban.md#L1 "View Source") Getting Started With Ash Oban
AshOban will likely grow to provide many more oban-related features, but for now the primary focus is on "triggers".
A trigger describes an action that is run periodically.
## [](getting-started-with-ash-oban.html#get-familiar-with-ash-resources)Get familiar with Ash resources
If you haven't already, read the [Ash Getting Started Guide](../ash/get-started.html), and familiarize yourself with Ash and Ash resources.
## [](getting-started-with-ash-oban.html#bring-in-the-ash_oban-dependency)Bring in the `ash_oban` dependency
```
{:ash_oban, "~> 0.2.6"}
```
## [](getting-started-with-ash-oban.html#setup)Setup
First, follow the [Oban setup guide](../oban/installation.html).
### [](getting-started-with-ash-oban.html#oban-pro)Oban Pro
If you are using Oban Pro, set the following configuration:
```
config :ash_oban, :pro?, true
```
Oban Pro lives in a separate hex repository, and therefore we, unfortunately, cannot have an explicit version dependency on it. What this means is that any version you use in hex will technically be accepted, and if you don't have the oban pro package installed and you use the above configuration, you will get compile time errors/warnings.
### [](getting-started-with-ash-oban.html#setting-up-ashoban)Setting up AshOban
Next, allow AshOban to alter your configuration in your Application module:
```
# Replace this
{Oban, your_oban_config}
# With this
{Oban, AshOban.config(Application.fetch_env!(:my_app, :ash_domains), your_oban_config)}
# OR this, to selectively enable AshOban only for specific domains
{Oban, AshOban.config([YourDomain, YourOtherDomain], your_oban_config)}
```
## [](getting-started-with-ash-oban.html#usage)Usage
Finally, configure your triggers in your resources.
Add the [`AshOban`](AshOban.html) extension:
```
use Ash.Resource, domain: MyDomain, extensions: [AshOban]
```
For example:
```
oban do
triggers do
# add a trigger called `:process`
trigger :process do
# this trigger calls the `process` action
action :process
# for any record that has `processed != true`
where expr(processed != true)
# checking for matches every minute
scheduler_cron "* * * * *"
on_error :errored
end
end
end
```
See the DSL documentation for more: [`AshOban`](dsl-ashoban.html)
## [](getting-started-with-ash-oban.html#handling-errors)Handling Errors
Error handling is done by adding an `on_error` to your trigger. This is an update action that will get the error as an argument called `:error`. The error will be an Ash error class. These error classes can contain many kinds of errors, so you will need to figure out handling specific errors on your own. Be sure to add the `:error` argument to the action if you want to receive the error.
This is *not* foolproof. You want to be sure that your `on_error` action is as simple as possible, because if an exception is raised during the `on_error` action, the oban job will fail. If you are relying on your `on_error` logic to alter the resource to make it no longer apply to a trigger, consider making your action do *only that*. Then you can add another trigger watching for things in an errored state to do more rich error handling behavior.
## [](getting-started-with-ash-oban.html#changing-triggers-when-using-oban-pro)Changing Triggers when using Oban Pro
To remove or disable triggers, *do not just remove them from your resource*. Due to the way that Oban Pro implements cron jobs, if you just remove them from your resource, the cron will attempt to continue scheduling jobs. Instead, set `paused true` or `delete true` on the trigger. See the oban docs for more: [https://getoban.pro/docs/pro/0.14.1/Oban.Pro.Plugins.DynamicCron.html#module-using-and-configuring](https://getoban.pro/docs/pro/0.14.1/Oban.Pro.Plugins.DynamicCron.html#module-using-and-configuring)
PS: `delete true` is also indempotent, so there is no issue with deploying with that flag set to true multiple times. After you have deployed once with `delete true` you can safely delete the trigger.
When not using Oban Pro, all crons are simply loaded on boot time and there is no side effects to simply deleting an unused trigger.
## [](getting-started-with-ash-oban.html#transactions)Transactions
AshOban adds two new transaction reasons, as it uses explicit transactions to ensure that each triggered record is properly locked and executed in serially.
```
%{
type: :ash_oban_trigger,
metadata: %{
resource: Resource,
trigger: :trigger_name,
primary_key: %{primary_key_fields: value}
}
}
```
and
```
%{
type: :ash_oban_trigger_error,
metadata: %{
resource: Resource
trigger: :trigger_name,
primary_key: %{primary_key_fields: value},
error: <the error (this will be an ash error class)>
}
}
```
## [](getting-started-with-ash-oban.html#authorizing-actions)Authorizing actions
As of v0.2, `authorize?: true` is passed into every action that is called. This may be a breaking change for some users that are using policies. There are two ways to get around this:
1. you can set `config :ash_oban, authorize?: false` (easiest, reverts to old behavior, but not recommended)
2. you can install the bypass at the top of your policies in any resource that you have triggers on that has policies:
```
policies do
bypass AshOban.Checks.AshObanInteraction do
authorize_if always()
end
...the rest of your policies
end
```
## [](getting-started-with-ash-oban.html#persisting-the-actor-along-with-a-job)Persisting the actor along with a job
Create a module that is responsible for translating the current user to a value that will be JSON encoded, and for turning that encoded value back into an actor.
```
defmodule MyApp.AshObanActorPersister do
use AshOban.PersistActor
def store(%MyApp.User{id: id}), do: %{"type" => "user", "id" => id}
def lookup(%{"type" => "user", "id" => id}), do: MyApp.Accounts.get(MyApp.User, id)
# This allows you to set a default actor
# in cases where no actor was present
# when scheduling.
def lookup(nil), do: {:ok, nil}
end
```
Then, configure this in application config.
```
config :ash_oban, :actor_persister, MyApp.AshObanActorPersister
```
### [](getting-started-with-ash-oban.html#considerations)Considerations
There are a few things that are important to keep in mind:
1. The actor could be deleted or otherwise unavailable when you look it up. You very likely want your `lookup/1` to return an error in that scenario.
2. The actor can have changed between when the job was scheduled and when the trigger is executing. It can even change across retries. If you are trying to authorize access for a given trigger's update action to a given actor, keep in mind that just because the trigger is running for a given action, does *not* mean that the conditions that allowed them to originally *schedule* that action are still true.
[← Previous Page Home](readme.html)
[Next Page → DSL: AshOban](dsl-ashoban.html)
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) ([current file](https://preview.hex.pm/preview/ash_oban/0.2.6/show/documentation/tutorials/getting-started-with-ash-oban.md)) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
[](https://github.com/ash-project/ash_oban)
[ash\_oban](https://github.com/ash-project/ash_oban)
v0.2.6
- GUIDES
- Modules
<!--THE END-->
<!--THE END-->
Search documentation of ash\_oban
Settings
# [View Source](https://github.com/ash-project/ash_oban/blob/v0.2.6/README.md#L1 "View Source") Home
 
 [](https://opensource.org/licenses/MIT) [](https://hex.pm/packages/ash_oban) [](../ash_oban.html)
# AshOban
Welcome! This is the extension for integrating [Ash](../ash.html) resources with [Oban](../oban.html). This extension allows you to easily execute resource actions in the background, and trigger actions based on data conditions.
## [](readme.html#tutorials)Tutorials
- [Getting Started with AshOban](getting-started-with-ash-oban.html)
## [](readme.html#reference)Reference
- [AshOban DSL](dsl-ashoban.html)
[← Previous Page API Reference](api-reference.html)
[Next Page → Getting Started With Ash Oban](getting-started-with-ash-oban.html)
[Hex Package](https://hex.pm/packages/ash_oban/0.2.6) [Hex Preview](https://preview.hex.pm/preview/ash_oban/0.2.6) ([current file](https://preview.hex.pm/preview/ash_oban/0.2.6/show/README.md)) Search HexDocs [Download ePub version](ash_oban.epub "ePub version")
Built using [ExDoc](https://github.com/elixir-lang/ex_doc "ExDoc") (v0.34.2) for the [Elixir programming language](https://elixir-lang.org "Elixir")
```