# `SferaDoc.Store.Adapter`
[🔗](https://github.com/sfera-lab/sfera-doc/blob/v0.1.0/lib/sfera_doc/store/adapter.ex#L1)

Behaviour that all SferaDoc storage backends must implement.

Templates are identified by their `name` (a human-readable string). Each name
can have multiple numbered versions; at most one version per name is active at
any time.

## Implementing a Custom Adapter

1. `use` or `@behaviour SferaDoc.Store.Adapter`
2. Implement all callbacks
3. Return `nil` from `worker_spec/0` if your adapter uses an externally
   supervised process (e.g. an Ecto Repo managed by the host application)
4. Configure the library to use your adapter:

       config :sfera_doc, :store, adapter: MyApp.CustomAdapter

# `name`

```elixir
@type name() :: String.t()
```

# `reason`

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

# `version`

```elixir
@type version() :: pos_integer()
```

# `activate_version`

```elixir
@callback activate_version(name(), version()) ::
  {:ok, SferaDoc.Template.t()} | {:error, :not_found} | {:error, reason()}
```

Makes the given version the active one for the template name.
Deactivates all other versions for that name.

# `delete`

```elixir
@callback delete(name()) :: :ok | {:error, reason()}
```

Deletes all versions of a template by name.

# `get`

```elixir
@callback get(name()) ::
  {:ok, SferaDoc.Template.t()} | {:error, :not_found} | {:error, reason()}
```

Fetches the currently active template for the given name.

# `get_version`

```elixir
@callback get_version(name(), version()) ::
  {:ok, SferaDoc.Template.t()} | {:error, :not_found} | {:error, reason()}
```

Fetches a specific version of a template by name and version number.

# `list`

```elixir
@callback list() :: {:ok, [SferaDoc.Template.t()]} | {:error, reason()}
```

Returns all templates (latest active version per name).

# `list_versions`

```elixir
@callback list_versions(name()) :: {:ok, [SferaDoc.Template.t()]} | {:error, reason()}
```

Returns all versions for a given template name, ordered by version descending.

# `put`

```elixir
@callback put(SferaDoc.Template.t()) :: {:ok, SferaDoc.Template.t()} | {:error, reason()}
```

Persists a new version of the template.

The adapter is responsible for:
- computing the next version number (`MAX(existing versions) + 1`, or `1` if new)
- setting `is_active: true` on the new record
- setting `is_active: false` on all previous versions for the same name

Both create and update go through this single callback.

# `worker_spec`

```elixir
@callback worker_spec() :: Supervisor.child_spec() | nil
```

Returns a child spec for processes this adapter needs, or `nil` if the
adapter relies on externally managed processes (e.g. Ecto repos).

The supervisor filters out `nil` values, so returning `nil` is safe.

---

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