Repository navigation
Development
How the code is organized and how to work on it.
- Setup
- Repository layout
- Architecture
- The API
- Frontend
- Tests
- Demo data
- Screenshots
- Code style
- Releasing
git clone https://github.com/brookisme/financial_planner.git
cd financial_planner
pixi install -e dev # Python, Node, pytest…
pixi run -e dev test-allsrc/financial_planner/
schema.py pydantic models for every config section
config.py merge config/*.yaml, validate, save sections (comments kept)
sources.py CSV parsing: column mapping, date/amount detection, inspect
rules.py categorization rules and precedence
summary.py data window, category totals, child timelines, the web payload
state.py .financial_planner/state.json
server.py FastAPI app and JSON API (localhost only)
launcher.py remembered plan, desktop shortcuts
cli.py the financial_plan command
templates/ blank plan for `init`
web/ BUILT frontend (committed so users don't need Node)
web/
src/model.ts all projection math (pure functions, no DOM)
src/ui/*.ts one module per section, settings and categorize
src/main.ts loading and routing
test/ vitest tests for model.ts
examples/demo/ fictional demo plan
scripts/ make_demo_data.py, frame_screenshots.py
tests/ pytest
- Python owns the data: reading config and CSVs, categorizing, averaging, validating and saving settings. It sends the browser one JSON payload.
-
TypeScript owns the interaction and the projections, so sliders respond instantly. The math is
isolated in
model.tsand tested on its own. - State (page edits, saved budgets, presets) goes back to the server and is stored in the plan folder.
- Config saves go through the same pydantic validation as loading, so invalid YAML never reaches disk.
All under /api, on 127.0.0.1 only. Requests that change anything need the header
X-Financial-Planner: 1.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/payload |
Everything the main page needs. |
| GET | /api/config |
Raw merged config, owning files, validation error, data files. |
| PUT | /api/config/{section} |
Validate and save one section. |
| GET | /api/transactions |
All transactions with category and how it was set; rules; categories. |
| POST | /api/rules/preview |
What a candidate rule would match / change. |
| POST | /api/rules |
Add a rule (row rules replace older ones for the same row). |
| GET / POST | /api/files |
List / upload CSVs in data/. |
| GET | /api/inspect?file=… |
Columns, sample and guesses for a CSV. |
| POST | /api/sources/preview |
Parse files with unsaved source settings. |
| GET / PUT |
/api/state, /api/state/{ui|budgets|presets|scenarios}
|
Page state, saved budgets (and picker choices), return / inflation presets. scenarios is kept for older plans. |
pixi run -e dev web-build # type-check + bundle into src/financial_planner/web/
cd web && npx tsc --noEmit # type-check only (or: pixi run -e dev web-check)
cd web && node build.mjs --watchRun the app against the demo (pixi run demo) and reload after a rebuild. Commit the built files
in src/financial_planner/web/ with source changes.
pixi run -e dev test # pytest: config, sources, rules, summary, server, CLI
pixi run -e dev web-test # vitest: forecast mathThe forecast math is tested against closed-form results and hand calculations; add a test with any
change to model.ts.
scripts/make_demo_data.py writes deterministic, fictional CSVs (a card with debit/credit columns
and a checking account with a signed amount column):
pixi run -e dev demo-dataNever commit real data. .gitignore refuses CSVs outside the demo and test fixtures.
Take wiki screenshots from the demo plan only (never a real plan), in light mode, then give them some room around the edges, a gray border and rounded corners so they stand out on light and dark pages:
python scripts/frame_screenshots.py ../financial_planner.wiki/assets/*.png \
--skip app-icon.png menu-bar-icon.pngImages that are already framed are left alone, so it's safe to run on the whole folder. Frame the new screenshots as taken; framing an already framed one would add a second frame.
- Python: PEP 8 (100 columns), type hints, Google-style docstrings, module sections in the order Imports / Constants / Public / Internal, BSD 3-Clause header.
- TypeScript: the Google TypeScript style guide, same section order and license header.
Publishing to PyPI (and the desktop app downloads) is a copy-paste checklist on the Releasing page. The short version:
pixi run -e dev test-all
pixi run -e dev publish-test # TestPyPI
pixi run -e dev publish # PyPIGetting started
Using the app
Setting up your plan
- Plan Folder
- Settings Editor
- Data Sources (CSVs)
- Categories
- Categorizing and Rules
- Setup with an AI Assistant
Reference