Skip to content

Latest commit

 

History

66 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FinAI — Personal Finance Chatbot

A production-grade, AI-powered personal finance platform built for individuals who want full visibility and control over their money. Features bank account sync via Plaid, a conversational AI assistant powered by Google Gemini with native Function Calling (create budgets and log transactions directly from chat), a 6-tab Analytics suite with interactive charts, a Merchant Deep-Dive modal, spending velocity tracking, date-range transaction filtering, theme customization, keyboard shortcuts, mobile-responsive navigation, savings goal deadline alerts, animated budget utilization dial, and a full suite of automated spending insights, CSV exports, and subscription detection.

Features

Investment Portfolio Tracking

  • Manual Holdings Tracking: Add, edit, and delete positions (stock tickers, crypto, ETFs) with quantity, average cost basis, and acquisition date
  • Live Market Price Feeds: Automated price fetching via Twelve Data API with zero-key Yahoo Finance fallback — prices are cached for 15 minutes to respect rate limits
  • Stale Price Fallback: If external market data APIs are unreachable, the system gracefully marks holdings with is_stale: true and displays last-known cached prices with visual warning indicators
  • Gain / Loss & Performance Analytics: Real-time calculation of unrealized dollar gain/loss and percentage return per holding and across the entire portfolio
  • Asset Allocation Donut Chart: Interactive Recharts pie chart showing portfolio composition by ticker with percentage breakdown and custom tooltips
  • Portfolio History Area Chart: Tracks daily portfolio value against total cost basis over time with dual-gradient fills
  • Daily Portfolio Value Snapshots: Automated node-cron job runs at 11:50 PM daily to snapshot total portfolio value and cost basis into portfolio_history
  • Net Worth Aggregation: Automatically combines bank checking/savings balances from Plaid with live investment portfolio values in the dashboard Net Worth header

Core Functionality

  • Bank Account Linking: Connect real bank accounts via Plaid Link with OAuth-safe public token exchange — access tokens are AES-256 encrypted at rest before storage
  • Automatic Transaction Sync: Cursor-based Plaid transactionsSync API with full pagination — fetches added, modified, and removed transactions incrementally without re-fetching historical data
  • Dashboard Overview: Unified financial command center showing net worth (including investments), stat cards (total spent, top category, biggest transaction), spending velocity banner, end-of-month forecast, budget utilization dial, charts, budgets, savings goals, subscriptions, and linked account balances — all in a single glassmorphic dark-mode interface
  • User Authentication: Secure registration and login with bcrypt password hashing and HTTP-only JWT cookies

AI & Chat Features

  • Conversational AI Assistant: Full-context chat powered by Google Gemini that reads your real transaction history, budgets, savings goals, and account balances before every response — answers are grounded in your actual financial data, not generic advice
  • Gemini Function Calling — Budget Creation: Say "Set a $300 budget for food" in chat and FinAI automatically creates the budget in the database and confirms it — no separate form required
  • Gemini Function Calling — Transaction Logging: Say "Log a $14.50 cash expense at McDonald's" and FinAI parses the amount, merchant, category, and date, then inserts it directly into your transaction history before responding conversationally
  • Enhanced Suggested Prompts: Chip shortcuts in the Chat UI are tuned to trigger Gemini's native tool calls — prompts like "Set a budget for Food" and "Log a $20 transport expense" invoke Function Calling immediately
  • Persistent Chat History: All messages are stored per-user in PostgreSQL and injected as conversation history on every new message, enabling true multi-turn memory across sessions
  • Clear Chat: One-click chat history deletion with a confirmation modal — wipes both the UI and the stored database history

Financial Tracking

  • Spending by Category: Bar chart showing where your money goes this month, with color-coded category legend pills and month-over-month percentage change badges
  • Cumulative Spending Trend: Area line chart plotting a rolling daily running total so you can spot overspending patterns before the month ends
  • Month-over-Month Comparison: Side-by-side dual progress bars for every category comparing current month vs. previous month spending — each card shows a +X% / -X% badge and an overall summary banner showing total delta and direction
  • Spending Velocity Banner: Real-time week-over-week comparison widget — shows this week's total vs. last week's, transaction count, and a ▲/▼ X% acceleration indicator in red (accelerating) or green (decelerating)
  • End-of-Month Forecast: Projects total spend to month-end using the current daily average, with color-coded status (green / amber / red) relative to your total budget limits
  • Recent Transactions Widget: Live table of the latest 10 transactions with merchant name, category, amount, and date

Analytics Suite (6-Tab Page)

  • Overview Tab: Monthly stat cards (Total Spent, Avg. Daily, Biggest Transaction, Total Transactions, Top Spending Day), a 12-month spending trend chart with Area/Bar toggle, and a day-of-week heatmap bar chart with busiest/quietest day callouts
  • Spending Tab: Category breakdown with horizontal progress bars and MoM change badges, donut pie chart with legend, and an interactive Top Merchants list — click any merchant to open the Merchant Deep-Dive Modal
  • Merchant Deep-Dive Modal: Click-to-explore panel showing KPI row (total spent, avg per transaction, count), a 6-month monthly spend bar chart, and a scrollable list of the 10 most recent transactions for that merchant — all fetched live from the API
  • Cash Flow Tab: Month-by-month income vs. expenses grouped bar chart, net cash flow line chart, best/worst month callouts, and a running balance trend
  • Budget Health Tab: Circular health score gauge, per-budget utilization bars with color-coded status (green/amber/red), and overall spend vs. budget summary
  • Savings Tab: Goal progress visualization with contribution history and deadline proximity indicators
  • AI Insights Tab: Gemini-powered spending pattern analysis, budget recommendations, and savings velocity commentary generated from your real data
  • Analytics CSV Export: One-click multi-section export covering Categories, Merchants, Cash Flow, and Budget Health in a single timestamped CSV file
  • Page Refresh: Manual refresh button on the Analytics header to re-fetch all data without a full page reload

Budget Management

  • Category Budget Limits: Set monthly spending limits per category (Food & Drink, Shops, Travel, Service, Recreation, Transfer, Payment)
  • Live Progress Bars: Each budget card shows a real-time fill bar — indigo at normal, amber at 80% utilization, and red when the limit is exceeded — with exact $spent / $limit amounts
  • Budget Keyword Search: Filter your budget list in real time with a search field — useful when managing many categories at once
  • Animated Budget Utilization Dial: SVG circular dial on the Dashboard overview showing total spend across all budgets as a percentage of total budget limits, color-coded by utilization level
  • Over-Budget Alert Banner: A red warning banner appears on the Dashboard whenever any category exceeds its limit — links directly to the Budget Health analytics tab
  • Budget Deletion: Remove any budget limit with a single button, with instant UI update

Savings Goals

  • Goal Creation: Define savings goals with a name, target amount, optional starting balance, and an optional target date
  • Contribution Tracking: Inline contribution form on each goal card — enter an amount and it accumulates toward the target
  • Visual Progress Bars: Animated progress indicators showing exact percentage completion for each goal
  • Savings Goal Alerts: Automatic status banners inside the Savings Goals widget — ⚠ red banner for goals past their target date that aren't complete, 🎯 green banner for goals that have reached ≥80% completion — no configuration required
  • Goal Deletion: Remove goals cleanly with cascade-safe database deletes

Transaction Tools

  • Manual Transaction Logging: Add cash expenses and off-platform spending via the + Add Transaction modal — supports amount, description, merchant, category, and date — immediately reflected in charts and AI context
  • Inline Category Editing: Click the ✏ pencil icon on any transaction row to edit its category in-place — changes are saved to the backend via PATCH /api/transactions/:id and reflected immediately in charts
  • Transaction Notes: Transactions support an optional freeform notes field for personal annotations
  • Date Range Filter: Filter your transaction list by a From/To date range using native date inputs — a "Clear dates ×" button resets the filter instantly
  • Min/Max Amount Filter: Narrow the transaction list to a specific spending band using minimum and maximum dollar inputs
  • Category Filter: Dropdown filter to show only transactions in a specific spending category
  • Free-Text Search: Search across merchant names and transaction descriptions in real time
  • Paginated History: Full transaction history with configurable page size, previous/next navigation, and live total count
  • Manual Transaction Deletion: Remove manually-logged entries; Plaid-synced transactions are protected from manual deletion
  • CSV Export: Download the full filtered transaction list as a CSV file — no server roundtrip required

