System Overview
Money Tracker is a full-stack application built with modern, serverless technologies. The architecture emphasizes real-time data processing, AI-powered extraction, and scalable infrastructure.Tech Stack Breakdown
Frontend
React with modern tooling:- React 19: Latest React with Server Components support (not used yet)
- React Router 7: File-based routing with data loading
- Bun: Fast JavaScript runtime and bundler (replaces Node.js + Webpack)
- TanStack Query: Server state management, caching, and synchronization
- Automatic background refetching
- Optimistic updates for better UX
- DevTools for debugging queries
- Tailwind CSS 4: Utility-first CSS framework
- Framer Motion: Animation library for smooth transitions
- Lucide React: Icon library
- Recharts: Charting library for financial visualizations
- Sonner: Toast notifications
- React Hook Form: Performant form handling
- Zod: TypeScript-first schema validation
- Used for both frontend forms and AI output validation
- Supports English and Spanish
- Automatic language detection from browser settings
- All UI strings are externalized in JSON files
Backend
Supabase provides the entire backend infrastructure:-
PostgreSQL Database
- Stores users, transactions, OAuth tokens, Gmail watches
- Row-Level Security (RLS) policies for data isolation
- Vault extension for encrypted secrets
- pg_cron for scheduled jobs (Gmail watch renewal)
-
Supabase Auth
- Email/password authentication
- User session management
- Automatic user record creation via database triggers
-
Edge Functions (Deno runtime)
auth-start: Initiates Gmail OAuth flowauth-callback: Handles OAuth redirectgmail-webhook: Processes real-time Gmail notificationsseed-emails: Imports historical emailsprocess-document: Extracts transactions from uploaded filesrenew-watches: Cron job to renew Gmail watches every 7 daysgmail-disconnect: Disconnects Gmail accounthealth: Health check endpoint
-
Realtime
- WebSocket subscriptions for live transaction updates
- Broadcasts database changes to connected clients
- Used for instant UI updates when new transactions arrive
AI Engine
xAI Grok with structured output:- Structured output using Zod schemas
- Vision API for image/PDF analysis
- Multi-modal extraction (text + images + PDFs)
- Handles various email formats and languages
- Traces every AI extraction call
- Monitors token usage, latency, and costs
- Debugging failed extractions
- Performance analytics
Integrations
Gmail API:users.messages.list: List messages matching a queryusers.messages.get: Fetch full message detailsusers.history.list: Get mailbox changes since a historyIdusers.watch: Set up push notifications for new emails
- Scopes requested:
https://www.googleapis.com/auth/gmail.readonly - Token storage: Encrypted in Supabase
- Automatic token refresh when expired
- Topic:
projects/{PROJECT_ID}/topics/gmail-notifications - Push subscription to Supabase Edge Function
- Delivers Gmail Watch notifications in real-time
Database Schema
Core Tables
usersRow-Level Security (RLS)
All tables have RLS policies to ensure users can only access their own data:Data Flow
Real-Time Email Processing
Gmail Watch notification
When a new email arrives in the user’s inbox, Gmail sends a notification to Google Pub/Sub.
Pub/Sub pushes to webhook
The Pub/Sub push subscription delivers the notification to the
gmail-webhook Edge Function:Fetch OAuth tokens
The function queries
user_oauth_tokens to find all active tokens for this Gmail account:Realtime broadcast
Supabase Realtime automatically broadcasts the new transaction to all connected clients subscribed to the
transactions table.Historical Email Import
User initiates seed
User clicks “Import Emails” in settings. Frontend calls the
seed-emails Edge Function:Auto-resume
After each chunk, the Edge Function invokes itself to process the next chunk:This continues until all emails are processed.
Document Upload
User uploads file
User selects a PDF or image receipt. The file is converted to base64 and sent to the
process-document Edge Function.Component Interaction
Frontend Architecture
Edge Functions Architecture
Deployment Architecture
Local Development
host.docker.internal to reach the Supabase stack.
Production (Example)
- Frontend: Deployed to Vercel, Netlify, or Railway
- Backend: Supabase Cloud (managed PostgreSQL, Auth, Edge Functions)
- Secrets: Stored in Supabase Edge Function secrets and Vault
- Gmail OAuth: Configured with production redirect URIs
- Pub/Sub: Google Cloud Pub/Sub with push subscription to production webhook URL
Performance Considerations
AI Extraction
- Batching: Process 10 emails concurrently during seed
- Chunking: Process 30 emails per batch to avoid timeouts
- Caching: Deduplicate emails using
source_message_idunique constraint - Fallback: Use keyword detection if AI extraction fails
Database Optimization
- Indexes: All foreign keys and frequently queried columns are indexed
- RLS: Row-Level Security policies filter data at the database level
- Realtime: Only broadcast changes to subscribed clients
Frontend Optimization
- Query caching: TanStack Query caches server data for 5 minutes
- Optimistic updates: UI updates immediately before server confirms
- Code splitting: React Router lazy-loads routes
- Bun: Fast bundling and hot reload during development
Security Model
Authentication Flow
- User signs up/logs in with email/password via Supabase Auth
- Supabase issues a JWT access token
- Frontend stores the token in localStorage
- All API requests include the token in the Authorization header
- Edge Functions verify the token with Supabase Auth
OAuth Token Management
- OAuth tokens are stored in
user_oauth_tokenstable - Access tokens expire after 1 hour
- Refresh tokens are used to get new access tokens
- If refresh fails, the connection is marked as inactive and the user is notified
- Tokens are encrypted at rest in Supabase
Data Isolation
- All tables have RLS policies that filter by
user_id - Edge Functions use the service role key to bypass RLS when needed
- User-provided JWT is validated before processing requests
- Gmail emails are never stored—only extracted transaction data
Monitoring and Observability
Langfuse Integration
All AI operations are traced:Logs
- Edge Functions: Console logs are available in Supabase Dashboard
- Frontend: Browser console in development; error tracking in production
- Database: Supabase provides query logs and slow query detection
Scaling Considerations
Current Limits
- Gmail API: 250 quota units/second (list messages = 5 units, get message = 5 units)
- Edge Functions: 2 GB RAM, 150-second timeout per invocation
- Supabase Realtime: 1000 concurrent connections per project
- xAI API: Rate limits depend on your plan
Scaling Strategies
- Batch processing: Process emails in chunks to avoid timeouts
- Queue-based architecture: Use a job queue for large imports
- Horizontal scaling: Edge Functions scale automatically with load
- Caching: Cache Gmail API responses to reduce API calls
- Rate limiting: Implement rate limiting for user-initiated actions
Next Steps
Deployment Guide
Learn how to deploy Money Tracker
Edge Functions
Explore the Edge Functions API