Lotus.Config (Lotus v0.16.4)

Copy Markdown View Source

Configuration management for Lotus.

Handles loading and validating configuration from the application environment using NimbleOptions.

Required Configuration

Lotus requires a storage repository where it will store query definitions:

config :lotus,
  ecto_repo: MyApp.Repo  # Where Lotus stores its query definitions

Data Repositories Configuration

Configure named data repositories that Lotus can execute queries against:

config :lotus,
  data_repos: %{
    "primary" => MyApp.Repo,
    "analytics" => MyApp.AnalyticsRepo,
    "warehouse" => MyApp.WarehouseRepo
  }

Visibility Configuration

Control which schemas and tables are accessible through Lotus with visibility rules:

config :lotus,
  # Schema-level rules (higher precedence)
  schema_visibility: %{
    postgres: [
      allow: ["public", ~r/^tenant_/],  # Only public + tenant schemas
      deny: ["legacy"]                  # Block legacy schema
    ],
    mysql: [
      # In MySQL, schemas = databases
      allow: ["app_db", "analytics_db"],
      deny: ["staging_db"]
    ]
  },

  # Table-level rules (lower precedence)
  table_visibility: %{
    default: [
      deny: ["user_passwords", "api_keys", ~r/^audit_/]
    ],
    postgres: [
      allow: [
        {"public", ~r/^dim_/},      # Dimension tables only
        {"analytics", ~r/.*/}       # All analytics tables
      ]
    ]
  }

Key Principle: Schema visibility gates table visibility. If a schema is denied, all tables within it are blocked regardless of table-level rules.

Database-Specific Schema Behavior:

  • PostgreSQL: True namespaced schemas within a database (public, reporting, etc.)
  • MySQL: Schemas = Databases (when you connect to MySQL, you can access multiple databases)
  • SQLite: Schema-less (visibility rules don't apply)

See the Visibility Guide for detailed configuration examples.

Optional Configuration

config :lotus,
  default_repo: "primary",       # Default data repo for queries
  unique_names: false,           # Defaults to true
  read_only: false               # Defaults to true; set to false to allow writes

Summary

Functions

Returns AI configuration keyword list.

Returns whether AI features are enabled.

Returns the entire validated configuration as a map.

Returns cache adapter module if configured.

Returns the cache configuration.

Returns the cache namespace.

Returns cache settings for a specific profile.

Returns column visibility rules for a specific repository.

Returns the configured data repositories.

Returns the globally configured default cache profile.

Returns the default data repository as a {name, module} tuple.

Returns the globally configured default page size for windowed pagination, if any.

Gets a configuration value by key.

Gets a data repository by name.

Lists the names of all configured data repositories.

Loads and validates the Lotus configuration.

Returns middleware configuration map, or empty map if not configured.

Returns whether queries are restricted to read-only operations.

Returns the configured Ecto repository.

Returns table visibility rules for a specific repository.

Returns schema visibility rules for a specific repository.

Returns whether unique query names are enforced.

Types

cache_config()

@type cache_config() :: %{
  optional(:cachex_opts) => keyword(),
  adapter: module() | nil,
  namespace: String.t(),
  profiles: %{required(atom()) => keyword()},
  compress: boolean(),
  max_bytes: non_neg_integer(),
  lock_timeout: non_neg_integer(),
  default_ttl_ms: non_neg_integer(),
  default_profile: atom()
}

t()

@type t() :: %{
  ecto_repo: module(),
  read_only: boolean(),
  unique_names: boolean(),
  data_repos: %{required(String.t()) => module()},
  default_repo: String.t() | nil,
  default_page_size: pos_integer() | nil,
  table_visibility: map(),
  column_visibility: map(),
  schema_visibility: map(),
  cache: cache_config()
}

Functions

ai()

@spec ai() :: keyword()

Returns AI configuration keyword list.

ai_enabled?()

@spec ai_enabled?() :: boolean()

Returns whether AI features are enabled.

all()

@spec all() :: t() | keyword()

Returns the entire validated configuration as a map.

Useful for debugging or inspection.

cache_adapter()

@spec cache_adapter() :: {:ok, module()} | :error

Returns cache adapter module if configured.

cache_config()

@spec cache_config() :: cache_config() | nil

Returns the cache configuration.

cache_namespace()

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

Returns the cache namespace.

cache_profile_settings(profile_name)

@spec cache_profile_settings(atom()) :: keyword()

Returns cache settings for a specific profile.

Falls back to built-in defaults for :results, :schema, and :options profiles. Users can override these defaults in their configuration.

column_rules_for_repo_name(repo_name)

@spec column_rules_for_repo_name(String.t()) :: list()

Returns column visibility rules for a specific repository.

Falls back to default rules if repo-specific rules are not configured.

data_repos()

@spec data_repos() :: %{required(String.t()) => module()}

Returns the configured data repositories.

default_cache_profile()

@spec default_cache_profile() :: atom()

Returns the globally configured default cache profile.

Falls back to :results if none configured.

default_data_repo()

@spec default_data_repo() :: {String.t(), module()}

Returns the default data repository as a {name, module} tuple.

  • If default_repo is configured, returns that repo
  • If default_repo is not configured, returns the first available repo
  • If no data repos are configured, raises an error

default_page_size()

@spec default_page_size() :: pos_integer() | nil

Returns the globally configured default page size for windowed pagination, if any.

When nil, Lotus uses its built-in default page size.

get(key)

@spec get(atom()) :: any()

Gets a configuration value by key.

Returns the configuration for the given key from the application environment.

get_data_repo!(name)

@spec get_data_repo!(String.t()) :: module()

Gets a data repository by name.

Returns the repo module or raises if not found.

list_data_repo_names()

@spec list_data_repo_names() :: [String.t()]

Lists the names of all configured data repositories.

load!(opts \\ get_lotus_config())

@spec load!(keyword()) :: t() | keyword()

Loads and validates the Lotus configuration.

Raises ArgumentError if the configuration is invalid.

middleware()

@spec middleware() :: map()

Returns middleware configuration map, or empty map if not configured.

read_only?()

@spec read_only?() :: boolean()

Returns whether queries are restricted to read-only operations.

repo!()

@spec repo!() :: module()

Returns the configured Ecto repository.

rules_for_repo_name(repo_name)

@spec rules_for_repo_name(String.t()) :: keyword()

Returns table visibility rules for a specific repository.

Falls back to default rules if repo-specific rules are not configured.

schema_rules_for_repo_name(repo_name)

@spec schema_rules_for_repo_name(String.t()) :: keyword()

Returns schema visibility rules for a specific repository.

Falls back to default rules if repo-specific rules are not configured.

unique_names?()

@spec unique_names?() :: boolean()

Returns whether unique query names are enforced.