UX & Navigation

  • Keyboard Shortcuts: Global keyboard shortcuts for power users — D jumps to Dashboard, A to Analytics, I to Investments, C to Chat — implemented as a reusable useKeyboardShortcuts hook
  • Mobile Bottom Navigation: Floating bottom nav bar for mobile screens on Dashboard, Analytics, Investments, and Chat pages — smooth transitions between routes with active state highlighting
  • Back to Dashboard Link: Chat page header includes a ← Back to Dashboard shortcut for quick navigation
  • Theme Preset Selector: Four built-in color themes — Indigo (default), Emerald, Sunset, and Slate — selectable in the Settings modal and persisted to localStorage via CSS custom property injection

Account Management

  • Linked Accounts Widget: Real-time balance display for every connected bank account — checking, savings, and credit cards — with account type badges and institution names
  • Net Worth Banner: Welcome header shows total net worth (assets minus liabilities) alongside a greeting and quick-action buttons
  • Plaid Connection Manager: View all connected banks from the Settings modal and disconnect any item — revokes the Plaid access token via item/remove and deletes the encrypted credentials from the database
  • Profile & Security Settings: Change email address or password directly from the Settings modal — password changes validate the current password before hashing and storing the new one with bcrypt
  • Theme Settings Tab: Dedicated theme selector in the Settings modal with visual preview swatches for all four presets

Subscriptions & Recurring Bills

  • Automatic Subscription Detection: Server-side algorithm scans transaction history for recurring patterns — same merchant, similar amounts, monthly intervals — and surfaces them as detected subscriptions
  • Subscriptions Card: Dedicated sidebar widget listing detected recurring bills with estimated monthly cost totals and next billing date projections
  • Zero Configuration: Detection runs on-demand from existing transaction data — no user tagging or manual input required

Infrastructure

  • Encrypted Credential Storage: All Plaid access tokens are AES-256-CBC encrypted using a 32-byte hex key before being written to the database — the raw token never touches disk
  • Daily Transaction Sync Cron: Automated node-cron job runs at 2:00 AM every night — iterates all Plaid items and runs a full cursor-based sync for each, keeping data fresh without user action
  • Promise.allSettled Fetching: Dashboard data loading uses Promise.allSettled so a single failing endpoint never silently breaks unrelated widgets — each panel degrades independently
  • Resilient Balance Fallback: If a Plaid sandbox call fails or no accounts are connected, the balance endpoint returns realistic mock data so the UI never shows blank states during development
  • Spending Velocity API: Dedicated /api/analytics/velocity route computing this-week vs. last-week spending totals and transaction counts, with an accelerating boolean and percentage change

Tech Stack

Backend

  • Node.js with Express.js
  • PostgreSQL for persistent storage (users, transactions, budgets, savings goals, chat history)
  • JWT for authentication via HTTP-only cookies
  • bcrypt for password hashing
  • Google Gemini AI (gemini-2.0-flash) for conversational responses and native Function Calling (tool execution)
  • Plaid Node SDK for bank linking, transaction sync, and account balance retrieval
  • AES-256-CBC encryption via Node.js crypto module for access token security
  • node-cron for scheduled daily transaction sync (runs at 2:00 AM)
  • dotenv for environment variable management

Frontend

  • React 18 with Vite for fast development and optimized production builds
  • React Router v6 for client-side navigation
  • Axios for API requests with a base URL proxy configuration
  • Recharts for all charts — Area, Bar, Line, Pie, RadialBar — across Dashboard and Analytics pages
  • Lucide React for consistent iconography
  • React Icons (react-icons/fa) for analytics tab icons and date picker controls
  • Tailwind CSS for all styling — glassmorphic dark-mode design system with HSL-tuned color palette, CSS custom property theming, gradient accents, and micro-animations
  • Custom Component Library: CustomDatePicker, CustomSelectDropdown, PlaidLink, SettingsModal, TransactionList, MobileBottomNav, MerchantModal — all built in-house with zero UI framework dependency

