Skip to main content

Overview

The Construction Backend API is a RESTful service built with Node.js, Express, and MongoDB. It provides endpoints for user authentication and quotation management for construction projects.
This guide will help you set up and run the API locally on your machine. Make sure you have Node.js 16+ and MongoDB Atlas account ready.

Prerequisites

Before you begin, ensure you have the following installed:
  • Node.js (version 16 or higher)
  • npm or yarn package manager
  • MongoDB Atlas account (free tier available)
  • A code editor (VS Code recommended)

Installation

1

Clone the repository

First, clone the repository to your local machine:
git clone <your-repository-url>
cd construction_backend_mongo
2

Install dependencies

Install all required npm packages:
npm install
This will install the following key dependencies:
  • express - Web framework
  • mongoose - MongoDB object modeling
  • bcryptjs - Password hashing
  • cors - Cross-origin resource sharing
  • dotenv - Environment variable management
3

Configure environment variables

Create a .env file in the root directory:
touch .env
Add your MongoDB connection string and port configuration:
MONGO_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/<database>?retryWrites=true&w=majority
PORT=3000
Replace <username>, <password>, <cluster>, and <database> with your actual MongoDB Atlas credentials. Never commit your .env file to version control.
4

Start the server

Run the development server with hot reload:
npm run dev
Or start the production server:
npm start
You should see the following output:
Bienvenido a Vidpher API
MONGO_URI: mongodb+srv://...
PORT: 3000
Connected to MongoDB Atlas

Database connection

The API uses Mongoose to connect to MongoDB Atlas. Here’s how the connection is established:
src/database/connection.js
import mongoose from 'mongoose';
import { MONGO_URI } from './config.js';

export const connectDB = async () => {
  try {
    await mongoose.connect(MONGO_URI);

    // Connection events
    mongoose.connection.on('connected', () => {
      console.log('Connected to MongoDB Atlas');
    });

    mongoose.connection.on('error', (err) => {
      console.error('MongoDB connection error:', err);
    });

    mongoose.connection.on('disconnected', () => {
      console.log('Disconnected from MongoDB Atlas');
    });

  } catch (error) {
    console.error('Error connecting to MongoDB Atlas:', error);
  }
};
The connection configuration is loaded from environment variables:
src/database/config.js
import dotenv from 'dotenv';

dotenv.config();

export const MONGO_URI = process.env.MONGO_URI;
export const PORT = process.env.PORT || 3000;

Your first API call

Once the server is running, you can start making API calls. The API is available at http://localhost:3000.

Test the connection

Verify the server is running:
curl http://localhost:3000/ruta-prueba
Response:
{
  "message": "Ruta de prueba"
}

User authentication

Register a new user

Create a new user account:
curl -X POST http://localhost:3000/api/user/register \
  -H "Content-Type: application/json" \
  -d '{
    "document": "1234567890",
    "email": "[email protected]",
    "password": "securePassword123",
    "name": "John",
    "last_name": "Doe",
    "cellphone": "+1234567890",
    "user_type": "contractor"
  }'
Response:
{
  "message": "Usuario registrado correctamente",
  "user": {
    "document": "1234567890",
    "email": "[email protected]",
    "name": "John",
    "last_name": "Doe",
    "cellphone": "+1234567890",
    "user_type": "contractor",
    "_id": "507f1f77bcf86cd799439011"
  }
}
The user model includes the following fields:
  • document (String, required, unique) - User’s identification document
  • email (String, required, unique) - User’s email address
  • password (String, required) - Hashed password using bcryptjs
  • name (String, required) - User’s first name
  • last_name (String, required) - User’s last name
  • cellphone (String, required) - User’s phone number
  • user_type (String, required) - Type of user (e.g., contractor, admin)

Login

Authenticate an existing user:
curl -X POST http://localhost:3000/api/user/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "securePassword123"
  }'
Response:
{
  "message": "Usuario logueado correctamente",
  "user": {
    "document": "1234567890",
    "email": "[email protected]",
    "name": "John",
    "last_name": "Doe",
    "cellphone": "+1234567890",
    "user_type": "contractor"
  }
}
The password is never returned in responses. The API uses bcryptjs with a salt rounds of 10 for secure password hashing.

