# `Concord.Lease`
[🔗](https://github.com/gsmlg-dev/concord/blob/main/lib/concord/lease.ex#L1)

Public API for Concord's grouped TTL / lease system.

A lease is a named TTL contract: keys attached to a lease are atomically
deleted when the lease expires or is revoked. Leases unify TTL management
and provide group-level expiration.

## Usage

    # Grant a 30-second lease
    {:ok, %{lease_id: id}} = Concord.Lease.grant(30)

    # Attach keys to the lease
    Concord.KV.put("key1", "val1", lease: id)
    Concord.KV.put("key2", "val2", lease: id)

    # Keep alive (reset TTL)
    :ok = Concord.Lease.keep_alive(id)

    # Revoke (deletes all attached keys atomically)
    :ok = Concord.Lease.revoke(id)

## Lease Object

    %{
      id:           integer(),
      ttl:          integer(),     # granted TTL in seconds
      remaining:    integer(),     # remaining TTL in seconds
      granted_at:   integer(),     # revision when granted
      keys:         [binary()]     # currently attached keys
    }

# `grant`

```elixir
@spec grant(
  pos_integer(),
  keyword()
) :: {:ok, map()} | {:error, term()}
```

Grants a new lease with the given TTL in seconds.

## Options

- `:timeout` — operation timeout in ms (default: 5000)

## Returns

`{:ok, %{lease_id: integer(), ttl: integer()}}` on success.

# `info`

```elixir
@spec info(
  integer(),
  keyword()
) :: {:ok, map()} | {:error, term()}
```

Returns information about a lease.

# `keep_alive`

```elixir
@spec keep_alive(
  integer(),
  keyword()
) :: :ok | {:error, term()}
```

Refreshes a lease, resetting its TTL to the original granted value.

## Returns

`:ok` on success, `{:error, :lease_not_found}` if the lease doesn't exist.

# `list`

```elixir
@spec list(keyword()) :: {:ok, [map()]} | {:error, term()}
```

Lists all active leases.

# `revoke`

```elixir
@spec revoke(
  integer(),
  keyword()
) :: {:ok, map()} | {:error, term()}
```

Revokes a lease and atomically deletes all attached keys.

## Returns

`{:ok, %{deleted_keys: integer()}}` on success.

