# `Hephaestus.Workflow`
[🔗](https://github.com/hephaestus-org/hephaestus_core/blob/v0.3.1/lib/hephaestus/core/workflow.ex#L275)

Macro module for defining workflows with callback-based pattern matching.

Add `use Hephaestus.Workflow` to a module to declare a workflow via
`start/0` and `transit/3`. Static clauses ignore the context argument
with `_ctx`. Dynamic clauses use `@targets` before the clause to declare
possible destinations for DAG validation. The macro extracts the step DAG
at compile time, validates it with `libgraph`, cross-checks `events/0`
declarations, and generates helper functions for runtime coordination.

## Options

  * `:tags` — a list of strings used as labels for observability and filtering
    (default: `[]`). Runner adapters can use these to tag jobs or events.

  * `:metadata` — a map with string keys and JSON-safe values (strings, numbers,
    booleans, nil, or nested maps/lists) for custom observability data (default: `%{}`).
    Atom keys are rejected because they lose identity after JSON round-tripping in
    adapters like Oban.

  * `:unique` — required keyword options used to build a `%Hephaestus.Workflow.Unique{}`
    for runtime uniqueness checks.

  * `:hephaestus` — optional module reference for multi-instance setups that need to
    identify which Hephaestus facade module should coordinate the workflow.

  * `:version` — a positive integer identifying this workflow definition version
    (default: `1`). Used by versioned workflow registries to route instances to the
    correct module.

  * `:versions` — a map of `%{version_integer => workflow_module}` that turns the
    module into an umbrella dispatcher. Umbrella modules do **not** define `start/0`
    or `transit/3` and skip DAG validation entirely. Instead they generate dispatcher
    functions (`__versions__/0`, `current_version/0`, `resolve_version/1`, and
    overridable `version_for/2`).

  * `:current` — required when `:versions` is set. The version integer that
    `resolve_version(nil)` and `current_version/0` resolve to.

## Generated Functions

When you `use Hephaestus.Workflow`, the following functions are generated in your module:

  * `__tags__/0` — returns the list of tags declared via the `:tags` option (default: `[]`).

  * `__metadata__/0` — returns the metadata map declared via the `:metadata` option
    (default: `%{}`).

  * `__unique__/0` — returns the validated `%Hephaestus.Workflow.Unique{}` declared via
    the required `:unique` option.

  * `__hephaestus__/0` — returns the optional module passed via the `:hephaestus`
    option, or `nil` when not configured.

  * `__predecessors__/1` — returns the set of immediate predecessor steps for a given
    step module as a `MapSet`. Used by `Hephaestus.Core.Engine` to implement join
    semantics: a step is only activated when all of its predecessors have completed.
    Returns an empty `MapSet` for the start step or unknown modules.

  * `__graph__/0` — returns the complete workflow DAG as a `Graph` struct (from the
    `libgraph` library). Useful for introspection and tooling such as
    `mix hephaestus.gen.docs`.

  * `__edges__/0` — returns the raw list of edge maps extracted at compile time. Each
    edge is a map with `:from`, `:event`, `:targets`, and `:dynamic?` keys. Used by
    tooling (e.g., `mix hephaestus.gen.docs`) to render event-annotated workflow
    diagrams.

  * `__version__/0` — returns the workflow version as a positive integer (default: `1`).
    Umbrella dispatcher modules instead return `nil`.

  * `__versioned__?/0` — returns `false` for standalone workflows. Version-dispatcher
    umbrella modules override this to return `true`.

  * `resolve_version/1` — given `nil` or the matching version integer, returns
    `{version, module}`. Raises `ArgumentError` for any other version.

### Umbrella-only functions (when `:versions` is set)

  * `__versions__/0` — returns the version map passed via the `:versions` option.

  * `current_version/0` — returns the version integer passed via the `:current` option.

  * `resolve_version/1` — given `nil`, returns `{current, module}`. Given a version
    integer present in the map, returns `{version, module}`. Raises `ArgumentError`
    for unknown versions.

  * `version_for/2` — receives the version map and an opts keyword list. Returns `nil`
    by default. The opts keyword list is forwarded from `start_instance/3` as-is,
    but the callback is only consulted when no explicit `opts[:version]` was passed.
    The core reserves `:version` and `:telemetry_metadata`, so custom routing
    should avoid those keys. Can be overridden (`defoverridable`) to implement
    custom version selection logic.

## Validation Rules

Standard workflows validate `:version` as a positive integer.

Umbrella workflows additionally validate that:

  * `:version` and `:versions` are not used together
  * every key in `:versions` is a positive integer
  * `:current` is present in `:versions`
  * every referenced version module implements `Hephaestus.Core.Workflow`
  * every referenced version module reports the same `__version__/0` as its map key
  * every referenced version module is nested under the umbrella module namespace

Umbrella modules are dispatchers, so they do not generate DAG helper functions like
`__graph__/0`, `__edges__/0`, or `__predecessors__/1`.

---

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