* 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