A full-stack financial management application built with Node.js, Express, TypeScript, Prisma, PostgreSQL, Socket.IO, and React.
PayFlow is a personal financial management app that lets you manage multiple bank accounts, track income and expenses through a folder-based system, make real-time transfers, and send money to other users — all in a clean, modern dark-themed UI.
Built as a full-stack learning project to master Node.js, Express, TypeScript, Prisma, and React — covering everything from JWT authentication, atomic database transactions, real-time Socket.IO events, to production deployment.
- Create and manage multiple bank accounts (Savings, Current, Salary, Fixed Deposit)
- Real-time balance tracking across all accounts
- Account activation/deactivation with safe deletion
- Manual debit and credit transaction entry
- Assign transactions to folders for categorization
- Filter transactions by type, date range, account, or folder
- Paginated transaction history
- Real-time transaction updates via Socket.IO
- Create income and expense folders (e.g. Salary, Rent, Food, Shopping)
- Set monthly budget limits per folder
- Visual budget progress bar with over-budget alerts
- Monthly spending summary per folder
- All-time statistics per folder
- Atomic account-to-account transfers (uses Prisma
$transaction) - Transfer history with full account details
- Monthly and all-time transfer statistics
- Prevents partial transfers — if either side fails, both roll back
- Search other registered users by email
- View their linked accounts
- Send money directly from your account to theirs
- Socket.IO integration for live transaction notifications
- Authenticated socket connections using JWT
- Per-user private rooms for secure event delivery
- JWT-based authentication with access + refresh token strategy
- Bcrypt password hashing (12 rounds)
- Protected routes on both frontend and backend
- Auto token refresh on expiry
| Technology | Purpose |
|---|---|
| Node.js 20+ | Runtime |
| Express.js | Web framework |
| TypeScript | Type safety |
| Prisma ORM | Database access |
| PostgreSQL | Primary database |
| Socket.IO | Real-time events |
| JWT | Authentication |
| Bcrypt | Password hashing |
| Zod | Input validation |
| Helmet | Security headers |
| Morgan | HTTP logging |
| CORS | Cross-origin requests |
| Technology | Purpose |
|---|---|
| React 18 | UI framework |
| TypeScript | Type safety |
| Vite | Build tool |
| Tailwind CSS v3 | Styling |
| Zustand | State management |
| Axios | HTTP client |
| Socket.IO Client | Real-time connection |
| Recharts | Data visualization |
| React Router v6 | Client-side routing |
| Lucide React | Icons |
| React Hot Toast | Notifications |
PayFlow/
├── backend/
│ ├── src/
│ │ ├── config/
│ │ │ ├── database.ts # Prisma client singleton
│ │ │ ├── env.ts # Zod env validation
│ │ │ └── socket.ts # Socket.IO setup
│ │ ├── modules/
│ │ │ ├── auth/ # Register, login, refresh
│ │ │ ├── accounts/ # Bank account CRUD
│ │ │ ├── transactions/ # Transaction management
│ │ │ ├── folders/ # Folder system
│ │ │ ├── transfers/ # Account transfers
│ │ │ └── users/ # User search
│ │ ├── middleware/
│ │ │ ├── auth.middleware.ts # JWT protection
│ │ │ ├── error.middleware.ts# Global error handler
│ │ │ └── validate.middleware.ts # Zod validation
│ │ ├── shared/
│ │ │ ├── types/ # Shared TypeScript types
│ │ │ └── utils/ # ApiError, ApiResponse, asyncHandler
│ │ └── app.ts # Express entry point
│ ├── prisma/
│ │ └── schema.prisma # Database schema
│ ├── .env.example
│ ├── package.json
│ └── tsconfig.json
│
└── frontend/
├── src/
│ ├── api/ # Axios API modules
│ ├── assets/ # Logo and images
│ ├── components/
│ │ ├── layout/ # Sidebar, Header, Layout
│ │ └── ui/ # Button, Card, Input, Modal, Badge
│ ├── hooks/ # useSocket
│ ├── pages/ # All page components
│ ├── store/ # Zustand auth + socket stores
│ ├── types/ # TypeScript interfaces
│ └── main.tsx # App entry + router
├── .env.example
├── tailwind.config.js
└── vite.config.ts
- Node.js 20+
- PostgreSQL 14+
- npm or yarn
git clone https://github.com/subhamdas29/Financial_management_app.git
cd Financial_management_appcd backend
npm installCopy the example env file and fill in your values:
cp .env.example .envRun database migrations:
npx prisma migrate dev --name initStart the backend dev server:
npm run devBackend runs at http://localhost:3000
cd frontend
npm install
npm run devFrontend runs at http://localhost:5173
DATABASE_URL="postgresql://postgres:yourpassword@localhost:5432/bankingapp"
JWT_SECRET="your_super_secret_jwt_key_minimum_32_characters_long"
JWT_REFRESH_SECRET="your_super_secret_refresh_key_minimum_32_characters"
JWT_ACCESS_EXPIRES_IN="15m"
JWT_REFRESH_EXPIRES_IN="7d"
PORT=3000
NODE_ENV=developmentVITE_API_URL=http://localhost:3000/api
VITE_SOCKET_URL=http://localhost:3000| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Register new user |
| POST | /api/auth/login |
Login and get tokens |
| POST | /api/auth/refresh |
Refresh access token |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/accounts |
Get all accounts |
| GET | /api/accounts/summary |
Get total balance summary |
| GET | /api/accounts/:id |
Get single account |
| POST | /api/accounts |
Create account |
| PATCH | /api/accounts/:id |
Update account |
| DELETE | /api/accounts/:id |
Delete/deactivate account |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/transactions |
Get transactions (paginated, filterable) |
| GET | /api/transactions/stats |
Get income/expense stats |
| GET | /api/transactions/:id |
Get single transaction |
| POST | /api/transactions |
Create transaction |
| PATCH | /api/transactions/:id |
Update transaction (assign folder) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/folders |
Get all folders |
| GET | /api/folders/summary |
Get all folders with monthly spending |
| GET | /api/folders/:id |
Get single folder |
| GET | /api/folders/:id/summary |
Get folder detail with budget status |
| POST | /api/folders |
Create folder |
| PATCH | /api/folders/:id |
Update folder |
| DELETE | /api/folders/:id |
Delete folder |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/transfers |
Get all transfers |
| GET | /api/transfers/stats |
Get transfer statistics |
| GET | /api/transfers/:id |
Get single transfer |
| POST | /api/transfers |
Create transfer |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users/search?email= |
Search users by email |
User
├── id, email, passwordHash, name
├── → Account[]
└── → Folder[]
Account
├── id, userId, name, accountNumber
├── accountType (SAVINGS/CURRENT/SALARY/FIXED_DEPOSIT)
├── balance (Decimal 15,2), currency, isActive
├── → Transaction[]
├── → Transfer[] (sent)
└── → Transfer[] (received)
Folder
├── id, userId, name
├── type (INCOME/EXPENSE)
├── color, icon, description, budgetLimit
└── → Transaction[]
Transaction
├── id, accountId, folderId (nullable)
├── amount, type (CREDIT/DEBIT)
├── description, merchant, status
├── transactedAt, metadata (JSON)
└── indexes on accountId, folderId, transactedAt
Transfer
├── id, fromAccountId, toAccountId
├── amount, description, status
└── transferredAt
- Push code to GitHub
- Create new project on railway.app
- Add PostgreSQL database plugin
- Set environment variables
- Railway auto-deploys on push
- Import repo on vercel.com
- Set root directory to
frontend - Add
VITE_API_URLandVITE_SOCKET_URLenvironment variables - Deploy
Subham Das
- GitHub: @subhamdas29
This project is open source and available under the MIT License.
Built with ❤️ to master Node.js, Express, TypeScript, Prisma, and React
