* fix(family): include HSA depository accounts in tax-advantaged exclusion
`Family#tax_advantaged_account_ids` is the ID set the budget engine uses
to exclude tax-advantaged account activity from income / expense /
cashflow totals. PR #724 originated this method and explicitly listed HSA
in scope ("401k, IRA, HSA, Roth IRA, etc."), but the implementation only
joined `investments` and `cryptos`. `Depository::SUBTYPES["hsa"]` already
exists and Plaid routes `depository.hsa` accounts to `Depository` (not
`Investment`) via `PlaidAccount::TypeMappable`, so HSA cash accounts were
silently absent from the filter and HSA contributions/withdrawals showed
up in household expense totals.
- Add `Depository::TAX_ADVANTAGED_SUBTYPES = %w[hsa]` + a `tax_treatment`
instance method (mirrors `Investment#tax_treatment`).
`TaxTreatable#tax_advantaged?` picks it up via the existing `respond_to?`
check, so `Account#tax_advantaged?` now flips to true for HSA depositories
without touching the concern.
- Extract `Family#tax_advantaged_depository_account_ids` (private) that
joins `depositories` and filters by `Depository::TAX_ADVANTAGED_SUBTYPES`,
mirroring the existing `investment_ids` / `crypto_ids` extraction style.
Append it to the union in `tax_advantaged_account_ids`.
Behavior change is scoped: HSA depositories now exit the budget engine via
the same path as 401k / IRA / Roth IRA. Non-HSA depositories continue to
report `tax_treatment: :taxable` (was `nil`), so `Account#taxable?` returns
true for them via the existing `== :taxable` clause — no expense-total
change for Checking / Savings / CD / Money Market.
Tests:
- `test/models/account_test.rb` — rewrite "tax_treatment returns nil for
non-investment accounts" (was implicitly testing the bug) into two tests:
one asserting `:taxable` for non-HSA depositories and a new sibling
asserting `nil` for accountables that genuinely lack `tax_treatment`
(CreditCard). Add an HSA-depository test asserting `tax_advantaged?`.
- `test/models/income_statement_test.rb` — new test asserting an HSA
depository is included in `tax_advantaged_account_ids` and a `savings`
depository is not.
No schema migration, no controller change, no provider integration change.
* [200~fix(family): return nil for non-HSA depository tax_treatment
* optimize net_category_totals() by using memoized cache
* fix issue - net_category_totals cache is never populated - suggested by coderabbitAI
* fix 422 error for service-worker
* remove warning of [assigned but unused variables] - income_statement.rb
* remove warnings of [assigned but unused] from Prism - income_statement_test.rb
* add some measurements to improve docstring coverage, follow CodeRabbit recommendation
* attach Skylight monitoring for dev env as well - use my own Skylight auth token
* integrate Skylight with my own account auth token for local benchmark
* fix PR review suggestion - Move fallback release-note copy to i18n keys
* follow PR review - Fix changelog GitHub fetch timeout bounding
* FIX - Variable shadowing; Prefer stubbing the specific instance over any_instance.expects
* fix CodeRabbit feedback - Reusing the same stub for both classifications hides a contract mismatch
* fix CodeRabbit FEEDBACK - Reconsider enabling Skylight by default in development
* fix CodeRabbitAI FEEDBACK - reconsider unconditionally enabling Skylight in development
* fix Security scan FEEDBACK before PR merge
* fix jjmata feedback
* third party provider scoping
* Simplify logic and allow only admins to mange providers
* Broadcast fixes
* FIX tests and build
* Fixes
* Reviews
* Scope merchants
* DRY fixes
* Make categories global
This solves us A LOT of cash flow and budgeting problems.
* Update schema.rb
* Update auto_categorizer.rb
* Update income_statement.rb
* FIX budget sub-categories
* FIX sub-categories and tests
* Add 2 step migration
- Removed `exclude_from_cashflow` attribute across models, controllers, and views.
- Updated queries to rely solely on the `excluded` flag for filtering transactions and entries.
- Simplified migration by consolidating `exclude_from_cashflow` functionality into the existing `excluded` toggle.
- Refactored related tests to remove outdated logic and ensured compatibility with the updated implementation.
- Introduced `InvestmentActivityDetector` to mark internal investment activity as excluded from cashflow and assign appropriate labels.
- Added `exclude_from_cashflow` flag to `entries` and `investment_activity_label` to `transactions` with migrations.
- Implemented rake tasks to backfill and clear investment activity labels.
- Updated `PlaidAccount::Investments::TransactionsProcessor` to map Plaid transaction types to labels.
- Included comprehensive test coverage for new functionality.
* Separate exclude and one-time transaction handling
- Split transaction "exclude" and "one-time" toggles into separate controls in transaction detail view
- Updated Transaction::Search to show excluded transactions with grayed-out styling instead of filtering them out
- Modified IncomeStatement calculations to exclude both excluded and one_time transactions from totals
- Added migration to convert existing excluded transactions to also be one_time for backward compatibility
- Updated transaction list view to show asterisk for one_time transactions and gray out excluded ones
- Added controller support for kind parameter in transaction updates
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix linting issues
- Remove trailing whitespace from migration
- Fix ERB formatting throughout templates
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Since the very first 0.1.0-alpha.1 release, we've been moving quickly to add new features to the Maybe app. In doing so, some parts of the codebase have become outdated, unnecessary, or overly-complex as a natural result of this feature prioritization.
Now that "core" Maybe is complete, we're moving into a second phase of development where we'll be working hard to improve the accuracy of existing features and build additional features on top of "core". This PR is a quick overhaul of the existing codebase aimed to:
- Establish the brand new and simplified dashboard view (pictured above)
- Establish and move towards the conventions introduced in Cursor rules and project design overview #1788
- Consolidate layouts and improve the performance of layout queries
- Organize the core models of the Maybe domain (i.e. Account::Entry, Account::Transaction, etc.) and break out specific traits of each model into dedicated concerns for better readability
- Remove stale / dead code from codebase
- Remove overly complex code paths in favor of simpler ones