fix: correct return_notifications? logic to prevent missed notifications
All checks were successful
continuous-integration/drone/push Build is passing

Fix the logic for return_notifications? in create_cycles
This commit is contained in:
Moritz 2025-12-15 13:22:35 +01:00
parent 3fad912025
commit 65d1561803
Signed by: moritz
GPG key ID: 1020A035E5DD0824

View file

@ -216,16 +216,16 @@ defmodule Mv.MembershipFees.CycleGenerator do
end
# Execute function within transaction and return normalized result
# When not in transaction, create_cycles returns {:ok, cycles, notifications}
# When in transaction, create_cycles returns {:ok, cycles} (notifications handled by Ash)
# When in transaction, create_cycles returns {:ok, cycles, notifications}
# When not in transaction, create_cycles returns {:ok, cycles}
defp execute_within_transaction(fun) do
case fun.() do
{:ok, result, notifications} when is_list(notifications) ->
# Return result and notifications separately (not in transaction case)
# In transaction case: return result and notifications separately
{result, notifications}
{:ok, result} ->
# In transaction case: notifications handled by Ash automatically
# Not in transaction case: notifications handled by Ash automatically
{result, []}
{:error, reason} ->
@ -234,11 +234,11 @@ defmodule Mv.MembershipFees.CycleGenerator do
end
# Normalize function result to consistent format
# When in transaction, create_cycles returns {:ok, cycles} (notifications handled by Ash)
# When not in transaction, create_cycles returns {:ok, cycles, notifications}
# When in transaction, create_cycles returns {:ok, cycles, notifications}
# When not in transaction, create_cycles returns {:ok, cycles}
defp normalize_fun_result({:ok, result, _notifications}) do
# This case should not occur when in transaction (create_cycles handles it)
# But handle it for safety
# In transaction case: notifications will be sent after outer transaction commits
# Return in same format as non-transaction case for consistency
{:ok, result}
end
@ -388,9 +388,10 @@ defmodule Mv.MembershipFees.CycleGenerator do
end
defp create_cycles(cycle_starts, member_id, fee_type_id, amount) do
# If already in a transaction, let Ash handle notifications automatically
# Otherwise, return notifications to send them after transaction commits
return_notifications? = not Repo.in_transaction?()
# Always return notifications when in a transaction (required by Ash)
# When not in transaction, Ash handles notifications automatically
# When in transaction, we must return notifications and send them after commit
return_notifications? = Repo.in_transaction?()
results =
Enum.map(cycle_starts, fn cycle_start ->
@ -426,7 +427,7 @@ defmodule Mv.MembershipFees.CycleGenerator do
# Return cycles and notifications to be sent after transaction commits
{:ok, successful_cycles, all_notifications}
else
# Notifications are handled automatically by Ash when in transaction
# Not in transaction: Ash handles notifications automatically
{:ok, successful_cycles}
end
else