Skip to content

SG Income Tax → Multi-Year Projection Engine #193

@jcleow

Description

@jcleow

Summary

Enable multi-year income tax projections integrated into the timeline engine. Tax estimates currently exist only as single-year frontend calculations (taxCalculations.ts + localStorage) — this connects them to the projection pipeline so tax liability is projected across years, deducted from cash flow, and reflected in net worth.

Full spec: spec/tax-projection-multi-year.md

Problem

  • Tax liability is invisible in net worth projections
  • Tax payments don't reduce cash flow in the timeline
  • Income growth in the projection engine isn't reflected in tax estimates
  • Scenario impacts (job changes, marriage, children) don't auto-adjust tax reliefs
  • No year-to-year view — users must manually switch assessment years

Architecture

Follows the same integration pattern as the insurance premium → net worth integration:

  • Port tax calculator from TypeScript to Go (financial_v2/tax/calculator.go)
  • Add processTaxPayments() as a new step in processMonth() pipeline
  • Tax payments reduce cash flow via calcCashAllocationWithRules
  • New GET /api/v2/tax/projections endpoint for multi-year data
processMonth() pipeline:
  1. Reset CPF YTD
  2. Apply growth
  3. Process liabilities
  4. Apply scenarios
  5. CPF contributions
  6. CPF Engine
  7. Insurance premiums      ← recently added
  8. Tax payments            ← NEW
  9. Transfer rules
  10. Payment rules
  11. Expense rules
  12. Cash allocation
  13. Build response

Implementation Phases

Phase 1: Backend Tax Calculator

  • Create backend/internal/financial_v2/tax/ package
  • Port progressive bracket calculation from taxCalculations.ts to calculator.go
  • Port relief application logic (CPF auto-calc, $80k cap)
  • Unit tests for all 13 bracket boundaries

Phase 2: Income Aggregation

  • projector.go — aggregate annual income from EffectiveRows with growth applied
  • Categorize by type (employment, rental, business, investment)
  • Calculate CPF contributions for auto-relief

Phase 3: Multi-Year Projection API

  • GET /api/v2/tax/projections endpoint (pure computation, no DB table)
  • Returns per-year: income breakdown, reliefs, tax calculation, payment schedule
  • Handler + route registration

Phase 4: Timeline Integration

  • Pre-compute tax for all years before monthly loop
  • Add processTaxPayments() step in processMonth()
  • Add TaxPayment field to CashAllocationParams
  • Add TaxPaymentDetail to MonthDetailResponse

Phase 5: Frontend — Multi-Year Tax View

  • TaxProjection/ component with year-by-year table
  • useTaxProjectionsQuery hook
  • financialApi.getTaxProjections() service method
  • Optional: tax bar chart overlay on projection chart

Phase 6 (Future): Config, Overrides & Scenarios

  • sg_income_tax database table for per-year overrides
  • CRUD endpoints for tax config
  • Scenario-relief mapping (marriage → spouse relief, child → child relief)
  • Copy-forward logic for relief configuration
  • Migrate from localStorage to API-backed storage

Key Files

New Purpose
tax/calculator.go Tax engine (port from TS)
tax/projector.go Multi-year projection + income aggregation
tax/types.go Go structs
handlers/tax.go API handler
TaxProjection/index.tsx Frontend projection view
useTaxProjectionsQuery.ts React Query hook
Modified Change
timeline/service.go Add processTaxPayments(), modify cash allocation
timeline/types.go Add TaxPayment to response
financialApi.ts Add getTaxProjections()

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium priorityfeatureNew feature request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions