feat(web): Phase 4c — household & income editor - #199
Merged
Merged
Conversation
Capture Phase 4c brainstorming decisions (CalSTRS pension preset, SS XML upload, PersonMaxAgeBoundary terminals, section forms) and point the rebuild index at the new spec. Gitignore personal SSA statement downloads. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…x fields Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…or banner Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…ect parent index Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…ible while scrolled Co-authored-by: Cursor <cursoragent@cursor.com>
Null starts were projection-equivalent to Now at timeline month 0; requiring an explicit Boundary and defaulting new rows to Now removes the redundant option while coercing legacy nulls on load. Co-authored-by: Cursor <cursoragent@cursor.com>
No migration: recreate personal DB from blank template if needed. Co-authored-by: Cursor <cursoragent@cursor.com>
Makes room for more presets later; default is None, CalSTRS 2% at 62 is the first option. Co-authored-by: Cursor <cursoragent@cursor.com>
Show whole-dollar currency in money fields, align checkbox labels with their text, and keep year/month boundary inputs on one line. Co-authored-by: Cursor <cursoragent@cursor.com>
Boundary calendar dates and household birth months now pick Jan–Dec instead of bare numbers. Co-authored-by: Cursor <cursoragent@cursor.com>
Label as Month of Birth with month and year controls on one row. Co-authored-by: Cursor <cursoragent@cursor.com>
Offer California/New York from tax tables plus No income-tax state, with a thumbs-up link to #200 for requesting additional states. Co-authored-by: Cursor <cursoragent@cursor.com>
FastAPI treats empty Form strings as missing, so the prior empty-option value never updated the plan and California tax kept applying. Co-authored-by: Cursor <cursoragent@cursor.com>
Display 0–1 fractions as one-decimal percents in the editor, parse them back on save, and label job raises as above inflation. Co-authored-by: Cursor <cursoragent@cursor.com>
Surface month-0 total spending and the minimum along the lowest-percentile path so the summary line is readable without reading the chart. Co-authored-by: Cursor <cursoragent@cursor.com>
Require person-age years, drop dummy partner defaults, and share people choices plus the plan_id fixture so the editor has fewer special cases. Co-authored-by: Cursor <cursoragent@cursor.com>
A partner-referencing boundary crashed with an uncaught AttributeError when the partner was removed, making the partner impossible to delete. A pension saved against an open-ended job persisted fine but then raised on every subsequent simulation. An unmodeled residence state was stored and then silently treated as zero state tax, and omitted household percent fields quietly reset stored values to their defaults. Also caps the SSA statement upload, returns its error partial with a status htmx will actually swap, stops "add row" from firing a save that cannot pass validation, and replaces leaked decimal.InvalidOperation text with user-facing messages. Co-authored-by: Cursor <cursoragent@cursor.com>
… display Confirm before partner removal, pension clear/overwrite, and row deletes. Stop contiguous client reindex in favor of mint-max+1 sparse indices covered by Python wire tests. Format percents with variable precision that strips float junk without forcing one decimal place. Co-authored-by: Cursor <cursoragent@cursor.com>
Embed custom pension tables and preserve echoed USD values so autosave and delete-then-edit paths stop silently losing data; always confirm partner removal and drop Max age from stream starts. Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve previous rows by USD display match when existing_index is stale, remint indices after successful saves, and cover parser/echo error paths. Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Summary
Phase 4c makes the income-side plan domains editable in the split-pane HTMX editor: household demographics + tax, jobs (with sabbaticals and a CalSTRS 2%-at-62 pension preset), Social Security (claim age + SSA XML earnings import), and manual income streams. Executed subagent-driven from
docs/superpowers/plans/2026-06-12-phase-4c-editor-income.md(8 tasks, per-task spec+quality review, plus a whole-branch review).PersonMaxAgeBoundaryon theBoundaryunion + timeline resolution (birth_year + max_age_years,birth_month).Plan(fixes a data-loss bug that droppedjobs/social_security/tax on save); adds explicit Single/MFJ filing status, residence state, SS/pension taxable fraction, and SS trust factor.web/boundaries.py(flat-form ↔Boundaryparsing + indexed/nested-row collectors), a reusable_boundary.htmlboundary-control macro, andeditor_lists.js(row add/remove/reindex + boundary toggling). "Now" stamps aCalendarMonthBoundaryat save; "max age" persists symbolically.earnings_record, read-only summary, 422 + partial re-render on bad XML), and manual income streams.core.*and surfaces as 422. HTMLnameattributes come from constants.Test plan
makegreen on the final branch (ruff + format + pyright + full pytest, 434 tests)🤖 Generated with subagent-driven development
Made with Cursor