Database Schema

  • users — UUID primary key, email, bcrypt password hash, created timestamp
  • plaid_items — encrypted access token, item ID, institution name, sync cursor, last synced timestamp
  • transactions — Plaid transaction ID, amount, category, subcategory, merchant name, description, notes, date, pending flag, manual flag
  • chat_messages — user ID, role (user / assistant), content, created timestamp
  • budgets — user ID + category unique constraint, limit amount
  • savings_goals — name, target amount, current amount, optional target date
  • holdings — manual investment positions with user ID, symbol, quantity, cost basis, source, acquired date
  • price_cache — cached asset prices with ticker symbol, latest price, updated timestamp (15-min TTL)
  • portfolio_history — daily snapshot records with user ID, date, total portfolio market value, and total cost basis

System Architecture

The system follows a modern full-stack architecture with a clean separation between the React client and Express API server, with Plaid and Google Gemini as external service dependencies.

graph TD
    subgraph Client ["Frontend (React/Vite)"]
        UI["UI Components (Tailwind CSS + CSS Themes)"]
        Pages["Pages (Dashboard, Analytics, Chat, Login, Signup)"]
        Charts["Charts (Recharts — Area, Bar, Line, Pie, Radial)"]
        Modals["Modals (MerchantModal, SettingsModal, AddTx)"]
        Nav["MobileBottomNav + Keyboard Shortcuts"]
    end

    subgraph Server ["Backend (Node.js/Express)"]
        Auth["Auth Routes (JWT/bcrypt)"]
        TxRoutes["Transaction Routes (sync, CRUD, PATCH, filters)"]
        AnalyticsRoutes["Analytics Routes (overview, monthly, velocity, merchant-detail, cashflow, budget-health)"]
        BudgetRoutes["Budget Routes"]
        SavingsRoutes["Savings Routes"]
        SubRoutes["Subscription Detection"]
        ChatRoutes["Chat Routes"]
        PlaidRoutes["Plaid Routes (link, exchange, balances, disconnect)"]
        Cron["Daily Sync Cron (2:00 AM)"]
        Crypto["AES-256 Crypto Service"]
    end

    subgraph External ["External Services"]
        PlaidAPI["Plaid API (Sandbox/Production)"]
        GeminiAI["Google Gemini AI (Function Calling)"]
        DB[(PostgreSQL Database)]
    end

    UI --> Pages
    Pages --> Charts
    Pages --> Modals
    Pages --> Nav
    Pages --> Auth
    Pages --> TxRoutes
    Pages --> AnalyticsRoutes
    Pages --> BudgetRoutes
    Pages --> SavingsRoutes
    Pages --> SubRoutes
    Pages --> ChatRoutes
    Pages --> PlaidRoutes
    Auth --> DB
    TxRoutes --> DB
    TxRoutes --> PlaidAPI
    AnalyticsRoutes --> DB
    BudgetRoutes --> DB
    SavingsRoutes --> DB
    SubRoutes --> DB
    ChatRoutes --> GeminiAI
    ChatRoutes --> DB
    PlaidRoutes --> PlaidAPI
    PlaidRoutes --> Crypto
    Crypto --> DB
    Cron --> PlaidAPI
    Cron --> DB
Loading

Module Dependency

graph LR
    subgraph BE ["Backend Module Flow"]
        AuthMod[Auth Module] --> TxMod[Transaction Module]
        AuthMod --> PlaidMod[Plaid Module]
        PlaidMod --> CryptoSvc[Crypto Service]
        TxMod --> SummaryAPI["Summary & Analytics Routes"]
        AnalyticsMod[Analytics Module] --> VelocityAPI[Velocity API]
        AnalyticsMod --> MerchantAPI[Merchant Detail API]
        TxMod --> CronJob[Daily Sync Cron]
        ChatMod[Chat Module] --> GeminiSvc[Gemini Function Calling]
        GeminiSvc --> BudgetMod[Budget Module]
        GeminiSvc --> TxMod
        BudgetMod --> DB[(PostgreSQL)]
        SavingsMod[Savings Module] --> DB
        SubMod[Subscription Detector] --> DB
    end

    subgraph FE ["Frontend Module Flow"]
        App[App Router] --> DashPage[Dashboard Page]
        App --> AnalyticsPage[Analytics Page]
        App --> ChatPage[Chat Page]
        DashPage --> StatCards[Stat Cards]
        DashPage --> VelocityBanner[Spending Velocity Banner]
        DashPage --> ForecastBanner[End-of-Month Forecast]
        DashPage --> UtilDial[Budget Utilization Dial]
        DashPage --> MoMWidget["Month-over-Month Widget"]
        DashPage --> BudgetCards[Budget Progress Cards]
        DashPage --> SavingsAlerts[Savings Goal Alerts]
        DashPage --> SubCard[Subscriptions Card]
        DashPage --> TxList[Transaction List]
        DashPage --> SettingsModal[Settings Modal]
        AnalyticsPage --> OverviewTab[Overview Tab]
        AnalyticsPage --> SpendingTab[Spending Tab]
        SpendingTab --> MerchantModal[Merchant Deep-Dive Modal]
        AnalyticsPage --> CashFlowTab[Cash Flow Tab]
        AnalyticsPage --> BudgetHealthTab[Budget Health Tab]
        AnalyticsPage --> SavingsTab[Savings Tab]
        AnalyticsPage --> AIInsightsTab[AI Insights Tab]
        ChatPage --> AIChat[AI Chat Window]
        AIChat --> SuggestedChips[Suggested Prompt Chips]
    end
