# `Arcana.Documents`
[🔗](https://github.com/georgeguimaraes/arcana/blob/main/lib/arcana/documents.ex#L1)

Public read API for documents.

Lets host apps build admin surfaces (list a collection's documents,
show ingestion status, paginate) and assert on ingestion outcomes in
tests without querying Arcana's schemas through Ecto directly.

`Arcana.Document` is the stable public shape: `id`, `status`,
`chunk_count`, `metadata`, `source_id`, `content_type`, timestamps,
and the preloaded `collection`.

# `count_documents`

Counts documents matching the same filters as `list_documents/1`
(`:collection`, `:status`, `:source_id`), for building pagination.

## Examples

    {:ok, total} = Arcana.count_documents(repo: MyApp.Repo, collection: "products")

# `get_document`

Fetches a single document by id, with its collection preloaded.

Returns `{:ok, document}` or `{:error, :not_found}`.

## Options

  * `:repo` - The Ecto repo to use (required unless configured globally)
  * `:collection` - Limit the lookup to `:all`, one collection name, a list
    of names, or `[]` to match nothing

## Examples

    {:ok, document} = Arcana.get_document(id, repo: MyApp.Repo)
    {:ok, document} =
      Arcana.get_document(id, repo: MyApp.Repo, collection: ["support", "api"])

# `get_document_metadata`

```elixir
@spec get_document_metadata([Ecto.UUID.t()], keyword()) ::
  {:ok, %{optional(Ecto.UUID.t()) =&gt; Arcana.DocumentMetadata.t()}}
  | {:error, {:invalid_document_id, term()}}
```

Fetches sparse metadata for several published documents in one query.

A collection scope is required. Pass `collection: "support"`,
`collection: ["support", "api"]`, or an explicit `collection: :all`.
Missing IDs, documents outside the scope, and documents that have not
completed ingestion are omitted from the returned ID-keyed map. Duplicate
IDs are queried once.

Returns `{:error, {:invalid_document_id, id}}` without querying when any ID
is not a valid UUID.

## Options

  * `:repo` - The Ecto repo to use (required unless configured globally)
  * `:collection` - `:all`, one collection name, a list of names, or `[]`

# `list_documents`

Lists documents, newest first.

## Options

  * `:repo` - The Ecto repo to use (required unless configured globally)
  * `:collection` - Filter by `:all`, one collection name, a list of names,
    or `[]` to match nothing. Unknown names never widen the query.
  * `:status` - Filter by status (`:pending`, `:processing`,
    `:completed`, `:failed`)
  * `:source_id` - Filter by source id
  * `:limit` - Maximum documents to return (default: 50)
  * `:offset` - Number of documents to skip (default: 0)

## Examples

    {:ok, docs} = Arcana.list_documents(repo: MyApp.Repo, collection: "products")
    {:ok, failed} = Arcana.list_documents(repo: MyApp.Repo, status: :failed)
    {:ok, page2} = Arcana.list_documents(repo: MyApp.Repo, limit: 20, offset: 20)

---

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