# `Lotus.Cache`
[🔗](https://github.com/elixir-lotus/lotus/blob/v1.0.0/lib/lotus/cache.ex#L1)

Lotus cache facade. If no adapter configured, acts as a no-op pass-through.

# `key`

```elixir
@type key() :: binary()
```

# `opts`

```elixir
@type opts() :: Keyword.t()
```

# `ttl_ms`

```elixir
@type ttl_ms() :: non_neg_integer()
```

# `value`

```elixir
@type value() :: any()
```

# `build_options`

```elixir
@spec build_options(term(), [String.t()]) :: opts()
```

Builds the per-entry options for a cache write.

Layers the caller's `:cache` option over the entry options set in
application config, then adds the invalidation tags. A caller that passes
no `:cache` option, or an atom such as `:bypass`, still gets the
configured defaults.

# `delete`

```elixir
@spec delete(key()) :: :ok | {:error, term()}
```

# `enabled?`

```elixir
@spec enabled?() :: boolean()
```

# `get`

```elixir
@spec get(key()) :: {:ok, value()} | :miss
```

# `get_or_store`

```elixir
@spec get_or_store(key(), ttl_ms(), (-&gt; value()), opts()) ::
  {:ok, value(), :hit | :miss | atom()} | {:error, term()}
```

# `invalidate_scope`

```elixir
@spec invalidate_scope(term()) :: :ok | {:error, term()}
```

Invalidates all cache entries associated with the given scope.

Uses tag-based invalidation — each scoped cache entry is tagged with
`"scope:<digest>"`, so this clears only entries for the specified scope
without flushing the entire source cache.

## Examples

    Lotus.Cache.invalidate_scope(%{tenant_id: 42})
    Lotus.Cache.invalidate_scope(%{role: :admin})

# `invalidate_tags`

```elixir
@spec invalidate_tags([binary()]) :: :ok | {:error, term()}
```

# `put`

```elixir
@spec put(key(), value(), ttl_ms(), opts()) :: :ok | {:error, term()}
```

---

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