Add Path to Freedom — dividend-income projection feature#179
Merged
Conversation
Motivational calculator that turns the user's current portfolio, monthly contribution, dividend goal and estimated inflation into a year-by-year projection until passive income covers the objective. Inputs are real (today's money); both contributions and the goal inflate during the simulation so the ETA is honest. Backend: - Migration adds motivation_* columns on users (monthly invest, objective, inflation, optional yield override, start year) - MotivationProjectionService: pure projection math + Rails.cache wrapper (6h TTL, invalidated on motivation_*, preferred_currency, or Holding changes) so the dashboard mini doesn't run the math per visit - PortfolioStatsService now also returns displayMarketValue - ProfilesController accepts/serves the new inputs and a precomputed summary Frontend: - /freedom page (auth + /demo/freedom): inputs card with auto-suggested start year from earliest dividend, four insight stat cards, progress bar, two stacked charts (portfolio growth + dividend income vs the inflating goal), and a per-year breakdown table - Past portion uses an annuity model so portfolio > contributions whenever yield > 0, and both lines meet at $0 at the user's start year - PathToFreedomMini on the logged-in dashboard, reading the cached summary - PathToFreedomShowcase on the anon homepage; Top-Scored moved below the showcase banners so all pitches come before live community data - DemoDashboardHome at /demo — logged-in-style tour with a curated profile (motivationSummary included in the demo bundle) - Bilingual (en + es); Spanish ETA renders full words to avoid ambiguity Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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
/freedompage (auth) +/demo/freedom, aPathToFreedomMiniwidget on the logged-in dashboard, and aPathToFreedomShowcasebanner on the anon homepage. New/demolands on a logged-in-styleDemoDashboardHomeso anonymous visitors see the feature in context.MotivationProjectionServiceprecomputes the summary per user and stores it viaRails.cache(6h TTL, invalidated on motivation input / preferred currency / Holding changes), so the dashboard mini never re-runs the math on visit.What's in the page
c = portfolioValue · y / ((1+y)^N − 1)) so portfolio > contributions whenever yield > 0, and both lines meet at $0 at the user's start year.Backend
motivation_monthly_invest,motivation_monthly_objective,motivation_inflation_pct,motivation_yield_override_pct,motivation_start_yearcolumns onusersPortfolioStatsServicenow also returnsdisplayMarketValue(needed for the projection's starting value in preferred currency)ProfilesControlleraccepts/serves the new fields + a precomputedmotivationSummaryapp/frontend/lib/motivation.ts) for live in-page interactivityTest plan
bundle exec rspec— 706 examples pass (existing + new model/controller/service specs)npx tsc --noEmitcleannpx vite buildcleanbin/rubocopandbin/brakemanclean/freedom, fill inputs, observe live chart updates/—PathToFreedomMinishows progress bar + ETA without recomputing/—PathToFreedomShowcasecard renders with working signup CTA/demo— anonymous tour lands on the dashboard with a curatedmotivationSummary🤖 Generated with Claude Code