Skip to content

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

Node.js Express.js TypeScript JavaScript REST API MongoDB PostgreSQL JWT Docker Postman GitHub Actions Render

Finance Dashboard API

A backend API for a multi-role finance dashboard. Supports financial record management, role-based access control, JWT authentication, and dashboard analytics.


Tech Stack

Layer Choice
Runtime Node.js + TypeScript
Framework Express
ORM Prisma
Database SQLite (dev) / PostgreSQL (prod)
Auth JWT + bcrypt
Validation Zod
Tests Vitest
Rate limiting express-rate-limit

Quick Start

# 1. Install dependencies, generate Prisma client, create DB, seed data
npm run setup

# 2. Start dev server with hot reload
npm run dev

Server starts at http://localhost:3000


Environment Variables

Copy .env.example to .env and fill in:

DATABASE_URL="file:./dev.db"       # SQLite path (or postgres:// for Postgres)
JWT_SECRET="your-secret-here"      # Change in production
JWT_EXPIRES_IN="7d"
PORT=3000
NODE_ENV=development

Test Credentials (after seeding)

Email Password Role
admin@finance.dev password123 ADMIN
analyst@finance.dev password123 ANALYST
viewer@finance.dev password123 VIEWER

Roles & Permissions

Action VIEWER ANALYST ADMIN
View records ✅ ✅ ✅
View dashboard ✅ ✅ ✅
View trends ❌ ✅ ✅
Create records ❌ ✅ ✅
Update own records ❌ ✅ ✅
Update any record ❌ ❌ ✅
Delete records (soft) ❌ ❌ ✅
Manage users ❌ ❌ ✅

API Reference

Auth

POST   /auth/register          Create account (role defaults to VIEWER)
POST   /auth/login             Get JWT token
GET    /auth/me                Get current user (requires token)

Users (ADMIN only)

GET    /users                  List users  ?role=ADMIN&isActive=true&page=1&limit=20
GET    /users/:id              Get user by ID
PATCH  /users/:id/role         Change role  { "role": "ANALYST" }
PATCH  /users/:id/status       Toggle active  { "isActive": false }
DELETE /users/:id              Permanently delete user

Financial Records

GET    /records                List records (VIEWER+)
                               ?type=income&category=Salary&from=2024-01-01T00:00:00Z
                               &to=2024-12-31T23:59:59Z&search=rent&page=1&limit=20
                               &sortBy=date&order=desc
GET    /records/:id            Get single record (VIEWER+)
POST   /records                Create record (ANALYST+)
PATCH  /records/:id            Update record (ANALYST+ and must own it, or ADMIN)
DELETE /records/:id            Soft delete (ADMIN only)

Dashboard

GET    /dashboard/summary           Totals + net balance (VIEWER+)
GET    /dashboard/categories        Category breakdown (VIEWER+)
GET    /dashboard/recent?limit=10   Recent activity (VIEWER+)
GET    /dashboard/top-categories    Top 5 income/expense categories (VIEWER+)
GET    /dashboard/trends/monthly    Month-by-month trends (ANALYST+)  ?months=12
GET    /dashboard/trends/weekly     Week-by-week trends (ANALYST+)    ?weeks=8

Health

GET    /health                 Server status check

Example Requests

1. Login and get token

curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@finance.dev","password":"password123"}'

2. Create a financial record

curl -X POST http://localhost:3000/records \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4500,
    "type": "income",
    "category": "Salary",
    "date": "2024-01-15T00:00:00Z",
    "description": "January salary"
  }'

3. Get dashboard summary

curl http://localhost:3000/dashboard/summary \
  -H "Authorization: Bearer <token>"

4. Filter records

curl "http://localhost:3000/records?type=expense&category=Rent&from=2024-01-01T00:00:00Z" \
  -H "Authorization: Bearer <token>"

Running Tests

npm test

Tests cover:

  • Dashboard aggregation logic (summary, category totals, monthly trends)
  • RBAC middleware (role hierarchy, blocking, allowing)

Design Decisions & Assumptions

  1. SQLite by default — Zero-config for evaluation. Change DATABASE_URL to a Postgres connection string and re-run prisma migrate dev to use Postgres; no code changes needed.

  2. Roles are hierarchical — ADMIN > ANALYST > VIEWER. The requireRole("ANALYST") guard allows ANALYST and ADMIN, not just ANALYST.

  3. Soft deletes — Records are never physically removed. They get a deletedAt timestamp and are excluded from all queries. This preserves audit history.

  4. Owner-or-admin for PATCH — An ANALYST can only update records they created. ADMINs can update any record.

  5. JWT expiry — 7 days, configurable via JWT_EXPIRES_IN in .env. No refresh token mechanism (out of scope), but trivial to add.

  6. Pagination defaults — page=1, limit=20, max limit=100.

  7. New users default to VIEWER — Only an ADMIN can promote a user to ANALYST or ADMIN after registration.

  8. Rate limiting — 200 req/15min globally; 20 req/15min on auth routes specifically to mitigate brute-force attacks.


Switching to PostgreSQL

DATABASE_URL="postgresql://user:password@localhost:5432/finance_db"
npx prisma migrate dev --name init
npm run db:seed

About

A backend API for a multi-role finance dashboard. Built with Node.js, Express, TypeScript, and Prisma. Features JWT authentication, role-based access control (Admin, Analyst, Viewer), financial record management with filtering and pagination, and dashboard analytics including category breakdowns and monthly trends.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages