# `AshOnetime.Transaction`
[🔗](https://github.com/baselabs/ash_onetime/blob/v1.5.0/lib/ash_onetime/transaction.ex#L1)

Transaction-owned idempotency and one-time nonce admission.

This boundary is for hosts that already own one authoritative Ecto transaction and need
`ash_onetime` admission to commit or roll back with the host's effect. It never starts or
commits a transaction. The repository must already be inside a PostgreSQL `READ COMMITTED`
transaction.

`:operation` is a local-code `{module, action}` pair. `:partition`, `:scope`, and `:key` are
exact bounded UTF-8 binaries. A logical partition isolates otherwise identical locators in one
store installation without importing a host application's tenant or actor types.

# `admission`

```elixir
@opaque admission()
```

Opaque fresh idempotency admission returned by `idempotency/2`.

# `claim_id`

```elixir
@spec claim_id(admission()) :: Ecto.UUID.t()
```

Returns the claim UUID of a fresh admission.

`Admission` is opaque by contract; this is the one sanctioned accessor. The
UUID is the durable address of the claim inside the store — persisting it
lets a host correlate its own invocation records with the claim (and hand
the unchanged UUID to an external execute/recover peer). A pure read: no
process, transaction, or store interaction.

# `complete`

```elixir
@spec complete(admission(), binary()) :: :ok | {:error, AshOnetime.Error.t()}
```

Completes a fresh idempotency admission with exact response bytes.

Completion must run in the same process and caller-owned transaction as `idempotency/2`.
The codec selected during admission, the SHA-256 digest, and the exact bytes are bound
atomically to the claim.

# `idempotency`

```elixir
@spec idempotency(Ecto.Repo.t(), keyword()) ::
  {:execute, admission()} | {:replay, binary()} | {:error, AshOnetime.Error.t()}
```

Reserves an idempotency key inside the caller's current transaction.

Returns `{:execute, admission}` for a new request, `{:replay, exact_bytes}` for a completed
matching request, or a typed `AshOnetime.Error`. Reusing the locator with a different
fingerprint returns `:key_reused_with_different_request`; an incomplete matching request
returns `:request_in_progress`.

# `nonce`

```elixir
@spec nonce(Ecto.Repo.t(), keyword()) :: :ok | {:error, AshOnetime.Error.t()}
```

Reserves a one-time nonce inside the caller's current transaction.

`:verified` must contain trusted `AshOnetime.Verified` facts whose exact key equals `:key`.
A collision returns the typed `:nonce_already_used` error. No response payload is created.

---

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