PhoenixKit.Install.ChildOrder (phoenix_kit v1.7.208)

Copy Markdown View Source

Reads a host application's application.ex and checks that the Ecto Repo starts BEFORE PhoenixKit.Supervisor and Oban in the supervision children list.

PhoenixKit.Supervisor reads Settings / OAuth configuration from the database as it boots, and Oban opens a connection pool against the same Repo — so both MUST appear after the Repo in the children list. A mis-ordered list crashes the app at startup (typically an Oban crash-loop: the pool has no database to reach yet).

mix phoenix_kit.install positions its child after the detected Repo, but a hand-edited application.ex — or an Igniter anchor miss that prepends the child instead of inserting it after the Repo — can regress the order. This module is the deterministic safety net: mix phoenix_kit.doctor runs check/2 against the host's source so both fresh and existing installs are caught, independent of how the children ended up ordered.

Everything here is a pure function over source text — no application boot, no database — so it is unit-testable in isolation.

Summary

Types

A module extracted from a child spec, or nil when unrecognized.

Functions

Checks the child ordering in source relative to repo_module.

Extracts the ordered list of head modules from the host's children list.

Types

child()

@type child() :: module() | nil

A module extracted from a child spec, or nil when unrecognized.

Functions

check(source, repo_module)

@spec check(String.t(), module()) ::
  {:ok, String.t()}
  | {:misordered, [module()]}
  | :no_repo_in_children
  | :no_children

Checks the child ordering in source relative to repo_module.

Returns:

  • {:ok, detail} — the Repo precedes every Repo-dependent child that is present (or none are present); detail is a human-readable summary.
  • {:misordered, [module]} — the listed Repo-dependent modules appear before the Repo. This is the crash case.
  • :no_repo_in_childrenrepo_module wasn't found in the children list, so ordering can't be judged (verify manually).
  • :no_children — no children list could be located in the source.

ordered_children(source)

@spec ordered_children(String.t()) :: {:ok, [child()]} | :error

Extracts the ordered list of head modules from the host's children list.

Each element is the module heading a child spec (MyApp.Repo, {Oban, opts}Oban, {Phoenix.PubSub, ...}Phoenix.PubSub), or nil for a spec whose module can't be read cheaply (e.g. a %{} map spec). Returns :error if no children list can be found.