EislM0203andClaude Sonnet 4.6 082b6081b7 feat: fin CLI + agent skill + opt-in API bearer auth
Adds `fin` — a typer/httpx CLI for the deployed API — so Claude Code and
other agents can consume fin over HTTP without an MCP server.

Backend:
- api/app/auth.py: require_api_token dependency (no-op unless FIN_API_TOKEN
  env is set; RFC 7235 case-insensitive Bearer, constant-time compare). All
  nine routers wired; /api/health exempt for k8s probes.
- GET /api/openapi.json added as an explicit token-gated route (FastAPI's
  built-in openapi_url bypasses dependency injection).
- GET /api/transactions gains an optional `limit` query param (ge=1).

CLI (cli/):
- fin_cli/client.py: FinClient — sync httpx wrapper, zero typer/rich imports
  (MCP-ready core for a future MCP server).
- Subcommands: networth, accounts, categories, tx, transfer, settle,
  split-expense, splitwise-paid, reconcile, holdings, stock, rsu,
  spending, prices. Every command supports --json for agent use.
- fin tx add refuses transfer/settlement types to prevent single-leg writes.
- Config via FIN_API_URL (required) and FIN_API_TOKEN (optional).

Agent skill: .claude/skills/fin/SKILL.md — command map, jq patterns, and
domain invariants (two-leg atomicity, net-share splitwise math, derived
holdings, funded-buy, soft-deactivate, FIN_API_TOKEN web-UI lockout warning).

Tests: 25 e2e tests (FinClient → real routes → temp SQLite) covering auth
on/off, all key invariants (two-leg linkage, fee-in-balance, net-share math),
transfer whole-group delete, and linked-leg edit rejection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPBt3s7Jyr2nozQTrVVGA4
2026-07-03 19:22:15 +00:00
2026-06-30 08:37:45 +02:00

fin

A self-hosted, single-user personal net worth tracker. fin aggregates bank accounts, investment portfolios, Splitwise balances, and receivables into a single EUR-denominated view, with daily automated snapshots and live stock prices.

Features

  • Dashboard — current net worth broken down by account group, plus recent transactions
  • Spending — monthly expense breakdown by category with a pie chart
  • Portfolio — investment account holdings with live USD prices (via yfinance), P&L per position, and EUR conversion
  • History — net worth over time as a line chart; snapshots taken automatically at midnight
  • Transactions — full transaction log across all accounts
  • Quick-add flows — mobile-friendly sheet for logging expenses, transfers, Splitwise splits/settlements, and stock trades
  • Settings — manage accounts (bank, investment, RSU, Splitwise, receivable) and spending categories; manual balance override per account
  • Multi-currency — EUR base currency; exchange rates via Frankfurter API

Quick Start

git clone <repo>
cd fin
docker compose up -d

The app is available at http://localhost.

Environment / Config

Set in docker-compose.yml under the api service:

Variable Default Description
DATABASE_URL sqlite:////data/fin.db SQLite path inside the container

Data is persisted in a named Docker volume (sqlite_data). No other configuration is required.

Architecture

The backend is a Python FastAPI app backed by SQLite via SQLAlchemy; APScheduler runs a nightly job to fetch stock prices (yfinance) and currency rates (Frankfurter) and record a net worth snapshot. The frontend is a React + TypeScript SPA served by Nginx, communicating with the API through the same Nginx container via reverse proxy.

S
Description
No description provided
Readme
638 KiB
Languages
TypeScript 54.1%
Python 44.9%
JavaScript 0.3%
Dockerfile 0.2%
Mako 0.2%
Other 0.3%