Skip to content

francis-rf/Expense-Manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Expense Manager πŸ’°

Python FastAPI MySQL AWS License

A full-stack expense tracking application with glassmorphism UI, real-time analytics, and comprehensive testing. Built with FastAPI backend serving both the REST API and the vanilla JavaScript frontend as a single unified server.

🎯 Features

  • Glassmorphism UI β€” Modern frosted glass design with animated gradients
  • Expense Management β€” Add, view, filter, and delete expenses with category tracking
  • Analytics Dashboard β€” Visual category breakdown with date range analysis
  • RESTful API β€” FastAPI backend with Pydantic validation
  • MySQL Database β€” Persistent storage with parameterized queries
  • Comprehensive Testing β€” 41+ test cases covering all functionality
  • Logging β€” File and console logging for debugging
  • Single Server β€” Frontend served as static files from the FastAPI backend

☁️ AWS Deployment Architecture

Live URL: http://<elastic-beanstalk-url>

Architecture

GitHub Push
    ↓
GitHub Actions (CI/CD)
    ↓ Deploy
Elastic Beanstalk (Python + Docker)
    ↓ connects
RDS MySQL (managed database)
    ↓ fetches credentials
AWS Secrets Manager (DB credentials)

AWS Services Used

Service Purpose
Elastic Beanstalk Hosts the FastAPI application (auto-scaling, load balancing)
RDS MySQL Managed relational database (automated backups, high availability)
Secrets Manager Stores database credentials securely (no .env files on server)
IAM Role Grants Beanstalk permission to access Secrets Manager
GitHub Actions Auto-deploys on every push to main branch

Deployment Steps

1. Create RDS MySQL instance

AWS Console β†’ RDS β†’ Create database β†’ MySQL
- Template: Free tier
- DB identifier: expense-manager-db
- Username: admin
- Enable public access: No (private within VPC)

2. Store DB credentials in Secrets Manager

# AWS Console β†’ Secrets Manager β†’ Store a new secret
# Secret name: expense-manager/db-credentials
# Keys: DB_HOST, DB_USER, DB_PASSWORD, DB_NAME

3. Create IAM Role for Elastic Beanstalk

IAM β†’ Roles β†’ Create role β†’ EC2
Attach: SecretsManagerReadWrite
Name: expense-manager-eb-role

4. Create Elastic Beanstalk environment

Elastic Beanstalk β†’ Create environment β†’ Web server environment
- Platform: Python or Docker
- Upload your application code as a zip
- Attach IAM instance profile: expense-manager-eb-role

5. Set environment variables in Beanstalk

Configuration β†’ Software β†’ Environment properties
DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
(pulled from Secrets Manager at startup)

6. GitHub Actions CI/CD

Add these secrets in GitHub β†’ Settings β†’ Secrets β†’ Actions:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • EB_APP_NAME - Elastic Beanstalk application name
  • EB_ENV_NAME - Elastic Beanstalk environment name

Every push to main automatically packages and deploys the application.

Pause / Cleanup

# Pause: Beanstalk Console β†’ Environment β†’ Actions β†’ Terminate environment
# Full cleanup: Terminate environment β†’ Delete application β†’ Delete RDS instance β†’ Delete secret

πŸ“ Project Structure

expense-manager/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ server.py           # FastAPI application (serves API + frontend)
β”‚   └── db_helper.py        # Database operations
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ index.html          # Main HTML structure
β”‚   β”œβ”€β”€ style.css           # Glassmorphism styling
β”‚   └── app.js              # JavaScript logic (uses relative API URLs)
β”œβ”€β”€ tests/
β”‚   └── backend/
β”‚       β”œβ”€β”€ test_db_helper.py   # Database tests
β”‚       └── test_server.py      # API endpoint tests
β”œβ”€β”€ logs/                   # Application logs
β”œβ”€β”€ schema.sql              # Database setup script
β”œβ”€β”€ Dockerfile              # Container configuration
β”œβ”€β”€ requirements.txt
└── pyproject.toml          # Pytest configuration

πŸš€ Getting Started (Local)

Prerequisites

  • Python 3.8+
  • MySQL 8.0+

Database Setup

The project includes a schema.sql file for easy database setup. Run it using:

mysql -u root -p < schema.sql

Or manually create the database:

CREATE DATABASE expense_manager;
USE expense_manager;

CREATE TABLE expenses (
    id INT AUTO_INCREMENT PRIMARY KEY,
    expense_date DATE NOT NULL,
    category VARCHAR(100) NOT NULL,
    notes TEXT,
    amount DECIMAL(10, 2) NOT NULL CHECK (amount > 0),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_expense_date (expense_date),
    INDEX idx_category (category)
);

Installation

  1. Clone the repository
git clone <your-repo-url>
cd expense-manager
  1. Set up MySQL database
mysql -u root -p < schema.sql
  1. Install Python dependencies
pip install -r requirements.txt
  1. Configure environment variables
cp .env.example .env

Edit .env with your MySQL credentials:

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_password_here
DB_NAME=expense_manager
  1. Run the server (serves both API and frontend)
uvicorn backend.server:app --host 0.0.0.0 --port 8000

Open http://localhost:8000 β€” the frontend loads automatically.

πŸ’» Usage

API Endpoints

Method Endpoint Description
GET / Serves the frontend UI
GET /health Health check
GET /expenses/{date} Get expenses for a date
POST /expenses/{date} Add expenses for a date
DELETE /expenses/{date} Delete expenses for a date
GET /summary?start_date=X&end_date=Y Get expense summary

Example Requests

Add Expense:

curl -X POST "http://localhost:8000/expenses/2025-12-07" \
  -H "Content-Type: application/json" \
  -d '[{"category": "Food", "notes": "Lunch", "amount": 250.50}]'

Get Summary:

curl "http://localhost:8000/summary?start_date=2025-12-01&end_date=2025-12-07"

πŸ“Έ Screenshots

Application Interface Expense-Manager Application Interface

πŸ§ͺ Testing

Run all tests:

pytest

Run with coverage:

pytest --cov=backend --cov-report=html

🐳 Docker

Build Image

docker build -t expense-manager .

Run Container

docker run -p 8000:8000 --env-file .env expense-manager

πŸ”§ Troubleshooting

Database Connection Issues

Error: "Access denied for user"

  • Check your MySQL credentials in .env
  • Ensure MySQL user has permissions: GRANT ALL ON expense_manager.* TO 'root'@'localhost';

Error: "Can't connect to MySQL server"

  • Verify MySQL is running: sudo service mysql status (Linux) or check services (Windows)
  • Check DB_HOST in .env matches your MySQL host

Error: "Unknown database 'expense_manager'"

  • Run the schema script: mysql -u root -p < schema.sql

Port Conflicts

If port 8000 is already in use:

uvicorn backend.server:app --host 0.0.0.0 --port 8001

πŸ“„ License

MIT License

About

Full-stack expense tracking application with glassmorphism UI, real-time analytics, and MySQL backend. Built with FastAPI and vanilla JavaScript.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors