towerops/lib/towerops/settings/application_setting.ex

75 lines
2 KiB
Elixir

defmodule Towerops.Settings.ApplicationSetting do
@moduledoc """
Application-wide settings schema.
Stores global configuration values that affect the entire application,
regardless of organization. Only accessible by superadmins.
"""
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "application_settings" do
field :key, :string
field :value, :string
field :value_type, :string, default: "string"
field :description, :string
timestamps(type: :utc_datetime)
end
@type t :: %__MODULE__{
id: Ecto.UUID.t(),
key: String.t(),
value: String.t() | nil,
value_type: String.t(),
description: String.t() | nil,
inserted_at: DateTime.t(),
updated_at: DateTime.t()
}
@doc false
def changeset(setting, attrs) do
setting
|> cast(attrs, [:key, :value, :value_type, :description])
|> validate_required([:key, :value_type])
|> validate_inclusion(:value_type, ["string", "integer", "uuid", "boolean", "json"])
|> unique_constraint(:key)
end
@doc """
Parses the value field according to value_type.
## Examples
iex> parse_value(%ApplicationSetting{value: "abc-123", value_type: "uuid"})
"abc-123"
iex> parse_value(%ApplicationSetting{value: nil, value_type: "uuid"})
nil
"""
def parse_value(%__MODULE__{value: nil}), do: nil
def parse_value(%__MODULE__{value: value, value_type: "string"}), do: value
def parse_value(%__MODULE__{value: value, value_type: "uuid"}), do: value
def parse_value(%__MODULE__{value: value, value_type: "integer"}) do
case Integer.parse(value) do
{int, _} -> int
:error -> nil
end
end
def parse_value(%__MODULE__{value: value, value_type: "boolean"}) do
value in ["true", "1", "yes"]
end
def parse_value(%__MODULE__{value: value, value_type: "json"}) do
case Jason.decode(value) do
{:ok, decoded} -> decoded
{:error, _} -> nil
end
end
end