Loading

Project Structure

personal-finance-chatbot/
├── backend/                        # Node.js/Express API server
│   ├── src/
│   │   ├── config/
│   │   │   ├── db.js               # PostgreSQL connection pool (pg)
│   │   │   └── plaidClient.js      # Plaid SDK client initialization
│   │   ├── cron/
│   │   │   └── syncTransactions.js # Daily 2 AM transaction sync for all Plaid items
│   │   ├── db/
│   │   │   └── schema.sql          # Full PostgreSQL schema (auto-run on server start)
│   │   ├── middleware/
│   │   │   └── auth.js             # JWT verification middleware
│   │   ├── routes/
│   │   │   ├── analytics.js        # GET /overview, /monthly, /categories, /merchants, /cashflow, /budget-health, /savings-projection, /day-of-week, /velocity, /merchant-detail
│   │   │   ├── auth.js             # POST /register, /login, /logout, /me, /change-password, /change-email
│   │   │   ├── budgets.js          # GET/POST/DELETE /api/budgets
│   │   │   ├── chat.js             # POST /api/chat, DELETE /api/chat/history
│   │   │   ├── plaid.js            # POST /create-link-token, /exchange-token, GET /items, /balances, DELETE /items/:id
│   │   │   ├── savings.js          # GET/POST/PUT/DELETE /api/savings
│   │   │   ├── subscriptions.js    # GET /api/subscriptions (auto-detection algorithm)
│   │   │   └── transactions.js     # GET /, /summary, /by-category, /daily-trend, /monthly-compare, POST /, PATCH /:id, DELETE /:id, POST /sync
│   │   ├── services/
│   │   │   ├── chatService.js      # Gemini chat orchestration with Function Calling tools
│   │   │   └── cryptoService.js    # AES-256-CBC encrypt/decrypt for Plaid access tokens
│   │   └── server.js               # Express app, middleware, route mounting, DB init, cron bootstrap
│   ├── .env                        # DATABASE_URL, JWT_SECRET, ENCRYPTION_KEY, PLAID_*, GEMINI_API_KEY
│   └── package.json
├── frontend/                       # React 18 + Vite client
│   ├── src/
│   │   ├── components/
│   │   │   ├── charts/
│   │   │   │   ├── CategoryBarChart.jsx    # Recharts horizontal bar chart by spending category
│   │   │   │   └── SpendingLineChart.jsx   # Recharts cumulative area chart with gradient fill
│   │   │   ├── export/
│   │   │   │   └── ExportButton.jsx        # Multi-section Analytics CSV export
│   │   │   ├── CustomDatePicker.jsx        # Fully custom accessible calendar with month navigation
│   │   │   ├── CustomSelectDropdown.jsx    # Animated dropdown replacing native select
│   │   │   ├── MobileBottomNav.jsx         # Floating bottom nav bar for mobile screens
│   │   │   ├── PlaidLink.jsx               # Plaid Link widget integration with token exchange
│   │   │   ├── ProtectedRoute.jsx          # Auth guard redirecting unauthenticated users
│   │   │   ├── SettingsModal.jsx           # Email/password change + Plaid disconnect + theme selector
│   │   │   └── TransactionList.jsx         # Paginated list with search, date range, amount filters, inline edit, CSV export
│   │   ├── contexts/
│   │   │   └── AuthContext.jsx             # JWT user state provider with login/logout helpers
│   │   ├── hooks/
│   │   │   └── useKeyboardShortcuts.js     # Global D/A/C keyboard navigation shortcuts
│   │   ├── pages/
│   │   │   ├── Analytics.jsx               # 6-tab analytics suite with MerchantModal
│   │   │   ├── Chat.jsx                    # AI chat interface with suggested prompt chips and clear history
│   │   │   ├── Dashboard.jsx               # Main financial dashboard (overview + transactions + savings + subscriptions tabs)
│   │   │   ├── Login.jsx                   # Login form with JWT cookie auth
│   │   │   └── Signup.jsx                  # Registration form with validation
│   │   ├── App.jsx                         # React Router route definitions
│   │   ├── index.css                       # Global Tailwind base styles + CSS custom property theme variables
│   │   └── main.jsx                        # Theme initialization from localStorage on app boot
│   ├── .env                                # VITE_API_URL
│   └── package.json
└── README.md

