This guide will help you set up the FinFlow API for local development. Choose either the Local Setup (without Docker for the app) or Docker Setup (recommended for consistency).
- Prerequisites
- Environment Configuration
- Local Setup (Without Docker)
- Docker Setup (Recommended)
- Third-Party Services Configuration
- Troubleshooting
Before starting, ensure you have the following installed:
| Tool | Version | Required For |
|---|---|---|
| Node.js | 22+ | Local setup |
| npm | 10+ | Local setup |
| Docker | 24+ | Docker setup |
| Docker Compose | 2.20+ | Docker setup |
| Git | 2.40+ | Both |
git clone https://github.com/anuragsahu-dev/finflow-api.git
cd finflow-apicp .env.example .envOpen .env and configure the following:
# Server
PORT=3000
NODE_ENV=development
CLIENT_URL=http://localhost:5173
APP_URL=http://localhost:3000
# Database (Local Docker)
DATABASE_URL=postgresql://postgres:password@localhost:5432/finflowdb
# Redis (Local Docker)
REDIS_HOST=localhost
REDIS_PORT=6379
# JWT (Generate secure random strings for production)
ACCESS_TOKEN_SECRET=your-super-secret-access-token-key
REFRESH_TOKEN_SECRET=your-super-secret-refresh-token-key
ACCESS_TOKEN_EXPIRY=15m
REFRESH_TOKEN_EXPIRY=7d
SALT_ROUNDS=10
# Email (Required for OTP)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-passwordNote: See Third-Party Services Configuration for Razorpay and AWS S3 setup.
Use this approach if you want to run the Node.js app locally while using Docker only for PostgreSQL and Redis.
npm installdocker compose -f compose.dev.yaml up postgres redis -dnpx prisma generatenpx prisma migrate devnpm run seednpm run dev| Service | URL |
|---|---|
| API | http://localhost:3000/api/v1 |
| Swagger Docs | http://localhost:3000/api-docs |
| Health Check | http://localhost:3000/health |
Use this approach to run the entire stack (PostgreSQL, Redis, and the app) inside Docker containers. This ensures consistency across different development environments.
Run these commands in order to build and initialize the project from scratch:
# 1. Build the images (clean build with no cache)
docker compose -f compose.dev.yaml build --no-cache
# 2. Start all services in detached mode (background)
docker compose -f compose.dev.yaml up -d
# 3. Apply database migrations
docker compose -f compose.dev.yaml exec server npx prisma migrate dev
# 4. Seed database with initial data
docker compose -f compose.dev.yaml exec server npm run seed| Service | URL |
|---|---|
| API | http://localhost:3000/api/v1 |
| Swagger Docs | http://localhost:3000/api-docs |
| Health Check | http://localhost:3000/health |
Starts all services in the background:
docker compose -f compose.dev.yaml up -dStream logs to your terminal:
docker compose -f compose.dev.yaml logs serverStops and removes the containers (data is preserved):
docker compose -f compose.dev.yaml downStops containers and removes volumes. Use this to start fresh:
docker compose -f compose.dev.yaml down -vWarning: This deletes all database data. You'll need to run migrations and seed again.
Action: Just save the file. The app will auto-reload instantly via nodemon. No restart needed.
Action: Rebuild to install new dependencies:
docker compose -f compose.dev.yaml up --build -dAction: Create a new migration:
docker compose -f compose.dev.yaml exec server npx prisma migrate dev --name "your_migration_name"Action: Use Prisma Studio:
# Local setup
npx prisma studio
# Docker setup
docker compose -f compose.dev.yaml exec server npx prisma studio| Command | Description |
|---|---|
docker compose -f compose.dev.yaml ps |
List running containers |
docker compose -f compose.dev.yaml logs -f |
Stream all logs |
docker compose -f compose.dev.yaml logs -f server |
Stream only app logs |
docker compose -f compose.dev.yaml exec server sh |
Shell into app container |
docker compose -f compose.dev.yaml restart server |
Restart only the app |
docker compose -f compose.dev.yaml down |
Stop all containers |
docker compose -f compose.dev.yaml down -v |
Stop and remove volumes |
Razorpay is required for the payment and subscription features.
- Create an account at Razorpay Dashboard
- Go to Settings → API Keys
- Click Generate Test Key
- Copy the Key ID and Key Secret
- Install ngrok:
npm install -g ngrok - Start your server:
npm run devordocker compose up -d - Expose your server:
ngrok http 3000 - Copy the HTTPS URL (e.g.,
https://abc123.ngrok.io) - In Razorpay Dashboard → Settings → Webhooks:
- URL:
https://abc123.ngrok.io/api/v1/payments/webhook - Events:
payment.captured,payment.failed
- URL:
- Copy the Webhook Secret
RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxx
RAZORPAY_KEY_SECRET=your-razorpay-key-secret
RAZORPAY_WEBHOOK_SECRET=your-webhook-secretLearn More: See docs/PAYMENT_SYSTEM.md for complete payment flow documentation.
AWS S3 is required for avatar uploads using pre-signed URLs.
- Go to AWS S3 Console
- Click Create bucket
- Choose a unique bucket name (e.g.,
finflow-avatars) - Select your preferred region
- Uncheck Block all public access (for avatar URLs to be accessible)
- Create the bucket
In your bucket settings, add this CORS configuration:
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedOrigins": [
"http://localhost:5173",
"https://your-frontend-domain.com"
],
"ExposeHeaders": ["ETag"]
}
]- Go to AWS IAM Console
- Create a new user with Programmatic access
- Attach the
AmazonS3FullAccesspolicy (or create a custom policy for your bucket) - Save the Access Key ID and Secret Access Key
AWS_REGION=ap-south-1
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
AWS_S3_BUCKET_NAME=your-bucket-nameRequired for "Login with Google" feature.
- Go to Google Cloud Console
- Create a new project or select existing
- Go to APIs & Services → Credentials
- Click Create Credentials → OAuth 2.0 Client IDs
- Application type: Web application
- Add authorized redirect URI:
http://localhost:3000/api/v1/auth/google/callback
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_CALLBACK_URL=http://localhost:3000/api/v1/auth/google/callback# Find process using port 3000
lsof -i :3000
# or on Windows
netstat -ano | findstr :3000
# Kill the process
kill -9 <PID>- Ensure PostgreSQL is running:
docker compose -f compose.dev.yaml ps
- Check if the
DATABASE_URLin.envis correct - Wait a few seconds for the database to be ready after starting
- Ensure Redis is running:
docker compose -f compose.dev.yaml ps
- Check
REDIS_HOSTandREDIS_PORTin.env
# Reset the database (WARNING: Deletes all data)
npx prisma migrate reset
# Generate Prisma client
npx prisma generate# Remove all containers and rebuild
docker compose -f compose.dev.yaml down -v
docker compose -f compose.dev.yaml build --no-cache
docker compose -f compose.dev.yaml up -d- Access Swagger documentation at
http://localhost:3000/api-docs - Test the authentication flow with OTP
- Set up Razorpay for payment testing (see docs/PAYMENT_SYSTEM.md)
- Explore the API endpoints