README.md

# Altworx Runbox

**Runbox** is a runtime environment for Altworx scenarios.
It provides essential data structures, APIs, and tools for developing, testing, and packaging scenarios.

Check out also [Toolbox](https://hex.pm/packages/altworx_toolbox), which builds on top of Runbox and
provides conveniences and additional abstractions for writing scenarios.

Note that there are two types of documentation for Runbox.
The [main documentation](https://hexdocs.pm/altworx_runbox) (the one you are probably seeing now)
covers all user-facing modules. This is the go-to documentation when writing scenarios.
However, there is also the [internal documentation](https://hexdocs.pm/altworx_runbox/internal)
that covers also internal modules. That documentation might be useful if you want to dig deeper
into how scenarios run.

## Scenario projects

Scenarios in Altworx are developed as Elixir/Mix projects, with a single project potentially containing
multiple scenarios. When packaged, all scenarios in a project are bundled together.

To start a new scenario project, create a blank project using `mix new project_name`, then add Runbox
as a dependency in your `mix.exs`:

```elixir
defp deps do
  [
    {:runbox, "~> 9.0", hex: :altworx_runbox}
  ]
end
```

### Scenario structure

Scenario is a collection of Elixir modules. The main module is a manifest module. Manifest module
describes the scenario - carries its metadata. Manifest module must be named `Scenario(s).X`, where
`X` is anything you choose, but it cannot have any further structure. E.g. `Scenarios.MyScenario` is
OK while `Scenarios.My.Scenario` is not. You can read more about a manifest here -
`Runbox.Scenario.Manifest`.

Then a scenario needs modules which define it's behaviour - what the scenario does. These modules
and their structure depend on the scenario type. There may be multiple different scenario types.
Each can behave and run differently and every type has it's own strengths and weaknesses. Available
types are defined in `Runbox.Scenario.Type`.

For more in-depth details about how scenario works and how to write one, see the following modules.
- `Simple` scenario runtime - see `Runbox.Scenario.Simple`
- `StageBased` scenario runtime - see `Runbox.Scenario.Template.StageBased`

Scenario can define and use other modules. These modules don't have any predefined meaning nor do we
require any specific module names.

### Configuration

Runbox requires the `:scenario_config_dir` environment variable under the :runbox app to be set.
This is automatically handled when running in Altworx but may need to be configured for the `test`
environment. You can use a dummy value for testing, like so in `config/test.exs`:

```elixir
import Config

config :runbox, scenario_config_dir: "/non-existing/does/not/matter"
```

## Building scenario artefacts

Using Runbox, scenarios are packaged into *artefacts* (also called *releases*) that can be deployed
to and run in Altworx. These artefacts include both the scenarios code and the runtime environment.
To build a scenario artefact, make sure you have Docker installed and then run

```sh
mix altworx.scenario_release
```

You can then load the built scenario artifact in the Admin UI. Do not forget to restart Altworx
afterwards.

## Architectural details

Altworx runs in a single BEAM node and spawns a separate BEAM node for each scenario release.
Both Altworx and the scenario nodes run the Runbox app, so Runbox also serves for communication
between these two. On the Altworx node, it is responsible for starting the scenario nodes.

Scenario nodes can are used for:
* listing scenarios in a scenario release
* spawning components for a scenario "run"
* processing notification templates