Tayori.Inbox (Tayori v0.1.0)

Copy Markdown View Source

The changes that shipped, before they become entries: what the app's sources bring (Tayori.Source), what its CI, GitHub and its own code add, what an agent adds over MCP. The admin reads them in the inbox, puts aside what readers need not know, and a digest makes an entry of the rest (Tayori.Digest).

A change is the source's and its ref's: adding it again changes nothing, so a source can give all it has each time it is read.

Tayori.Inbox.add(%{ref: "pr-1234", title: "Exports in two clicks", kind: "added"},
  source: "app"
)

A change that does not say its audience takes the :inbox config's ("public"); one that does not say its category takes its kind's (the config's :kinds, or the category whose key is the kind).

Summary

Functions

Adds a change, or finds the one with the same source and ref. Options: :source ("app"). Returns {:ok, change}, or {:error, changeset}.

Adds changes, each as add/2 would. Returns how many were new, how many were there already, and the errors of those that could not be added, {index, changeset}.

How many changes are in each state.

A change by its id, or nil.

Puts a change aside: no digest takes it.

Reads every source of the :inbox config, and adds their changes. Returns each source's result, by its name: {:ok, counts} (as add_many/2), or {:error, reason}, logged. With the :digest config's every: :ingest, new changes start a digest (Tayori.Digest.after_ingest/1).

The changes, the newest first. Options: :state ("new", "drafted", "hidden"), :source, :audience, :entry_id, :ids, :search (words of the title), :limit (100).

The changes waiting for a digest: new, and for the public. Options: :ids (only these), :since and :until (when they happened).

How many changes are waiting for a digest: new, and for the public.

Brings back a change put aside, or one drafted whose entry is gone.

Changes what a change says: its title, body, category, audience, segments, highlight.

Functions

add(attrs, opts \\ [])

@spec add(map(), keyword()) :: {:ok, Tayori.Change.t()} | {:error, Ecto.Changeset.t()}

Adds a change, or finds the one with the same source and ref. Options: :source ("app"). Returns {:ok, change}, or {:error, changeset}.

add_many(changes, opts \\ [])

@spec add_many([map()], keyword()) :: %{
  added: non_neg_integer(),
  existing: non_neg_integer(),
  errors: [{non_neg_integer(), Ecto.Changeset.t()}]
}

Adds changes, each as add/2 would. Returns how many were new, how many were there already, and the errors of those that could not be added, {index, changeset}.

counts()

@spec counts() :: %{required(String.t()) => non_neg_integer()}

How many changes are in each state.

get(id)

@spec get(Ecto.UUID.t()) :: Tayori.Change.t() | nil

A change by its id, or nil.

hide(change)

@spec hide(Tayori.Change.t()) :: {:ok, Tayori.Change.t()}

Puts a change aside: no digest takes it.

ingest()

@spec ingest() :: %{required(String.t()) => {:ok, map()} | {:error, term()}}

Reads every source of the :inbox config, and adds their changes. Returns each source's result, by its name: {:ok, counts} (as add_many/2), or {:error, reason}, logged. With the :digest config's every: :ingest, new changes start a digest (Tayori.Digest.after_ingest/1).

list(opts \\ [])

@spec list(keyword()) :: [Tayori.Change.t()]

The changes, the newest first. Options: :state ("new", "drafted", "hidden"), :source, :audience, :entry_id, :ids, :search (words of the title), :limit (100).

pending(opts \\ [])

@spec pending(keyword()) :: [Tayori.Change.t()]

The changes waiting for a digest: new, and for the public. Options: :ids (only these), :since and :until (when they happened).

pending_count()

@spec pending_count() :: non_neg_integer()

How many changes are waiting for a digest: new, and for the public.

restore(change)

@spec restore(Tayori.Change.t()) :: {:ok, Tayori.Change.t()}

Brings back a change put aside, or one drafted whose entry is gone.

update(change, attrs)

@spec update(Tayori.Change.t(), map()) ::
  {:ok, Tayori.Change.t()} | {:error, Ecto.Changeset.t()}

Changes what a change says: its title, body, category, audience, segments, highlight.