# `Bourse.Extract.JsonLoader`
[🔗](https://github.com/ZenHive/bourse/blob/main/lib/bourse/extract/json_loader.ex#L1)

Generates JSON loading boilerplate with `:persistent_term` caching.

Documents are decoded through `Bourse.JsonDocument`, so duplicate object keys
fail loudly (file, key, object path) rather than silently keeping the first
occurrence.

# `decode_file!`

```elixir
@spec decode_file!(String.t()) :: map()
```

Decodes an extractor document after rejecting duplicate JSON object keys.

Shared path used by generated loaders; also the entry point for tests and
catalog validation.

# `validate_all_documents!`

```elixir
@spec validate_all_documents!() :: :ok
```

Validates every JSON document under `priv/extractor/`.

Hand-edited extractor documents (e.g. `ccxt_emulated_methods.json` with
`authored_delegate` entries) are covered the moment they land — duplicate-key
loss is a property of hand-editing, not of machine-frozen distill output.

---

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