feat(membership-fees): denormalize cycle_end so fee status filters run in the database
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.
This commit is contained in:
parent
a629bfb617
commit
b745b13ca5
7 changed files with 448 additions and 4 deletions
|
|
@ -13,7 +13,9 @@ defmodule Mv.MembershipFees.MembershipFeeCycle do
|
|||
- `notes` - Optional notes for this cycle
|
||||
|
||||
## Design Decisions
|
||||
- **No cycle_end field**: Calculated from cycle_start + interval (from fee type)
|
||||
- **Denormalized cycle_end**: Set at create from cycle_start + interval (fee type).
|
||||
Because the fee type interval and the cycle_start are immutable after create,
|
||||
cycle_end never drifts, so it can be filtered/sorted in SQL.
|
||||
- **Amount stored per cycle**: Preserves historical amounts when fee type changes
|
||||
- **Calendar-aligned cycles**: All cycles start on calendar boundaries
|
||||
|
||||
|
|
@ -46,6 +48,14 @@ defmodule Mv.MembershipFees.MembershipFeeCycle do
|
|||
create :create do
|
||||
primary? true
|
||||
accept [:cycle_start, :amount, :status, :notes, :member_id, :membership_fee_type_id]
|
||||
|
||||
argument :interval, :atom do
|
||||
allow_nil? true
|
||||
|
||||
description "Optional pre-resolved fee-type interval; when given, SetCycleEnd skips the fee-type lookup"
|
||||
end
|
||||
|
||||
change Mv.MembershipFees.MembershipFeeCycle.Changes.SetCycleEnd
|
||||
end
|
||||
|
||||
update :update do
|
||||
|
|
@ -106,6 +116,13 @@ defmodule Mv.MembershipFees.MembershipFeeCycle do
|
|||
description "Start date of the billing cycle"
|
||||
end
|
||||
|
||||
attribute :cycle_end, :date do
|
||||
allow_nil? false
|
||||
public? true
|
||||
|
||||
description "Denormalized end date of the cycle (cycle_start + interval), set at create"
|
||||
end
|
||||
|
||||
attribute :amount, :decimal do
|
||||
allow_nil? false
|
||||
public? true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue