Skip to content

Add multi-method tax engine with FX-ready pricing hierarchy (#317) - #382

Merged
robertocarlous merged 3 commits into
Neurowealth:mainfrom
B-Hands:feature/317-tax-methods
Aug 27, 2026
Merged

Add multi-method tax engine with FX-ready pricing hierarchy (#317)#382
robertocarlous merged 3 commits into
Neurowealth:mainfrom
B-Hands:feature/317-tax-methods

Conversation

@Anuoluwapo25

@Anuoluwapo25 Anuoluwapo25 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Cost-basis consumption is now method-parameterized (FIFO/LIFO/HIFO/SPECIFIC_ID) via a whitelisted registry in src/tax/methods/, resolved per user from the new User.accountingMethod (default FIFO, byte-identical to the pre-existing behavior — verified against the original FIFO fixture tests).
  • SPECIFIC_ID withdrawals carry their lot selection on the new Transaction.selectedLotIds column so the Stellar event listener has it once the on-chain withdrawal confirms (disposal recording happens on that confirmation path, the same timing every other method already uses).
  • Method changes are forward-only (User.methodEffectiveAt) — disposals already recorded are never rewritten. buildTaxReport's ?method= query param is a confirmation gate against the account's real setting, not a what-if recompute switch, since the ledger is an immutable record of what actually happened; a mid-year method change is flagged in the report's caveats instead of silently mixed.
  • Pricing (src/tax/pricing.ts) gains a real source hierarchy — user-declared → market feed → stablecoin assumption → unpriced — with a documented, always-null feed stub as the integration point for a future price source (no live feed/credentials exist yet, so volatile assets stay honestly unpriced).
  • Full design rationale, known limitations, and the forward-only policy are written up in docs/TAX_REPORT.md.

Test plan

  • npx tsc --noEmit clean
  • npx eslint clean on all new/touched files
  • Full unit suite green (997 tests, including 27 new/updated tests: cross-method reconciliation on identical fixture lots, HIFO determinism/tie-breaks, SPECIFIC_ID validation, method-mismatch rejection, mid-year method-change caveat)
  • Migration applied cleanly against a local Postgres instance (prisma migrate reset + migrate dev, no drift)
  • Manual exercise against a running server: set a user's accountingMethod to LIFO/HIFO, deposit + withdraw, confirm the report reflects the expected consumption order and rejects a mismatched ?method= query param with 400.

closes #317

…lth#317)

Cost-basis consumption is now method-parameterized (FIFO/LIFO/HIFO/
SPECIFIC_ID) via a whitelisted registry in src/tax/methods/, resolved
per user from the new User.accountingMethod (default FIFO, byte-
identical to prior behavior). SPECIFIC_ID withdrawals carry their lot
selection on Transaction.selectedLotIds so the event listener has it
when disposals are recorded on confirmation.

Method changes are forward-only (User.methodEffectiveAt) — disposals
already recorded are never rewritten. The tax report's `method` query
param is a confirmation gate against the account's real setting, not a
what-if recompute switch, since disposals are an immutable ledger of
what actually happened. A mid-year method change is flagged in the
report's caveats rather than silently mixed.

Pricing gains a real source hierarchy (user-declared -> market feed ->
stablecoin assumption -> unpriced) with a documented, always-null feed
stub as the integration point for a future price source. See
docs/TAX_REPORT.md.
Syncs with 40+ commits of upstream history (websocket streaming, user
API keys, session hardening, the user-event bridge replacing the old
webhook dispatcher, etc.) — no real conflicts, git merged cleanly.

Adds the rollback.sql the migration-rollback-check CI job requires for
20260824215727_add_multi_method_tax_engine.
@robertocarlous
robertocarlous merged commit 02d406e into Neurowealth:main Aug 27, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-Method Tax Engine (LIFO / HIFO / Specific ID) with Multi-Currency Cost Basis

2 participants