Personal finance management app — track income & expenses, set budgets, save toward goals, and analyze your spending habits with interactive charts.
FinFlow helps users take control of their finances by providing:
- Transaction tracking with multi-currency support (USD, UZS, RUB)
- Budget monitoring with visual alerts when approaching or exceeding limits
- Savings goals with smart analytics, projections, and pace insights
- Interactive dashboard with trend charts, category breakdowns, and period comparisons
- Data export in CSV, Excel, and PDF formats
- AI-powered insights — spending analysis, trend detection, anomaly alerts, and money-saving tips via Groq (Llama 3.3)
- Smart categorization — AI suggests the best category for a transaction based on its note
- Google OAuth — sign in with Google alongside email/password
- Multi-language UI — English, Russian, Uzbek
- Dark mode — Light / Dark / System
Exchange rates are fetched in real-time from the Central Bank of Uzbekistan API.
Central financial overview with four key metrics (balance, income, expenses, net), a trend chart (week/month/year), top expense categories, category distribution breakdown, period-over-period comparison, and budget alert cards.
Full CRUD with inline editing, bulk delete, and advanced filtering (by type, category, date range, search query). Supports pagination (20/page) and sorting by date or amount. Per-transaction currency selector (USD, UZS, RUB) — amounts stored as entered. Global currency switcher converts all amounts for display.
User-defined categories with custom name and color. 10 default categories seeded on registration (Salary, Freelance, Products, Transport, Entertainment, Rent, Healthcare, Education, Restaurants, Utilities). Used across transactions, budgets, and analytics.
Monthly spending limits per category with a visual progress bar. Three status levels:
- On Track (< 80%) — blue
- Near Limit (80–99%) — yellow warning
- Over Budget (≥ 100%) — red alert
Create goals with a target amount, optional deadline, color, and icon. Deposit or withdraw funds manually. Smart analytics per goal:
- Status tracking (Completed / Ahead / On Track / Behind / No Deadline)
- Projected completion date based on average savings rate
- Required monthly amount to meet the deadline
- Contextual insights and recommendations
Export filtered transactions in three formats:
- CSV — plain text with columns: Date, Type, Category, Amount, Currency, Note
- Excel (XLSX) — formatted spreadsheet with bold headers and currency column
- PDF — formatted document with table layout and currency-aware amounts
Real-time rates from CBU API for USD, UZS, and RUB. Cached for 1 hour with fallback values. Used for display conversion when the global currency differs from a transaction's stored currency.
Available to ADMIN role users:
- User stats — total, new (7d/30d), active users
- Transaction stats — platform-wide totals, top categories, recent activity
- User management — paginated table with delete capability
AI-powered financial analysis using Groq (Llama 3.3 70B by default, configurable via GROQ_MODEL). Analyzes up to 3 months of transactions and returns:
- Summary — brief overview of spending habits
- Spending by category — breakdown with amounts and percentages (bar chart)
- Trends — 2–4 observations about spending patterns
- Anomalies — unusual transactions or spending spikes
- Tips — 3–5 actionable money-saving recommendations
All analyses are auto-saved and browsable from the history list with a dual-view UI (list + detail). Each entry shows a locale badge indicating the language it was generated in (EN/RU/UZ). Rate-limited to 5 requests/min.
When creating a transaction, click the "AI" button next to the category selector — the AI reads the transaction note and suggests the best matching category from the user's list. Rate-limited to 15 requests/min.
- Three themes: Light / Dark / System (saved in localStorage)
- Three languages: English, Russian, Uzbek
- Locale-aware number/date formatting
Mobile-first layout with collapsible sidebar, hamburger menu on small screens, full-width inputs on mobile, and touch-friendly controls.
| Layer | Technology |
|---|---|
| Backend | NestJS 11, Prisma ORM, PostgreSQL, JWT, Google OAuth, Groq AI |
| Frontend | Next.js 16 (App Router), React 19, Recharts |
| Styling | Tailwind CSS v4 |
| Export | ExcelJS, PDFKit |
| API Docs | Swagger (/api/docs) |
| Security | Helmet, CSRF, Throttler, httpOnly cookies, CORS |
| Hosting | Vercel (frontend), Render (backend), Neon (database) |
| Measure | Details |
|---|---|
| Authentication | JWT access + refresh tokens in httpOnly cookies, Google OAuth |
| CSRF Protection | Token in cookie, validated via X-CSRF-Token header |
| Rate Limiting | 100 req/min global, 5/min login, 3/hour registration, 5/min AI insights, 15/min AI categorization |
| Data Isolation | Users can only access their own data |
| Password Hashing | bcrypt |
| Input Validation | Server-side validation on all endpoints |
finflow/
├── apps/
│ ├── backend/ # NestJS API server
│ │ ├── prisma/
│ │ │ └── schema.prisma # Database schema
│ │ └── src/
│ │ ├── auth/ # JWT + Google OAuth
│ │ ├── transaction/ # Income/expense CRUD
│ │ ├── category/ # Category management
│ │ ├── budget/ # Budget tracking
│ │ ├── savings-goal/ # Goal tracking + analytics
│ │ ├── dashboard/ # Analytics & summaries
│ │ ├── exchange-rate/ # CBU API integration
│ │ ├── export/ # CSV, Excel, PDF generation
│ │ ├── ai/ # AI insights & categorization (Groq)
│ │ ├── admin/ # Admin panel & user management
│ │ └── prisma/ # Database service
│ │
│ └── frontend/ # Next.js client
│ ├── app/
│ │ ├── (auth)/ # Login, Register pages
│ │ └── (dashboard)/ # Dashboard, Transactions, Categories,
│ │ # Budgets, Goals, AI Insights, Admin
│ ├── components/ # UI & feature components
│ └── lib/
│ ├── api.ts # Centralized API client
│ ├── auth-context.tsx
│ ├── currency-context.tsx # Global currency switcher
│ ├── theme-context.tsx
│ ├── toast-context.tsx
│ └── i18n/ # Translations (en, ru, uz)
- Node.js 18+
- PostgreSQL
- npm
git clone https://github.com/ShavkatjonB/finflow.git
cd finflowcd apps/backend
npm installCreate apps/backend/.env:
NODE_ENV="development"
DATABASE_URL="postgresql://postgres:password@localhost:5432/finflow"
JWT_SECRET="your-jwt-secret-min-32-chars-here"
JWT_EXPIRES_IN="15m"
JWT_REFRESH_SECRET="your-jwt-refresh-secret-min-32-chars"
JWT_REFRESH_EXPIRES_IN="7d"
CORS_ORIGIN="http://localhost:1000"
PORT=1001
# Swagger API docs at /api/docs — "true" to enable, "false" or omit to disable
SWAGGER="true"
# Google OAuth (get from https://console.cloud.google.com/apis/credentials)
GOOGLE_CLIENT_ID="your-google-client-id.apps.googleusercontent.com"
# Groq AI (get from https://console.groq.com/keys)
GROQ_API_KEY="your-groq-api-key"
GROQ_MODEL="llama-3.3-70b-versatile" # optional, defaults to llama-3.3-70b-versatileRun database migrations and start the server:
npx prisma migrate dev
npm run start:devBackend runs on http://localhost:1001. Swagger docs at http://localhost:1001/api/docs.
cd apps/frontend
npm installCreate apps/frontend/.env:
NEXT_PUBLIC_API_URL=http://localhost:1001/api
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.comStart the dev server:
npm run devFrontend runs on http://localhost:1000.
User ──── Transaction ──── Category
├── Category
├── Budget ────────── Category
├── SavingsGoal
└── AiInsight
| Model | Key Fields |
|---|---|
| User | id (UUID), email, password?, googleId?, role (USER/ADMIN) |
| Transaction | type (INCOME/EXPENSE), amount (Decimal), currency, date, note, categoryId |
| Category | name, color, icon, isDefault |
| Budget | amount, period, categoryId (unique per user+category+period) |
| SavingsGoal | name, targetAmount, savedAmount, deadline, color, icon |
| AiInsight | locale, data (JSON), createdAt |
10 default categories are seeded on user registration: Salary, Freelance, Products, Transport, Entertainment, Rent, Healthcare, Education, Restaurants, Utilities.
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/register |
Register new user |
| POST | /auth/login |
Login (sets httpOnly cookie tokens) |
| POST | /auth/google |
Google OAuth sign-in / sign-up |
| POST | /auth/refresh |
Refresh tokens via refresh_token cookie |
| POST | /auth/logout |
Logout (clears cookie tokens) |
| GET | /auth/me |
Get current user from token |
| Method | Endpoint | Description |
|---|---|---|
| GET | /transactions |
List (paginated, filtered) |
| POST | /transactions |
Create transaction |
| PATCH | /transactions/:id |
Update transaction |
| DELETE | /transactions/:id |
Delete transaction |
| DELETE | /transactions/bulk |
Bulk delete |
| Method | Endpoint | Description |
|---|---|---|
| GET | /categories |
List all |
| POST | /categories |
Create category |
| PATCH | /categories/:id |
Update category |
| DELETE | /categories/:id |
Delete category |
| Method | Endpoint | Description |
|---|---|---|
| GET | /budgets |
List all |
| POST | /budgets |
Create budget |
| PATCH | /budgets/:id |
Update budget |
| DELETE | /budgets/:id |
Delete budget |
| Method | Endpoint | Description |
|---|---|---|
| GET | /savings-goals |
List all |
| POST | /savings-goals |
Create goal |
| GET | /savings-goals/:id |
Get goal details |
| PATCH | /savings-goals/:id |
Update goal |
| DELETE | /savings-goals/:id |
Delete goal |
| POST | /savings-goals/:id/deposit |
Deposit/withdraw |
| Method | Endpoint | Description |
|---|---|---|
| GET | /dashboard/summary |
Balance overview |
| GET | /dashboard/comparison?period= |
Period comparison |
| GET | /dashboard/trend?period= |
Income/expense trends |
| GET | /dashboard/top-categories |
Top 5 expense categories |
| GET | /dashboard/category-distribution |
Category breakdown |
| Method | Endpoint | Description |
|---|---|---|
| GET | /export/csv |
Export transactions CSV |
| GET | /export/excel |
Export transactions XLSX |
| GET | /export/pdf |
Export transactions PDF |
| GET | /exchange-rates |
Current exchange rates |
| Method | Endpoint | Description |
|---|---|---|
| POST | /ai/insights |
Generate AI analysis (auto-saved) |
| GET | /ai/insights |
List saved analyses |
| GET | /ai/insights/:id |
Get saved analysis by ID |
| DELETE | /ai/insights/:id |
Delete saved analysis |
| POST | /ai/categorize |
AI category suggestion for a transaction |
| Method | Endpoint | Description |
|---|---|---|
| GET | /admin/stats/users |
User statistics |
| GET | /admin/stats/transactions |
Transaction statistics |
| GET | /admin/users |
Paginated user list |
| DELETE | /admin/users/:id |
Delete user |
Authentication uses httpOnly cookies set on login. Bearer token header is also supported as fallback (useful for Swagger/API testing).
npm run start:dev # Development with hot reload
npm run build # Production build
npm run start # Production server
npm run lint # ESLint
npm run test # Unit tests
npm run test:e2e # E2E testsnpm run dev # Development server (port 1000)
npm run build # Production build
npm run start # Production server
npm run lint # ESLintMIT