API Reference

Authentication — /api/auth

  • POST /api/auth/register — Create a new account with email and password (bcrypt hashed).
  • POST /api/auth/login — Authenticate and receive an HTTP-only JWT cookie.
  • POST /api/auth/logout — Clear the auth cookie.
  • GET /api/auth/me — Return the authenticated user profile.
  • POST /api/auth/change-email — Update account email (requires current password verification).
  • POST /api/auth/change-password — Update password (validates current password, re-hashes new one with bcrypt).

Transactions — /api/transactions

  • POST /api/transactions/sync — Trigger an on-demand Plaid transactionsSync for all linked items. Returns added/modified/removed counts.
  • GET /api/transactions — Fetch paginated transactions with optional start_date, end_date, category, search, min_amount, max_amount, page, and limit filters.
  • GET /api/transactions/summary — Aggregated totals, top merchants, and daily spending for a date range.
  • GET /api/transactions/by-category — Current month spending grouped and sorted by category.
  • GET /api/transactions/daily-trend — Daily spending totals for the current month for the area chart.
  • GET /api/transactions/monthly-compare — Category-level and total spending for current vs. previous month, with diff and pct fields per category.
  • POST /api/transactions — Log a manual transaction (amount, name, category, merchant, date).
  • PATCH /api/transactions/:id — Update a transaction's category and/or notes field.
  • DELETE /api/transactions/:id — Delete a manual transaction only; Plaid-synced entries are protected.

Investments — /api/investments

  • GET /api/investments/holdings — Fetch all manual positions enriched with real-time market prices, allocations, and unrealized gain/loss metrics.
  • POST /api/investments/holdings — Add a new manual holding (ticker symbol, quantity, average cost basis, optional acquired date).
  • PATCH /api/investments/holdings/:id — Update holding quantity, cost basis, or acquisition date.
  • DELETE /api/investments/holdings/:id — Remove a holding position from the user's portfolio.
  • GET /api/investments/summary — Aggregated portfolio statistics (total value, total cost, total gain/loss %, allocation breakdown, and historical daily valuation snapshots).

Budgets — /api/budgets

  • GET /api/budgets — List all budget limits for the authenticated user.
  • POST /api/budgets — Create or update a budget limit for a category (upsert on user_id + category).
  • DELETE /api/budgets/:id — Remove a budget limit.

Savings Goals — /api/savings

  • GET /api/savings — List all savings goals.
  • POST /api/savings — Create a new savings goal (name, target amount, current amount, optional target date).
  • PUT /api/savings/:id — Update a savings goal's current amount (used by the contribution flow).
  • DELETE /api/savings/:id — Delete a savings goal.

Subscriptions

  • GET /api/subscriptions — Run the recurring transaction detection algorithm and return detected subscription entries with estimated monthly cost and next billing date.

AI Chat — /api/chat

  • POST /api/chat — Send a user message. The service fetches full financial context, builds a Gemini prompt with Function Calling tools, and returns a response. If Gemini invokes createBudget or logTransaction, the server executes the database write before returning the final text reply.
  • DELETE /api/chat/history — Permanently delete all stored chat messages for the authenticated user.

