# `Weavr.Bulk`
[🔗](https://github.com/iamkanishka/weavr/blob/main/lib/weavr/bulk.ex#L1)

Bulk process operations for the Weavr Multi API.

Bulk processing lets you submit up to 10,000 individual operations
(e.g. creating Authorised Users, blocking/unblocking Managed Cards,
creating Outgoing Wire Transfers) in a single request, then manage
their asynchronous execution as a unit.

## Lifecycle

A bulk process moves through the following states:

    SUBMITTED --execute--> RUNNING --(completes)--> COMPLETED | PARTIALLY_COMPLETED
                                |  ^
                            pause|  |resume
                                v  |
                              PAUSED
                                |
                             cancel
                                v
                            CANCELLED (final)

  * `SUBMITTED` - data has been persisted and is ready for execution.
     This is the initial state. Submission does not expire, but it
     can be cancelled.
  * `RUNNING` - the bulk process is currently executing.
  * `PAUSED` - execution has been paused; can only be reached from
     `RUNNING` via `pause/3`, and only `RUNNING` accepts `pause/3`.
  * `COMPLETED` - a final state: every operation succeeded.
  * `PARTIALLY_COMPLETED` - a final state: execution finished but
     some individual operations failed.
  * `CANCELLED` - a final state, reachable from `RUNNING` or
     `PAUSED` via `cancel/3`. A cancelled bulk process cannot be
     resumed.

A submitted bulk process can be managed (executed, accessed, paused,
resumed, cancelled) by any Authorised User belonging to the same
identity as the user who originally submitted it — not only the
original submitter.

## Errors

Besides the standard `Weavr.Error.API` cases (400/401/403/404/
500/503), pause/resume/cancel/execute can return a
`BulkProcessorConflict` error code (still surfaced as a
`Weavr.Error.API` with `code: "BulkProcessorConflict"`) when the
bulk process isn't in a state that allows the requested transition
— e.g. calling `pause/3` on a process that isn't `RUNNING`.

## A note on operation payload shapes

This module implements the verified, stable parts of the bulk
lifecycle: submit, execute, get, list, pause, resume, cancel, and
list-operations. The exact JSON shape of each *kind* of bulk
operation payload (e.g. exactly which fields a bulk "create
Authorised User" entry needs) is specific to the underlying
single-resource endpoint it wraps (`userCreate`, `sendCreate`, /
`outgoingWireTransferCreate`, etc) and is intentionally accepted here
as a plain map - build each entry according to the single-resource
endpoint's documented schema, and `submit/3` will pass your list
through as the `operations` array unmodified.

# `bulk_process`

```elixir
@type bulk_process() :: %{
  bulk_id: String.t() | nil,
  status: bulk_status(),
  raw: map()
}
```

# `bulk_status`

```elixir
@type bulk_status() :: String.t() | nil
```

# `cancel`

```elixir
@spec cancel(Weavr.Config.t(), String.t(), keyword()) ::
  :ok | {:error, Weavr.Error.t()}
```

Cancels a `RUNNING` or `PAUSED` bulk process, transitioning it to
the final `CANCELLED` state. A cancelled bulk process cannot be
resumed.

Sends `POST /bulks/{bulk_id}/cancel`.

# `execute`

```elixir
@spec execute(Weavr.Config.t(), String.t(), keyword()) ::
  :ok | {:error, Weavr.Error.t()}
```

Launches execution of a bulk process. Requires the process to be in
`SUBMITTED` state; transitions it to `RUNNING`.

Sends `POST /bulks/{bulk_id}/execute`. This operation is
asynchronous — it returns immediately, and you track progress via
`get/3`.

# `get`

```elixir
@spec get(Weavr.Config.t(), String.t(), keyword()) ::
  {:ok, bulk_process()} | {:error, Weavr.Error.t()}
```

Retrieves the current status and details of a bulk process.

Sends `GET /bulks/{bulk_id}`.

# `list`

```elixir
@spec list(
  Weavr.Config.t(),
  keyword()
) :: {:ok, [bulk_process()]} | {:error, Weavr.Error.t()}
```

Filters/lists bulk processes for the authenticated identity.

Sends `GET /bulks`. `filters` is passed through as query parameters
(e.g. `status: "RUNNING"`) — see your Weavr API reference for the
full set of supported filter fields.

# `list_operations`

```elixir
@spec list_operations(Weavr.Config.t(), String.t(), keyword()) ::
  {:ok, [map()]} | {:error, Weavr.Error.t()}
```

Retrieves the individual operations belonging to a bulk process
(their per-entry status, success/failure, errors, etc).

Sends `GET /bulks/{bulk_id}/operations`. Note: the names and
descriptions of fields in the operations array changed in a past
Weavr release — if you're matching on specific field names, check
your current API reference rather than relying on older
documentation or blog posts.

# `pause`

```elixir
@spec pause(Weavr.Config.t(), String.t(), keyword()) ::
  :ok | {:error, Weavr.Error.t()}
```

Pauses a `RUNNING` bulk process, transitioning it to `PAUSED`.

Sends `POST /bulks/{bulk_id}/pause`.

# `processor_conflict?`

```elixir
@spec processor_conflict?(Weavr.Error.t()) :: boolean()
```

Returns `true` if the given error represents a `BulkProcessorConflict`
— i.e. the requested transition (pause/resume/cancel/execute) isn't
valid for the bulk process's current state.

# `resume`

```elixir
@spec resume(Weavr.Config.t(), String.t(), keyword()) ::
  :ok | {:error, Weavr.Error.t()}
```

Resumes a `PAUSED` bulk process, transitioning it back to `RUNNING`.

Sends `POST /bulks/{bulk_id}/resume`.

# `submit`

```elixir
@spec submit(Weavr.Config.t(), String.t(), [map()], keyword()) ::
  {:ok, bulk_process()} | {:error, Weavr.Error.t()}
```

Submits a batch of operations as a new bulk process.

`operation_type` should match the underlying single-resource
operation each entry represents, as documented by Weavr for that
bulk endpoint (e.g. `"users"`, `"managed_cards/block"`,
`"managed_cards/unblock"`, `"sends"`). Because the set of supported
bulk operation kinds has grown over time and isn't fully enumerable
from the fragments of the spec available to this client, this
function accepts the path segment directly rather than an atom enum
— check your Weavr API reference's "Operations" section for the
exact path for the bulk operation you need.

`operations` is a list of up to 10,000 maps, each shaped like the
single-resource request body for `operation_type`.

Returns the new bulk process's id on success.

---

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