Skip to main content

Prerequisites

Before you begin, ensure you have the following installed:
  • Node.js 18+ and npm
  • PostgreSQL 14+ running locally or remotely
  • Git for cloning the repository
Make sure PostgreSQL is running and accessible before starting the application

Installation

1

Clone the Repository

Clone the source code to your local machine:
git clone <repository-url>
cd nest-uber-app-backend
2

Install Dependencies

Install all required npm packages:
npm install
This will install NestJS, TypeORM, Socket.IO, and all other dependencies defined in package.json.
3

Configure Environment Variables

Copy the example environment file and configure your settings:
cp .env.example .env
Edit .env with your database credentials and configuration:
.env
# Application
PORT=3000
NODE_ENV=development
CORS_ORIGINS=http://localhost:8100

# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=rodando
DB_SYNCHRONIZE=true
DB_LOGGING=true

# JWT Configuration
JWT_ACCESS_SECRET=your-access-secret-key-here
JWT_ACCESS_EXPIRES_IN=15m
JWT_REFRESH_SECRET=your-refresh-secret-key-here
JWT_REFRESH_EXPIRES_IN=7d
JWT_ISSUER=nest-uber-app-backend
JWT_AUDIENCE=nest-uber-app-frontend

# Bcrypt
BCRYPT_SALT_ROUNDS=12

# Driver Availability
DA_PRESENCE_TTL_SEC=120
DA_SWEEP_BATCH=1000

# Swagger Documentation
SWAGGER_ENABLED=true
SWAGGER_TITLE_API=Rodando Backend API
SWAGGER_VERSION_API=1.0
Generate secure random strings for JWT_ACCESS_SECRET and JWT_REFRESH_SECRET in production:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
4

Database Setup

The application will automatically create the database if it doesn’t exist (thanks to DatabaseInitService).If you have DB_SYNCHRONIZE=true, TypeORM will auto-create tables on startup.
Set DB_SYNCHRONIZE=false in production and use migrations instead
5

Start the Development Server

Run the application in development mode with hot-reload:
npm run start:dev
You should see output like:
[Nest] 12345  - 03/09/2026, 10:30:00 AM     LOG [NestFactory] Starting Nest application...
[Nest] 12345  - 03/09/2026, 10:30:01 AM     LOG [InstanceLoader] DatabaseModule dependencies initialized
[Nest] 12345  - 03/09/2026, 10:30:02 AM     LOG [RoutesResolver] AppController {/api}:
[Nest] 12345  - 03/09/2026, 10:30:02 AM     LOG [RouterExplorer] Mapped {/api/auth/login, POST} route
[Nest] 12345  - 03/09/2026, 10:30:02 AM     LOG [NestApplication] Nest application successfully started

Verify Installation

Once the server is running, verify everything is working:

Check API Health

The API runs on port 3000 by default with /api prefix:
curl http://localhost:3000/api

Access Swagger Documentation

Open your browser and navigate to:
http://localhost:3000/api
You’ll see the interactive Swagger UI with all available endpoints organized by module.
The API documentation is auto-generated from controller decorators and DTOs

Make Your First API Call

Let’s create a trip estimate to test the API:
1

Estimate a Trip

Send a POST request to estimate trip fare and duration:
curl -X POST http://localhost:3000/api/trips/estimate \
  -H "Content-Type: application/json" \
  -d '{
    "pickupLocation": {
      "latitude": 40.7128,
      "longitude": -74.0060,
      "address": "New York, NY"
    },
    "dropoffLocation": {
      "latitude": 40.7580,
      "longitude": -73.9855,
      "address": "Times Square, NY"
    },
    "vehicleTypeId": "00000000-0000-0000-0000-000000000001"
  }'
Expected response:
{
  "success": true,
  "message": "Estimate computed",
  "data": {
    "estimatedDistance": 5.2,
    "estimatedDuration": 15,
    "estimatedFare": 18.50,
    "fareBreakdown": {
      "baseFare": 3.50,
      "distanceFare": 12.00,
      "timeFare": 3.00
    }
  }
}
2

Create a User Account

Register a new passenger or driver:
curl -X POST http://localhost:3000/api/users/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePass123!",
    "firstName": "John",
    "lastName": "Doe",
    "phoneNumber": "+1234567890",
    "role": "passenger"
  }'
3

Login and Get Access Token

Authenticate to receive JWT tokens:
curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePass123!"
  }'
Response:
{
  "success": true,
  "message": "Login successful",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "sessionType": "mobile",
    "accessTokenExpiresAt": "2026-03-09T11:45:00Z",
    "refreshTokenExpiresAt": "2026-03-16T10:30:00Z"
  }
}
Save the accessToken to use in subsequent authenticated requests
4

Make an Authenticated Request

Use the access token to request protected resources:
curl -X GET http://localhost:3000/api/trips \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Development Commands

Here are useful commands for development:
# Start with hot-reload
npm run start:dev

# Start with debug mode
npm run start:debug

WebSocket Connection

The backend provides real-time updates via Socket.IO:
const io = require('socket.io-client');

// Connect as a driver
const socket = io('http://localhost:3000', {
  auth: {
    token: 'YOUR_ACCESS_TOKEN'
  }
});

socket.on('connect', () => {
  console.log('Connected to server');
});

// Listen for trip assignments
socket.on('trip.assignment.offer', (data) => {
  console.log('New trip offer:', data);
});
WebSocket scripts are available in the scripts/ directory for testing real-time features

Common Issues

Error: Error: connect ECONNREFUSED 127.0.0.1:5432Solution:
  • Ensure PostgreSQL is running: sudo service postgresql start
  • Check DB_HOST, DB_PORT, DB_USER, and DB_PASSWORD in .env
  • Verify the user has permissions to create databases
Error: Error: listen EADDRINUSE: address already in use :::3000Solution:
  • Change the PORT in .env to a different value (e.g., 3001)
  • Or kill the process using port 3000:
    lsof -ti:3000 | xargs kill -9
    
Error: JsonWebTokenError: invalid signatureSolution:
  • Ensure JWT_ACCESS_SECRET and JWT_REFRESH_SECRET are set in .env
  • Regenerate tokens after changing secrets
  • Don’t use the example secrets in production
Error: Access to fetch blocked by CORS policySolution:
  • Add your frontend URL to CORS_ORIGINS in .env:
    CORS_ORIGINS=http://localhost:8100,http://localhost:3001
    
  • Multiple origins should be comma-separated

Next Steps

Now that you have the API running:

Explore the Architecture

Learn about the system design and module organization

API Reference

Browse detailed endpoint documentation

Configuration Guide

Learn about environment configuration

Authentication Guide

Understand the JWT authentication flow

WebSocket Guide

Learn about real-time communication

Build docs developers (and LLMs) love