2026-06-05 09:29:41 -04:00
2026-06-05 09:29:41 -04:00
2026-06-04 11:05:49 -04:00
2026-05-31 22:40:02 -04:00
2026-05-31 10:46:29 -04:00
2026-06-01 20:54:16 -04:00
2026-06-04 11:58:04 -04:00
2026-05-31 17:28:50 -04:00
2026-05-31 10:03:28 -04:00
2026-05-31 09:45:26 -04:00
2026-06-03 15:27:27 -04:00
2026-06-03 16:43:39 -04:00
2026-05-31 10:46:29 -04:00

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
  2. Getting Started
  3. Dashboard
  4. Transactions
  5. Accounts
  6. Categories
  7. Budgets
  8. Goals & Savings
  9. Investments
  10. AI Assistant
  11. Reports & Export
  12. Settings
  13. Recurring Transactions
  14. CSV Import
  15. Receipt OCR
  16. Teller Bank Sync
  17. Schwab Bank Sync
  18. USD → VND Rate Widget
  19. 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
  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 (8099%) → 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 ConnectionsDisconnect 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
S
Description
Personal Finance Management app
Readme GPL-3.0
552 KiB
Languages
HTML 50.8%
Python 49.2%