Skip to content

Latest commit

Β 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ’° Expense Tracker

A production-grade MERN stack financial management application with automated microservices for daily PDF email delivery, real-time expense analytics, Google OAuth, and multi-format data export.

Node.js React MongoDB Express JWT


                                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                      β”‚           User                β”‚
                                      β”‚        (Web Browser)          β”‚
                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                     β”‚
                                              HTTP / HTTPS
                                                     β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                  React Frontend (SPA)                           β”‚
                    β”‚                                                                β”‚
                    β”‚ β€’ Authentication                                               β”‚
                    β”‚ β€’ Dashboard & Analytics                                        β”‚
                    β”‚ β€’ Expense Management                                           β”‚
                    β”‚ β€’ Reports & Export                                             β”‚
                    β”‚ β€’ Google OAuth Login                                           β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                    β”‚
                                              REST API (JWT)
                                                    β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                  Express.js Backend API                         β”‚
                    β”‚                                                                β”‚
                    β”‚ Routes β†’ Middleware β†’ Controllers β†’ Services β†’ Models          β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚                               β”‚
                                    β”‚                               β”‚
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚      MongoDB         β”‚        β”‚    Authentication       β”‚
                        β”‚                      β”‚        β”‚                         β”‚
                        β”‚ β€’ Users             β”‚        β”‚ β€’ JWT                   β”‚
                        β”‚ β€’ Expenses          β”‚        β”‚ β€’ Google OAuth          β”‚
                        β”‚ β€’ Categories        β”‚        β”‚ β€’ OTP Verification      β”‚
                        β”‚ β€’ OTP Tokens        β”‚        β”‚ β€’ Password Reset        β”‚
                        β”‚ β€’ Reset Tokens      β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚ LangChain /       β”‚
                          β”‚ LangGraph         β”‚
                          β”‚ Workflow Engine   β”‚
                          β”‚                  β”‚
                          β”‚ β€’ Orchestrates   β”‚
                          β”‚   report flow    β”‚
                          β”‚ β€’ Coordinates    β”‚
                          β”‚   services       β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                 β”‚                  β”‚                             β”‚
      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
      β”‚ PDF Service         β”‚ β”‚ Email Service       β”‚ β”‚ Scheduler Service    β”‚
      β”‚ (PDFKit)            β”‚ β”‚ (Nodemailer)        β”‚ β”‚ (Node-Cron)          β”‚
      β”‚                     β”‚ β”‚                     β”‚ β”‚                      β”‚
      β”‚ β€’ Generate Reports  β”‚ β”‚ β€’ OTP Emails       β”‚ β”‚ β€’ Daily 6:00 AM Job  β”‚
      β”‚ β€’ Export PDFs       β”‚ β”‚ β€’ Reset Emails     β”‚ β”‚ β€’ Trigger Workflow   β”‚
      β”‚                     β”‚ β”‚ β€’ PDF Delivery     β”‚ β”‚                      β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β”‚
                                  SMTP (Gmail)
                                        β”‚
                             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                             β”‚   User's Email      β”‚
                             β”‚                     β”‚
                             β”‚ β€’ OTP              β”‚
                             β”‚ β€’ Password Reset   β”‚
                             β”‚ β€’ Daily PDF Report β”‚
                             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

⚑ Core Strengths β€” What Makes This Different

This is not a basic CRUD expense app. The Expense Tracker is built around three production-grade microservices that automate the financial reporting experience:


πŸ“¬ Microservice 1 β€” Daily PDF Email Delivery

The flagship feature of this application.

Every day at 8:00 AM, an automated background service powered by Node-Cron and Nodemailer runs a scheduled job that:

  1. πŸ” Queries MongoDB for all registered users
  2. πŸ“Š Fetches each user's expenses from the previous 24 hours
  3. πŸ“„ Generates a beautifully formatted PDF financial summary using PDFKit
  4. πŸ“§ Attaches the PDF and delivers it directly to each user's email inbox
  5. πŸ“ Logs delivery status for debugging and monitoring

This is a fully automated, zero-user-interaction financial reporting pipeline β€” the same pattern used by banks and financial SaaS products to deliver statements to customers.