Analytics — /api/analytics

  • GET /api/analytics/overview — Monthly stat cards: total spent, avg daily, biggest transaction, unique merchants, and top spending day (date + total).
  • GET /api/analytics/monthly — Last 12 months of spending totals for the trend chart.
  • GET /api/analytics/categories — Current month spending by category with MoM comparison percentages.
  • GET /api/analytics/merchants — Top merchants ranked by spend, with category and transaction count.
  • GET /api/analytics/cashflow — Month-by-month income vs. expenses with net flow and running balance.
  • GET /api/analytics/budget-health — Per-budget utilization, health score (0–100), and overall spend vs. limit.
  • GET /api/analytics/savings-projection — Projected savings goal completion dates based on contribution rate.
  • GET /api/analytics/day-of-week — Average spend and transaction count per weekday over the last 90 days.
  • GET /api/analytics/velocity — This week vs. last week spending totals and transaction counts, with accelerating boolean and pct change.
  • GET /api/analytics/merchant-detail?name=... — 6-month monthly spend trend and 10 most recent transactions for a specific merchant.

Plaid — /api/plaid

  • POST /api/plaid/create-link-token — Generate a short-lived Plaid Link token for the frontend widget.
  • POST /api/plaid/exchange-token — Exchange a one-time public_token for a permanent access_token (AES-256 encrypted before storage).
  • GET /api/plaid/items — List all connected bank items for the current user.
  • GET /api/plaid/balances — Fetch real-time account balances from Plaid. Returns mock data gracefully if no items are connected.
  • DELETE /api/plaid/items/:itemId — Call Plaid item/remove, revoke the access token, and delete the item from the database.

Features in Detail

AI Chat & Function Calling

The chat service builds a complete financial context window before every Gemini API call. It queries the user's last 50 transactions, all active budgets, savings goals, and Plaid account balances, then injects a structured system prompt that grounds every answer in real data. The model is configured with two tool declarations:

createBudget accepts category and limit_amount. When the user says something like "Set a $200 budget for groceries," Gemini invokes the tool with the parsed arguments and the server creates or updates the budget row, then confirms it in the reply.

logTransaction accepts amount, name, category, merchant_name, and date. When the user says "I spent $45 on gas at Shell today," Gemini extracts and structures the fields, the server inserts the manual transaction, and the assistant acknowledges it naturally.

Both tools execute database writes on the server before the final response is sent — the user sees a single, coherent conversational reply that reflects the action already taken.

Analytics Suite

The Analytics page is a standalone route (/analytics) with six tabs, each powered by dedicated API endpoints. All data fetches use Promise.allSettled so a single failing endpoint never breaks an adjacent tab. The Overview tab fetches the month's top spending day directly from a SQL ORDER BY daily_total DESC LIMIT 1 query and displays it alongside the standard KPI cards.

The Merchant Deep-Dive Modal opens when any merchant row is clicked in the Spending tab. It fires a live request to /api/analytics/merchant-detail?name=... which runs two parallel queries: a 6-month GROUP BY month aggregation and a ORDER BY date DESC LIMIT 10 recent transactions fetch. The modal renders an inline Recharts bar chart and a scrollable transaction list, all inside a backdrop-blurred overlay.

Spending Velocity

The /api/analytics/velocity route computes two ISO week ranges — the current week (Monday–today) and the previous full week — and runs two SUM(amount) aggregations. The response includes this_week.total, last_week.total, transaction counts for both, and an accelerating: boolean flag. The Dashboard banner renders this as a compact row widget with ▲/▼ indicators, showing at a glance whether spending is ramping up or slowing down.

Savings Goal Alerts

The savings goal widget on the Dashboard computes two alert sets client-side before rendering the goal list: goals whose target_date is in the past and whose current_amount / target_amount < 100% (overdue), and goals where the completion percentage is ≥80% but < 100% (near-complete). Both alert types render as pill banners above the goal list with emoji icons and natural-language descriptions — no backend endpoint needed since all data is already fetched.

Month-over-Month Comparison

The /api/transactions/monthly-compare endpoint computes two separate date ranges — the current calendar month and the immediately preceding month — and runs parallel GROUP BY category queries for both. It builds a unified category list, computes per-category diff and pct change values, and returns a summary object with overall totals.

The frontend renders a summary banner showing last month's total, the delta amount, and this month's total. Below it, each detected category gets a card with two 1.5px progress bars — indigo for the current month, gray for the previous — scaled proportionally to the larger of the two values. Change badges are green for decreases and red for increases.

