Skip to content

SyedMuhammadFaheem/Budget-Tracker-App

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Budget Tracker App

A full-stack personal finance app built with the PERN stack (PostgreSQL, Express, React, Node.js). Track income, log expenses, manage savings goals, and sign in with Google.


Tech Stack

Layer Technology
Frontend React 18, Ant Design, React Router v6
Backend Node.js, Express
Database PostgreSQL, TypeORM
Auth JWT (httpOnly cookie), Google OAuth 2.0
Security helmet, express-rate-limit, express-validator

Prerequisites

Make sure you have these installed before starting:

  • Node.js v18 or higher
  • PostgreSQL v14 or higher
  • npm (comes with Node.js)
  • A Google Cloud project with OAuth 2.0 credentials (for Google login — see step below)

Project Structure

Budget-Tracker-App/
├── client/
│   └── budget-tracker-app/     ← React frontend
└── server/                     ← Express backend

Step 1 — Clone the Repository

git clone <your-repo-url>
cd Budget-Tracker-App

Step 2 — Set Up PostgreSQL

  1. Open psql (or pgAdmin) and create a new database:
CREATE DATABASE "Budget-Tracker-App";
  1. Note your PostgreSQL username, password, host (localhost), and port (5432). You'll need these in the next step.

Step 3 — Get a Google OAuth Client ID (for Google login)

Skip this if you don't need Google login. The rest of the app works without it.

  1. Go to Google Cloud Console
  2. Create a new project (or use an existing one)
  3. Navigate to APIs & Services → Credentials
  4. Click Create Credentials → OAuth 2.0 Client ID
  5. Application type: Web application
  6. Add http://localhost:3000 to Authorized JavaScript origins
  7. Copy the Client ID — you'll use it in both .env files below

Step 4 — Configure the Server

cd server
cp .env.example .env

Open server/.env and fill in your values:

PORT=3001
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres        # your PostgreSQL username
DB_PASSWORD=your_password   # your PostgreSQL password
DB_NAME=Budget-Tracker-App
JWT_SECRET=some_long_random_string_here   # any secret, min 32 chars
CORS_ORIGIN=http://localhost:3000
NODE_ENV=development
GOOGLE_CLIENT_ID=           # paste your Google OAuth Client ID here

Generating a strong JWT_SECRET:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Copy the output and paste it as the value for JWT_SECRET.


Step 5 — Install Server Dependencies

# still inside server/
npm install

Step 6 — Run Database Migration

This creates all the tables in your PostgreSQL database:

npm run migration:run

You should see output like:

query: CREATE TABLE "users" ...
query: CREATE TABLE "incomes" ...
query: CREATE TABLE "expenses" ...
query: CREATE TABLE "savings" ...
Migration 1000000000000-InitialSchema has been executed successfully.

If you see ECONNREFUSED, PostgreSQL isn't running. Start it first:

  • macOS: brew services start postgresql
  • Windows: Start the PostgreSQL service from Services panel
  • Linux: sudo systemctl start postgresql

Step 7 — Start the Server

npm run dev

The server starts on http://localhost:3001. You should see:

Server is running on port 3001

To verify it's healthy:

curl http://localhost:3001/health
# → {"status":"ok"}

Step 8 — Configure the Client

Open a new terminal:

cd client/budget-tracker-app
cp .env.example .env.local

Open client/budget-tracker-app/.env.local and fill in:

REACT_APP_API_URL=http://localhost:3001
REACT_APP_GOOGLE_CLIENT_ID=    # same Client ID from Step 3

Step 9 — Install Client Dependencies

# still inside client/budget-tracker-app/
npm install

Step 10 — Start the Client

npm start

The app opens at http://localhost:3000.


Manual Testing Checklist

Run through these in order to verify everything works end-to-end:

Auth

  • Sign up — go to /user/signup, create an account with name, email, password. Should redirect to the dashboard.
  • Login — log out, go to /user/login, log in with the same credentials. Should redirect to the dashboard.
  • JWT cookie set — open browser DevTools → Application → Cookies → localhost:3000. You should see a token cookie with HttpOnly checked and no value visible.
  • Private route — while logged out, navigate directly to http://localhost:3000/user/dashboard/1. Should redirect to /user/login.
  • Logout — click logout. Cookie should be cleared. Navigating to dashboard should redirect to login.
  • Google login (if configured) — click "Login with Google", complete OAuth flow, should land on the dashboard.

Expenses

  • Add expense — click Add Expense, fill in name, amount, type, date. Should appear in the table without a page reload.
  • Edit expense — click the edit icon on a row, change a field, save. Row should update.
  • Delete expense — click the delete icon. Row should disappear from the table without a page reload.

Income

  • Add income — same flow as expenses with type (Regular / One-Time / Passive).
  • Edit income — verify changes persist.
  • Delete income — row removed from table without reload.

Savings

  • Add saving — enter name, target amount, deadline.
  • Edit saving — modify and save.
  • Delete saving — row removed.

Dashboard numbers

  • Total income / expenses show correct sums.
  • Current Balance = total income this month − total expenses this month.
  • Monthly cards update when you add/delete income or expenses.

Edit Profile

  • Go to Edit Profile. You should only see Name and Email fields — no role or password fields.
  • Update name. Should save and reflect immediately.

Security spot-checks

  • Cross-user access — sign up as User A (note their ID from the URL). Sign up as User B in an incognito window. While logged in as User B, paste http://localhost:3000/user/dashboard/<User A's ID> in the address bar. Should get a 403 error, not User A's data.
  • API without cookie — open a new terminal and run:
    curl http://localhost:3001/expense/get-expenses/1
    Should return {"error":"Unauthorized"}, not expense data.
  • Security headers — run:
    curl -I http://localhost:3001/health
    Response should include X-Frame-Options, X-Content-Type-Options, X-DNS-Prefetch-Control headers.
  • Rate limiting — run this 11 times quickly on the login route:
    for i in $(seq 1 11); do curl -s -o /dev/null -w "%{http_code}\n" -X POST http://localhost:3001/user/login -H "Content-Type: application/json" -d '{"email":"a@b.com","password":"wrong"}'; done
    The 11th request should return 429.

Available Scripts

Server (server/)

Script Description
npm run dev Start with nodemon (auto-restart on file changes)
npm start Start without nodemon (production-style)
npm run migration:run Apply pending database migrations
npm run migration:generate Generate a new migration from entity changes

Client (client/budget-tracker-app/)

Script Description
npm start Start development server on port 3000
npm run build Create optimized production build

Common Issues

ECONNREFUSED when running migration PostgreSQL is not running. Start it first (see Step 6).

invalid signature or jwt malformed errors The JWT_SECRET in .env was changed after users logged in. Clear your browser cookies and log in again.

Google login shows error or does nothing

  • Check that REACT_APP_GOOGLE_CLIENT_ID in .env.local matches the server's GOOGLE_CLIENT_ID in .env
  • Ensure http://localhost:3000 is listed in your Google Cloud Console under Authorized JavaScript origins

Cannot find module on server start Run npm install inside the server/ directory.

Blank page or white screen on the client Open browser DevTools → Console. If it says a component crashed, refresh — the ErrorBoundary will catch it and show a recovery button.

Port already in use

# Find and kill the process on port 3001
lsof -ti:3001 | xargs kill -9
# Or for port 3000
lsof -ti:3000 | xargs kill -9

About

Budget Tracker is a web app made with the PERN stack. It helps you manage expenses, track income, and plan savings securely. With features like Google login and clear permissions, you can trust your data's privacy. Whether it's for personal use or small-scale finance tracking, our app keeps things easy and reliable.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors