refactor: improve cycle generation code quality and documentation
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
- Remove Process.sleep calls from integration tests (tests run synchronously in SQL sandbox) - Improve error handling: membership_fee_type_not_found now returns changeset error instead of just logging - Clarify partial_failure documentation: successful_cycles are not persisted on rollback - Update documentation: joined_at → join_date, left_at → exit_date - Document PostgreSQL advisory locks per member (not whole table lock) - Document gap handling: explicitly deleted cycles are not recreated
This commit is contained in:
parent
e6ac5d1ab1
commit
82897d5cd3
5 changed files with 53 additions and 51 deletions
|
|
@ -64,13 +64,26 @@ defmodule Mv.MembershipFees.Changes.SetMembershipFeeStartDate do
|
|||
start_date = calculate_start_date(join_date, interval, include_joining_cycle)
|
||||
Ash.Changeset.force_change_attribute(changeset, :membership_fee_start_date, start_date)
|
||||
else
|
||||
{:error, reason} ->
|
||||
# Log warning for debugging purposes, but don't fail the action
|
||||
# Missing join_date or membership_fee_type_id is expected for partial creates
|
||||
unless reason in [:join_date_not_set, :membership_fee_type_not_set] do
|
||||
Logger.warning("Could not auto-set membership_fee_start_date: #{inspect(reason)}")
|
||||
end
|
||||
{:error, :join_date_not_set} ->
|
||||
# Missing join_date is expected for partial creates
|
||||
changeset
|
||||
|
||||
{:error, :membership_fee_type_not_set} ->
|
||||
# Missing membership_fee_type_id is expected for partial creates
|
||||
changeset
|
||||
|
||||
{:error, :membership_fee_type_not_found} ->
|
||||
# This is a data integrity error - membership_fee_type_id references non-existent type
|
||||
# Return changeset error to fail the action
|
||||
Ash.Changeset.add_error(
|
||||
changeset,
|
||||
field: :membership_fee_type_id,
|
||||
message: "not found"
|
||||
)
|
||||
|
||||
{:error, reason} ->
|
||||
# Log warning for other unexpected errors
|
||||
Logger.warning("Could not auto-set membership_fee_start_date: #{inspect(reason)}")
|
||||
changeset
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -371,19 +371,20 @@ defmodule Mv.MembershipFees.CycleGenerator do
|
|||
end)
|
||||
|
||||
{successes, errors} = Enum.split_with(results, &match?({:ok, _, _}, &1))
|
||||
successful_cycles = Enum.map(successes, fn {:ok, cycle, _notifications} -> cycle end)
|
||||
|
||||
all_notifications =
|
||||
Enum.flat_map(successes, fn {:ok, _cycle, notifications} -> notifications end)
|
||||
|
||||
if Enum.empty?(errors) do
|
||||
successful_cycles = Enum.map(successes, fn {:ok, cycle, _notifications} -> cycle end)
|
||||
# Return cycles and notifications to be sent after transaction commits
|
||||
{:ok, successful_cycles, all_notifications}
|
||||
else
|
||||
Logger.warning("Some cycles failed to create: #{inspect(errors)}")
|
||||
# Return partial failure with both successful and failed cycles
|
||||
# This allows callers to decide how to handle partial failures
|
||||
{:error, {:partial_failure, successful_cycles, errors}}
|
||||
# Return partial failure with errors
|
||||
# Note: When this error occurs, the transaction will be rolled back,
|
||||
# so no cycles were actually persisted in the database
|
||||
{:error, {:partial_failure, errors}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue