| URL | |
|---|---|
| Frontend | https://lootledger-gamma.vercel.app |
| Backend API | https://lootledger.onrender.com |
Note: Backend is hosted on Render's free tier and may take 30–60 seconds to wake up on first request.
LootLedger is a full-stack personal finance tracker built specifically for gaming platform economies. Whether you're flipping CS2 skins, trading in-game items, or tracking Valorant point purchases — LootLedger gives you a clear, data-driven picture of exactly where your money goes and what comes back.
Log every deposit, withdrawal, profit, and loss. The dashboard then aggregates your transactions into weekly, monthly, and yearly profit/loss reports with interactive charts — so you always know if you're actually winning.
Most finance apps aren't built for gamers. They don't understand the difference between money added, money withdrawn, profits from trades, or losses from bets. LootLedger is purpose-built for that use case, with a clean REST API designed to eventually plug into live gaming platform APIs for automated tracking.
- 🔐 JWT Authentication — Secure register/login with bcrypt password hashing
- 💸 Transaction Logging — Add, edit, and delete transactions with type, category, date, and notes
- 📊 P&L Analytics — Automatic profit/loss calculation across all transactions
- 📅 Time Filters — Summary views for this week, this month, this year, and all-time
- 🔍 Advanced Filtering — Filter transactions by type and custom date ranges
- 📈 Interactive Charts — Line chart showing money in vs money out over time
| Type | Description |
|---|---|
deposit |
Money added to a platform |
withdrawal |
Money taken out from a platform |
profit |
Money earned from trades, bets, or sales |
loss |
Money lost on trades, bets, or purchases |
- 📤 CSV export of transaction history
- 🔗 Live Steam Marketplace API integration
- 🪙 Coinbase OAuth for crypto gaming wallets
- 📧 Weekly P&L summary via email
- 🌐 Chrome extension for auto-logging on gaming marketplaces
| Technology | Purpose |
|---|---|
| Node.js | Runtime environment |
| Express.js | REST API framework |
| PostgreSQL | Relational database |
| Prisma ORM | Type-safe database access and migrations |
| JWT | Stateless authentication |
| bcryptjs | Password hashing |
| Jest + Supertest | Unit and integration testing |
| Nodemon | Development hot-reload |
| Technology | Purpose |
|---|---|
| React (Vite) | UI framework |
| Tailwind CSS v4 | Utility-first styling |
| Recharts | Interactive data charts |
| Axios | HTTP client with interceptors |
| React Router v7 | Client-side routing |
| Service | Purpose |
|---|---|
| Render | Backend API + PostgreSQL hosting |
| Vercel | Frontend hosting with CI/CD |
| GitHub | Version control |
lootledger/
│
├── client/ # React frontend (Vite)
│ └── src/
│ ├── api/
│ │ └── axios.js # Base Axios instance with interceptors
│ ├── components/
│ │ ├── Navbar.jsx
│ │ └── TransactionCard.jsx
│ ├── context/
│ │ └── AuthContext.jsx # Global auth state
│ ├── pages/
│ │ ├── Login.jsx
│ │ ├── Register.jsx
│ │ ├── Dashboard.jsx # Analytics + charts
│ │ └── Transactions.jsx # CRUD interface
│ ├── App.jsx
│ └── main.jsx
│
├── server/ # Node.js backend
│ ├── controllers/
│ │ ├── authController.js # Register + login logic
│ │ └── transactionController.js # Full CRUD + summary logic
│ ├── middleware/
│ │ └── auth.js # JWT verification middleware
│ ├── prisma/
│ │ ├── migrations/ # Auto-generated migration history
│ │ └── schema.prisma # Database schema
│ ├── routes/
│ │ ├── auth.js # Auth route mapping
│ │ └── transactions.js # Transaction route mapping
│ ├── .env # Environment variables (gitignored)
│ ├── .gitignore
│ ├── index.js # Express entry point
│ └── package.json
│
└── README.md
- Node.js v18+
- PostgreSQL installed and running locally
- Git
git clone https://github.com/ari9516/lootledger.git
cd lootledgercd server
npm installCreate a .env file inside /server:
DATABASE_URL="postgresql://youruser:yourpassword@localhost:5432/lootledger"
JWT_SECRET="your_super_secret_jwt_key_here"
PORT=5000Run Prisma migrations and start the server:
npx prisma migrate dev --name init
npm run devBackend runs at → http://localhost:5000
cd ../client
npm install
npm run devCreate a .env file inside /client:
VITE_API_URL=http://localhost:5000/apiFrontend runs at → http://localhost:5173
https://lootledger.onrender.com/api
| Method | Endpoint | Auth | Body | Description |
|---|---|---|---|---|
POST |
/auth/register |
❌ | { email, password } |
Register new user |
POST |
/auth/login |
❌ | { email, password } |
Login and receive JWT |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/transactions |
✅ | Get all transactions |
GET |
/transactions?type=profit |
✅ | Filter by type |
GET |
/transactions?startDate=&endDate= |
✅ | Filter by date range |
GET |
/transactions/summary |
✅ | All-time P&L summary |
GET |
/transactions/summary?period=week |
✅ | Weekly summary |
GET |
/transactions/summary?period=month |
✅ | Monthly summary |
GET |
/transactions/summary?period=year |
✅ | Yearly summary |
POST |
/transactions |
✅ | Create new transaction |
PUT |
/transactions/:id |
✅ | Update transaction |
DELETE |
/transactions/:id |
✅ | Delete transaction |
Register
POST /api/auth/register
{
"email": "ari@example.com",
"password": "securepass123"
}
Response 201:
{
"token": "eyJhbGciOiJIUzI1NiIsInR...",
"user": { "id": "uuid", "email": "ari@example.com" }
}Create Transaction
POST /api/transactions
Authorization: Bearer <token>
{
"amount": 1250.00,
"type": "profit",
"category": "Tournament Win",
"date": "2026-06-07",
"notes": "Won CS2 tournament"
}
Response 201:
{
"id": "uuid",
"amount": 1250,
"type": "profit",
"category": "Tournament Win",
"date": "2026-06-07T00:00:00.000Z",
"notes": "Won CS2 tournament",
"userId": "uuid",
"createdAt": "2026-06-07T10:30:00.000Z",
"updatedAt": "2026-06-07T10:30:00.000Z"
}Summary Response
GET /api/transactions/summary?period=month
Authorization: Bearer <token>
{
"totalIn": 3200.00,
"totalOut": 1800.00,
"netProfit": 1400.00,
"transactionCount": 12,
"period": "month"
}All transaction routes require a valid JWT in the Authorization header:
Authorization: Bearer <your_jwt_token>
Tokens are valid for 7 days. On expiry, re-authenticate via /api/auth/login.
model User {
id String @id @default(uuid())
email String @unique
password String
createdAt DateTime @default(now())
transactions Transaction[]
}
model Transaction {
id String @id @default(uuid())
amount Float
type String // deposit | withdrawal | profit | loss
category String
date DateTime
notes String?
userId String
user User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}cd server
npm testTests cover:
- Transaction P&L calculation logic
- Summary aggregation by period
- Auth middleware token verification
- Push code to GitHub
- Go to render.com → New Web Service → connect repo
- Set root directory to
server - Set build command:
npm install && npx prisma generate - Set start command:
npx prisma migrate deploy && node index.js - Create a PostgreSQL database on Render
- Add environment variables:
DATABASE_URL,JWT_SECRET,NODE_ENV=production
- Go to vercel.com → Import GitHub repo
- Set root directory to
client - Add environment variable:
VITE_API_URL=https://lootledger.onrender.com/api - Add
vercel.jsonin/clientfor React Router support - Deploy
Contributions are welcome. To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Commit your changes (
git commit -m 'feat: add your feature') - Push to the branch (
git push origin feature/your-feature) - Open a Pull Request
Please follow Conventional Commits for commit messages.
Arnab Kumar Computer Science @ VIT Bhopal University
Distributed under the MIT License. See LICENSE for more information.