# `Ithibati.Schema.Invitation`
[🔗](https://github.com/oliverandrich/ithibati/blob/v0.6.2/lib/ithibati/schema/invitation.ex#L1)

Adds invitation-token fields and validation to an application-owned schema.

Declare the invitation's identifier and add your own fields for what accepting it grants:

    defmodule MyApp.Accounts.Invitation do
      use Ecto.Schema
      import Ecto.Changeset

      alias Ithibati.Schema.Identifier
      alias Ithibati.Schema.Invitation

      use Invitation, identifier: :email, format: Identifier.email_format()

      schema "invitations" do
        ithibati_invitation()

        field :role, Ecto.Enum, values: [:admin, :author]
        belongs_to :site, MyApp.Sites.Site

        timestamps(type: :utc_datetime_usec)
      end

      def changeset(invitation, attrs, opts \ []) do
        invitation
        |> invitation_changeset(attrs, opts)
        |> cast(attrs, [:role, :site_id])
        |> validate_required([:role, :site_id])
      end
    end

The options match `Ithibati.Schema.User`: required `:identifier`, optional `:format` and
`:format_message`, plus `:constraint_name` and `:unique_index`. On invitations, the index
options refer to `token_hash`, not the identifier. Non-identifier options can be module
attributes declared before `use`; explicit `nil` values are rejected.

The identifier field must match the configured account schema's identifier. That agreement is
checked when `Ithibati.Config.invitation_schema/0` reads the application configuration.

Call `ithibati_invitation/0` inside the schema. The macro generates `invitation_changeset/3`
and `__ithibati_invitation__/1`; defining either yourself is rejected at compile time.
[Invitations](invitations.md) covers the table, token index and acceptance transaction.

# `invitation_schema?`

Returns whether the module is loaded and exports the invitation-schema metadata function.

This identifies the schema integration. `Ithibati.Config.invitation_schema/0` additionally
checks agreement with the account identifier; migration and doctor checks inspect the table.

# `ithibati_invitation`
*macro* 

Declares invitation fields inside the application's schema block.

Adds the configured identifier as `:string`, `:token_hash` as `:binary`, and
`:expires_at` and `:accepted_at` as `:utc_datetime_usec`. It also adds a virtual `:token`
string for the plaintext token returned when a valid new invitation is built.

Only the digest is stored. Retain the plaintext token to deliver the invitation link;
reloading the row does not recover it.

---

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