A comprehensive expense tracking application with Android frontend and Python FastAPI backend, featuring AI-powered expense categorization.
- β User registration and authentication
- β Add expenses with automatic AI categorization
- β View and manage expense list
- β Generate reports (this month, last month, custom date range)
- β Category management with manual editing
- β INR currency support
- π€ Claude Sonnet AI-powered expense categorization with keyword fallback
- π± Material Design 3 Android app
- π JWT-based authentication
- π Real-time expense analytics
- βοΈ Supabase backend integration
βββββββββββββββββββ HTTP/REST βββββββββββββββββββ SQL βββββββββββββββββββ
β Android App β ββββββββββββββββ β FastAPI Backend β βββββββββ β Supabase β
β (Jetpack β β (Python) β β (PostgreSQL) β
β Compose) β β β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
- Framework: FastAPI (Python)
- Database: Supabase (PostgreSQL)
- Authentication: JWT tokens
- AI: Claude Sonnet API with keyword fallback
- Testing: Pytest
- UI: Jetpack Compose + Material Design 3
- Architecture: MVVM with Hilt DI
- Navigation: Navigation Compose
- Networking: Retrofit + OkHttp
- Testing: JUnit + Espresso
- Python 3.8+
- Android Studio (latest version)
- Supabase account
-
Create Supabase Project
# Go to https://supabase.com and create a new project # Get your URL and API keys
-
Database Schema
-- Run this in Supabase SQL editor -- Users table CREATE TABLE users ( id uuid DEFAULT gen_random_uuid() PRIMARY KEY, email varchar UNIQUE NOT NULL, full_name varchar NOT NULL, password_hash varchar NOT NULL, created_at timestamptz DEFAULT now(), updated_at timestamptz DEFAULT now() ); -- Categories table CREATE TABLE categories ( id uuid DEFAULT gen_random_uuid() PRIMARY KEY, name varchar NOT NULL, emoji varchar, is_system boolean DEFAULT false, user_id uuid REFERENCES users(id) ON DELETE CASCADE, created_at timestamptz DEFAULT now(), updated_at timestamptz DEFAULT now(), UNIQUE(name, user_id) ); -- Expenses table CREATE TABLE expenses ( id uuid DEFAULT gen_random_uuid() PRIMARY KEY, user_id uuid REFERENCES users(id) ON DELETE CASCADE NOT NULL, amount decimal(10,2) NOT NULL CHECK (amount > 0), note varchar(500) NOT NULL, date date NOT NULL, category_id uuid REFERENCES categories(id) NOT NULL, created_at timestamptz DEFAULT now(), updated_at timestamptz DEFAULT now() ); -- Indexes CREATE INDEX idx_expenses_user_id ON expenses(user_id); CREATE INDEX idx_expenses_date ON expenses(date); CREATE INDEX idx_expenses_category_id ON expenses(category_id); CREATE INDEX idx_categories_user_id ON categories(user_id);
-
Backend Installation
cd backend python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install -r requirements.txt
-
Environment Setup
cp .env.example .env # Edit .env with your Supabase and Claude API credentials: # SUPABASE_URL=your_supabase_url # SUPABASE_KEY=your_supabase_anon_key # SUPABASE_SERVICE_KEY=your_supabase_service_key # JWT_SECRET=your_jwt_secret_key # ANTHROPIC_API_KEY=your_claude_api_key
-
Run Backend
python main.py # API will be available at http://localhost:8000
-
Open in Android Studio
# Open android-app folder in Android Studio -
Build Project
# Android Studio will automatically download dependencies # Make sure backend is running on localhost:8000
-
Run App
# Use Android Studio's run button or ./gradlew installDebug
cd backend
pytest -v
pytest tests/test_auth.py -v
pytest tests/test_expenses.py -v
pytest tests/test_ai_categorizer.py -vcd android-app
./gradlew test # Unit tests
./gradlew connectedAndroidTest # Integration testsPOST /api/auth/register- Register new userPOST /api/auth/login- Login userPOST /api/auth/refresh- Refresh access tokenGET /api/auth/me- Get current user info
POST /api/expenses/- Create expenseGET /api/expenses/- List expenses (with filters)GET /api/expenses/{id}- Get expense detailsPUT /api/expenses/{id}- Update expenseDELETE /api/expenses/{id}- Delete expensePOST /api/expenses/categorize-preview- Preview categorization
GET /api/categories/- List categoriesPOST /api/categories/- Create categoryPUT /api/categories/{id}- Update categoryDELETE /api/categories/{id}- Delete category
POST /api/reports/- Generate custom reportGET /api/reports/this-month- This month reportGET /api/reports/last-month- Last month reportGET /api/reports/last-n-months/{n}- Last N months reportGET /api/reports/monthly-trend- Monthly trend dataGET /api/reports/summary- Overall summary
The app uses Claude Sonnet AI for intelligent expense categorization with keyword-based fallback. This provides:
- π½οΈ Food: restaurant, lunch, coffee, grocery, etc.
- π Transport: uber, taxi, fuel, bus, flight, etc.
- π¬ Entertainment: movie, netflix, gym, concert, etc.
- π Shopping: clothes, amazon, electronics, etc.
- π₯ Healthcare: doctor, medicine, hospital, etc.
- π‘ Utilities: electricity, internet, rent, etc.
- π Education: course, books, fees, etc.
- π Other: fallback category
- Claude AI Analysis: Uses Claude Sonnet to understand context and nuances
- Indian Context Aware: Recognizes Swiggy=Food, Ola=Transport, etc.
- Keyword Fallback: Falls back to keyword matching if API unavailable
- Robust Error Handling: Always provides a category, never fails
- Superior Context Understanding: Better than keyword matching alone
- Indian Market Awareness: Understands local brands and services
- Cost Efficient: Generally more cost-effective than GPT-4
- Reliable Fallback: Keyword system ensures 100% uptime
- β Amount validation (positive, reasonable limits)
- β Note length limits and required fields
- β Date validation (no future dates beyond reasonable)
- β Category ownership verification
- β Network timeouts and retries
- β Authentication token expiry
- β Database constraint violations
- β Invalid input sanitization
- β Empty expense lists
- β Category deletion (moves to "Other")
- β Concurrent data modifications
- β Large dataset performance
Backend
backend/
βββ app/
β βββ routers/ # API endpoints
β βββ models.py # Pydantic models
β βββ auth.py # Authentication logic
β βββ database.py # Database connection
β βββ ai_categorizer.py # AI categorization
β βββ config.py # Configuration
βββ tests/ # Test files
βββ main.py # FastAPI app
Android
android-app/src/main/java/com/expensetracker/app/
βββ data/ # Data layer (repositories, API)
βββ domain/ # Business logic (models, use cases)
βββ presentation/ # UI layer (Compose screens)
βββ di/ # Dependency injection
βββ utils/ # Utility functions
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
- Write tests for all new features
- Maintain >80% code coverage
- Test both happy path and error scenarios
- Include integration tests for API endpoints
- Deploy to platforms like Railway, Render, or AWS
- Set environment variables for production
- Use production Supabase instance
- Build release APK:
./gradlew assembleRelease - Upload to Google Play Store
- Update API endpoint to production URL
This project is licensed under the MIT License - see the LICENSE file for details.
For support or questions:
- Create an issue in the repository
- Check existing documentation
- Review test files for usage examples