A full-stack personal finance tracker with multi-currency support, investment portfolio monitoring, recurring transactions automation, and real-time market data integration.
- Overview
- Screenshots
- Quick Start
- Architecture
- Core Features
- How It Works
- Security
- Development
- API Documentation
Finance Manager is a modern, privacy-focused personal finance application that helps you track your net worth, manage multiple accounts, monitor investments, automate recurring transactions, and analyze spending patterns. Built on Cloudflare's edge network for global performance and security.
Main dashboard showing accounts, transactions, and financial overview
Detailed analytics with charts and insights
Portfolio tracking with real-time market data
Automated recurring transaction management with calendar view
cd api
npx wrangler d1 execute finance-db --remote --file=schema.sql
npm run deploycd client
npm run build
npx wrangler pages deploy dist --project-name=finance-clientUse the deployment script to deploy everything at once:
./deploy.sh finance-clientThis script handles:
- Database schema updates — Applies migrations to your D1 database
- API deployment — Deploys backend to Cloudflare Workers
- Client build & deploy — Builds React app and deploys to Cloudflare Pages
Finance Manager follows clean architecture principles with clear separation of concerns:
- Backend: Layered architecture with controllers, services, repositories, DTOs, and mappers
- Frontend: Component-based React architecture with context for global state
- Database: Edge-deployed SQLite (Cloudflare D1) for low-latency data access
- Deployment: Fully automated via deployment script
For detailed architecture documentation, see API/ARCHITECTURE.md.
Backend
- Runtime: Cloudflare Workers (serverless, edge-deployed)
- Framework: Hono ^4.0 (lightweight web framework)
- Database: Cloudflare D1 (SQLite at the edge)
- Market Data: Yahoo Finance API (yahoo-finance2 ^3.10)
- Architecture: Clean architecture with controllers, services, repositories, DTOs, and mappers
Frontend
- Framework: React ^19.2 with TypeScript
- Build Tool: Vite ^7.2
- Styling: Tailwind CSS ^4.1 with custom design system
- Charts: Recharts ^3.5 for data visualization
- Icons: Lucide React ^0.554
- State: React Context API (Privacy, Alerts, Locked Accounts)
- PWA: Progressive Web App with offline support and service workers
- Date Handling: date-fns ^2.30 for date formatting and manipulation
- UI Utilities: clsx ^2.1, tailwind-merge ^3.4
finance/
├── api/ # Backend (Cloudflare Workers)
│ ├── src/
│ │ ├── config/ # Application configuration
│ │ ├── controllers/ # HTTP request handlers
│ │ │ ├── account.controller.ts
│ │ │ ├── category.controller.ts
│ │ │ ├── dashboard.controller.ts
│ │ │ ├── investment-transaction.controller.ts
│ │ │ ├── market-data.controller.ts
│ │ │ ├── recurring-schedule.controller.ts
│ │ │ ├── transaction.controller.ts
│ │ │ └── transfer.controller.ts
│ │ ├── dtos/ # Data Transfer Objects
│ │ ├── mappers/ # Entity-DTO mapping
│ │ ├── middlewares/ # CORS & authentication
│ │ ├── models/ # Domain entities
│ │ ├── repositories/ # Database access layer
│ │ ├── routes/ # Route definitions
│ │ ├── services/ # Business logic layer
│ │ ├── types/ # TypeScript types
│ │ ├── utils/ # Utility functions
│ │ └── index.ts # Application entry point
│ ├── schema.sql # Database schema
│ ├── wrangler.toml # Cloudflare Workers config
│ ├── ARCHITECTURE.md # Detailed architecture docs
│ └── package.json
│
├── client/ # Frontend (React + Vite)
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── AccountList.tsx
│ │ │ ├── TransactionList.tsx
│ │ │ ├── Investments.tsx
│ │ │ ├── InvestmentChart.tsx
│ │ │ ├── Analytics.tsx
│ │ │ ├── DateRangePicker.tsx
│ │ │ ├── TransferForm.tsx
│ │ │ ├── RecurringTransactions.tsx
│ │ │ ├── Settings.tsx
│ │ │ ├── AdjustmentChoiceModal.tsx
│ │ │ ├── SplitTransactionModal.tsx
│ │ │ └── ui/ # Reusable UI components
│ │ │ ├── button.tsx
│ │ │ ├── card.tsx
│ │ │ ├── input.tsx
│ │ │ ├── label.tsx
│ │ │ ├── modal.tsx
│ │ │ └── select.tsx
│ │ ├── context/
│ │ │ ├── PrivacyContext.tsx
│ │ │ ├── AlertContext.tsx
│ │ │ └── LockedAccountsContext.tsx
│ │ ├── lib/
│ │ │ └── utils.ts # Helper functions
│ │ ├── App.tsx # Main application
│ │ ├── config.ts # API configuration
│ │ └── main.tsx # Entry point
│ ├── public/ # Static assets
│ │ ├── icon-192.png # PWA icon (192x192)
│ │ ├── icon-512.png # PWA icon (512x512)
│ │ └── favicon.svg # Favicon
│ ├── vite.config.ts # Vite & PWA configuration
│ └── package.json
│
├── screenshots/ # Application screenshots
├── deploy.sh # Automated deployment script
└── package.json # Workspace root
✨ Multi-Account Management
- Cash accounts (checking, savings, wallet)
- Investment accounts (stocks, crypto, manual assets)
- Multi-currency support with real-time conversion
- Account locking (prevent accidental modifications)
- Account exclusion options (exclude from net worth or cash balance calculations)
📊 Transaction Tracking
- Categorized income & expenses
- Recurring transactions with automated scheduling
- Linked transfers between accounts
- Custom categories with emoji icons
- Split transactions - divide a single transaction across multiple categories
- Balance adjustments - reconcile account balances with single or split transactions
- Transaction filtering by type, category, and date range
- Monthly transaction views with pagination
📈 Investment Portfolio
- Real-time stock/crypto prices via Yahoo Finance
- Portfolio value tracking with multi-currency support
- Transaction history (buy/sell)
- Performance charts and analytics
- Auto-refresh prices (every 5 minutes)
- Manual asset tracking without market data
🔒 Privacy & Security
- Privacy mode to hide sensitive financial data
- Persistent user preference (localStorage + cookie)
- Quick eye icon toggle in header
- Account locking to prevent accidental changes
- Alert system for user notifications
- Three-layer security model (Cloudflare Access, API Key, CORS)
📉 Analytics Dashboard
- Net worth overview with real-time calculation
- Income vs. expenses tracking
- Category breakdown charts
- Monthly trends and patterns
- Date range filtering for custom periods
- Period selection (7 days, 30 days, 90 days, year, all time, custom)
- Cash flow visualization
🔄 Recurring Transactions
- Automated recurring transaction management
- Daily, weekly, and monthly schedules
- Projected cash flow (end of month)
- Next 30 days income/expense forecasting
- Account status monitoring (sufficient funds alerts)
- Interactive calendar view of upcoming transactions
- Cloudflare Cron Triggers for automated processing
⚙️ Settings & Customization
- Master currency selection (HUF, EUR, USD, GBP, CHF, PLN, CZK, RON)
- Category management with custom icons (150+ emoji options)
- Privacy mode toggle
- Cache management and force reload
- Data export (CSV and JSON formats)
- PWA cache control
🌍 Global Deployment
- Edge-deployed on Cloudflare network
- Sub-50ms response times worldwide
- Automatic HTTPS and DDoS protection
📱 Progressive Web App (PWA)
- Install on mobile devices and desktop
- Offline support with service workers
- Auto-updates and caching
- Native app-like experience
- Custom app icons and splash screens
The application supports two types of accounts:
-
Cash Accounts — Traditional bank accounts, wallets
- Direct balance management
- Currency-specific
-
Investment Accounts — Asset holdings
- Stock/Crypto: Auto-updates price from Yahoo Finance
- Manual: User-defined assets without market data
- Balance calculated from:
transactions × current_price
Every financial action is recorded as a transaction:
User Action → Transaction Record → Account Balance Update
Example: Transfer $100 from Checking to Savings
- Creates 2 linked transactions:
- Transaction A: Checking -$100 (expense)
- Transaction B: Savings +$100 (income)
- Both transactions share a
linked_transaction_id - Account balances update atomically
Investment Transactions are tracked via regular transactions with a price field:
- Buy: Negative amount, increases holdings
- Sell: Positive amount, decreases holdings
Investment accounts use a transaction-based approach:
- User buys 10 shares of AAPL at $150/share
- System creates transaction:
-$1500amount,price: 150,quantity: 10 - Current balance =
SUM(transactions.amount / price) × current_market_price
Auto-refresh runs on:
- Page load
- Manual refresh button
- Every 5 minutes (in dashboard view)
Privacy mode uses React Context to globally mask sensitive data:
// When enabled, transforms:
"$12,345.67" → "••••••"
"150 shares" → "•••"- Preference saved in localStorage + cookie
- Survives page refresh
- Applies to: balances, amounts, quantities, charts
- Configurable startup behavior (hide on startup option)
- Quick toggle via eye icon in header
The application supports automated recurring transactions with advanced scheduling:
- Mark any transaction as recurring when creating it
- Choose frequency: daily, weekly, or monthly
- Set specific days (day of week for weekly, day of month for monthly)
- A Cloudflare Cron Trigger runs daily at midnight
- Recurring schedules are automatically processed and transactions created
- Configured in
wrangler.toml:crons = ["0 0 * * *"]
Features:
- Projected cash flow calculations (end of month)
- Next 30 days income/expense forecasting
- Account status monitoring with insufficient funds alerts
- Interactive calendar view showing upcoming transactions
- Support for both single transactions and transfers
This enables automated handling of:
- Regular salary deposits
- Monthly subscriptions
- Recurring bills and expenses
- Weekly allowances
- Daily automated transactions
Split a single transaction across multiple categories for detailed expense tracking:
- Choose to split when adjusting an account balance or creating a transaction
- Define multiple splits with individual amounts, descriptions, and categories
- System ensures total matches the transaction amount
- Visual indicators show split vs. allocation progress
- Percentage-based splitting for easy distribution
Use cases:
- Shopping trips with groceries, household items, and personal care
- Utility bills split between housing and utilities categories
- Mixed business/personal expenses
- Detailed expense tracking for reimbursements
Reconcile account balances when they don't match reality:
- Enter the correct balance in account settings
- System calculates the adjustment amount
- Choose between:
- Single transaction: One adjustment entry in a category
- Split transaction: Distribute adjustment across multiple categories
- Account balance updates to match the correct amount
Perfect for:
- Fixing data entry errors
- Reconciling with bank statements
- Adjusting for cash transactions not yet recorded
- Correcting rounding differences in currency conversions
Three-Layer Security Model:
-
Cloudflare Access (Frontend)
- Email-based authentication
- Only authorized users can view the app
- 24-hour session duration
-
API Key Authentication (Backend)
- Every API request requires
X-API-Keyheader - Key stored in environment variables
- Validates on every request
- Every API request requires
-
CORS Protection (Backend)
- Origin whitelist validation
- Rejects unauthorized domains
- Configurable via
ALLOWED_ORIGINSenv var
Environment Secrets:
API_SECRET— Backend API keyALLOWED_ORIGINS— Comma-separated allowed domainsVITE_API_KEY— Client-side API key (injected at build time)
- Node.js 18+ and npm
- Cloudflare account with Workers + D1 access
- Wrangler CLI (installed via npm)
-
Clone and install dependencies:
git clone <repo-url> cd finance npm install
-
Configure the API:
cd api cp wrangler.toml.example wrangler.toml # Edit wrangler.toml: # - Set database_id (create D1 database first) # - Configure API_SECRET and ALLOWED_ORIGINS
-
Initialize database:
npx wrangler d1 execute finance-db --local --file=schema.sql
-
Configure the client:
cd ../client # Create .env.local file: echo "VITE_API_KEY=your-api-key-here" > .env.local echo "VITE_API_DOMAIN=localhost:8787" >> .env.local
-
Run development servers:
cd .. npm run dev # API: http://localhost:8787 # Client: http://localhost:5173
API (wrangler.toml secrets):
[vars]
API_SECRET = "your-secret-key"
ALLOWED_ORIGINS = "http://localhost:5173,https://finance.yourdomain.com"Client (.env.local):
VITE_API_KEY=your-secret-key
VITE_API_DOMAIN=localhost:8787 # or api.yourdomain.com for prodBase URL: https://api.finance.yourdomain.com
Authentication: Include X-API-Key header in all requests.
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Health check |
GET |
/version |
API version |
| Accounts | ||
GET |
/accounts |
List all accounts |
POST |
/accounts |
Create account |
PUT |
/accounts/:id |
Update account |
DELETE |
/accounts/:id |
Delete account |
| Transactions | ||
GET |
/transactions |
List all transactions |
GET |
/transactions/paginated |
Get paginated transactions |
GET |
/transactions/date-range |
Get transactions by date range |
GET |
/transactions/from-date |
Get transactions from a specific date |
POST |
/transactions |
Create transaction |
PUT |
/transactions/:id |
Update transaction |
DELETE |
/transactions/:id |
Delete transaction |
| Categories | ||
GET |
/categories |
List categories |
POST |
/categories |
Create category |
PUT |
/categories/:id |
Update category |
DELETE |
/categories/:id |
Delete category |
POST |
/categories/reset |
Reset categories to defaults |
| Investment Transactions | ||
GET |
/investment-transactions |
List investment transactions |
POST |
/investment-transactions |
Create investment transaction |
DELETE |
/investment-transactions/:id |
Delete investment transaction |
| Recurring Schedules | ||
GET |
/recurring-schedules |
List all recurring schedules |
POST |
/recurring-schedules |
Create recurring schedule |
PUT |
/recurring-schedules/:id |
Update recurring schedule |
DELETE |
/recurring-schedules/:id |
Delete recurring schedule |
POST |
/recurring-schedules/process |
Process recurring schedules (cron) |
GET |
/recurring-schedules/calendar |
Get calendar view of upcoming transactions |
| Transfers | ||
GET |
/transfers/exchange-rate |
Get exchange rate between currencies |
POST |
/transfers |
Create transfer between accounts |
| Dashboard | ||
GET |
/dashboard/net-worth |
Calculate net worth |
| Market Data | ||
GET |
/market/search |
Search for stocks/crypto symbols |
GET |
/market/quote |
Get current price quote |
GET |
/market/chart |
Get historical price chart data |
Example Request:
curl -H "X-API-Key: your-key" \
https://api.finance.yourdomain.com/accountsAPI Version: 1.1.4
Client Version: 1.2.3
License: MIT
Maintained by: apptrackit
- API Architecture Documentation — Detailed documentation of the clean architecture pattern used in the API
- Deployment Script — Automated deployment with
./deploy.sh - Database Schema — See
api/schema.sqlfor complete database structure - PWA Configuration — See
client/vite.config.tsfor Progressive Web App setup