-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
Description
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 inprocessMonth()pipeline - Tax payments reduce cash flow via
calcCashAllocationWithRules - New
GET /api/v2/tax/projectionsendpoint 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.tstocalculator.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 fromEffectiveRowswith 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/projectionsendpoint (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 inprocessMonth() - Add
TaxPaymentfield toCashAllocationParams - Add
TaxPaymentDetailtoMonthDetailResponse
Phase 5: Frontend — Multi-Year Tax View
-
TaxProjection/component with year-by-year table -
useTaxProjectionsQueryhook -
financialApi.getTaxProjections()service method - Optional: tax bar chart overlay on projection chart
Phase 6 (Future): Config, Overrides & Scenarios
-
sg_income_taxdatabase 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
- Follows pattern from: Insurance Premium → Net Worth Integration (Cash + CPF) #191 (Insurance Premium → Net Worth Integration)
- Existing backlog spec:
specs/backlog/sg-income-tax-projections.md - Frontend tax engine:
frontend/src/lib/taxCalculations.ts
Reactions are currently unavailable