refactor: consolidate settings lookups and secrets loading

- Extract fetch_setting/1 in Settings (4 callsites → 1 repo lookup)
- Replace hardcoded load_stripe_config with registry-driven load_all
- Adding new secrets is now a one-line @secret_registry entry
- Mark DRY refactor plan as complete (all 8 items done)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-08 14:42:13 +00:00
parent 3eacd91fda
commit 3b8d5faf3b
5 changed files with 39 additions and 33 deletions

View File

@@ -13,30 +13,27 @@ defmodule SimpleshopTheme.Secrets do
require Logger
# Registry of {settings_key, app, env_key} — add new secrets here
@secret_registry [
{"stripe_api_key", :stripity_stripe, :api_key},
{"stripe_signing_secret", :stripity_stripe, :signing_secret}
]
@doc """
Loads all secrets from the database into Application env.
Called at startup from the supervision tree, after the Repo is ready.
"""
def load_all do
load_stripe_config()
end
for {settings_key, app, env_key} <- @secret_registry do
case Settings.get_secret(settings_key) do
nil ->
:skip
@doc """
Loads Stripe credentials from encrypted settings into Application env.
"""
def load_stripe_config do
api_key = Settings.get_secret("stripe_api_key")
signing_secret = Settings.get_secret("stripe_signing_secret")
if api_key do
Application.put_env(:stripity_stripe, :api_key, api_key)
Logger.debug("Stripe API key loaded from database")
end
if signing_secret do
Application.put_env(:stripity_stripe, :signing_secret, signing_secret)
Logger.debug("Stripe webhook secret loaded from database")
value ->
Application.put_env(app, env_key, value)
Logger.debug("Loaded #{settings_key} from database")
end
end
:ok

View File

@@ -18,9 +18,9 @@ defmodule SimpleshopTheme.Settings do
"""
def get_setting(key, default \\ nil) do
case Repo.get_by(Setting, key: key) do
nil -> default
setting -> decode_value(setting)
case fetch_setting(key) do
{:ok, setting} -> decode_value(setting)
:not_found -> default
end
end
@@ -120,9 +120,9 @@ defmodule SimpleshopTheme.Settings do
Deletes a setting by key.
"""
def delete_setting(key) do
case Repo.get_by(Setting, key: key) do
nil -> :ok
setting -> Repo.delete(setting)
case fetch_setting(key) do
{:ok, setting} -> Repo.delete(setting)
:not_found -> :ok
end
end
@@ -157,8 +157,9 @@ defmodule SimpleshopTheme.Settings do
Returns the plaintext value or the default if not found.
"""
def get_secret(key, default \\ nil) do
case Repo.get_by(Setting, key: key) do
%Setting{value_type: "encrypted", encrypted_value: encrypted} when not is_nil(encrypted) ->
case fetch_setting(key) do
{:ok, %Setting{value_type: "encrypted", encrypted_value: encrypted}}
when not is_nil(encrypted) ->
case Vault.decrypt(encrypted) do
{:ok, plaintext} -> plaintext
{:error, _} -> default
@@ -173,8 +174,9 @@ defmodule SimpleshopTheme.Settings do
Checks whether an encrypted secret exists in the database.
"""
def has_secret?(key) do
case Repo.get_by(Setting, key: key) do
%Setting{value_type: "encrypted", encrypted_value: encrypted} when not is_nil(encrypted) ->
case fetch_setting(key) do
{:ok, %Setting{value_type: "encrypted", encrypted_value: encrypted}}
when not is_nil(encrypted) ->
true
_ ->
@@ -204,6 +206,13 @@ defmodule SimpleshopTheme.Settings do
# Private helpers
defp fetch_setting(key) do
case Repo.get_by(Setting, key: key) do
nil -> :not_found
setting -> {:ok, setting}
end
end
defp decode_value(%Setting{value_type: "encrypted", encrypted_value: encrypted})
when not is_nil(encrypted) do
case Vault.decrypt(encrypted) do

View File

@@ -36,13 +36,13 @@ defmodule SimpleshopTheme.Stripe.Setup do
case maybe_create_webhook(api_key) do
{:ok, result} ->
Secrets.load_stripe_config()
Secrets.load_all()
{:ok, result}
{:error, reason} ->
# Key is valid and stored, but webhook creation failed.
# Still load the key so checkout works (webhooks can be set up manually).
Secrets.load_stripe_config()
Secrets.load_all()
{:error, reason}
end
end
@@ -68,7 +68,7 @@ defmodule SimpleshopTheme.Stripe.Setup do
"""
def save_signing_secret(signing_secret) do
Settings.put_secret("stripe_signing_secret", signing_secret)
Secrets.load_stripe_config()
Secrets.load_all()
end
@doc """