# `Mediate.Schema`
[🔗](https://github.com/mrmeku/mediate/blob/v0.1.0/lib/mediate/schema.ex#L39)

Declarations on an Ecto schema. They say:

- the object type it protects
- the associations its decision covers
- what kind of thing its rows are
- the fact mapping, column by column

Each macro records its declaration and does nothing else. The seam reads
them back through `__mediate__/1`.

    defmodule Example.Domain.Visibility do
      use Ecto.Schema
      use Mediate.Schema

      object_type(:visibility)
      audited(:entity)
      fact(:labels, kind: :object_attribute, object: :repository_id, element: :label)
      fact(:restrictions, kind: :object_attribute, object: :repository_id, element: :restriction)
      fact(:releasable_to, kind: :object_attribute, object: :repository_id, element: :country)
      fact(:invited, kind: :relationship, object: :repository_id, element: :user)
    end

A schema that declares an object type is protected: the seam refuses to
read or write it without a decision. A schema that declares
`carries/1` names the associations the root's decision covers. A grant
row declares `relationship/1` with its subject and object columns.

`__mediate__/1` answers each declaration:

- `:object_type`, the declared type or `nil`
- `:carries`, the carried association names
- `:kind`, the kind `audited/1` declared or `nil`
- `:facts`, the `Mediate.Schema.Fact` records in declaration order
- `:relationship`, the `Mediate.Schema.Relationship` or `nil`

This file defines every structure it needs, so a schema's compile-time
dependency on it reaches nothing else.

# `audited`
*macro* 

Declare what kind of thing a row of this schema is, which is what makes its writes audited. An audited schema need not declare an object type, and then the seam records its writes and passes them without a decision.

# `audited?`

```elixir
@spec audited?(term()) :: boolean()
```

Whether the seam audits a module's writes, which is whether it declares what kind of thing its rows are.

# `carries`
*macro* 

Declare the associations the parent's decision covers.

# `carries_of`

```elixir
@spec carries_of(term()) :: [atom()]
```

The associations a module's decision covers, or `[]` where it declares none.

# `declares?`

```elixir
@spec declares?(term()) :: boolean()
```

Whether a module used `Mediate.Schema`.

# `fact`
*macro* 

Declare one fact column and how it maps to a fact kind.

# `fact_columns`

```elixir
@spec fact_columns(term()) :: [atom()]
```

The columns a module declares as facts: its fact columns and the columns
of its relationship, each once, in declaration order.

# `fact_schema?`

```elixir
@spec fact_schema?(term()) :: boolean()
```

Whether a module carries fact declarations: a fact column or a relationship.

# `facts_of`

```elixir
@spec facts_of(term()) :: [Mediate.Schema.Fact.t()]
```

The fact columns a module declares, in declaration order, or `[]` where it declares none.

# `id_of`

```elixir
@spec id_of(struct()) :: term()
```

A row's primary key: the value of its one key column, or a map of the columns where it has several.

# `kind_of`

```elixir
@spec kind_of(term()) :: atom() | nil
```

What kind of thing a module's rows are, or `nil` for a module that declares none.

# `object_type`
*macro* 

Declare the object type this schema's rows are, so a query over it needs a decision.

# `object_type_of`

```elixir
@spec object_type_of(term()) :: atom() | nil
```

The object type a module declares, or `nil` for a module that declares none or is not a schema.

# `relationship`
*macro* 

Declare that a row of this schema is a relationship grant.

# `relationship_of`

```elixir
@spec relationship_of(term()) :: Mediate.Schema.Relationship.t() | nil
```

The relationship a module's rows are, or `nil`.

---

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