- Add configuration system (config/*.exs, OrgGarden.Config) - Refactor supervision tree with DynamicSupervisor and Registry - Add OrgGarden.Server for serve mode lifecycle management - Add health check HTTP endpoints (Bandit/Plug on :9090) - Add telemetry events for export and watcher operations - Implement graceful shutdown with SIGTERM handling - Add Mix Release support with overlay scripts - Add NixOS module for systemd service deployment - Update documentation with service usage
99 lines
2.3 KiB
Elixir
99 lines
2.3 KiB
Elixir
defmodule OrgGarden.Config do
|
|
@moduledoc """
|
|
Centralized configuration access with validation.
|
|
|
|
Provides a unified interface for accessing configuration values,
|
|
with support for defaults and required value validation.
|
|
|
|
## Usage
|
|
|
|
OrgGarden.Config.get(:http_port)
|
|
#=> 8080
|
|
|
|
OrgGarden.Config.get!(:quartz_path)
|
|
#=> "/path/to/quartz" or raises if not set
|
|
|
|
OrgGarden.Config.pipeline_opts()
|
|
#=> %{zotero_url: "...", bibtex_file: nil, citation_mode: :warn}
|
|
"""
|
|
|
|
@doc """
|
|
Get a configuration value with an optional default.
|
|
"""
|
|
def get(key, default \\ nil) do
|
|
Application.get_env(:org_garden, key, default)
|
|
end
|
|
|
|
@doc """
|
|
Get a required configuration value. Raises if not set.
|
|
"""
|
|
def get!(key) do
|
|
case Application.get_env(:org_garden, key) do
|
|
nil -> raise ArgumentError, "Missing required configuration: #{key}"
|
|
value -> value
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Build pipeline options map for transforms.
|
|
"""
|
|
def pipeline_opts do
|
|
%{
|
|
zotero_url: get(:zotero_url, "http://localhost:23119"),
|
|
bibtex_file: get(:bibtex_file),
|
|
citation_mode: get(:citation_mode, :warn)
|
|
}
|
|
end
|
|
|
|
@doc """
|
|
Validate that all required configuration is present.
|
|
Returns :ok or {:error, reasons}.
|
|
"""
|
|
def validate do
|
|
errors =
|
|
[]
|
|
|> validate_quartz_path()
|
|
|> validate_citation_mode()
|
|
|
|
case errors do
|
|
[] -> :ok
|
|
errors -> {:error, errors}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Validate configuration and raise on errors.
|
|
"""
|
|
def validate! do
|
|
case validate() do
|
|
:ok -> :ok
|
|
{:error, errors} -> raise "Configuration errors: #{inspect(errors)}"
|
|
end
|
|
end
|
|
|
|
# Private validation helpers
|
|
|
|
defp validate_quartz_path(errors) do
|
|
case get(:quartz_path) do
|
|
nil ->
|
|
errors
|
|
|
|
path ->
|
|
cli_path = Path.join(path, "quartz/bootstrap-cli.mjs")
|
|
|
|
if File.exists?(cli_path) do
|
|
errors
|
|
else
|
|
[{:quartz_path, "bootstrap-cli.mjs not found at #{cli_path}"} | errors]
|
|
end
|
|
end
|
|
end
|
|
|
|
defp validate_citation_mode(errors) do
|
|
case get(:citation_mode) do
|
|
mode when mode in [:silent, :warn, :strict] -> errors
|
|
other -> [{:citation_mode, "Invalid citation mode: #{inspect(other)}"} | errors]
|
|
end
|
|
end
|
|
end
|