Vedant Misra
Velocity / FinAssist
mlWorking MVP / prototype

Velocity / FinAssist

Personal Finance Dashboard - Plaid, Supabase, FastAPI, and Tool-Grounded AI

Turned raw connected-account data into a product workflow for balances, budgets, goals, and conversational financial insight.

Role

Primary full-stack implementer across frontend, backend, data model, sync, and AI workflows

Timeline

2026

Context

Personal finance product build

Architecture

React + FastAPI + Supabase

Focus

Fintech data workflows and AI UX

Plaid

Bank Connectivity

Secure token exchange

DB-first

Dashboard Reads

Supabase-backed sync

AI

FinAssist

Tool-grounded answers

ReactFastAPISupabasePostgreSQLPlaidDedalusMCPAI AssistantFintech

Overview

Velocity is a full-stack personal finance dashboard built around a simple product idea: connected bank data is only useful when it becomes a workflow. The application combines Supabase authentication, Plaid bank linking, account and transaction sync, category budgeting, savings-goal tracking, and an AI assistant called FinAssist that answers financial questions with tool calls against stored user data.

The strongest engineering story in this project is the system evolution. It started as a React dashboard with a server-mediated Plaid flow, then moved toward a more durable database-first architecture with FastAPI, Supabase Postgres, background synchronization, and typed domain APIs. That shift turned the app from "call Plaid whenever the dashboard loads" into a local financial data platform that can support charts, budgets, goals, and grounded AI responses from the same stored source of truth.

Problem and Motivation

Most personal finance tools show balances and transactions, but the hard part is helping users understand what those numbers mean. A useful dashboard has to connect several concerns at once:

  • Authenticate users without leaking financial credentials.
  • Connect external banks without exposing Plaid secrets in the browser.
  • Normalize account and transaction data into an internal model.
  • Show spending, budgets, and savings progress in one place.
  • Let users ask natural-language questions without the AI hallucinating financial facts.

Velocity was built to solve that full product loop. The dashboard gives users visibility into accounts and spending, while FinAssist turns the same underlying data into conversational analysis: spending summaries, recent transaction lookups, budget status, and savings suggestions grounded in real records.

Product Scope

The implemented product surface spans four user-facing areas:

  • Connected accounts: users authenticate, link institutions with Plaid Link, and view accounts, balances, institutions, and recent transactions.
  • Spending analysis: users inspect transaction history, category breakdowns, debits, income, and filtered spending patterns.
  • Budgeting: users create monthly category budgets, track progress, and see remaining or over-budget states.
  • Goals: users define savings goals with targets, weights, colors, target dates, contribution history, and progress visualizations.
  • FinAssist: users open a chat drawer and ask financial questions answered through backend tools instead of freeform model guesses.

The system is best described as a working MVP. It demonstrates end-to-end functionality and a serious architecture, while leaving production hardening items such as token encryption at rest, rate limiting, secret rotation, and deeper monitoring as future work.

System Architecture

The current architecture is organized around a React frontend, a FastAPI backend, Supabase Auth/Postgres, Plaid, and a Dedalus-powered AI workflow.

System Architecture Diagram

  • User
    • Interacts with React dashboard
      • Supabase Auth session
      • Plaid Link bank connection
      • FinAssist chat drawer
    • Makes API requests to FastAPI backend
      • Verifies Supabase JWT
      • Exposes dashboard, budget, goal, sync, and chat APIs
      • Schedules Plaid sync work
    • Reads/Writes to Supabase Postgres
      • plaid_items, accounts, transactions
      • categories, budgets, goals, goal_contributions
  • FinAssist
    • Calls Dedalus LLM + local financial tools
      • spending summary, recent transactions
      • budget status, savings insights

This shape keeps the browser away from Plaid secrets and service credentials. The frontend sends authenticated requests, the backend validates the Supabase token, and Plaid access tokens stay on the server side.

Key Engineering Decisions

Database-first dashboard reads

The most important architectural change was moving dashboard reads away from live Plaid calls. Early versions queried Plaid directly when loading dashboard data. That is simple, but it couples page performance to an external API and makes historical analysis harder.

The later FastAPI path syncs Plaid accounts and transactions into Supabase first, then serves dashboard data from the local database. This added complexity - sync cursors, category mapping, cleanup, and bulk upserts - but it made the product much more flexible. Budgets, goals, category rollups, and AI tools can all query the same local model.

FastAPI alongside the original Express path

The repository contains both an earlier Express backend and a richer FastAPI backend. The Express path handled the initial secure Plaid integration: create link token, exchange public token, fetch dashboard data, and remove banks. The FastAPI path expands the domain model with budgets, goals, contributions, sync, and chat.

This overlap reflects real iteration. The project kept frontend compatibility while shifting toward typed Python services and a broader data model. The tradeoff is that the repository has two backend generations, so the canonical runtime path needs clear documentation.

Tool-calling AI instead of freeform finance chat

FinAssist is not just a chatbot layered on top of static prompt text. It uses local tool functions to answer questions from stored financial data. For example, when a user asks about spending or budgets, the assistant can call backend functions that retrieve summaries, inspect recent transactions, evaluate budget status, or generate savings recommendations.

That design matters because personal finance is a high-trust domain. The AI should not invent numbers. Tool calls make the assistant more grounded and inspectable, even though they introduce orchestration complexity and a stronger dependency on tool schemas.

Data Flow

Bank connection

  1. The frontend requests a Plaid link token from the backend.
  2. The backend verifies the Supabase JWT and calls Plaid.
  3. The user completes Plaid Link in the browser.
  4. The frontend receives a public token and sends it to the backend.
  5. The backend exchanges the public token for an access token.
  6. Plaid item metadata and access credentials are stored server-side.
  7. A background sync imports accounts and transactions into Supabase.

Dashboard rendering

  1. The authenticated user opens the dashboard.
  2. The frontend calls the dashboard API with the Supabase bearer token.
  3. FastAPI verifies the user and reads local account, transaction, category, and institution data.
  4. The backend returns dashboard-ready aggregates.
  5. The frontend renders balances, recent transactions, category charts, budgets, and goals.

FinAssist chat

  1. The user sends a chat message from the dashboard drawer.
  2. The backend injects user context and the financial-assistant system prompt.
  3. Dedalus calls the model with financial tool definitions.
  4. If the model requests a tool, the backend executes the mapped Python function against Supabase-backed data.
  5. Tool outputs are appended to the conversation.
  6. The model synthesizes a final answer from retrieved data rather than guessing.

Core Features

Authentication and protected routes

Velocity uses Supabase Auth for sign-up, sign-in, session handling, password reset, and route protection. Auth state is centralized in the frontend so dashboard routes, spending pages, budgets, goals, and profile views stay behind a user session.

Plaid integration

The bank-linking flow is server-mediated. The backend creates Plaid link tokens, exchanges public tokens, stores item metadata, and later removes connected banks with associated cleanup. The important security property is that Plaid secrets and access tokens are not exposed directly to the browser.

Plaid-to-Supabase sync

The sync layer imports accounts and transactions into internal tables. It maps Plaid categories into application categories, stores Plaid metadata, supports bulk upserts, and tracks sync cursors for incremental updates. This is the layer that unlocks faster dashboard reads and historical product features.

Budgeting workflow

Users can create, update, delete, and inspect monthly category budgets. The database enforces uniqueness per user, category, and month, while the UI calculates progress, remaining spend, and over-budget indicators.

Savings goals

The goals system lets users define targets, current amounts, weights, colors, icons, optional dates, and descriptions. Contributions are stored separately so the UI can render progress and time-series views rather than a single static number.

FinAssist

FinAssist connects the product's UI and data model to an AI workflow. It supports financial Q&A through local tools such as spending summaries, recent transactions, budget checks, and savings insights. This makes the assistant feel like part of the product instead of a generic chatbot.

Implementation Details

The frontend is a React application adapted from a dashboard template into a finance-specific product. It uses protected routes, dashboard layouts, context providers, service clients, and charting components for account, budget, spending, and goal views.

The backend service boundaries are organized around:

  • auth.py for Supabase JWT verification.
  • database.py for CRUD and query operations against Supabase.
  • plaid_sync.py for account and transaction ingestion.
  • main.py for HTTP endpoints and background task coordination.
  • chat_service.py for Dedalus orchestration.
  • mcp_tools.py for model-callable financial analysis functions.

The storage model includes Plaid items, accounts, transactions, categories, budgets, goals, and goal contributions. Most reads and writes are scoped by user_id, and bulk upsert patterns are used for synced financial records.

Validation and Reliability

The project includes several practical validation paths:

  • setup verification scripts for the JavaScript and backend environments
  • health endpoints across backend services
  • manual quickstart and troubleshooting documents
  • Python test/demo scripts around chat, Dedalus integration, natural-language transactions, and Plaid webhook behavior in adjacent experimental services

The strongest reliability improvement is architectural rather than test-only: moving repeated dashboard reads to local database queries reduces dependence on live Plaid calls and gives the product more control over category aggregation, history, and AI retrieval.

Challenges and Tradeoffs

The hardest part of Velocity was not building one isolated feature. It was making several layers agree with each other: auth, Plaid, database schema, frontend state, sync jobs, charting, and AI tools.

Important tradeoffs included:

  • Speed versus hardening: the MVP implemented broad product functionality first, while items like token encryption at rest, robust rate limiting, and production monitoring remained future work.
  • Live API simplicity versus local data ownership: direct Plaid reads are easier to start with, but local sync supports better UX, history, budgeting, and AI features.
  • Template velocity versus custom product fit: adapting an existing dashboard accelerated UI work, but required careful conversion into finance-specific flows.
  • Tool-grounded AI versus simple chat: tool calling made answers more trustworthy, but increased backend orchestration complexity.

What This Demonstrates

Velocity demonstrates end-to-end product engineering across the full stack:

  • frontend product workflows for finance-specific tasks
  • secure backend integration with an external financial API
  • Postgres schema design for accounts, transactions, budgets, and goals
  • background data synchronization and incremental updates
  • typed Python APIs and service boundaries
  • AI integration with grounded tool calls
  • setup and troubleshooting documentation for a fast-moving codebase

It is a strong example of building beyond a demo. The project does not stop at connecting an API or rendering a dashboard; it builds the application layer needed to make financial data actionable.

Future Work

The next phase would focus on production confidence:

  • encrypt Plaid access tokens at rest and document secret rotation
  • add rate limiting and abuse protection around financial and chat endpoints
  • move long-running sync work to a dedicated worker or queue
  • add structured observability for sync failures and chat tool execution
  • clarify the canonical backend path and retire or document the legacy Express flow
  • evaluate FinAssist answers with deterministic test fixtures and traceable tool outputs

These improvements would make the system safer, more maintainable, and more suitable for real users while preserving the product direction already built in the MVP.