# `Codat.Platform.PushOperations`
[🔗](https://github.com/iamkanishka/codat.git/blob/v1.0.0/lib/codat/platform/push_operations.ex#L1)

Track asynchronous write (push) operations.

All Codat write operations (create, update, delete) are **asynchronous**.
The API immediately returns a push operation in `Pending` status.
Use this module to poll for completion, or subscribe to the appropriate
webhook event (e.g., `invoices.write.successful`).

## Push Operation Statuses

| Status      | Description                                                       |
|-------------|-------------------------------------------------------------------|
| `Pending`   | Operation queued, not yet processed by the integration.           |
| `Processing`| Operation is being submitted to the accounting platform.          |
| `Success`   | Operation completed successfully. Data is in the platform.        |
| `Failed`    | Operation failed. Check `errorMessage` and `validation` fields.   |
| `TimedOut`  | Operation exceeded the configured `timeoutInMinutes`.             |

## Example

    # Create an invoice — returns a push operation immediately
    {:ok, push_op} = Codat.Accounting.Invoices.create(client, company_id, conn_id, body)
    key = push_op["pushOperationKey"]

    # Poll until complete (or subscribe to webhooks instead)
    {:ok, op} = Codat.Platform.PushOperations.poll_until_done(client, company_id, key)
    op["status"]  # => "Success"

# `get`

```elixir
@spec get(Codat.Client.t() | String.t(), String.t(), String.t() | keyword()) ::
  {:ok, map()} | {:error, Codat.Error.t()}
```

Returns a single push operation by its key.

## Example

    {:ok, op} = Codat.Platform.PushOperations.get(client, "company-id", "push-op-key")
    op["status"]           # => "Success"
    op["dataType"]         # => "invoices"
    op["completedOnUtc"]   # => "2024-01-15T10:30:00Z"

# `list`

```elixir
@spec list(Codat.Client.t() | String.t(), String.t() | keyword(), keyword()) ::
  {:ok, Codat.Pagination.t()} | {:error, Codat.Error.t()}
```

Returns a paginated list of push operations for a company.

## Options

- `:page`, `:page_size` — pagination
- `:query` — filter, e.g. `"status=Failed&&dataType=invoices"`

## Example

    {:ok, page} = Codat.Platform.PushOperations.list(client, "company-id")
    {:ok, page} = Codat.Platform.PushOperations.list("company-id", query: "status=Failed")

# `poll_until_done`

```elixir
@spec poll_until_done(
  Codat.Client.t() | String.t(),
  String.t(),
  String.t() | keyword(),
  keyword()
) :: {:ok, map()} | {:error, Codat.Error.t()}
```

Polls a push operation until it reaches a terminal status (`Success`, `Failed`, `TimedOut`)
or the polling timeout is exceeded.

## Options

- `:poll_interval` — ms between polls (default: 2000ms)
- `:timeout` — max total wait time in ms (default: 120000ms)

## Returns

- `{:ok, push_op}` with `status: "Success"` on success
- `{:ok, push_op}` with `status: "Failed"` if the operation failed in the integration
- `{:error, %Codat.Error{type: :timeout}}` if polling timed out
- `{:error, %Codat.Error{}}` on HTTP error

## Example

    {:ok, op} = Codat.Platform.PushOperations.poll_until_done(
      client, "company-id", "push-key",
      poll_interval: 1_000,
      timeout: 60_000
    )

    case op["status"] do
      "Success" -> IO.puts("Created! ID: " <> op["data"]["id"])
      "Failed"  -> IO.puts("Failed: " <> op["errorMessage"])
    end

---

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