Finance Dashboard API is an Express and PostgreSQL backend for managing users, transactions, and dashboard analytics. It uses JWT authentication, role-based access control, soft deletes, and raw SQL aggregation queries.
- Clone the repository and install dependencies.
- Copy
.env.exampleto.envand fill in the values. - Run the migration in
migrations/init.sqlagainst PostgreSQL. - Start the app with
npm run devfor development ornpm startfor production. - Optionally run
npm run seedto populate demo users and transactions.
PORT- HTTP server port.DATABASE_URL- PostgreSQL connection string.JWT_SECRET- Secret used to sign access tokens.JWT_EXPIRES_IN- JWT expiration time, such as7d.
curl http://localhost:3000/health
# { "success": true, "data": { "status": "ok" } }POST /api/auth/registerPOST /api/auth/login
Example login response:
{
"success": true,
"data": {
"token": "jwt-token",
"user": {
"id": "uuid",
"name": "Admin User",
"email": "admin@example.com",
"role": "admin"
}
}
}Admin only.
GET /api/usersGET /api/users/:idPOST /api/usersPATCH /api/users/:idDELETE /api/users/:id
curl http://localhost:3000/api/users \
-H "Authorization: Bearer <your-jwt-token>"{
"success": true,
"data": [
{
"id": "uuid",
"name": "Admin User",
"email": "admin@finance.com",
"role": "admin",
"is_active": true,
"created_at": "2024-01-01T00:00:00.000Z"
}
]
}GET /api/transactions?type=income&category=salary&from=2024-01-01&to=2024-12-31&page=1&limit=20GET /api/transactions/:idPOST /api/transactionsPATCH /api/transactions/:idDELETE /api/transactions/:id
Create, update, and delete are admin only.
curl "http://localhost:3000/api/transactions?type=income&page=1" \
-H "Authorization: Bearer <your-jwt-token>"{
"success": true,
"data": {
"items": [
{
"id": "uuid",
"user_id": "uuid",
"amount": "5000.00",
"type": "income",
"category": "Salary",
"date": "2024-03-15",
"notes": "March salary",
"is_deleted": false,
"created_at": "2024-03-15T10:00:00.000Z",
"updated_at": "2024-03-15T10:00:00.000Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 1 }
}
}curl -X POST http://localhost:3000/api/transactions \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"amount": 1500.00,
"type": "income",
"category": "Freelance",
"date": "2024-03-28",
"notes": "Consulting project"
}'{
"success": true,
"data": {
"id": "uuid",
"user_id": null,
"amount": "1500.00",
"type": "income",
"category": "Freelance",
"date": "2024-03-28",
"notes": "Consulting project",
"is_deleted": false,
"created_at": "2024-03-28T12:00:00.000Z",
"updated_at": "2024-03-28T12:00:00.000Z"
}
}GET /api/dashboard/summaryGET /api/dashboard/by-categoryGET /api/dashboard/trendsGET /api/dashboard/recent
curl http://localhost:3000/api/dashboard/summary \
-H "Authorization: Bearer <your-jwt-token>"{
"success": true,
"data": {
"total_income": "15800.00",
"total_expense": "1990.00",
"net_balance": "13810.00"
}
}viewer- can log in and view transactions and dashboard data.analyst- can log in and view transactions and dashboard data.admin- can do everything, including managing users and transactions.
- Soft delete is used for transactions and user deactivation.
- JWT access tokens are used without refresh tokens.
- UUIDs are used as primary keys.
- Input validation is enforced on POST and PATCH routes.
- Dashboard endpoints are intentionally open to all authenticated roles (viewer, analyst, admin) as per the role matrix.
user_idon a transaction cannot be unlinked once set (COALESCE behavior by design).- The
notesfield accepts raw strings; XSS sanitization is out of scope for a pure API backend. - No refresh token flow — JWT expiry is configured via
JWT_EXPIRES_INin.env.
- Add rate limiting.
- Add refresh tokens.
- Add automated tests.
- Add pagination metadata for dashboard lists if needed.
To verify and test the functionality of all backend APIs, Postman was used as an API testing tool. A collection named "Finance Dashboard API" was created, containing all endpoints related to authentication, user management, transactions, and dashboard analytics.
Collection variables such as base URL and authentication token were configured to streamline request execution. The login API was used to generate a token dynamically, which was then automatically stored and applied to all secured endpoints using Bearer authentication.
The following screenshot shows the organized Postman collection with all API requests used for testing the system.

All API endpoints were successfully tested using Postman. The system correctly handled CRUD operations for users and transactions, and provided accurate dashboard insights such as total income, expenses, and trends. The use of Postman collections improved testing efficiency and ensured consistency across all API requests.