<!--
This file was generated by Spark. Do not edit it by hand.
-->
# AshNeo4j.DataLayer
Ash DataLayer for Neo4j.
## Errors (#372)
Every error the behaviour callbacks (`create`/`update`/`destroy`/`run_query`/…)
return is a **typed struct** — never a bare string (a string becomes
`Ash.Error.Unknown.UnknownError`: unclassified and only substring-matchable).
Pick by meaning:
* **Server/Bolt error** → `AshNeo4j.Error.Neo4j` (classifies by category).
* **Deliberate refusal** ("can't push this down / won't render it") → the
`AshNeo4j.Error.Unsupported*` / `Requires*` family (`class: :invalid`).
* **The node/edge we expected to act on wasn't there** → reuse Ash's own:
`Ash.Error.Changes.StaleRecord` (the record is gone / a guard no longer holds)
or `Ash.Error.Invalid.Unavailable` (a preservation guard blocked a destroy).
* **An internal invariant we couldn't satisfy** (unexpected input shape, a
relationship/aggregate path that won't resolve) → `AshNeo4j.Error.Internal`
(`class: :unknown`).
Two standing rules: **reuse an Ash error before inventing an `AshNeo4j.Error.*`**,
and **return, never raise**, from the behaviour path. Internal sentinels between
helpers (e.g. `{:error, :nothing_deleted}` from `run_expecting_deletions/2`) are
atoms, not strings, and are converted to a typed error before escaping. The
contract is enforced by `test/error_contract_test.exs`.
`Ash.Type` callbacks (cast/dump/load) are a separate contract — they follow Ash's
type-error convention (message strings), not this one.
## neo4j
### Examples
```
neo4j do
label :Comment
relate [{:post, :BELONGS_TO, :outgoing, :Post}]
end
```
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`label`](#neo4j-label){: #neo4j-label } | `atom` | | Optional node label |
| [`relate`](#neo4j-relate){: #neo4j-relate } | `list({atom, atom, atom, atom})` | `[]` | Optional list of relationships, as tuples of {relationship_name, edge_label, edge_direction, destination_label} |
| [`guard`](#neo4j-guard){: #neo4j-guard } | `list({atom, atom, atom})` | `[]` | Optional list of node relationships, as tuples of {edge_label, edge_direction, destination_label} |
| [`skip`](#neo4j-skip){: #neo4j-skip } | `list(atom)` | `[]` | Optional list of attributes not to be stored directly as node properties |
<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>