Environment diagnostics and auto-repair — returns structured results.
Define checks and use run/1 to diagnose or fix/1 to repair.
All functions return data structures — the caller decides how to display.
Check definition
config = %{
app_name: "myapp",
checks: [
%{
id: :postgresql,
name: "PostgreSQL",
description: "Database server",
priority: 1,
check: fn -> {:ok, "v14"} end,
fix: fn -> {:ok, "installed"} end,
fix_command: "sudo apt install postgresql-14"
}
]
}Each check/0 returns {:ok, msg}, {:warning, msg} or {:error, msg}.
Each fix/0 returns {:ok, msg}, {:error, msg} or :skipped.
Return values
run/1 returns {:ok, results} — all checks always return ok wrapper,
the individual status is embedded in each result map.
fix/1 returns {:ok, fix_report} — a detailed report of what was applied.
summary/1 returns a map with counts and a passed? boolean.
Timeout support
Checks can specify a timeout in milliseconds:
%{
id: :slow_check,
name: "Slow Check",
timeout: 5000, # 5 second timeout
check: fn -> ... end
}The default timeout is 30 seconds. Global timeout can be overridden in run/2.
Summary
Functions
Returns available battery checks (predefined health checks).
Runs fixes for all checks with errors and returns a detailed report.
Returns a diagnostic snapshot of the current Botica.Flags registry.
Formats the flags_summary/0 output as a human-readable string suitable
for the delfos doctor-style banners.
Runs a quick health check and returns a simple pass/fail map.
Runs all checks in parallel and returns structured results.
Runs all checks in parallel with custom options.
Sorts checks by priority (lower values run first).
Summarizes a list of check results into a single map.
Validates the configuration and returns :ok or {:error, reason}.
Types
@type check_def() :: Botica.Types.check_def()
@type check_id() :: Botica.Types.check_id()
@type check_result() :: Botica.Types.check_result()
@type config() :: Botica.Types.config()
@type fix_report() :: Botica.Types.fix_report()
@type fix_result() :: Botica.Types.fix_result()
@type result() :: Botica.Types.result()
@type summary() :: Botica.Types.summary()
Functions
@spec batteries() :: [check_def()]
Returns available battery checks (predefined health checks).
Examples
iex> batteries = Botica.Doctor.batteries()
iex> is_list(batteries)
true
@spec fix(config()) :: {:ok, fix_report()} | {:error, String.t()}
Runs fixes for all checks with errors and returns a detailed report.
Examples
iex> config = %{
...> app_name: "myapp",
...> checks: [
...> %{
...> id: :failing,
...> name: "Failing",
...> description: "A failing check",
...> priority: 1,
...> check: fn -> {:error, "something wrong"} end,
...> fix: fn -> {:ok, "fixed!"} end,
...> fix_command: "some command"
...> }
...> ]
...> }
iex> {:ok, report} = Botica.Doctor.fix(config)
iex> report.applied
[:failing]
@spec flags_summary() :: %{count: non_neg_integer(), flags: [map()]}
Returns a diagnostic snapshot of the current Botica.Flags registry.
Shape:
%{
count: 3,
flags: [
%{name: :beta_search, status: :enabled, default: true, rollout: nil},
%{name: :new_dashboard, status: :disabled, default: false, rollout: nil},
%{name: :rate_limiting, status: :rollout, default: false, rollout: 25}
]
}Intended to be printed by CLI / REPL wrappers as part of the botica
diagnostic banner. Safe to call when no flags are defined — returns an
empty list under :flags.
@spec format_flags_summary() :: String.t()
Formats the flags_summary/0 output as a human-readable string suitable
for the delfos doctor-style banners.
Returns an empty string when no flags are defined.
Example output
Flags (3 defined):
✓ beta_search enabled (default: true)
✗ new_dashboard disabled (default: false)
~ rate_limiting rollout 25% (default: false)
@spec health_check(config()) :: %{status: :ok | :degraded | :fail, summary: summary()} | %{status: :fail, summary: summary(), error: String.t()}
Runs a quick health check and returns a simple pass/fail map.
Shorthand for run/1 + summary/1 — returns %{status: :ok | :degraded | :fail, summary: summary()}.
Examples
iex> config = %{
...> app_name: "myapp",
...> checks: [
...> %{
...> id: :check1,
...> name: "Check 1",
...> description: "A check",
...> priority: 1,
...> check: fn -> {:ok, "ok"} end,
...> fix: fn -> :skipped end,
...> fix_command: nil
...> }
...> ]
...> }
iex> result = Botica.Doctor.health_check(config)
iex> result.status
:ok
iex> result.summary.passed?
true
Runs all checks in parallel and returns structured results.
Options
:timeout- Global timeout per check in ms (default: 30_000):stop_on_first_error- Stop after first error (default: false):continue_on_error- Continue after errors (default: true)
Examples
iex> config = %{
...> app_name: "myapp",
...> checks: [
...> %{
...> id: :check1,
...> name: "Check 1",
...> description: "A check",
...> priority: 1,
...> check: fn -> {:ok, "ok"} end,
...> fix: fn -> :skipped end,
...> fix_command: nil
...> }
...> ]
...> }
iex> {:ok, [result]} = Botica.Doctor.run(config)
iex> result.status
:ok
@spec run(config(), Botica.Types.executor_options()) :: {:ok, [result()]} | {:error, String.t()}
Runs all checks in parallel with custom options.
Options
:timeout- Global timeout per check in ms (default: 30_000):stop_on_first_error- Stop after first error (default: false):continue_on_error- Continue after errors (default: true)
Sorts checks by priority (lower values run first).
Examples
iex> checks = [
...> %{id: :b, priority: 2},
...> %{id: :a, priority: 1}
...> ]
iex> Botica.Doctor.sort_checks(checks)
[%{id: :a, priority: 1}, %{id: :b, priority: 2}]
Summarizes a list of check results into a single map.
Examples
iex> results = [
...> %{status: :ok},
...> %{status: :ok},
...> %{status: :warning},
...> %{status: :error}
...> ]
iex> Botica.Doctor.summary(results)
%{ok: 2, warning: 1, error: 1, total: 4, passed?: false}
Validates the configuration and returns :ok or {:error, reason}.
Examples
iex> Botica.Doctor.validate(%{app_name: "test", checks: []})
:ok
iex> Botica.Doctor.validate(%{app_name: "test"})
{:error, "config.checks must be a list"}
iex> Botica.Doctor.validate(%{checks: []})
{:error, "config.app_name must be a string"}