Theme System

Four color themes are available — Indigo (default), Emerald, Sunset, and Slate — implemented as CSS custom property overrides on :root. Selecting a theme in the Settings modal updates --color-primary, --color-primary-light, --color-primary-dark, and --color-accent. The selected theme is written to localStorage as finai-theme and re-applied on every page load via an initialization script in main.jsx, so the theme persists across sessions and page refreshes with no flash of unstyled content.

Subscription Detection

The detection algorithm queries the last 90 days of transactions and groups them by merchant name. A merchant is flagged as a subscription if it appears at least twice, the amounts are within 10% of each other (allowing for minor billing fluctuations), and the average interval between charges is between 25 and 40 days. The algorithm estimates the next billing date by projecting the average interval forward from the last charge date.

Encrypted Token Storage

Every Plaid access_token is encrypted with AES-256-CBC before being written to the database. The encryption key is a 32-byte (64-character hex) secret loaded from the ENCRYPTION_KEY environment variable. The cryptoService.js generates a fresh random 16-byte IV for every encryption operation and prepends it to the ciphertext, so no two encrypted tokens are identical even for the same input. Decryption extracts the IV from the first 32 hex characters before deciphering.

Daily Transaction Sync

The initTransactionCron function registers a node-cron schedule for 0 2 * * * (2:00 AM daily). On each trigger it queries all plaid_items rows, decrypts each access token, and runs a full cursor-based transactionsSync call for each item. Added and modified transactions are upserted; removed transactions are hard-deleted. Each item's cursor is updated atomically. Errors on individual items are caught and logged without aborting the rest of the batch.

Environment Variables

Backend (backend/.env)

DATABASE_URL=postgresql://user:password@localhost:5432/finai
JWT_SECRET=your-jwt-secret-min-32-chars
ENCRYPTION_KEY=64-char-hex-string-for-aes256
PLAID_CLIENT_ID=your-plaid-client-id
PLAID_SECRET=your-plaid-sandbox-secret
PLAID_ENV=sandbox
GEMINI_API_KEY=your-google-gemini-api-key
PORT=5000

# Optional: Twelve Data API key for live market prices (free tier: 800 req/day)
# If omitted, Yahoo Finance public endpoints are used automatically with zero setup
TWELVE_DATA_API_KEY=your_twelve_data_api_key_here

Generate a secure encryption key:

openssl rand -hex 32

Frontend (frontend/.env)

VITE_API_URL=http://localhost:5000

Getting Started

Prerequisites

  • Node.js 18+
  • PostgreSQL 14+
  • A Plaid developer account (free Sandbox tier)
  • A Google AI Studio API key for Gemini

Installation

  1. Clone the repository

    git clone https://github.com/Giancyril/FinBot.git
    cd FinBot
  2. Install dependencies

    npm install
    cd backend && npm install
    cd ../frontend && npm install
  3. Configure environment variables — fill in backend/.env and frontend/.env as shown above

  4. Start both servers

    npm run dev
    • Backend API: http://localhost:5000
    • Frontend: http://localhost:5174

The backend auto-creates all database tables on first boot via schema.sql — no manual migration step required.

Connecting a Test Bank (Plaid Sandbox)

  1. Click Connect Bank on the Dashboard
  2. Search for any institution (e.g., Chase) in the Plaid Link widget
  3. Use credentials user_good / pass_good
  4. Click Sync Transactions — your transaction history will be imported immediately

Security Notes

  • Plaid access tokens are never logged or stored in plaintext — only AES-256-CBC ciphertext reaches the database
  • JWT tokens are stored in HTTP-only cookies — inaccessible to JavaScript and immune to XSS token theft
  • Password changes require the current password to be validated before the new hash is stored
  • The ENCRYPTION_KEY must be exactly 64 hex characters (32 bytes) — the server performs a length check on startup and exits with a FATAL error if misconfigured
  • Plaid item disconnection calls Plaid item/remove first to revoke the token at the source before deleting the local record

About

AI-powered personal finance chatbot with Plaid bank sync, Google Gemini Function Calling (create budgets & log transactions via chat), spending analytics, month-over-month comparisons, savings goals, subscription detection & AES-256 encrypted token storage. Built with React, Node.js & PostgreSQL.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages