refactor: reduce nesting depth in regenerate_cycles_on_type_change

Split the function into smaller, focused functions to reduce nesting depth
This commit is contained in:
Moritz 2025-12-15 13:15:31 +01:00
parent 2f83f35bcc
commit 3fad912025
Signed by: moritz
GPG key ID: 1020A035E5DD0824

View file

@ -705,7 +705,6 @@ defmodule Mv.Membership.Member do
# Deletes future unpaid cycles and regenerates them with the new type/amount # Deletes future unpaid cycles and regenerates them with the new type/amount
# Uses advisory lock to prevent concurrent modifications # Uses advisory lock to prevent concurrent modifications
defp regenerate_cycles_on_type_change(member) do defp regenerate_cycles_on_type_change(member) do
require Ash.Query
alias Mv.Repo alias Mv.Repo
today = Date.utc_today() today = Date.utc_today()
@ -714,26 +713,39 @@ defmodule Mv.Membership.Member do
# Use advisory lock to prevent concurrent deletion and regeneration # Use advisory lock to prevent concurrent deletion and regeneration
# This ensures atomicity when multiple updates happen simultaneously # This ensures atomicity when multiple updates happen simultaneously
if Repo.in_transaction?() do if Repo.in_transaction?() do
# Already in transaction: use advisory lock directly regenerate_cycles_in_transaction(member, today, lock_key)
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
do_regenerate_cycles_on_type_change(member, today)
else else
# Not in transaction: start new transaction with advisory lock regenerate_cycles_new_transaction(member, today, lock_key)
Repo.transaction(fn ->
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
case do_regenerate_cycles_on_type_change(member, today) do
:ok -> :ok
{:error, reason} -> Repo.rollback(reason)
end
end)
|> case do
{:ok, result} -> result
{:error, reason} -> {:error, reason}
end
end end
end end
# Already in transaction: use advisory lock directly
defp regenerate_cycles_in_transaction(member, today, lock_key) do
alias Mv.Repo
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
do_regenerate_cycles_on_type_change(member, today)
end
# Not in transaction: start new transaction with advisory lock
defp regenerate_cycles_new_transaction(member, today, lock_key) do
alias Mv.Repo
Repo.transaction(fn ->
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
case do_regenerate_cycles_on_type_change(member, today) do
:ok -> :ok
{:error, reason} -> Repo.rollback(reason)
end
end)
|> handle_transaction_result()
end
# Handle transaction result
defp handle_transaction_result({:ok, result}), do: result
defp handle_transaction_result({:error, reason}), do: {:error, reason}
# Performs the actual cycle deletion and regeneration # Performs the actual cycle deletion and regeneration
defp do_regenerate_cycles_on_type_change(member, today) do defp do_regenerate_cycles_on_type_change(member, today) do
require Ash.Query require Ash.Query