Store the cycle's end date alongside its start so the payment-status
filter can be a plain date comparison in SQL instead of loading every
cycle and classifying it in memory. The value is fixed when the cycle
is created (the fee type's interval is immutable and the update action
never changes the start date), so the denormalized column can never
drift from the computed end and needs no write-time reconciliation.
Replace the create_fee_type/create_cycle helpers duplicated across 18/8
membership-fee test files with a single shared definition in Mv.Fixtures,
reconciling the divergent local signatures (including the reversed
argument order) into one superset so behavior is unchanged.
- Replace Enum.map |> Enum.join with Enum.map_join for efficiency
- Extract helper functions to reduce nesting depth from 4 to 2
- Rename is_current_cycle? to current_cycle? following Elixir conventions
- Implemented regenerate_cycles_on_type_change helper in Member resource
- Cycles that haven't ended yet (cycle_end >= today) are deleted and regenerated
- Paid and suspended cycles remain unchanged (not deleted)
- CycleGenerator reloads member with new membership_fee_type_id
- Adjusted tests to work with current cycles only (no future cycles)
- All integration tests passing
Phase 4 completed: Cycle regeneration on type change
- 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
- Add create_member_with_cycles helper that uses fixed 'today' date
- Update tests to use explicit 'today:' option instead of Date.utc_today()
- Prevents test failures when current date changes (e.g., in 2026+)
- Tests now explicitly delete and regenerate cycles with fixed dates
- Ensures consistent test behavior regardless of execution date