Asset movements between own accounts (buy/sell cash leg, reconciling a
receivable or payable) were typed 'expense'/'income', so they showed up in
the spending and income metrics. They are now typed 'transfer'/'settlement',
which the spending queries already exclude.
Backend:
- funded-buy/sell bank leg now typed 'transfer' (linked to investment account)
instead of 'expense' — buys no longer inflate spending
- FundedBuyRequest accepts type 'sell' in addition to 'buy'; the sell leg
credits proceeds (shares × price − fee) to the bank account
- /reconcile legs retyped to 'settlement' — collecting a receivable no longer
inflates income, paying off a payable no longer inflates spending
- RSU vest picks currency from PriceCache instead of hardcoding 'USD'
- create_account writes account + opening balance in one atomic commit
- create_split_expense links the expense row to the transfer legs so deleting
any one of the three rows deletes the whole group
- delete_transaction follows linked_transaction_id in both directions to
collect and delete the full linked group atomically
- splitwise-i-paid rejects partner_share >= total_amount (422)
- Migration h8c9d0e1f2a3 retypes historical rows the same way
Frontend:
- StockTradeFlow: sell now shows bank-account selector ('Credit proceeds…');
selector shown for both buy and sell, hidden only for rsu_vest
- Portfolio Add Trade form: same buy/sell bank-account selector added,
routes to createFundedBuy when an account is chosen
- Portfolio price-fetch handlers guard against stale ticker closures
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>