A modern, full-stack expense tracking application built with React and Node.js, featuring real-time data synchronization, multi-language support, and intelligent financial insights.
| Name | GitHub | Role |
|---|---|---|
| Hananel Sabag | @HananelSabag | Lead developer |
| Yuda Sabag | yudasabag@gmail.com | Collaborator — bank-scraper integration |
Portfolio Project — full-stack personal finance PWA with Israeli bank sync, built with React, Node.js, and PostgreSQL.
This repository is shared for educational and portfolio demonstration purposes only.
- ✅ Clone and explore the codebase to see implementation patterns
- ✅ Study the architecture and coding techniques used
- ✅ Review the documentation and project structure
- ✅ Use as reference for learning full-stack development
- ❌ Do NOT deploy this project as your own website
- ❌ Do NOT use for commercial purposes
- ❌ Do NOT claim as your own work
- ❌ Critical configuration files are excluded for security
For security reasons, sensitive configuration files and production secrets are not included in this repository. The project is designed to showcase code quality and architecture while protecting the live production environment.
SpendWise is a comprehensive personal finance management tool that helps users track expenses, manage budgets, and gain insights into their spending patterns. The application features a clean, responsive interface with support for both English and Hebrew languages, dark/light themes, and offline capabilities through Progressive Web App (PWA) technology.
SpendWise connects to spendwise-agent — a security-first companion that pulls real transactions from Israeli banks (Yahav, Leumi, Isracard, Max, Discount) into SpendWise automatically.
Users connect a bank from the app; credentials are encrypted in the browser (X25519) with the agent's public key, so the server stores only ciphertext it can never read. The local agent — the only holder of the private key — claims sync jobs, decrypts them in memory, scrapes, and reports back.
Browser (seal X25519) ──► bank_connections (ciphertext only) ──► local agent decrypts in RAM
bank_sync_jobs queue (cron 2×/day) scrapes → POST results
• hard dedup (UNIQUE bank_sync_id)
• per-account tracking + sync toggle
New in SpendWise:
/bank-connections— self-service connect/manage (JWT); credentials arrive as browser-sealed ciphertext/bank-agent— machine-to-machine job queue for the agent (X-Agent-Key)GET /api/v1/bank-sync/stats— per-bank stats for the dashboard (JWT)/bank-syncpage — connection hub: connect banks, per-account balances + toggles, live job statusbank_accountstable — real per-account balance;bank_connections/bank_sync_jobs— encrypted creds + queue
- Smart Transaction Management - Add, edit, and categorize transactions with intelligent suggestions
- Real-time Dashboard - Visual insights with charts and spending analytics
- Multi-language Support - Full Hebrew and English localization with RTL support
- Responsive Design - Optimized for desktop, tablet, and mobile devices
- Offline Capabilities - PWA with offline data synchronization
- Secure Authentication - JWT-based authentication with email verification
- Data Export - Export transactions in CSV, JSON, and PDF formats
- Category Management - Custom categories with icons and descriptions
- Dark/Light Themes - User preference-based theme switching
- Automated Testing - Unit and integration test suite (Vitest for frontend, Jest for backend)
- CI/CD Pipeline - GitHub Actions for automated testing and linting on every push
- Row-Level Security (RLS) - Supabase RLS policies for data isolation per user
- Framework: React 18 with Vite
- Styling: Tailwind CSS with custom components
- State Management: TanStack Query (React Query) + Zustand
- Routing: React Router v6
- Forms: React Hook Form with Zod validation
- Charts: Recharts for data visualization
- Icons: Lucide React + Heroicons
- PWA: Vite PWA plugin with Workbox
- Testing: Vitest + React Testing Library
- Runtime: Node.js 18+
- Framework: Express.js
- Database: PostgreSQL with native pg driver
- Authentication: JWT with bcrypt password hashing
- Email: Nodemailer with Gmail SMTP
- File Upload: Multer for profile images
- Security: Helmet, CORS, XSS protection, rate limiting
- Logging: Winston with daily log rotation
- Scheduling: Node-cron for automated tasks
- Testing: Jest with supertest
- Database: Supabase (PostgreSQL)
- Backend Hosting: Render
- Frontend Hosting: Vercel
- File Storage: Server-based uploads with CORS support
- GitHub Actions
SpendWise/
├── .github/ # CI/CD workflows (GitHub Actions)
├── client/ # Frontend React application
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Main application pages
│ │ ├── hooks/ # Custom React hooks
│ │ ├── context/ # React context providers
│ │ ├── utils/ # Utility functions
│ │ └── config/ # Configuration files
│ ├── public/ # Static assets
│ └── dist/ # Production build output
├── server/ # Backend Node.js application
│ ├── routes/ # API route definitions
│ ├── controllers/ # Business logic controllers
│ ├── middleware/ # Express middleware
│ ├── config/ # Database and app configuration
│ ├── utils/ # Server utilities
│ ├── __tests__/ # Backend test suite (Jest)
│ └── uploads/ # File upload storage
└── mcp-tools/ # MCP server for AI-powered database queries
- Node.js 18+ and npm 8+
- PostgreSQL database (or Supabase account)
- Gmail account for email services (optional)
git clone https://github.com/HananelSabag/SpendWise.git
cd SpendWise# Install client dependencies
cd client
npm install
# Install server dependencies
cd ../server
npm installNote: You'll need to create your own environment files as they're not included in the repository for security reasons.
Server (.env in server/ directory):
# Database
DATABASE_URL=postgresql://username:password@host:port/database
# JWT
JWT_SECRET=your-super-secret-jwt-key
JWT_REFRESH_SECRET=your-refresh-secret-key
# Email (optional)
GMAIL_USER=your-email@gmail.com
GMAIL_APP_PASSWORD=your-app-password
# Server
PORT=5000
NODE_ENV=development
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000Client (.env in client/ directory):
# API Configuration
VITE_API_URL=http://localhost:5000
VITE_CLIENT_URL=http://localhost:5173
VITE_ENVIRONMENT=development
VITE_DEBUG_MODE=trueRun the database migrations (if using local PostgreSQL):
cd server
npm run migrateFor Supabase, import the provided SQL schema file.
Terminal 1 - Backend:
cd server
npm run devTerminal 2 - Frontend:
cd client
npm run devThe application will be available at:
- Frontend: http://localhost:5173
- Backend API: http://localhost:5000
The application supports mobile development with network access:
# Start with network access for mobile testing
cd client
npm run dev:mobile
# Your mobile device can access the app at:
# http://YOUR_LOCAL_IP:5173# Run frontend tests (Vitest)
cd client
npm run test
# Run frontend tests with coverage
cd client
npm run test:coverage
# Run backend tests (Jest)
cd server
npm test
# Lint frontend code
cd client
npm run lintEvery push to main triggers the GitHub Actions pipeline which:
- Runs all frontend tests (Vitest)
- Runs all backend tests (Jest)
- Lints the frontend codebase (ESLint)
This project is licensed under the ISC License - see the LICENSE file for details.
This is a portfolio project, but feedback and suggestions are welcome:
- Fork the repository
- Create a feature branch (
git checkout -b feature/suggestion) - Commit your changes (
git commit -m 'Add suggestion') - Push to the branch (
git push origin feature/suggestion) - Open a Pull Request
Hananel Sabag — @HananelSabag — hananel12345@gmail.com
Yuda Sabag — yudasabag@gmail.com
SpendWise — full-stack personal finance PWA with Israeli bank sync.