Auto funded envelopes - #792
Merged
Merged
Conversation
Budgets fill themselves from a monthly amount instead of the user splitting every paycheck by hand. A Funding records what one month put into one budget; balance is now fundings + allocations + adjustment. The job runs daily rather than monthly, since funding a month is idempotent, so a missed run heals itself. Rollover is per envelope. On, an overspend carries and eats into the next month. Off, the month funds what brings the balance back to the amount, so the envelope starts whole and leftover does not accumulate. Income is a fourth budget type, one per source, so a paycheck and a card reward are never the same figure. Income budgets receive and never spend; every other budget nets positive allocations against its spending, which is what makes a reimbursement cancel the spend it repays. Behaviour changes to expect on deploy: - Netting is retroactive. Any past month where a positive amount was allocated to a spending budget reports less spent than before. - Spendable no longer takes an overspent envelope off the pool twice. Anyone sitting on a negative envelope sees the figure move. - An envelope in the hole reads OVERSPENT with the shortfall as a positive figure, where it used to read LEFT with a minus sign. - rollover is required on the Budget API response. funding_amount ships nil everywhere, so no budget funds itself until the user sets an amount. Co-Authored-By: Claude Opus 5 <[email protected]>
An envelope had two amounts that were the same number wearing two hats: what its spending was measured against, and what a month put into it. That is what put two clocks on one card - a lifetime balance above a this-month bar, disagreeing. It keeps one. Having it is what makes the envelope fund itself, so the balance is always a figure the month can explain. The migration folds budgeted_amount into funding_amount, so no amount is lost and every existing envelope starts funding. Goals keep two, because a target and a monthly contribution are different numbers; tracking and income keep the figure they are measured against. The envelope card reads REMAINING, or OVERSPENT with the shortfall as a positive figure. The form asks two questions and no more: Budget Per Month, and Remaining. Funding a month by hand is gone with it - the fund_budget MCP tool and the update_funding action. A month is funded one way now, by the amount on the budget. That left Funding.changeset unreachable, so the schema is fields only. Behaviour changes to expect on deploy: - budgeted_amount is null on every envelope, and its value now lives in funding_amount. Clients reading the old field see nothing there. - Envelopes that had an amount but were never funded start funding. Their historical balance is left alone, so one that was spent from before funding existed still reads OVERSPENT until it is corrected. Co-Authored-By: Claude Opus 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.