Quotation management

Create a quotation

Create a new construction project quotation:
curl -X POST http://localhost:3000/api/quotation/register/quotation \
  -H "Content-Type: application/json" \
  -d '{
    "factory": "Main Construction Site",
    "fix": "Building Renovation",
    "description_quotation": "Complete office renovation including electrical and plumbing",
    "subtotal": 50000,
    "unexpected": 5000,
    "iva": 7500,
    "administratitive": 3000,
    "utility": 8000,
    "total_price": 73500,
    "sections": [
      {
        "description_sections": "Electrical Work",
        "section_price": 15000,
        "items": [
          {
            "item_name": "Wiring Installation",
            "item_description": "Install new electrical wiring throughout office",
            "item_total": 10000,
            "quantity": 100,
            "unity": "meters",
            "item_value": 100
          }
        ]
      }
    ]
  }'
Response:
{
  "message": "Cotización almacenada correctamente",
  "quotation": {
    "factory": "Main Construction Site",
    "fix": "Building Renovation",
    "description_quotation": "Complete office renovation including electrical and plumbing",
    "subtotal": 50000,
    "unexpected": 5000,
    "iva": 7500,
    "administratitive": 3000,
    "utility": 8000,
    "total_price": 73500,
    "sections": [...],
    "_id": "507f1f77bcf86cd799439012"
  }
}

Get all quotations

Retrieve all stored quotations:
curl http://localhost:3000/api/quotation/quotations
Response:
[
  {
    "_id": "507f1f77bcf86cd799439012",
    "factory": "Main Construction Site",
    "fix": "Building Renovation",
    "description_quotation": "Complete office renovation including electrical and plumbing",
    "subtotal": 50000,
    "unexpected": 5000,
    "iva": 7500,
    "administratitive": 3000,
    "utility": 8000,
    "total_price": 73500,
    "sections": [...]
  }
]
The quotation model includes the following structure:Main fields:
  • factory (String, required) - Factory or construction site name
  • fix (String, required) - Type of fix or construction work
  • description_quotation (String, required) - Overall quotation description
  • subtotal (Number, required) - Subtotal before taxes and fees
  • unexpected (Number, required) - Unexpected expenses buffer
  • iva (Number, required) - Tax amount (IVA)
  • administratitive (Number, required) - Administrative fees
  • utility (Number, required) - Profit margin
  • total_price (Number, required) - Final total price
Sections array:
  • description_sections (String, required) - Section description
  • section_price (Number, required) - Total price for section
Items array (nested within sections):
  • item_name (String, required) - Name of item
  • item_description (String, required) - Item description
  • item_total (Number, required) - Total cost for item
  • quantity (Number, required) - Quantity of items
  • unity (String, required) - Unit of measurement
  • item_value (Number, required) - Value per unit

API routes overview

The API exposes the following routes:

User routes (/api/user)

  • POST /api/user/register - Register a new user
  • POST /api/user/login - Authenticate a user

Quotation routes (/api/quotation)

  • GET /api/quotation/quotations - Get all quotations
  • POST /api/quotation/register/quotation - Create a new quotation

Test route

  • GET /ruta-prueba - Health check endpoint

Error handling

The API returns standard HTTP status codes:
  • 200 - Success
  • 201 - Resource created successfully
  • 400 - Bad request (validation error)
  • 401 - Unauthorized (authentication failed)
  • 500 - Internal server error
Example error response:
{
  "message": "Email y contraseña son obligatorios"
}

Next steps

Now that you have the API running, you can:
  • Explore the full API reference for detailed endpoint documentation
  • Learn about advanced MongoDB queries with Mongoose
  • Implement authentication tokens (JWT) for secure API access
  • Deploy your API to production using Vercel or other platforms
The API is configured to work with Vercel serverless functions. The app is exported as a module for serverless deployment.

Build docs developers (and LLMs) love