Tayori.Config (Tayori v0.1.0)

Copy Markdown View Source

The options of Tayori, given to its child in the app's supervision tree:

children = [
  MyApp.Repo,
  {Phoenix.PubSub, name: MyApp.PubSub},
  {Tayori,
   repo: MyApp.Repo,
   pubsub: MyApp.PubSub,
   secret_key_base: Application.fetch_env!(:my_app, MyAppWeb.Endpoint)[:secret_key_base],
   locales: ["en", "pt-PT"]},
  MyAppWeb.Endpoint
]

Options:

  • :repo - the app's Ecto repo, where the entries are (required).

  • :pubsub - the app's Phoenix.PubSub, on which the app's pages hear of a new entry as it is published (required).

  • :vault - the app's Cloak.Vault (MyApp.Vault), which encrypts the AI key of the admin with the app's own keys, and rotates them with the app's other secrets. Without it, :secret_key_base.

  • :secret_key_base - the secret the AI key is encrypted with when there is no :vault. With neither, the admin cannot keep a key, and has no AI.

  • :locales - the languages the entries are written in, the first the one every entry has (["en"]).

  • :prefix - the schema of the tables, in PostgreSQL.

  • :notifier - a module of the Tayori.Notifier behaviour, told of each entry once, when it is published.

  • :features - the extras the app wants, none by default; the changelog itself is always there. A feature that is off has no admin page, no route, no element and no process:

    • :reactions - readers react to an entry with an emoji.
    • :announcements - an entry shown as a popup, a toast or a banner in the app, until a date.
    • :analytics - the views of each entry, by where it was read.
    • :subscriptions - readers subscribe by email on the public page, and an entry can be sent to them.
    • :webhooks - webhooks, Slack and Discord, told of each entry.
    • :embed - the news on another origin than the app's, with a reader's signed token (Tayori.Embed).
  • :mailer - the app's Swoosh.Mailer, which sends the emails of the :subscriptions feature (required with it).

  • :email_from - who the emails are from: {"Atelier", "news@atelier.app"} or an address (required with :subscriptions).

  • :page_url - the address of the public page ("https://atelier.app/changelog"), for the links of the emails (required with :subscriptions).

  • :reactions - the emoji readers react with (["👍", "🎉", "❤️", "🚀", "👀"]).

  • :oban - the app's Oban, which then sends what a publication sends (the emails, the webhooks, the call to the :notifier) as jobs: oban: Oban, or oban: [name: MyApp.Oban, queue: :news] for another instance or queue (:default). The queue must be one the app runs. Without it, they are sent by tasks in the node, as Tayori.Jobs explains.

  • :inbox - where the changes of the inbox come from, and what they say when they do not (see Tayori.Inbox and the Automation guide):

    • :sources - {module, opts} of Tayori.Source, such as {Tayori.Sources.Changelog, path: {:my_app, "priv/CHANGELOG.md"}} or {Tayori.Sources.Fragments, path: {:my_app, "priv/news"}} ([]).
    • :ingest_on_start - read the sources when the app starts, which is a deploy's new code (true).
    • :audience - of a change that does not say: "public" or "internal" ("public").
    • :kinds - the category of each kind of change a source names, %{"added" => "new", "fixed" => "fixed"} (%{}). A kind that is a category's key is that category.
    • :github - how a merged pull request's labels speak to the inbox (see Tayori.GitHub): :label_prefix ("changelog:"), and :only_labeled, to take only the pull requests with a label of the prefix (false).
  • :digest - when the inbox becomes an entry (see Tayori.Digest):

    • :every - :manual (the admin asks), :ingest (each time changes come), {:weekly, day} (:monday ... :sunday; :weekly is Monday), :monthly (the first day), or {:days, n}, n days after the last (:manual).
    • :at - the time of day of a scheduled digest, UTC (~T[09:00:00]).
    • :publish - :draft, for the admin to read and publish, or :publish, at once (:draft).
    • :minimum - the changes a scheduled digest needs (1): with fewer, they wait for the next.
    • :translate - with AI, the entry in the other :locales too, translated by the model (false).
  • :emails - when the subscribers get the entries to email (the :subscriptions feature; see Tayori.Subscribers):

    • :every - :each, an email for each entry when it is published, or an email of the entries of a period: {:weekly, day} (:weekly is Monday), :monthly (the first day), or {:days, n} (:each).
    • :at - the time of day of an email of a period, UTC (~T[09:00:00]).
  • :mcp - the MCP server, Tayori.MCP, for an app that serves it with Sake (see the MCP guide):

    • :resolver - the app's Tayori.Resolver, which says what the principal of a request may do (Tayori.Resolver.resolve_access/1) and who writes (Tayori.Resolver.author/1), as in the admin. Without it, nobody may use the server.
    • :upload_url - the address of the uploads route of tayori_api, whole ("https://atelier.app/api/news/uploads"), where an agent sends its screenshots. Without it, an agent sends only small images, in the call.
    • :storage - the Kotoba.Storage of the uploads (Kotoba's own config when not given), the one of the admin's editor.
  • :scheduler - false runs no scheduler: nothing is announced, and no schedule runs, by itself. For an app's tests, where the scheduler's queries would outlive a test's sandbox, and Tayori.Test.announce!/0 announces in the test's process (true).

  • :embed - the sites of the :embed feature (required with it):

    • :origins - the origins the JSON API answers, each a scheme and a host, with a port if not the default (["https://www.atelier.app"]): no path, no wildcard.
    • :max_age - how long a reader token is valid, in seconds (86400, a day).

    The feature also needs :secret_key_base, which signs the tokens.

Summary

Types

The :digest option, checked.

The :emails option, checked.

An extra the app can turn on.

The :inbox option, checked.

The :mcp option, checked.

t()

Functions

The language every entry has.

Whether the app turned an extra on.

All the extras an app can turn on.

The config of the running Tayori. Raises when Tayori is not in the app's supervision tree.

Builds the config from the options of the child, and checks them.

Keeps the config for the whole node.

Types

digest()

@type digest() :: %{
  every:
    :manual | :ingest | :monthly | {:weekly, atom()} | {:days, pos_integer()},
  at: Time.t(),
  publish: :draft | :publish,
  minimum: pos_integer(),
  translate: boolean()
}

The :digest option, checked.

emails()

@type emails() :: %{
  every: :each | :monthly | {:weekly, atom()} | {:days, pos_integer()},
  at: Time.t()
}

The :emails option, checked.

feature()

@type feature() ::
  :reactions | :announcements | :analytics | :subscriptions | :webhooks | :embed

An extra the app can turn on.

inbox()

@type inbox() :: %{
  sources: [{module(), keyword()}],
  ingest_on_start: boolean(),
  audience: String.t(),
  kinds: %{required(String.t()) => String.t()},
  github: %{label_prefix: String.t(), only_labeled: boolean()}
}

The :inbox option, checked.

mcp()

@type mcp() :: %{
  resolver: module() | nil,
  upload_url: String.t() | nil,
  storage: module() | nil
}

The :mcp option, checked.

t()

@type t() :: %Tayori.Config{
  digest: digest(),
  email_from: String.t() | {String.t(), String.t()} | nil,
  emails: emails(),
  embed: %{origins: [String.t(), ...], max_age: pos_integer()} | nil,
  features: [feature()],
  inbox: inbox(),
  locales: [String.t(), ...],
  mailer: module() | nil,
  mcp: mcp() | nil,
  notifier: module() | nil,
  oban: %{name: term(), queue: atom()} | nil,
  page_url: String.t() | nil,
  prefix: String.t() | nil,
  pubsub: atom(),
  reactions: [String.t(), ...],
  repo: module(),
  scheduler: boolean(),
  secret_key_base: String.t() | nil,
  vault: module() | nil
}

Functions

default_locale(config)

@spec default_locale(t()) :: String.t()

The language every entry has.

feature?(config, feature)

@spec feature?(t(), feature()) :: boolean()

Whether the app turned an extra on.

features()

@spec features() :: [feature()]

All the extras an app can turn on.

get()

@spec get() :: t()

The config of the running Tayori. Raises when Tayori is not in the app's supervision tree.

new(opts)

@spec new(keyword()) :: t()

Builds the config from the options of the child, and checks them.

put(config)

@spec put(t()) :: :ok

Keeps the config for the whole node.