Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tutosrive/factus_challenge/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through cloning the Factus Challenge repository, wiring up your environment variables, and verifying that the backend can communicate with the Factus API — all the way to opening the frontend in your browser and issuing your first invoice.

Prerequisites

Before you begin, make sure you have the following ready:
  • Node.js 22+ — the backend uses --env-file (native .env loading) and ES modules, both of which require Node.js 22
  • PostgreSQL — a local instance or a managed service (the project was tested on Azure Database for PostgreSQL)
  • A Factus API account — sign up at factus.com.co and obtain your client_id, client_secret, email, and password for the sandbox (api-sandbox.factus.com.co) or production environment
Factus provides a free sandbox environment at https://api-sandbox.factus.com.co. Use it during development so you never touch real billing data.

Steps

1

Clone the repository

Clone the project from GitHub and move into the root directory:
git clone https://github.com/tutosrive/factus_challenge.git
cd factus_challenge
The repository contains two top-level directories:
  • bc-v1/ — the Node.js/Express backend
  • fr-v1/ — the static HTML/JS frontend
2

Install backend dependencies

Navigate into the backend directory and install all npm packages:
cd bc-v1
npm install
This installs the five runtime dependencies declared in package.json:
PackagePurpose
axiosHTTP client for proxying requests to the Factus API
expressWeb framework and HTTP router
morganRequest logger (prints to stdout in dev format)
pgPostgreSQL connection pool client
qsURL-encodes the OAuth 2.0 token request body
3

Create the .env file

Create a .env file inside bc-v1/. The server loads it automatically via Node’s --env-file flag when you run npm run dev.
# bc-v1/.env

# Express server port (defaults to 4500 if not set)
PORT=4500

# Factus API base URL — use the sandbox for development
url_api=https://api-sandbox.factus.com.co

# OAuth 2.0 client credentials (from your Factus account)
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET

# Resource-owner password credentials (used when no refresh_token exists)
email=YOUR_FACTUS_EMAIL
password=YOUR_FACTUS_PASSWORD

# Optional: provide a known refresh token to skip the password grant on startup
# refresh_token=YOUR_REFRESH_TOKEN

# PostgreSQL connection details
DB_USER=your_db_user
DB_HOST=your_db_host
DB_NAME=your_db_name
DB_PASSWORD=your_db_password
DB_SSL=true
Never commit your .env file to version control. Add bc-v1/.env to your .gitignore before your first commit.
Variable reference:
VariableRequiredDescription
PORTNoPort the Express server listens on. Defaults to 4500.
url_apiYesBase URL of the Factus API (sandbox or production).
client_idYesOAuth 2.0 client ID from your Factus application.
client_secretYesOAuth 2.0 client secret from your Factus application.
emailYesYour Factus account email (used as the OAuth username).
passwordYesYour Factus account password (used for the password grant type).
refresh_tokenNoIf provided, the token manager uses refresh_token grant instead of password grant on startup.
DB_USERYesPostgreSQL username.
DB_HOSTYesPostgreSQL host.
DB_NAMEYesPostgreSQL database name.
DB_PASSWORDYesPostgreSQL password.
DB_SSLYesSet to true to require SSL for the database connection.
4

Start the backend server

From inside bc-v1/, run:
npm run dev
This executes node --env-file .env --watch ./src/main.js. On startup, the server:
  1. Fetches an OAuth 2.0 token immediately by calling POST /oauth/token on the Factus API, storing the resulting access_token and refresh_token in process.env
  2. Starts Express on port 4500 (or the value of PORT)
  3. Schedules a token refresh every 55 minutes (3,300,000 ms) via setInterval
You should see output similar to:
NO existe un refresh token
Running server in port:  4500
The server auto-refreshes the OAuth access token every 55 minutes in the background. You do not need to restart the process to keep the token valid — this is handled entirely by bc-v1/src/auth/token.js.
5

Configure the frontend

The frontend reads its backend URL from a single JSON file. Open fr-v1/resources/assets/config.json and verify (or update) the url field to point at your running backend:
{
  "url": "http://localhost:4500"
}
If your backend is deployed remotely (e.g., on Koyeb), replace http://localhost:4500 with your deployment URL:
{
  "url": "https://your-app.koyeb.app"
}
6

Open the frontend in a browser

The frontend is fully static — no build step required. Simply open the entry point in your browser:
# macOS
open fr-v1/index.html

# Linux
xdg-open fr-v1/index.html

# Or just drag fr-v1/index.html into any browser window
The page loads Bootstrap 5.3.3 (Vapor dark theme) and Tabulator 6.3 from self-hosted files in fr-v1/resources/utils/ and immediately starts making requests to the backend URL defined in config.json.

Verify the Backend Is Working

Once the server is running, confirm it can reach the Factus API by listing invoices. Send a GET request to the /factura endpoint:
curl http://localhost:4500/factura
A successful response looks like this (the data array contains invoices returned by the Factus API):
{
  "status": 200,
  "message": "OK",
  "data": [...]
}
If you receive a 500 or a token-related error, double-check that url_api, client_id, client_secret, email, and password are all set correctly in your .env file.
curl http://localhost:4500/

Build docs developers (and LLMs) love