289

Finance Dashboard – Backend System

A production-quality REST API backend for a multi-tenant finance management platform — built in 2 weeks with Node.js, TypeScript, Express, and PostgreSQL. Features dual-scope RBAC, multi-method auth, financial analytics, and full Swagger API documentation.

GitHub →Website →

System design
System design

Finance Dashboard is a fully deployed backend system simulating a real-world multi-tenant finance management platform. Originally started as a technical assignment, I extended it into a complete learning project to build a full production-quality backend from scratch — authentication, authorization, financial data, analytics APIs, and documentation — with nothing left half-finished.

Built in approximately 2 weeks of focused development. Backend is live and Swagger API docs are publicly accessible at finance-dashboard.jagritnokwal.com/docs.

Multi-Tenant Architecture The system follows an Org → Project hierarchy where a single user can belong to multiple organizations, and within each organization, participate in multiple projects — each with independent role assignments. This structure cleanly separates permission boundaries across tenants.

Dual-Scope RBAC (the interesting part) Rather than a flat permission table, I implemented two separate role scopes with their own membership tables and enums:

Organization Level — OrganizationMember table with OrganizationRole: OWNER → ADMIN → MEMBER

Project Level — ProjectMember table with ProjectRole: OWNER → ADMIN → ANALYST → VIEWER

Both enforce uniqueness constraints at the DB level. Permission domains (Finance, Analytics) are layered on top of project roles, so a member can have READ + Finance access without MANAGE + Analytics.

The invitation system is also role-aware — a single invite can pre-assign an org role plus membership in multiple projects simultaneously, each with a different project role.

Authentication & Session Design Implemented multiple auth methods (Google OAuth, Email/Password, OTP) with a deliberate stateless vs. stateful decision baked in — JWT for stateless route verification where DB checks aren't needed, and stateful session validation where token revocation matters (logout, user status changes, refresh token rotation).

Financial Records & Analytics APIs Full financial record lifecycle: income/expense entries with categories, tags, currency, payment source tracking, filtering, pagination, and soft delete. Analytics endpoints serve pre-aggregated data for dashboards: total income/expenses, net balance, category-wise breakdowns, and monthly/weekly trends.

Tech Decisions

  • PostgreSQL via NeonDB — chosen for its serverless/headless hosting model, eliminating infra overhead while keeping full Postgres compatibility
  • Prisma ORM — clean schema definition, version-controlled migrations, and self-documenting models
  • Zod — schema-based API payload validation with structured error messaging out of the box