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.
173 lines
No EOL
4.1 KiB
JSON
173 lines
No EOL
4.1 KiB
JSON
{
|
|
"attributes": [
|
|
{
|
|
"allow_nil?": false,
|
|
"default": "fragment(\"uuid_generate_v7()\")",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": true,
|
|
"references": null,
|
|
"scale": null,
|
|
"size": null,
|
|
"source": "id",
|
|
"type": "uuid"
|
|
},
|
|
{
|
|
"allow_nil?": false,
|
|
"default": "nil",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": false,
|
|
"references": null,
|
|
"scale": null,
|
|
"size": null,
|
|
"source": "cycle_start",
|
|
"type": "date"
|
|
},
|
|
{
|
|
"allow_nil?": false,
|
|
"default": "nil",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": false,
|
|
"references": null,
|
|
"scale": null,
|
|
"size": null,
|
|
"source": "cycle_end",
|
|
"type": "date"
|
|
},
|
|
{
|
|
"allow_nil?": false,
|
|
"default": "nil",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": false,
|
|
"references": null,
|
|
"scale": 2,
|
|
"size": null,
|
|
"source": "amount",
|
|
"type": "decimal"
|
|
},
|
|
{
|
|
"allow_nil?": false,
|
|
"default": "\"unpaid\"",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": false,
|
|
"references": null,
|
|
"scale": null,
|
|
"size": null,
|
|
"source": "status",
|
|
"type": "text"
|
|
},
|
|
{
|
|
"allow_nil?": true,
|
|
"default": "nil",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": false,
|
|
"references": null,
|
|
"scale": null,
|
|
"size": null,
|
|
"source": "notes",
|
|
"type": "text"
|
|
},
|
|
{
|
|
"allow_nil?": false,
|
|
"default": "nil",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": false,
|
|
"references": {
|
|
"deferrable": false,
|
|
"destination_attribute": "id",
|
|
"destination_attribute_default": null,
|
|
"destination_attribute_generated": null,
|
|
"index?": false,
|
|
"match_type": null,
|
|
"match_with": null,
|
|
"multitenancy": {
|
|
"attribute": null,
|
|
"global": null,
|
|
"strategy": null
|
|
},
|
|
"name": "membership_fee_cycles_member_id_fkey",
|
|
"on_delete": null,
|
|
"on_update": null,
|
|
"primary_key?": true,
|
|
"schema": "public",
|
|
"table": "members"
|
|
},
|
|
"scale": null,
|
|
"size": null,
|
|
"source": "member_id",
|
|
"type": "uuid"
|
|
},
|
|
{
|
|
"allow_nil?": false,
|
|
"default": "nil",
|
|
"generated?": false,
|
|
"precision": null,
|
|
"primary_key?": false,
|
|
"references": {
|
|
"deferrable": false,
|
|
"destination_attribute": "id",
|
|
"destination_attribute_default": null,
|
|
"destination_attribute_generated": null,
|
|
"index?": false,
|
|
"match_type": null,
|
|
"match_with": null,
|
|
"multitenancy": {
|
|
"attribute": null,
|
|
"global": null,
|
|
"strategy": null
|
|
},
|
|
"name": "membership_fee_cycles_membership_fee_type_id_fkey",
|
|
"on_delete": null,
|
|
"on_update": null,
|
|
"primary_key?": true,
|
|
"schema": "public",
|
|
"table": "membership_fee_types"
|
|
},
|
|
"scale": null,
|
|
"size": null,
|
|
"source": "membership_fee_type_id",
|
|
"type": "uuid"
|
|
}
|
|
],
|
|
"base_filter": null,
|
|
"check_constraints": [],
|
|
"create_table_options": null,
|
|
"custom_indexes": [],
|
|
"custom_statements": [],
|
|
"has_create_action": true,
|
|
"hash": "455B6D49C804301DF13F950318644BF28B491535A94F4ABF7805AA1A53287401",
|
|
"identities": [
|
|
{
|
|
"all_tenants?": false,
|
|
"base_filter": null,
|
|
"index_name": "membership_fee_cycles_unique_cycle_per_member_index",
|
|
"keys": [
|
|
{
|
|
"type": "atom",
|
|
"value": "member_id"
|
|
},
|
|
{
|
|
"type": "atom",
|
|
"value": "cycle_start"
|
|
}
|
|
],
|
|
"name": "unique_cycle_per_member",
|
|
"nils_distinct?": true,
|
|
"where": null
|
|
}
|
|
],
|
|
"multitenancy": {
|
|
"attribute": null,
|
|
"global": null,
|
|
"strategy": null
|
|
},
|
|
"repo": "Elixir.Mv.Repo",
|
|
"schema": null,
|
|
"table": "membership_fee_cycles"
|
|
} |