Files
bDS2/lib/bds/ai/settings_store.ex
2026-05-01 17:49:50 +02:00

79 lines
2.1 KiB
Elixir

defmodule BDS.AI.SettingsStore do
@moduledoc false
import Ecto.Query
alias BDS.AI.CatalogMeta
alias BDS.AI.SecretBackend
alias BDS.Persistence
alias BDS.Repo
alias BDS.Settings.Setting
@spec get_setting(String.t()) :: String.t() | nil
def get_setting(key) do
case Repo.get(Setting, key) do
nil -> nil
setting -> setting.value
end
end
@spec put_setting(String.t(), String.t()) :: :ok
def put_setting(key, value) when is_binary(key) and is_binary(value) do
now = Persistence.now_ms()
%Setting{}
|> Setting.changeset(%{key: key, value: value, updated_at: now})
|> Repo.insert(
on_conflict: [set: [value: value, updated_at: now]],
conflict_target: [:key]
)
:ok
end
@spec delete_setting(String.t()) :: :ok
def delete_setting(key) do
Repo.delete_all(from(setting in Setting, where: setting.key == ^key))
:ok
end
@spec put_secret(String.t(), String.t() | nil, module()) :: :ok | {:error, term()}
def put_secret(_key, nil, _backend), do: :ok
def put_secret(key, value, backend) do
with {:ok, encrypted_value} <- backend.encrypt(value) do
put_setting(encrypted_key(key), encrypted_value)
end
end
@spec get_secret(String.t() | nil, module()) :: {:ok, String.t() | nil} | {:error, term()}
def get_secret(nil, _backend), do: {:ok, nil}
def get_secret(value, backend), do: backend.decrypt(value)
@spec encrypted_key(String.t()) :: String.t()
def encrypted_key(key), do: "__encrypted_#{key}"
@spec secret_backend() :: module()
def secret_backend, do: SecretBackend
@spec get_catalog_meta_value(String.t()) :: String.t() | nil
def get_catalog_meta_value(key) do
case Repo.get(CatalogMeta, key) do
nil -> get_setting("ai.catalog.#{key}")
meta -> meta.value
end
end
@spec put_catalog_meta(String.t(), String.t()) :: :ok
def put_catalog_meta(key, value) do
%CatalogMeta{}
|> CatalogMeta.changeset(%{key: key, value: value})
|> Repo.insert(
on_conflict: [set: [value: value]],
conflict_target: [:key]
)
:ok
end
end