371 lines
14 KiB
Markdown
371 lines
14 KiB
Markdown
# PFM — Personal Finance Manager
|
||
|
||
A self-hosted personal finance web application. Track income, expenses, investments, budgets, and savings goals. AI-powered financial assistant and receipt OCR built in. Sync bank accounts via Teller or Schwab.
|
||
|
||
**Live at:** https://pfm.ngodanguyen.tech
|
||
|
||
---
|
||
|
||
## Table of Contents
|
||
|
||
1. [Features Overview](#features-overview)
|
||
2. [Getting Started](#getting-started)
|
||
3. [Dashboard](#dashboard)
|
||
4. [Transactions](#transactions)
|
||
5. [Accounts](#accounts)
|
||
6. [Categories](#categories)
|
||
7. [Budgets](#budgets)
|
||
8. [Goals & Savings](#goals--savings)
|
||
9. [Investments](#investments)
|
||
10. [AI Assistant](#ai-assistant)
|
||
11. [Reports & Export](#reports--export)
|
||
12. [Settings](#settings)
|
||
13. [Recurring Transactions](#recurring-transactions)
|
||
14. [CSV Import](#csv-import)
|
||
15. [Receipt OCR](#receipt-ocr)
|
||
16. [Teller Bank Sync](#teller-bank-sync)
|
||
17. [Schwab Bank Sync](#schwab-bank-sync)
|
||
18. [USD → VND Rate Widget](#usd--vnd-rate-widget)
|
||
19. [Keyboard Shortcuts & Tips](#keyboard-shortcuts--tips)
|
||
|
||
---
|
||
|
||
## Features Overview
|
||
|
||
| Module | What it does |
|
||
|--------|-------------|
|
||
| **Dashboard** | Net worth, cash flow chart, budget gauges, AI insight, USD/VND rate |
|
||
| **Transactions** | Income + expense entry, transfer, filter, search, inline category change, receipt upload |
|
||
| **Accounts** | Multiple bank/cash/credit accounts, auto-calculated or provider-synced balances |
|
||
| **Categories** | Custom expense + income categories with color and icon |
|
||
| **Budgets** | Monthly spending limits per category with progress tracking |
|
||
| **Goals** | Savings goals with contribution tracking and projected completion |
|
||
| **Investments** | Stock/ETF/crypto/real estate portfolio, per-account view (Individual vs Roth IRA), live price fetch |
|
||
| **AI Assistant** | Chat with your finances via Groq (free), daily auto-insight |
|
||
| **Receipt OCR** | Drag-drop a receipt image — AI extracts and fills the form |
|
||
| **Reports** | Monthly/quarterly/yearly summaries, net worth history, PDF/CSV/Excel export |
|
||
| **Teller** | Live US bank account sync (mTLS), balance refresh, transaction import |
|
||
| **Schwab** | Schwab brokerage sync — balance, stock/ETF positions, transaction import |
|
||
| **Settings** | Profile, currency, recurring rules, CSV import, password |
|
||
|
||
---
|
||
|
||
## Getting Started
|
||
|
||
### First Login
|
||
|
||
1. Navigate to `https://pfm.ngodanguyen.tech`
|
||
2. Enter the username and password created during setup (`python scripts/init_db.py`)
|
||
3. Check "Remember me" to stay logged in across browser sessions
|
||
|
||
### Recommended Setup Order
|
||
|
||
1. **Add accounts** — add your bank accounts, cash wallet, and credit cards first
|
||
2. **Review categories** — default categories are already seeded; add custom ones if needed
|
||
3. **Set your currency** — go to Settings → Profile and set your app currency
|
||
4. **Connect bank sync** — connect Teller (US banks) or Schwab for automatic data
|
||
5. **Add transactions** — start entering income and expenses (or import via bank sync)
|
||
6. **Set budgets** — once you have categories, set monthly limits
|
||
7. **Create goals** — add savings goals and start contributing
|
||
8. **Add investments** — manually or via Schwab sync
|
||
|
||
---
|
||
|
||
## Dashboard
|
||
|
||
The dashboard is the home screen — accessible from the sidebar or by clicking the PFM logo.
|
||
|
||
### Period Selector
|
||
Three buttons in the top-right: **This Month**, **Last Month**, **Custom** (date range picker).
|
||
|
||
### Summary Cards
|
||
- **Income** — total income for the selected period
|
||
- **Expenses** — total expenses for the selected period
|
||
- **Net Cash Flow** — income minus expenses
|
||
- **Net Worth** — total assets minus liabilities across all accounts
|
||
|
||
### Cash Flow Chart
|
||
Bar chart showing the last 6 months of income (green) vs expenses (red).
|
||
|
||
### Accounts Panel
|
||
Lists all active accounts with current balances. Credit cards show the **Amount Owed** (positive number) instead of a raw negative balance. Green = positive balance, red = amount owed.
|
||
|
||
### AI Daily Insight
|
||
Auto-generated summary of your finances. Click "Open AI →" for the full chat interface.
|
||
|
||
### USD → VND Widget
|
||
Reference-only exchange rate. Click ↻ to refresh. Click the widget to show a 30-day chart.
|
||
|
||
---
|
||
|
||
## Transactions
|
||
|
||
### Viewing Transactions
|
||
Navigate via **Transactions** in the sidebar. Two tabs: **Expenses** and **Income**.
|
||
|
||
### Filtering
|
||
Search bar, category dropdown, account dropdown, date range. Click ✕ to clear all filters.
|
||
|
||
### Adding a Transaction
|
||
Use the sidebar links (Add Income / Add Expense), the dashboard quick-add buttons, or the topbar buttons on the transaction list.
|
||
|
||
### Inline Category Change
|
||
On any transaction row, click the **category dropdown** directly in the table to change the category without opening the edit form. The change saves automatically.
|
||
|
||
### Editing and Deleting
|
||
Click **Edit** to open the full form (same as adding, plus receipt management). Click **Del** to delete permanently.
|
||
|
||
### Transfers
|
||
Click **Transfer** in the topbar. Creates a single transfer between two accounts. Transfers are excluded from income/expense totals.
|
||
|
||
---
|
||
|
||
## Accounts
|
||
|
||
### Account Types
|
||
checking / savings / cash / credit_card / crypto / investment / other
|
||
|
||
### Balance Sources
|
||
- **Manually managed accounts** — balance is computed from all transactions (income − expenses − transfers out + transfers in). Updates automatically after every transaction.
|
||
- **Teller-linked accounts** — balance comes from Teller's live API. Shown with a blue **Teller** badge. Use the action buttons on the account card.
|
||
- **Schwab-linked accounts** — balance comes from Schwab's snapshot sync. Shown with a green **Schwab** badge. Use the action buttons on the account card.
|
||
|
||
### Teller Account Actions (on account card)
|
||
| Button | What it does |
|
||
|--------|-------------|
|
||
| **Refresh** | Pulls the live balance from Teller API (AJAX, no page reload) |
|
||
| **Sync** | Opens transaction preview — import new transactions from this account |
|
||
| **Reset** | Clears the sync cursor — next Sync will re-fetch the full 90-day history |
|
||
|
||
### Schwab Account Actions (on account card)
|
||
| Button | What it does |
|
||
|--------|-------------|
|
||
| **Balance & Positions** | Fetches live balance + investment holdings from Schwab, updates immediately |
|
||
| **Transactions** | Opens transaction import preview for this account |
|
||
|
||
### Credit Cards
|
||
Credit cards show two values:
|
||
- **Amount Owed** — how much you currently owe (positive number in red)
|
||
- **This Month** — expenses charged to the card this calendar month
|
||
|
||
### Opening Balance
|
||
When creating a new account, enter the current balance in the **Opening Balance** field. For credit cards, enter a **negative number** to indicate debt (e.g. `-500` if you owe $500).
|
||
|
||
---
|
||
|
||
## Categories
|
||
|
||
Navigate via the sidebar footer → **Categories**.
|
||
|
||
**Default Expense (14):** Housing, Food & Dining, Transport, Utilities, Health, Entertainment, Shopping, Education, Insurance, Personal Care, Travel, Subscriptions, Gifts, Other
|
||
|
||
**Default Income (7):** Salary, Freelance, Business, Investment, Rental, Gift Received, Other Income
|
||
|
||
System categories (grey badge) cannot be deleted but color/icon can be changed. Custom categories can be fully edited and deleted.
|
||
|
||
---
|
||
|
||
## Budgets
|
||
|
||
Navigate via **Budgets** in the sidebar. Use ◀ ▶ to navigate months.
|
||
|
||
- Set monthly limits per expense category
|
||
- Progress bars: green (< 80%) → amber (80–99%) → red (100%+)
|
||
- Rollover toggle: unspent budget carries forward to next month
|
||
- **Copy from previous month** — duplicate last month's budgets in one click
|
||
|
||
---
|
||
|
||
## Goals & Savings
|
||
|
||
Navigate via **Goals** in the sidebar.
|
||
|
||
- Create goals with target amount, target date, color, and icon
|
||
- Add contributions with dates and notes
|
||
- Auto-completes when target is reached
|
||
- **Emergency Fund Tracker** — shows how many months your liquid assets cover at current spending
|
||
|
||
---
|
||
|
||
## Investments
|
||
|
||
Navigate via **Investments** in the sidebar.
|
||
|
||
### Portfolio Overview
|
||
Summary cards: Total Value, Total Cost, Unrealized P&L, Return %. Allocation doughnut chart by asset type.
|
||
|
||
### Per-Account View
|
||
If you have investments in multiple accounts (e.g. Schwab Individual + Schwab Roth IRA), the holdings are displayed in **separate sections**, one per account. Each section shows the account name, total account value, and the holdings table for that account. The allocation chart sidebar also shows a "By Account" balance breakdown.
|
||
|
||
### Syncing from Schwab
|
||
Click **Sync Schwab** in the topbar to pull the latest holdings and balances for all mapped Schwab accounts. After syncing, each holding is associated with its source account so Individual and Roth IRA positions stay separate even if they hold the same tickers.
|
||
|
||
### Adding a Holding Manually
|
||
Click **Add Holding** in the topbar. After saving, go to the detail page to record buy transactions.
|
||
|
||
### Ticker Format
|
||
- US Stocks: `AAPL`, `MSFT`
|
||
- ETFs: `VOO`, `QQQ`
|
||
- Crypto: `BTC-USD`, `ETH-USD`
|
||
- Other markets: Yahoo Finance suffix (e.g. `VIC.VN`)
|
||
|
||
### Refreshing Prices
|
||
Click **Refresh Prices** in the topbar. Prices also auto-update daily at 4PM (weekdays).
|
||
|
||
---
|
||
|
||
## AI Assistant
|
||
|
||
Navigate via **AI Assistant** in the sidebar.
|
||
|
||
The AI has access to the last 90 days of transactions, budget status, goals, investments, and net worth. No personal names or identifying details are sent to Groq — only aggregated financial figures.
|
||
|
||
- Type and press **Enter** to send; **Shift+Enter** for new line
|
||
- Eight quick-question suggestion buttons on the right
|
||
- **Daily Insight** — auto-generated summary at midnight; click **Generate Now** to create on demand
|
||
- **Chat History** button — all past responses with timestamps
|
||
|
||
### AI Model
|
||
Change in Settings → Profile → AI Model: `llama-3.3-70b-versatile` (best quality) or `llama-3.1-8b-instant` (faster).
|
||
|
||
---
|
||
|
||
## Reports & Export
|
||
|
||
Navigate via **Reports** in the sidebar.
|
||
|
||
Four tabs: **Monthly**, **Quarterly**, **Yearly**, **Tax Year**.
|
||
|
||
Export buttons in the topbar: **CSV** (plain text), **Excel** (color-coded, formatted), **PDF** (printable report).
|
||
|
||
**Snapshot Now** — saves today's net worth to the history chart.
|
||
|
||
---
|
||
|
||
## Settings
|
||
|
||
Navigate via the gear icon at the bottom of the sidebar.
|
||
|
||
| Section | What you can change |
|
||
|---------|-------------------|
|
||
| Profile | Display name, email, timezone, currency, AI model |
|
||
| Password | Current password + new password (min 6 chars) |
|
||
| Recurring | Create/edit/pause recurring transaction rules |
|
||
| Import | Upload CSV to bulk-import transactions |
|
||
|
||
---
|
||
|
||
## Recurring Transactions
|
||
|
||
Navigate via Settings → **Recurring**.
|
||
|
||
Rules auto-create transactions on a schedule. Frequencies: daily, weekly, biweekly, monthly, quarterly, yearly. **Run Now** button processes all overdue rules immediately.
|
||
|
||
---
|
||
|
||
## CSV Import
|
||
|
||
Navigate via Settings → **Import**.
|
||
|
||
**Required columns:** `date`, `type` (income/expense), `description`, `amount`
|
||
|
||
**Optional:** `category`, `account`, `notes`
|
||
|
||
Process: upload → preview (with warnings for unmatched categories/accounts) → confirm.
|
||
|
||
---
|
||
|
||
## Receipt OCR
|
||
|
||
On the new expense form: drag-drop or click the purple panel to upload a receipt image (JPG/PNG/GIF/WEBP, max 10MB). The AI extracts amount, date, merchant, and category and fills the form. Always review before saving.
|
||
|
||
On the edit form: click **Re-extract** to re-run OCR on an already-attached receipt.
|
||
|
||
---
|
||
|
||
## Teller Bank Sync
|
||
|
||
Teller connects US bank accounts using a secure mTLS connection.
|
||
|
||
### Connecting
|
||
1. Go to **Bank Connections** in the sidebar
|
||
2. Click **Connect a Bank** — the Teller Connect modal opens
|
||
3. Select your bank and log in
|
||
4. After connecting, go to the **Map Accounts** page to link each Teller account to a PFM account
|
||
|
||
### Syncing Transactions
|
||
On the **Accounts** page, find your Teller-linked account (blue **Teller** badge) and click **Sync**. Review the transaction preview and confirm to import.
|
||
|
||
### Refreshing Balance
|
||
Click **Refresh** on a Teller account card to pull the live balance from your bank. For checking/savings this shows the available balance; for credit cards it shows the amount owed.
|
||
|
||
### Disconnecting
|
||
Go to **Bank Connections** → **Disconnect** next to the institution. Imported transactions are kept.
|
||
|
||
---
|
||
|
||
## Schwab Bank Sync
|
||
|
||
Schwab integration uses OAuth 2.0 to sync brokerage and IRA accounts.
|
||
|
||
### Connecting
|
||
1. Set `SCHWAB_CLIENT_ID`, `SCHWAB_CLIENT_SECRET`, `SCHWAB_REDIRECT_URI` in `.env`
|
||
2. Register the redirect URI in the Schwab developer portal
|
||
3. Go to **Schwab** in the sidebar → **Connect Schwab Account**
|
||
4. Authorize on Schwab's login page
|
||
5. On the **Map Accounts** page, link each Schwab account to a PFM account (or create new ones)
|
||
|
||
### Syncing Balance & Investment Positions
|
||
On the **Accounts** page, find your Schwab-linked account (green **Schwab** badge) and click **Balance & Positions**. This:
|
||
- Updates the account's balance to Schwab's total portfolio value
|
||
- Imports all stock/ETF/bond/fund holdings into the Investments section
|
||
- Associates each holding with the specific account (Individual vs Roth IRA stay separate)
|
||
|
||
You can also click **Sync Schwab** in the Investments page topbar to update all Schwab accounts at once.
|
||
|
||
### Syncing Transactions
|
||
Click **Transactions** on a Schwab account card. Review the preview and confirm to import.
|
||
|
||
### Per-Account Investment View
|
||
After syncing both Individual and Roth IRA accounts, the Investments page shows separate sections for each account — even if both hold the same ticker (e.g. AAPL appears in both sections independently).
|
||
|
||
### Disconnecting
|
||
Go to **Schwab** in the sidebar → **Disconnect**. Imported transactions and investment holdings are kept.
|
||
|
||
---
|
||
|
||
## USD → VND Rate Widget
|
||
|
||
Reference-only exchange rate on the dashboard. Does not affect any app calculations.
|
||
|
||
- Click ↻ to force-refresh without reloading the page
|
||
- Click the widget to show a 30-day trend chart
|
||
- ⚠ indicator appears if the cached rate is more than a day old
|
||
|
||
---
|
||
|
||
## Keyboard Shortcuts & Tips
|
||
|
||
### Navigation
|
||
- Sidebar collapses on desktop — click ☰ to toggle (state remembered)
|
||
- On mobile, tap outside the sidebar to close it
|
||
|
||
### Transactions
|
||
- **Enter** sends in AI chat; **Shift+Enter** adds a new line
|
||
- Change category directly in the transactions table — click the category dropdown on any row
|
||
- Date defaults to today; change it for past transactions
|
||
|
||
### Investments
|
||
- Click any row in the holdings table to go to the detail page
|
||
- **↓** button on the transaction price field fetches the current live price
|
||
- Ticker symbols are auto-uppercased on save
|
||
- **Sync Schwab** (topbar) syncs all Schwab accounts at once
|
||
|
||
### Budgets
|
||
- **Copy from previous month** button at the start of each month saves re-entering all budgets
|
||
- Rollover amounts appear as a blue "+rollover" badge
|
||
|
||
### Reports
|
||
- **Snapshot Now** button saves today's net worth to the history chart
|
||
- CSV/Excel exports use the period currently selected in the report view
|