Lotus.Config (Lotus v0.14.0)

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

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 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(),
  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.

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.