Product Requirements Document · v1.0
FinFlow — Personal Finance Manager
Hosted on Cloudflare Pages · Next.js 15 · TypeScript · Supabase
15 Core Features 4 Milestones AI-Powered OCR

Product summary

FinFlow is a SaaS personal finance manager that helps users track salary, allocate savings, manage bills and subscriptions, budget by category, and get AI-driven insights — all in a polished, mobile-first interface inspired by Monarch Money and Revolut.

Target users
Individuals
Deployment
CF Pages
Auth
Supabase

Core feature set

Dashboard
Monthly salary, income, expenses, savings, emergency fund, budget progress, upcoming bills, recent transactions with charts.
Salary & income
Manual entry or payslip upload. AI/OCR extracts employer, gross/net, tax, deductions, pay date — user confirms before saving.
Emergency fund
Auto-allocates 5% of salary monthly. Running balance, goal tracking, contribution history, editable percentage.
Savings goals
Auto-allocates 20% of salary. Multiple goals with name, target amount, target date, progress bars, history.
Bills & rent
Manual or uploaded. AI extracts company, amount, due date, billing period. Supports rent, utilities, insurance, custom.
Subscriptions
Popular presets (Netflix, Spotify, etc.) plus custom. Billing frequency, reminders, monthly spend total.
Budgets
Remaining balance after allocations distributed into categories. Percentage or fixed amount. Fully customisable.
Expenses
Manual or receipt upload. AI extracts merchant, date, total, suggests category. User reviews before saving.
AI insights
Spending trends, overspending alerts, savings forecasts, subscription suggestions, end-of-month predictions.
Reports
Monthly, yearly, budget, savings reports. Export to PDF, Excel, or CSV.

Allocation waterfall

Every month, salary flows through a fixed priority order before reaching discretionary budgets.

💰 Salary
🛡 Emergency 5%
🐷 Savings 20%
📄 Bills
🔄 Subscriptions
📊 Budget categories

End-of-month leftover

Remaining balance
60% → Savings
+
40% → Emergency

User-configurable percentages in settings.

Recommended tech stack

Cloudflare Pages hosts the Next.js frontend as a static export. API routes run as Cloudflare Workers (Edge Runtime). No Node.js server needed.

LayerChoiceReason
FrameworkNext.js 15App Router, RSC, Edge Runtime — compatible with CF Pages
LanguageTypeScriptType safety, better DX
StylingTailwind CSS v4Utility-first, small bundle
DatabasePostgreSQL via SupabaseRow-level security, realtime, auth built-in
ORMDrizzle ORMEdge-compatible (Prisma isn't for CF Workers)
AuthSupabase AuthSSO, magic link, email verify, RLS integration
File storageSupabase StoragePayslips, receipts, bill docs
OCR / AIAnthropic claude-3-5-haikuVision + JSON extraction for docs & receipts
AI insightsAnthropic claude-sonnetSpending analysis, forecasts
ChartsRechartsReact-native, composable, responsive
PDF export@react-pdf/rendererRuns on edge, typed React components
Excel/CSVxlsx (SheetJS)Lightweight, browser + edge support
EmailResendSimple API, great DX, CF-compatible
HostingCloudflare PagesGlobal CDN, free tier, Workers integration
CI/CDGitHub Actions → CF PagesAuto-deploy on push
MonitoringSentry + CF AnalyticsError tracking + edge analytics

Cloudflare Pages config

next.config.ts
Set output: 'export' for static export + @cloudflare/next-on-pages adapter for API routes as Workers. Use edge runtime on all API routes. Database connection via Supabase REST API (not direct pg connection — Workers don't support TCP).

Folder structure

finflow/ ├── app/ │ ├── (auth)/ # login, signup, forgot-pw │ ├── (app)/ # authenticated shell │ │ ├── dashboard/ │ │ ├── salary/ │ │ ├── emergency-fund/ │ │ ├── savings/ │ │ ├── bills/ │ │ ├── subscriptions/ │ │ ├── budgets/ │ │ ├── expenses/ │ │ ├── analytics/ │ │ ├── insights/ │ │ ├── reports/ │ │ └── settings/ │ └── api/ # edge API routes │ ├── ai/ │ ├── ocr/ │ └── export/ ├── components/ │ ├── ui/ # design system │ ├── charts/ │ ├── forms/ │ └── layout/ ├── lib/ │ ├── db/ # drizzle schema + queries │ ├── supabase/ │ ├── ai/ # anthropic client │ └── utils/ ├── types/ └── hooks/

Database schema

PostgreSQL via Supabase. All tables include created_at, updated_at. Row-level security enabled on every table keyed on user_id.

users

ColumnTypeNotes
iduuid PKSupabase auth.users reference
emailtext unique
full_nametext
avatar_urltext
currencytextdefault 'USD'
timezonetextdefault 'UTC'
budget_start_dayint1–28, default 1
emergency_pctnumericdefault 5.00
savings_pctnumericdefault 20.00
leftover_savings_pctnumericdefault 60.00
plantext'free' | 'pro'

salary_entries

ColumnTypeNotes
iduuid PK
user_iduuid FK→ users
pay_datedate
gross_paynumeric
net_paynumeric
taxnumeric
deductionsnumeric
bonusnumericdefault 0
overtimenumericdefault 0
employertext
sourcetext'manual' | 'payslip'
document_urltextSupabase Storage path
ai_extractedjsonbraw OCR output

savings_goals

ColumnTypeNotes
iduuid PK
user_iduuid FK
nametext
target_amountnumeric
target_datedatenullable
current_balancenumericdefault 0
icontextemoji or icon name
colortexthex
is_defaultboolreceives auto-allocation

bills

ColumnTypeNotes
iduuid PK
user_iduuid FK
nametexte.g. "Electricity"
companytext
amountnumeric
due_dayintday of month
categorytext'rent' | 'utility' | 'insurance' | 'custom'
is_activebooldefault true
document_urltextuploaded bill
reminder_daysintdays before due

subscriptions

ColumnTypeNotes
iduuid PK
user_iduuid FK
nametext
amountnumeric
billing_dayintday of month
frequencytext'monthly' | 'yearly' | 'weekly'
logo_urltextpreset logo or custom
colortext
reminder_enabledbooldefault true
is_activebooldefault true

budget_categories

ColumnTypeNotes
iduuid PK
user_iduuid FK
nametext
icontext
colortext
allocation_typetext'percentage' | 'fixed'
allocation_valuenumeric
monthly_limitnumericcomputed or manual
period_yearint
period_monthint

expenses

ColumnTypeNotes
iduuid PK
user_iduuid FK
amountnumeric
category_iduuid FK→ budget_categories
merchanttext
datedate
notestextnullable
payment_methodtext'card' | 'cash' | 'transfer'
receipt_urltextSupabase Storage
ai_extractedjsonbraw OCR output

Additional tables

emergency_fund
user_id, balance, goal_amount, monthly contributions jsonb history.
savings_contributions
id, user_id, goal_id, amount, date, type ('auto' | 'manual' | 'leftover').
notifications
id, user_id, type, title, body, read, scheduled_at, sent_at.
ai_insights
id, user_id, period_month, period_year, insights jsonb, generated_at.

API design

All routes live under /api/v1/. Edge Runtime on Cloudflare Workers. Auth via Supabase JWT in Authorization: Bearer header. RLS enforces user isolation at DB level.

Authentication

POST
/api/v1/auth/signup
Create account, send email verification
POST
/api/v1/auth/login
Email + password login → JWT
POST
/api/v1/auth/forgot-password
Send reset email via Resend

Salary

GET
/api/v1/salary
List salary entries, paginated
POST
/api/v1/salary
Create manual salary entry
POST
/api/v1/salary/upload
Upload payslip → AI extraction → returns extracted data for confirmation
POST
/api/v1/salary/confirm
Confirm AI-extracted data and save

Expenses

GET
/api/v1/expenses
List with filters: month, category, date range
POST
/api/v1/expenses
Create manual expense
POST
/api/v1/expenses/upload-receipt
Upload receipt → AI extraction
PUT
/api/v1/expenses/:id
Update expense
DEL
/api/v1/expenses/:id
Delete expense

Bills & subscriptions

GET
/api/v1/bills
List user bills
POST
/api/v1/bills
Create or upload bill
GET
/api/v1/subscriptions
List subscriptions with monthly total
POST
/api/v1/subscriptions
Add subscription (preset or custom)

Budgets & analytics

GET
/api/v1/budgets/:year/:month
Budget allocation for period
GET
/api/v1/analytics/spending
Spending by category, comparison, trends
GET
/api/v1/analytics/cashflow
Monthly income vs expense chart data
GET
/api/v1/analytics/savings-growth
Savings and emergency fund over time

AI

POST
/api/v1/ai/insights
Generate monthly AI insights (claude-sonnet-4-6)
POST
/api/v1/ai/ocr
Extract structured data from uploaded document
GET
/api/v1/ai/insights/:year/:month
Fetch cached insights for period

Reports & export

GET
/api/v1/reports/monthly/:year/:month
Monthly report data
POST
/api/v1/reports/export
Generate PDF/Excel/CSV export. Body: {type, period, format}

OCR prompt pattern

POST to claude-haiku vision
System: "Extract structured JSON from this document."
User: [image/pdf] + "Return only valid JSON: {employer, gross_pay, net_pay, tax, deductions, pay_date}"
Validate schema → return to frontend for user confirmation → save on confirm.

All pages

Auth pages

Sign up/signup
Log in/login
Forgot password/forgot-password
Reset password/reset-password
Verify email/verify-email
Onboarding/onboarding

Core app pages

Dashboard/dashboard
Salary & income/salary
Emergency fund/emergency-fund
Savings goals/savings
Savings goal detail/savings/:id
Bills/bills
Subscriptions/subscriptions
Budgets/budgets
Expenses/expenses
Expense detail/expenses/:id
Analytics/analytics
AI insights/insights
Reports/reports
Notifications/notifications
Settings/settings
Profile/settings/profile

Upload + confirm flow pages

Upload payslip/salary/upload
Confirm payslip data/salary/confirm
Upload bill/bills/upload
Confirm bill data/bills/confirm
Upload receipt/expenses/upload
Confirm receipt data/expenses/confirm

Key UI components

Stat cards
Label, value, change indicator, sparkline. Used in dashboard grid.
Budget progress bar
Category, spent/limit, % fill, color. Changes to warning/danger color near limit.
Transaction row
Merchant icon, name, category tag, amount (red if expense), date.
Upcoming bill card
Company logo, name, amount, days until due, urgency indicator.
AI extraction review
Side-by-side document preview and extracted fields. Edit before confirming.
Savings goal card
Goal name, icon, progress bar, % complete, target date countdown.

Color palette

A cool-toned financial palette — navy primary for trust, teal for success/savings, amber for warnings, rose for spending alerts. Light and dark mode support via CSS variables.

Navy
#1B3A5C
Blue
#2563EB
Teal
#0D9488
Green
#16A34A
Amber
#D97706
Rose
#E11D48
Surface
#F8FAFC
Dark bg
#0F172A

Semantic color usage

PurposeLightDark
Income / positive#16A34A (green)#4ADE80
Expense / negative#E11D48 (rose)#FB7185
Savings#0D9488 (teal)#2DD4BF
Emergency fund#D97706 (amber)#FCD34D
Budget warning (80%+)#F59E0B#FDE68A
Budget danger (100%+)#E11D48#FB7185
Primary action#2563EB (blue)#60A5FA

Typography

RoleFamilyWeightSize
Display / heroInter70032–48px
Heading H1Inter60024px
Heading H2Inter60018px
Heading H3Inter50015px
BodyInter40014px / 1.6
Caption / labelInter40012px
Numbers (financial)Inter Tabular500context
Mono / codeJetBrains Mono40012px

Use font-variant-numeric: tabular-nums on all financial values to prevent layout shifts.

Motion & animation

All animations wrapped in prefers-reduced-motion media query.

Responsive breakpoints

NameWidthLayout
Mobile< 640pxSingle column, bottom nav
Tablet640–1024pxCollapsible sidebar + 2-col grid
Desktop> 1024pxFixed sidebar + 3–4 col dashboard

Development roadmap

Milestone 1 · Weeks 1–3
Foundation
  • Project setup: Next.js 15 + Cloudflare Pages adapter + Tailwind + Drizzle
  • Supabase project, schema migration, RLS policies
  • Auth flow: signup, login, email verification, forgot password
  • Layout: sidebar navigation, responsive shell, dark/light mode toggle
  • Design system: component library (Button, Card, Input, Badge, Modal)
  • CI/CD: GitHub Actions → Cloudflare Pages auto-deploy
Milestone 2 · Weeks 4–7
Core finance features
  • Salary: manual entry + payslip upload + AI OCR extraction + confirm flow
  • Emergency fund: auto-allocation, balance tracking, history
  • Savings goals: multiple goals, contributions, progress bars
  • Bills: manual + upload + AI extraction + due date reminders
  • Subscriptions: preset library + custom + billing frequency
  • Budget categories: allocation waterfall, percentage/fixed amounts
  • Expenses: manual + receipt upload + AI categorisation
  • Dashboard: stat cards, budget progress, upcoming bills widget
Milestone 3 · Weeks 8–10
Analytics, AI & reports
  • Analytics page: spending by category, monthly comparison, cashflow charts
  • Savings growth & emergency fund growth charts
  • AI insights: claude-sonnet integration, monthly insight generation
  • End-of-month leftover auto-allocation job (Cloudflare Cron Worker)
  • Reports: monthly, yearly, budget — PDF / Excel / CSV export
  • Notifications: email + in-app for bills, budgets, milestones (Resend)
Milestone 4 · Weeks 11–13
Polish, subscriptions & launch
  • SaaS subscription: Stripe integration, free/pro plan gating
  • Settings: currency, timezone, percentages, notification preferences
  • Onboarding wizard: first-run salary, goals, bills setup
  • Mobile PWA optimisation: install prompt, offline support
  • Performance: bundle analysis, image optimisation, Core Web Vitals
  • Security audit, penetration test, OWASP checklist
  • Documentation, launch checklist, soft launch

Future features

Bank connection
Plaid or Teller API for automatic transaction import. Auto-categorise with AI.
Multi-currency
Track accounts in different currencies with live exchange rates.
Shared household
Invite partner/roommate. Split bills, shared budget view.
Investment tracking
Portfolio value, returns, net worth dashboard including investments.
Mobile app
React Native or Expo app for iOS/Android with camera receipt capture.
Tax preparation
Annual tax summary, deduction tracking, export for accountant.

Security recommendations

Financial data is sensitive. Implement all items below before launch.

Authentication & authorisation

Data protection

API security

Scalability recommendations

Cloudflare Pages + Supabase scales horizontally without configuration.