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:
parent
3eacd91fda
commit
3b8d5faf3b
@ -202,9 +202,9 @@ See: [ROADMAP.md](ROADMAP.md) for design notes
|
||||
See: [docs/plans/products-context.md](docs/plans/products-context.md) for schema design
|
||||
|
||||
### DRY Refactor
|
||||
**Status:** Planned
|
||||
**Status:** Complete
|
||||
|
||||
Codebase analysis identified ~380 lines of duplication across LiveViews, templates, and the theme editor. Top priorities: extract `ThemeHook` for shared mount logic, extract `<.shop_layout>` wrapper component, consolidate preview assigns. Also: split `shop_components.ex` (4,400 lines) into focused modules.
|
||||
All 8 items from the plan done. Key wins: ThemeHook eliminated mount duplication, shop_layout saved ~195 lines, shop_components split into 5 focused modules (largest file dropped from 4,487 to ~1,600 lines), Settings repo lookups consolidated via `fetch_setting/1`, secrets loading made scalable via registry pattern.
|
||||
|
||||
See: [docs/plans/dry-refactor.md](docs/plans/dry-refactor.md) for full analysis and plan
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# DRY refactor plan
|
||||
|
||||
Status: Planned
|
||||
Status: Complete
|
||||
|
||||
Codebase analysis identifying repeated patterns and consolidation opportunities. Ordered by impact.
|
||||
|
||||
|
||||
@ -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()
|
||||
for {settings_key, app, env_key} <- @secret_registry do
|
||||
case Settings.get_secret(settings_key) do
|
||||
nil ->
|
||||
:skip
|
||||
|
||||
value ->
|
||||
Application.put_env(app, env_key, value)
|
||||
Logger.debug("Loaded #{settings_key} from database")
|
||||
end
|
||||
|
||||
@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")
|
||||
end
|
||||
|
||||
:ok
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 """
|
||||
|
||||
Loading…
Reference in New Issue
Block a user