This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Ignidash is an open-source personal financial planning app (AGPL-3.0). It runs Monte Carlo simulations, historical backtesting, US tax estimation, and AI chat/insights for retirement planning.
- Frontend: Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS 4
- Backend: Convex (serverless DB + functions)
- Auth: Better-Auth with Convex integration + Google OAuth
- Payments: Stripe
- AI: Azure OpenAI (streaming chat + insights)
- State: Zustand 5 (with Immer, persist, devtools)
- Forms: React Hook Form + Zod 4 validation
- Charts: Recharts 3
- Analytics: PostHog
npm run dev # Next.js dev server
npm run dev:convex # Local Convex backend (run alongside dev)
npm run build # Production build
npm run lint:fix # ESLint auto-fix
npm run format # Prettier format all
npm run typecheck # TypeScript check (tsc --noEmit)
# Testing
npm run test # Vitest watch mode
npm run test:once # Vitest single run
npm run test:once -- src/lib/calc/__tests__/taxes.test.ts # Run single test file
npm run test:coverage # Coverage report
npm run test:e2e # Playwright e2e testsHusky runs lint-staged on commit, which auto-runs eslint --fix + prettier --write on staged .js/.jsx/.ts/.tsx files and prettier --write on .json/.md/.css. Files in convex/_generated/ are excluded.
@/*→src/*@/convex/*→convex/*
src/app/(auth)/— Sign in/up, password reset (public)src/app/(marketing)/— Home, pricing, about (public)src/app/(legal)/— Privacy, terms (public)src/app/dashboard/— Protected area: simulator, insights, comparesrc/app/dashboard/simulator/[planId]/— Main simulator view per plansrc/app/api/auth/— Better-Auth API endpoints
All server functions (queries, mutations, actions) live here. Key files:
plans.ts,account.ts,income.ts,expense.ts,debt.ts— CRUD for financial entitiesmessages.ts,conversations.ts— AI chatinsights.ts— AI-generated insightshttp.ts— HTTP endpoints (Stripe webhooks)utils/auth_utils.ts—getUserIdOrThrow(ctx)for auth in every query/mutationutils/sys_prompt_utils.ts— Dynamic AI system prompt from plan datavalidators/— Input validators for Convex functions_generated/— Auto-generated types and API (do not edit)betterAuth/_generated/— Auto-generated auth types (do not edit)
The core financial simulator runs month-by-month loops producing yearly SimulationDataPoints:
simulation-engine.ts—FinancialSimulationEngineorchestrates the loopportfolio.ts,account.ts,incomes.ts,expenses.ts,taxes.ts,debts.ts— Per-domain calculation modulesreturns-providers/— Strategy pattern:FixedReturnsProvider,StochasticReturnsProvider,LcgHistoricalBacktestReturnsProviderdata-extractors/— Extract chart data, table data, key metrics from simulation results__tests__/— Unit tests for the engine
Heavy simulation work runs off-main-thread via Comlink:
simulation-worker-api.ts— Worker pool managementsimulation.worker.ts— Runs individual simulationsmerge-worker-api.ts/merge.worker.ts— Aggregates multi-simulation results
Single Zustand store (useSimulatorStore) with slices: results, preferences, chat, insights, nux, numbers. Uses Immer middleware for mutable updates. Only preferences and nux are persisted to localStorage.
- Convex queries fetched via hooks in
src/hooks/use-convex-data.ts(wrapsuseQuery) - Data transformed from Convex documents → Zod types via
src/lib/utils/convex-to-zod-transformers.ts - Zod-validated inputs fed into simulation engine
- Results extracted by data extractors into chart/table/metric data
- SWR used for derived data caching (multi-simulation analysis)
inputs/simulator-schema.ts— RootSimulatorInputstype composing all sub-schemasinputs/— Per-domain form schemas (income, account, expense, etc.)finances/— Financial object schemastables/— Table row schemas
~25 custom hooks. Key ones:
use-convex-data.ts— All Convex query hooks (usePlanData,useIncomesData, etc.)use-results-state.ts— Simulation results stateuse-regen-simulation.ts— Trigger simulation re-runsuse-chart-*.ts— Chart data extraction hooks
src/components/ui/— shadcn/ui componentssrc/components/catalyst/— Catalyst UI library (custom form/table components)src/components/layout/sidebar/— Desktop and mobile sidebarssrc/components/providers/— Theme provider
Centralized in src/lib/config/currency.ts and src/lib/utils/format-currency.ts:
formatCurrency(amount, {cents?})— Full display ($1,234,567)formatCompactCurrency(amount, digits)— Compact ($1.5M, $200k)getCurrencySymbol()— Returns '$'formatCurrencyPlaceholder(amount)— Form placeholders
formatNumber in src/lib/utils.ts is only for non-currency values (percentages, plain numbers).
- Prettier: single quotes, semicolons, trailing commas (ES5), 140 char width, Tailwind class sorting
- ESLint: flat config (ESLint 9), extends
next/core-web-vitals+next/typescript+prettier - Unused variables: underscore prefix allowed (e.g.,
_unused) - All components are
'use client'unless explicitly server components