Skip to main content

Installation Guide

This guide provides detailed instructions for installing and configuring PaparcApp in both development and production environments.

Prerequisites

Before installing PaparcApp, ensure your system meets these requirements:

Required Software

Node.js

Version: 18.x or higherDownload Node.js

npm

Version: 9.x or higherIncluded with Node.js

PostgreSQL

Version: 14 or higherDownload PostgreSQL

System Requirements

ComponentMinimumRecommended
RAM2 GB4 GB
Storage500 MB1 GB
CPU1 core2 cores
OSLinux, macOS, WindowsLinux (Ubuntu 20.04+)

Verify Prerequisites

Check that all required software is installed:
node --version
# Expected: v18.0.0 or higher
If any version is below the minimum requirement, please upgrade before proceeding.

Installation Steps

1. Clone the Repository

Clone the PaparcApp repository from GitHub:
git clone https://github.com/rafakata/PaparcApp.git
cd PaparcApp
The project structure:
PaparcApp/
├── proyecto/                    # Main application directory
│   ├── app.js                   # Express configuration
│   ├── package.json             # Dependencies and scripts
│   ├── .env.example             # Environment template
│   ├── bin/www                  # HTTP server entry point
│   ├── config/
│   │   └── database.js          # PostgreSQL connection pool
│   ├── controllers/             # Business logic
│   ├── database/                # SQL schema files
│   ├── middlewares/             # Authentication guards
│   ├── models/                  # Data access objects (DAOs)
│   ├── routes/                  # Express routers
│   ├── services/                # Pricing engine, notifications
│   ├── public/                  # Static assets
│   ├── views/                   # EJS templates
│   └── tests/                   # Jest test suites
└── README.md

2. Install Dependencies

Navigate to the proyecto directory and install npm packages:
cd proyecto
npm install
This installs all production and development dependencies:
Production Dependencies:Development Dependencies:

3. Configure Environment Variables

Create .env File

Copy the example template and customize it:
cp .env.example .env

Environment Configuration Options

.env
# Server Configuration
PORT=3000
NODE_ENV=development

# Session Secret (generate a secure random string)
SESSION_SECRET=your_32_character_random_string_here

# PostgreSQL Local Connection
DB_USER=postgres
DB_PASSWORD=your_postgres_password
DB_HOST=localhost
DB_PORT=5432
DB_NAME=paparcapp_db
For local development, use the individual DB_* variables. The connection pool in config/database.js will use these.

Generate Secure SESSION_SECRET

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Security Best Practices:
  • Never commit .env to version control
  • Use different secrets for development and production
  • Rotate secrets periodically
  • Use at least 32 characters for SESSION_SECRET

4. Database Setup

Option A: Local PostgreSQL

1

Create Database

Connect to PostgreSQL and create the database:
# Connect as postgres superuser
sudo -u postgres psql
-- Create database
CREATE DATABASE paparcapp_db;

-- Create dedicated user (optional but recommended)
CREATE USER paparcapp_user WITH PASSWORD 'secure_password';

-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE paparcapp_db TO paparcapp_user;

-- Exit
\q
2

Load Database Schema

Execute the SQL files in the correct order:
# From the proyecto directory
psql -U postgres -d paparcapp_db -f database/01_tables.sql
psql -U postgres -d paparcapp_db -f database/02_constraints.sql
psql -U postgres -d paparcapp_db -f database/03_indexes.sql
psql -U postgres -d paparcapp_db -f database/04_initial_data.sql
Or combine into a single command:
cat database/*.sql | psql -U postgres -d paparcapp_db
3

Verify Setup

Check that all tables were created:
psql -U postgres -d paparcapp_db -c "\dt"
Expected output (13 tables):
Schema |              Name                | Type  |  Owner
--------+----------------------------------+-------+----------
public | additional_service               | table | postgres
public | contract                         | table | postgres
public | contract_plan                    | table | postgres
public | customer                         | table | postgres
public | customer_vehicle                 | table | postgres
public | main_service                     | table | postgres
public | notification                     | table | postgres
public | photo_evidence                   | table | postgres
public | reservation                      | table | postgres
public | reservation_additional_service   | table | postgres
public | service_rate                     | table | postgres
public | vehicle                          | table | postgres
public | vehicle_coefficient              | table | postgres

Option B: Neon.tech (Cloud PostgreSQL)

1

Create Neon Account

  1. Go to neon.tech
  2. Sign up for a free account
  3. Create a new project
2

Get Connection String

Copy the connection string from the Neon dashboard:
postgresql://username:[email protected]/dbname?sslmode=require
Add this to your .env file as DATABASE_URL.
3

Load Schema via psql

# Set connection string
export DATABASE_URL="postgresql://..."

# Load schema
psql $DATABASE_URL -f database/01_tables.sql
psql $DATABASE_URL -f database/02_constraints.sql
psql $DATABASE_URL -f database/03_indexes.sql
psql $DATABASE_URL -f database/04_initial_data.sql

Database Schema Files

Understanding what each SQL file does:
Creates all 13 tables with primary keys:
  • customer - System users (ADMIN, REGISTRADO, NO-REGISTRADO)
  • vehicle - Vehicle registry with unique license plates
  • customer_vehicle - N:M relationship (virtual garage)
  • vehicle_coefficient - Pricing multipliers by vehicle type
  • main_service - Three service tiers (ECO, TRANSFER, MEET)
  • service_rate - Pricing by day ranges for each service
  • additional_service - Extra services catalog (washes, ITV, etc.)
  • reservation - Booking records with lifecycle states
  • reservation_additional_service - N:M for extras per booking
  • photo_evidence - Vehicle condition photos
  • notification - Email log
  • contract_plan - Subscription plans
  • contract - Active subscriptions
Example: vehicle table
CREATE TABLE vehicle (
    id_vehicle         SERIAL PRIMARY KEY,
    license_plate      VARCHAR(15) NOT NULL UNIQUE,
    brand              VARCHAR(50) NOT NULL,
    model              VARCHAR(50) NOT NULL,
    color              VARCHAR(30) NOT NULL,
    type               VARCHAR(30) NOT NULL,
    registration_date  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
Adds foreign keys and CHECK constraints to enforce business logic:
  • Reservation status: only PENDIENTE, EN CURSO, FINALIZADA, CANCELADA
  • Payment method: only TARJETA, EFECTIVO, or NULL
  • Parking spot required for IN PROGRESS and COMPLETED states
  • Exit date must be after entry date
  • Price must be non-negative
  • Email and phone validation patterns
  • Vehicle multiplier must be positive
Example: reservation constraints
ALTER TABLE reservation ADD CONSTRAINT check_status 
  CHECK (status IN ('PENDIENTE', 'EN CURSO', 'FINALIZADA', 'CANCELADA'));

ALTER TABLE reservation ADD CONSTRAINT check_exit_after_entry 
  CHECK (exit_date > entry_date);

ALTER TABLE reservation ADD CONSTRAINT check_price_non_negative 
  CHECK (total_price >= 0);
Creates 9 additional indexes for frequently queried columns:
  • idx_reservation_id_vehicle - Fast vehicle lookup
  • idx_reservation_entry_date - Filter by check-in date
  • idx_reservation_exit_date - Filter by check-out date
  • idx_reservation_id_customer - Customer’s reservations
  • idx_reservation_status - Filter by state
  • idx_photo_evidence_id_reservation - Reservation photos
  • idx_notification_id_reservation - Notification history
  • And more…
Example indexes
CREATE INDEX idx_reservation_status ON reservation(status);
CREATE INDEX idx_reservation_entry_date ON reservation(entry_date);
CREATE INDEX idx_reservation_exit_date ON reservation(exit_date);
Loads essential configuration and test data:Master Configuration:
  • 5 vehicle coefficients (TURISMO ×1.0, MOTOCICLETA ×0.5, etc.)
  • 3 main services (ECO, TRANSFER, MEET) with descriptions
  • 12 service rate tiers (4 day ranges × 3 services)
  • 3 subscription plans (Quarterly, Semiannual, Annual)
  • Additional services catalog (washes, ITV, charging, etc.)
Test Data:
  • Sample customers (including admin users)
  • Test vehicles
  • Sample reservations in different states
  • Photo evidence examples
  • Notification logs
Example: pricing configuration
INSERT INTO vehicle_coefficient (vehicle_type, multiplier) VALUES 
('TURISMO', 1.00),
('MOTOCICLETA', 0.50),
('FURGONETA', 1.25),
('CARAVANA', 2.00),
('ESPECIAL', 1.50);

INSERT INTO service_rate (id_main_service, min_days, max_days, daily_price) VALUES
(1, 1, 3, 12.00),   -- ECO: 1-3 days = €12/day
(1, 4, 10, 8.00),   -- ECO: 4-10 days = €8/day
(1, 11, 15, 6.00),  -- ECO: 11-15 days = €6/day
(1, 16, 9999, 5.00); -- ECO: 16+ days = €5/day

5. Start the Application

Start with Nodemon for auto-restart on file changes:
npm run dev
Expected output:
[nodemon] 3.1.11
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,ejs
[nodemon] starting `node ./bin/www`
✓ Database connection pool initialized
✓ Pricing cache initialized successfully
Server listening on http://localhost:3000
Nodemon watches for file changes and automatically restarts the server. Perfect for development.

Post-Installation

Create Admin User

If the initial data script didn’t create an admin user, create one manually:
-- Generate password hash first
-- In Node.js console: require('bcrypt').hash('your_password', 10, console.log)

INSERT INTO customer (
  full_name, 
  email, 
  phone, 
  password_hash, 
  type, 
  is_active
) VALUES (
  'Admin User',
  '[email protected]',
  '+34600000001',
  '$2b$10$YourBcryptHashHere',  -- Replace with actual hash
  'ADMIN',
  true
);
// Create a script: hash-password.js
const bcrypt = require('bcrypt');

const password = process.argv[2] || 'admin123';
bcrypt.hash(password, 10, (err, hash) => {
  if (err) throw err;
  console.log('Password:', password);
  console.log('Hash:', hash);
});

// Run it:
// node hash-password.js your_password

Configure Firebase (Optional)

For social login (Google/Facebook), set up Firebase:
1

Create Firebase Project

  1. Go to Firebase Console
  2. Create a new project
  3. Enable Authentication
2

Enable Providers

In Authentication > Sign-in method:
  • Enable Google
  • Enable Facebook (requires Facebook App ID)
3

Get Config

From Project Settings > General, copy the Firebase config:
const firebaseConfig = {
  apiKey: "AIza...",
  authDomain: "paparcapp.firebaseapp.com",
  projectId: "paparcapp",
  storageBucket: "paparcapp.appspot.com",
  messagingSenderId: "123456789",
  appId: "1:123456789:web:abc123"
};
4

Update Client Config

Add the config to public/javascripts/firebase-config.js

Configure Email Notifications (Optional)

For automated emails via n8n:
1

Set Up n8n

Deploy n8n or use n8n.cloud
2

Create Workflow

Import the notification workflow (check services/templates/ for email templates)
3

Get Webhook URL

Copy the webhook URL from n8n
4

Update .env

N8N_WEBHOOK_URL=https://your-n8n-instance.com/webhook/...

Deployment Options

Deploy to Render

1

Create Render Account

Sign up at render.com
2

Create Web Service

  • Connect your GitHub repository
  • Select the proyecto directory
  • Set build command: npm install
  • Set start command: npm start
3

Configure Environment

Add environment variables in Render dashboard:
  • NODE_ENV=production
  • DATABASE_URL (from Neon.tech)
  • SESSION_SECRET
  • PORT=3000
4

Deploy

Render will automatically build and deploy

Deploy to Heroku

# Install Heroku CLI
curl https://cli-assets.heroku.com/install.sh | sh

# Login
heroku login

# Create app
cd proyecto
heroku create paparcapp

# Add PostgreSQL
heroku addons:create heroku-postgresql:mini

# Set environment variables
heroku config:set NODE_ENV=production
heroku config:set SESSION_SECRET=your_secret

# Deploy
git push heroku main

# Open app
heroku open

Deploy with Docker

Dockerfile
FROM node:18-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application
COPY . .

# Expose port
EXPOSE 3000

# Start server
CMD ["npm", "start"]
docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/paparcapp
      - SESSION_SECRET=your_secret
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_DB=paparcapp
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./database:/docker-entrypoint-initdb.d

volumes:
  pgdata:
# Build and run
docker-compose up -d

Troubleshooting

Symptoms:
Error: connect ECONNREFUSED 127.0.0.1:5432
Solutions:
  1. Check PostgreSQL is running:
    # Linux
    sudo systemctl status postgresql
    
    # macOS
    brew services list
    
    # Windows
    sc query postgresql
    
  2. Verify connection settings in .env
  3. Test direct connection:
    psql -U postgres -d paparcapp_db -c "SELECT 1;"
    
  4. Check PostgreSQL logs:
    # Linux
    sudo tail -f /var/log/postgresql/postgresql-*.log
    
    # macOS
    tail -f /usr/local/var/log/postgres.log
    
Symptoms:
Error initializing pricing cache
Process exited with code 1
Solutions:
  1. Ensure initial data was loaded:
    psql -U postgres -d paparcapp_db -c "SELECT COUNT(*) FROM vehicle_coefficient;"
    # Should return 5
    
  2. Check service rates exist:
    psql -U postgres -d paparcapp_db -c "SELECT COUNT(*) FROM service_rate;"
    # Should return 12
    
  3. Re-run initial data script:
    psql -U postgres -d paparcapp_db -f database/04_initial_data.sql
    
  4. Check database connection works before starting app
Symptoms:
  • Login succeeds but immediately logs out
  • Session data not persisting
  • “Unauthorized” errors
Solutions:
  1. Check SESSION_SECRET is set in .env
  2. Clear browser cookies and cache
  3. Verify express-session is installed:
    npm ls express-session
    
  4. In production, ensure HTTPS is enabled (session cookies require secure flag)
  5. Check trust proxy setting in app.js (required for Render/Heroku)
Symptoms:
Error: listen EADDRINUSE: address already in use :::3000
Solutions:
  1. Change port in .env:
    PORT=3001
    
  2. Kill the process using port 3000:
    # Linux/macOS
    lsof -ti:3000 | xargs kill -9
    
    # Windows
    netstat -ano | findstr :3000
    taskkill /PID <PID> /F
    
  3. Or run with custom port temporarily:
    PORT=3001 npm run dev
    
Symptoms:
Error: node-pre-gyp install --fallback-to-build
Solutions:
  1. Install build tools:
    # Linux
    sudo apt-get install build-essential
    
    # macOS
    xcode-select --install
    
    # Windows
    npm install --global windows-build-tools
    
  2. Rebuild bcrypt:
    npm rebuild bcrypt
    
  3. Or use pre-built binaries:
    npm uninstall bcrypt
    npm install bcrypt --build-from-source
    

Security Checklist

Before deploying to production:
1

Environment Security

  • Set NODE_ENV=production
  • Use strong SESSION_SECRET (min 32 chars)
  • Never commit .env to version control
  • Add .env to .gitignore
2

Database Security

  • Use SSL for database connections
  • Create dedicated database user (not postgres superuser)
  • Grant only necessary privileges
  • Regular backups configured
3

Application Security

  • HTTPS enabled (trust proxy configured)
  • Session cookies set to secure
  • All passwords use bcrypt (10+ rounds)
  • SQL queries use parameterization
  • Input validation on all forms
4

Monitoring

  • Error logging configured
  • Database connection pool monitoring
  • Set up health check endpoint
  • Configure uptime monitoring

Next Steps

Architecture Guide

Learn about the MVC pattern, service layers, and data flow

API Reference

Explore REST endpoints for pricing and reservations

Database Schema

Detailed documentation of all 13 tables and relationships

Quickstart

Get started quickly with PaparcApp

Need Help? Join the discussion on GitHub Issues or check the Quick Start Guide for a faster setup.

Build docs developers (and LLMs) love