A full-stack expense tracking app that uses AI to parse natural language input.
Built by: Anglesvar Appiya Chandrasekar GitHub: https://github.com/Anglesvar Time to build: [3 hours] (with AI assistance)
- Mobile: React Native, Expo, TypeScript
- Backend: Node.js, Express, TypeScript
- Database: SQLite
- AI: [Groq/OpenAI/Gemini] API
- Node.js 18+
- npm or yarn
- Expo CLI
- [AI Service] API key
cd backend
npm install
cp .env.example .env
# Add your AI API key to .env
npm run devcd mobile
npm install
npm start
# Scan QR code with Expo Go app
ai-expense-tracker/
backend/
βββ src/
β βββ index.ts # Application entry point
β βββ config/ # Configuration files
β β βββ config.ts # Environment config
β βββ database/ # Database layer
β β βββ connection.ts # DB connection & initialization
β | βββ utils.ts # DB utility functions
β β βββ dto/ # Data Transfer Objects
β β βββ create-expense.dto.ts
β β βββ update-expense.dto.ts
β β βββ index.ts
| |
β βββ services/ # Business logic layer
β β βββ expense.service.ts
β β βββ expense-parser.service.ts
β βββ types/ # Business logic layer
β β βββ expense.ts
β β βββ expense-filters.ts
β β βββ parsed-expense.ts
β β βββ index.ts
β βββ routes/ # API routes layer
β β βββ index.ts # Routes aggregator
β β βββ expenses.routes.ts # Expense endpoints
β βββ middleware/ # Express middleware
β β βββ error.middleware.ts
β β βββ validation.middleware.ts
β βββ utils/ # Helper utilities
β βββ async-handler.ts
β βββ validate-and-normalize.ts
βββ .env # Environment variables
βββ .env.example # Example env file
βββ package.json
βββ tsconfig.json
mobile/
βββ App.tsx # Main app entry point
βββ screens/
β βββ ExpenseTrackerScreen.tsx # Main screen with business logic
βββ components/
β βββ index.ts # Component exports
β βββ Header.tsx # App header with title
β βββ ExpenseInput.tsx # Input field with Add button
β β βββ TextInput
β β βββ AddButton
β β βββ LoadingIndicator
β βββ SuccessCard.tsx # Success feedback card
β βββ ExpenseList.tsx # FlatList with pull-to-refresh
β βββ ExpenseItem.tsx # Individual expense item
β βββ CategoryIcon (emoji + name)
β βββ Amount
β βββ Description
β βββ TimeAgo
β βββ DeleteButton
βββ api/ # API service layer
| helpers/
β βββ expense-api-error.ts
β βββ fetch-with-timeout.ts
β βββ handle-response.ts
β βββ add-expense.api.ts
β βββ delete-expense.api.ts
β βββ get-expense.api.ts
β βββ index.ts
βββ types.ts # TypeScript interfaces
βββ utils.ts # Utility functions
βββ config.ts # Configuration
βββ package.json # Dependencies
βββ tsconfig.json # TypeScript config
|-- README.md
I used this system prompt for expense parsing:
You are an expense parser. Extract expense information from natural language input.
RULES:
1. Extract the amount as a number (no currency symbols)
2. Default currency is INR unless explicitly mentioned (USD, EUR, etc.)
3. Categorize into EXACTLY one of these categories:
- Food & Dining (restaurants, cafes, food delivery, groceries)
- Transport (uber, ola, taxi, fuel, parking, metro)
- Shopping (clothes, electronics, amazon, flipkart)
- Entertainment (movies, netflix, spotify, games)
- Bills & Utilities (electricity, water, internet, phone)
- Health (medicine, doctor, gym, pharmacy)
- Travel (flights, hotels, trips)
- Other (anything that doesn't fit above)
4. Description should be a clean summary (not the raw input)
5. Merchant is the company/store name if mentioned, null otherwise
RESPOND ONLY WITH VALID JSON, no other text:
{
"amount": <number>,
"currency": "<string>",
"category": "<string>",
"description": "<string>",
"merchant": "<string or null>"
}
If the input is invalid or you cannot extract an amount, respond:
{
"error": "Could not parse expense. Please include an amount.",
"amount": null
}