Cron Schedule (Daily 8AM)
        β”‚
        β–Ό
  Query All Users
        β”‚
        β–Ό
  Fetch Daily Expenses (MongoDB)
        β”‚
        β–Ό
  Generate PDF Report (PDFKit)
        β”‚
        β–Ό
  Send Email with Attachment (Nodemailer + Gmail)
        β”‚
        β–Ό
  Log Delivery Result

βœ‰οΈ Microservice 2 β€” OTP Email Verification

On every new registration, a One-Time Password (OTP) is generated, stored with an expiry timestamp, and delivered to the user's inbox via Nodemailer. The user must verify their email before gaining access to the application. This microservice runs independently of the main Express request cycle.

User Registers β†’ OTP Generated (6-digit) β†’ Nodemailer Sends Email
                                                      β”‚
                                     User Enters OTP β—„β”˜
                                              β”‚
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         Valid + Not Expired?           Invalid / Expired
                              β”‚                               β”‚
                     Account Activated βœ…              Error Returned ❌

πŸ” Microservice 3 β€” Password Reset Email Flow

A secure token-based password reset pipeline:

  1. User requests reset β†’ unique token generated and stored in DB with expiry
  2. Nodemailer sends a time-limited reset link to the user's email
  3. User clicks the link β†’ token verified β†’ password updated and token invalidated

πŸ—‚οΈ Table of Contents


βœ… Features

πŸ”‘ Authentication & Security

  • πŸ“ User registration with OTP email verification
  • πŸ” Login with JWT authentication (access tokens)
  • 🌐 Google OAuth 2.0 login via Passport.js
  • πŸ”‘ Forgot password email flow with secure token reset
  • πŸ›‘οΈ Protected routes on both frontend and backend

πŸ’Έ Expense Management

  • βž• Add, ✏️ Edit, πŸ—‘οΈ Delete expenses with category tagging
  • 🏷️ Custom expense categories per user
  • πŸ” Search expenses by name, category, or description
  • πŸ“… Filter by weekly / monthly / yearly date ranges

πŸ“Š Analytics & Dashboard

  • πŸ“ˆ Real-time dashboard with pie and bar charts
  • πŸ’° Income vs expense balance overview
  • πŸ” Top spending category highlights
  • πŸ“† Day-by-day spending timeline

πŸ“€ Export & Reports

  • πŸ“„ On-demand PDF export of expense history
  • πŸ“Š Excel (XLSX) export for spreadsheet analysis
  • πŸ“¬ Daily automated PDF email sent to every user (microservice)

πŸ› οΈ Tech Stack

Layer Technology Purpose
Frontend React.js 18 SPA user interface
UI Library Ant Design / Bootstrap Components & layout
State Context API Global state management
Charts Chart.js / Recharts Data visualisation
Backend Node.js + Express.js REST API server
Database MongoDB + Mongoose Data persistence
Authentication JWT + Passport.js Auth & SSO
Email Nodemailer + Gmail Transactional emails
Scheduling Node-Cron Automated daily jobs
PDF PDFKit PDF generation
Excel xlsx / ExcelJS Spreadsheet export
OAuth Google OAuth 2.0 Social login

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     CLIENT (React SPA)                  β”‚
β”‚    Dashboard β”‚ Auth β”‚ Expenses β”‚ Reports β”‚ Settings     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚  HTTP / REST
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  EXPRESS REST API                        β”‚
β”‚  Routes β†’ Controllers β†’ Middleware β†’ Mongoose Models    β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   MongoDB   β”‚                    β”‚   MICROSERVICES       β”‚
β”‚  (Mongoose) β”‚                    β”‚                       β”‚
β”‚             β”‚                    β”‚  πŸ“¬ Daily PDF Emailer β”‚
β”‚  β€’ Users    │◄───────────────────│  (Node-Cron + PDFKit  β”‚
β”‚  β€’ Expenses β”‚                    β”‚   + Nodemailer)       β”‚
β”‚  β€’ Categoriesβ”‚                   β”‚                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚  βœ‰οΈ  OTP Verifier     β”‚
                                   β”‚  πŸ”‘ Password Reset    β”‚
                                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Getting Started

Prerequisites

  • Node.js 18+
  • MongoDB (local or Atlas)
  • Gmail account (for email features)
  • Google Cloud Console project (for OAuth)

Installation

# 1. Clone the repository
git clone https://github.com/MuhammadHaris249518/Expense-tracker.git
cd Expense-tracker/Expense-tracker

# 2. Install backend dependencies
cd backend
npm install

# 3. Install frontend dependencies
cd ../frontend
npm install

Running Locally

# Start MongoDB (if running locally)
mongod

# In one terminal β€” start the backend
cd backend
npm run dev

# In another terminal β€” start the frontend
cd frontend
npm start

The app will be available at http://localhost:3000 (frontend) and http://localhost:5000 (backend API).


πŸ” Environment Variables

Create a .env file in the /backend directory using the template below:

# ─── Server ──────────────────────────────
PORT=5000
NODE_ENV=development

# ─── Database ────────────────────────────
MONGODB_URI=mongodb://localhost:27017/expense-tracker

# ─── JWT ─────────────────────────────────
JWT_SECRET=your_strong_jwt_secret_here
JWT_EXPIRES_IN=7d

# ─── Email (Nodemailer) ──────────────────
EMAIL_USER=your_gmail@gmail.com
EMAIL_PASS=your_gmail_app_password   # Use App Password, NOT your main password

# ─── Google OAuth ─────────────────────────
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:5000/api/auth/google/callback

# ─── Frontend URL ────────────────────────
CLIENT_URL=http://localhost:3000

⚠️ Never commit your .env file. Make sure .env is listed in your .gitignore.


πŸ“‘ API Endpoints

Auth Routes β€” /api/auth

Method Endpoint Description
POST /register Register with OTP verification
POST /verify-otp Verify OTP code
POST /login Login with email + password
GET /google Initiate Google OAuth
GET /google/callback Google OAuth callback
POST /forgot-password Send password reset email
POST /reset-password/:token Reset password with token

Expense Routes β€” /api/expenses (πŸ”’ Protected)

Method Endpoint Description
GET / Get all expenses (with filter)
POST / Create a new expense
PUT /:id Update an expense
DELETE /:id Delete an expense
GET /export/pdf Download PDF report
GET /export/excel Download Excel export

Category Routes β€” /api/categories (πŸ”’ Protected)

Method Endpoint Description
GET / Get all categories
POST / Create category
DELETE /:id Delete category

πŸ“ Project Structure

Expense-tracker/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ controllers/       # Business logic
β”‚   β”‚   β”œβ”€β”€ authController.js
β”‚   β”‚   β”œβ”€β”€ expenseController.js
β”‚   β”‚   └── categoryController.js
β”‚   β”œβ”€β”€ models/            # Mongoose schemas
β”‚   β”‚   β”œβ”€β”€ User.js
β”‚   β”‚   β”œβ”€β”€ Expense.js
β”‚   β”‚   └── Category.js
β”‚   β”œβ”€β”€ routes/            # Express routes
β”‚   β”œβ”€β”€ middleware/        # Auth middleware
β”‚   β”œβ”€β”€ services/          # πŸ“¬ Microservices
β”‚   β”‚   β”œβ”€β”€ emailService.js      # Nodemailer config
β”‚   β”‚   β”œβ”€β”€ pdfService.js        # PDF generation
β”‚   β”‚   └── cronJob.js           # Daily scheduler
β”‚   β”œβ”€β”€ utils/             # Helper functions
β”‚   └── server.js          # Entry point
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/    # Reusable UI components
β”‚   β”‚   β”œβ”€β”€ pages/         # Page components
β”‚   β”‚   β”œβ”€β”€ context/       # State management
β”‚   β”‚   └── utils/         # API helpers
β”‚   └── public/
└── README.md

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Commit your changes: git commit -m 'feat: add your feature'
  4. Push to the branch: git push origin feature/your-feature-name
  5. Open a Pull Request

πŸ“œ License

This project is licensed under the MIT License.


Built with ❀️ by Muhammad Haris

MERN Stack Β· Microservices Β· Automated Financial Reporting

About

πŸ’» A full-stack web application built for securely storing, tracking, and organizing personal expenses. πŸ”’

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages