Skip to main content

Setup Guide

This guide provides detailed instructions for installing, configuring, and deploying Your Finance App. Whether you’re setting up for local development or preparing for production, this guide has you covered.

Prerequisites

System Requirements

Node.js

Version 18.0.0 or higher

pnpm

Version 8.0.0 or higher

PostgreSQL

Version 14+ (via Supabase)

Required Tools

  • Git - Version control system
  • Code Editor - VS Code recommended
  • HTTP Client - Postman, Thunder Client, or curl
  • Terminal - Command line interface

Operating System Support

  • Linux - Ubuntu 20.04+, Debian 11+, or similar
  • macOS - 12 (Monterey) or higher
  • Windows - Windows 10/11 with WSL2 recommended

Installation

Step 1: Install Node.js

Install Node.js using NodeSource:
# Download and run NodeSource setup script
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -

# Install Node.js
sudo apt-get install -y nodejs

# Verify installation
node --version  # Should show v18.x.x or higher
npm --version   # Should show 9.x.x or higher

Step 2: Install pnpm

# Install pnpm globally
npm install -g pnpm

# Verify installation
pnpm --version  # Should show 8.x.x or higher
Why pnpm?
  • 2-3x faster than npm
  • Saves disk space with content-addressable storage
  • Built-in monorepo workspace support
  • Strict dependency management prevents phantom dependencies

Step 3: Clone the Repository

# Create a directory for your projects
mkdir -p ~/dev
cd ~/dev

# Clone the repository
git clone https://github.com/RoAriel/your-finance-app.git
cd your-finance-app

# Explore the structure
ls -la
You should see:
drwxr-xr-x  apps/
drwxr-xr-x  docs/
-rw-r--r--  package.json
-rw-r--r--  pnpm-workspace.yaml
-rw-r--r--  README.md

Database Setup

Creating a Supabase Project

1

Sign up for Supabase

  1. Go to supabase.com
  2. Click “Start your project”
  3. Sign up with GitHub (recommended) or email
2

Create a new project

  1. Click “New Project” from your dashboard
  2. Fill in the project details:
    • Name: your-finance-app (or your preferred name)
    • Database Password: Generate a strong password and save it securely
    • Region: Choose the closest region to your users
    • Pricing Plan: Free (includes 500MB database, 1GB file storage)
  3. Click “Create new project”
  4. Wait approximately 2 minutes for provisioning
3

Get connection strings

Once your project is ready:
  1. Navigate to Settings (⚙️ icon) → Database
  2. Scroll to Connection string section
  3. Select URI from the mode dropdown
  4. You’ll see two connection types:
Transaction Mode (Port 6543) - Use for application queries:
postgresql://postgres.xxxxx:[email protected]:6543/postgres?pgbouncer=true
Session Mode (Port 5432) - Use for migrations:
postgresql://postgres.xxxxx:[email protected]:5432/postgres
Copy both connection strings - you’ll need them in the next step. Replace PASSWORD with your actual database password.

Understanding Connection Modes

Port: 6543Used for regular application queries through PgBouncer connection pooler.Advantages:
  • Connection pooling reduces database load
  • Better for high-traffic applications
  • Faster connection establishment
Use for:
  • Application runtime queries
  • Production environments
  • Any SELECT, INSERT, UPDATE, DELETE operations

Environment Configuration

Setting Up Environment Variables

1

Copy the example file

cd apps/backend
cp .env.example .env
2

Edit the .env file

Open apps/backend/.env in your editor and configure:
# ===========================================
# DATABASE CONFIGURATION
# ===========================================

# Transaction mode (port 6543) - For application queries
DATABASE_URL="postgresql://postgres.PROJECT_ID:[email protected]:6543/postgres?pgbouncer=true"

# Session mode (port 5432) - For migrations
DIRECT_URL="postgresql://postgres.PROJECT_ID:[email protected]:5432/postgres"

# ===========================================
# JWT CONFIGURATION
# ===========================================

# Secret key for signing JWT tokens
JWT_SECRET="your-secure-secret-key-here"

# Token expiration time (examples: 7d, 24h, 60m)
JWT_EXPIRES_IN="7d"
3

Generate a secure JWT secret

Use Node.js to generate a cryptographically secure random string:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Example output:
a3d8f9e2b1c4567890abcdef1234567890abcdef1234567890abcdef123456
Copy this value and paste it as your JWT_SECRET.
4

Replace placeholders

In your .env file, replace:
  • PROJECT_ID - Your Supabase project ID (from connection string)
  • YOUR_PASSWORD - Your Supabase database password
  • REGION - Your database region (e.g., aws-0-sa-east-1)
  • your-secure-secret-key-here - The generated JWT secret

Environment Variables Explained

DATABASE_URL
string
required
Connection string for application queries. Uses transaction mode (port 6543) with PgBouncer pooling.
DIRECT_URL
string
required
Connection string for migrations. Uses session mode (port 5432) for direct PostgreSQL access.
JWT_SECRET
string
required
Secret key used to sign and verify JWT tokens. Must be a long, random string. Never share this or commit it to version control.
JWT_EXPIRES_IN
string
default:"7d"
How long JWT tokens remain valid. Accepts formats like 7d (days), 24h (hours), 60m (minutes).
Security Best Practices:
  • Never commit .env files to version control
  • Use different secrets for development and production
  • Rotate JWT secrets periodically in production
  • Use strong, unique database passwords

Installing Dependencies

Install Workspace Dependencies

# From the project root
cd ~/dev/your-finance-app

# Install all dependencies for the monorepo
pnpm install
This command:
  1. Reads pnpm-workspace.yaml to identify workspaces
  2. Installs dependencies for all workspace packages
  3. Creates symlinks between local packages
  4. Downloads and caches external dependencies
Installation includes:
  • NestJS framework and modules
  • Prisma ORM and client
  • Authentication libraries (Passport, JWT, bcrypt)
  • Validation libraries (class-validator, class-transformer)
  • Development tools (ESLint, Prettier, TypeScript)
First installation typically takes 2-5 minutes depending on your internet speed. Subsequent installs are much faster due to pnpm’s caching.

Verify Installation

# Check that node_modules were created
ls -la node_modules/
ls -la apps/backend/node_modules/

# View installed packages
pnpm list --depth=0

Database Migrations

Running Migrations

1

Generate Prisma Client

Generate TypeScript types from your Prisma schema:
cd apps/backend
npx prisma generate
This creates:
  • Type-safe Prisma Client
  • TypeScript interfaces for your models
  • Auto-completion for queries
2

Deploy migrations

Apply all pending migrations to your database:
npx prisma migrate deploy
Expected output:
Applying migration `20260104185727_init`
Applying migration `20260109000725_add_transactions_and_categories`

The following migration(s) have been applied:

migrations/
  └─ 20260104185727_init/
    └─ migration.sql
  └─ 20260109000725_add_transactions_and_categories/
    └─ migration.sql

All migrations have been successfully applied.
3

Verify in Supabase

Check that tables were created:
  1. Go to your Supabase dashboard
  2. Click Table Editor
  3. Verify these tables exist:
    • users - User accounts
    • transactions - Financial transactions
    • categories - Transaction categories

Understanding the Schema

The Prisma schema defines three main models:
model User {
  id        String   @id @default(uuid())
  email     String   @unique
  password  String
  name      String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  
  transactions Transaction[]
  
  @@map("users")
}

Running the Application

Development Mode

Start the server with hot-reload enabled:
# From project root
pnpm dev:backend

# Or from apps/backend directory
cd apps/backend
pnpm run start:dev
What happens:
  1. NestJS compiles TypeScript to JavaScript
  2. Starts the server on port 3000
  3. Watches for file changes
  4. Auto-restarts on code modifications
Expected console output:
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [NestFactory] Starting Nest application...
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [InstanceLoader] PrismaModule dependencies initialized +20ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [InstanceLoader] ConfigModule dependencies initialized +5ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [InstanceLoader] AuthModule dependencies initialized +15ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [InstanceLoader] TransactionsModule dependencies initialized +10ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RoutesResolver] AppController {/}: +8ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RouterExplorer] Mapped {/, GET} route +3ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RoutesResolver] AuthController {/auth}: +1ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RouterExplorer] Mapped {/auth/register, POST} route +2ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RouterExplorer] Mapped {/auth/login, POST} route +1ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RouterExplorer] Mapped {/auth/profile, GET} route +1ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RoutesResolver] TransactionsController {/transactions}: +1ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RouterExplorer] Mapped {/transactions, POST} route +1ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RouterExplorer] Mapped {/transactions, GET} route +1ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [RouterExplorer] Mapped {/transactions/balance, GET} route +0ms
[Nest] 12345  - 03/04/2026, 10:30:00 AM     LOG [NestApplication] Nest application successfully started +5ms
The server is now running at http://localhost:3000

Production Mode

Build and run for production:
# Build the application
pnpm run build

# Start in production mode
pnpm run start:prod
Differences from development:
  • Code is optimized and minified
  • No file watching or hot reload
  • Better performance
  • Source maps disabled

Testing the Installation

Test Health Endpoint

curl http://localhost:3000
# Expected: "Hello World!"

Test User Registration

curl -X POST http://localhost:3000/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePass123!",
    "name": "Alice Johnson"
  }'
Expected response:
{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]",
    "name": "Alice Johnson",
    "createdAt": "2026-03-04T10:30:00.000Z",
    "updatedAt": "2026-03-04T10:30:00.000Z"
  },
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJlbWFpbCI6ImFsaWNlQGV4YW1wbGUuY29tIiwiaWF0IjoxNzA5NTUwNjAwLCJleHAiOjE3MTAxNTU0MDB9.signature"
}

Test Authentication

# Save the token
TOKEN="your-token-from-registration"

# Get user profile
curl http://localhost:3000/auth/profile \
  -H "Authorization: Bearer $TOKEN"

Test Transaction Creation

curl -X POST http://localhost:3000/transactions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "type": "expense",
    "amount": 1250.50,
    "description": "Grocery shopping",
    "currency": "USD"
  }'

Troubleshooting

Common Issues and Solutions

Cause: Dependencies not installed or corrupted.Solution:
cd apps/backend
rm -rf node_modules
pnpm install
Cause: .env file missing or not in correct location.Solution:
# Ensure .env exists in apps/backend/
ls -la apps/backend/.env

# If missing, copy from example
cp apps/backend/.env.example apps/backend/.env

# Edit with your values
nano apps/backend/.env
Cause: Cannot connect to database.Solutions:
  1. Verify Supabase project is running (check dashboard)
  2. Confirm connection strings are correct
  3. Check password doesn’t contain special characters that need escaping
  4. Ensure no trailing spaces in .env file
  5. Try pinging the database host
# Test connection with psql
psql "postgresql://postgres.xxxxx:[email protected]:5432/postgres"
Cause: Network or firewall issue.Solutions:
  1. Check your internet connection
  2. Verify firewall isn’t blocking ports 5432/6543
  3. Try using a different network
  4. Check if your organization blocks PostgreSQL ports
Cause: Another process is using port 3000.Solutions:Find and kill the process:
# On Mac/Linux
lsof -i :3000
kill -9 <PID>

# On Windows
netstat -ano | findstr :3000
taskkill /PID <PID> /F
Or change the port in apps/backend/src/main.ts:
await app.listen(process.env.PORT || 3001);
Cause: Prisma Client wasn’t generated after schema changes.Solution:
cd apps/backend
npx prisma generate
Cause: Database state doesn’t match migration history.Solution:
# Reset database (WARNING: Deletes all data)
npx prisma migrate reset

# Or manually resolve in Supabase dashboard

Getting More Help

Check Logs

Review server logs for detailed error messages

Prisma Studio

Use npx prisma studio to inspect database

GitHub Issues

Search or open issues on GitHub repository

Documentation

Review NestJS and Prisma official docs

Development Tools

{
  "recommendations": [
    "prisma.prisma",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "rangav.vscode-thunder-client",
    "ms-vscode.vscode-typescript-next"
  ]
}

Useful Commands

# Open Prisma Studio (database GUI)
npx prisma studio

# Create a new migration
npx prisma migrate dev --name migration_name

# Reset database (WARNING: deletes data)
npx prisma migrate reset

# Seed database
npx prisma db seed

Next Steps

Now that you have Your Finance App set up and running:

Explore the Architecture

Understand the modular structure

Learn the Database Schema

Deep dive into data models

Study Authentication

Learn how JWT auth works

API Reference

Explore all endpoints

Pro Tip: Keep your .env file secure and never commit it to version control. Use environment-specific .env files for different deployment environments.

Build docs developers (and LLMs) love