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.

The Factus Challenge uses a two-tier architecture: a Node.js/Express backend that acts as an authenticated proxy to the external Factus electronic invoicing API while managing supporting relational data in PostgreSQL, and a fully static HTML/JavaScript frontend that communicates exclusively with that backend — never directly with the Factus API or the database.

System Layers

Backend (bc-v1/)

The backend is the central hub of the application. It is an Express 4 server that starts on port 4500 (configurable via the PORT environment variable). The entry point is bc-v1/src/main.js, which performs three tasks at startup:
  1. Calls token() to immediately fetch an OAuth 2.0 access token from the Factus API
  2. Begins listening for HTTP connections
  3. Registers all route groups and global middleware
Middleware stack (in order):
MiddlewarePurpose
CORS headersAllows * origins; permits GET, POST, PUT, DELETE, PATCH methods
express.json()Parses JSON request bodies for POST and PUT routes
morgan('dev')Logs each incoming request to stdout with method, path, status, and response time
Route groups: The backend exposes three sets of routes, each handled by its own router module:
Defined in bc-v1/src/routes/factura.routes.js. These routes proxy operations directly to the Factus API using the in-memory access_token.
MethodPathDescription
GET/facturaRetrieve the latest list of invoices from Factus (/v1/bills/)
GET/factura/:numberRetrieve a single invoice by bill number (/v1/bills/show/:number)
GET/factura-download/:numberDownload the Base64-encoded PDF of an invoice (/v1/bills/download-pdf/:number)
POST/facturaValidate and create a new invoice (/v1/bills/validate)
DELETE/factura/:reference_codeDelete an unvalidated invoice by reference code (/v1/bills/destroy/reference/:reference_code)
OAuth 2.0 token manager: bc-v1/src/auth/token.js handles all OAuth lifecycle management. On first call it performs either a password grant (using email + password from .env) or a refresh_token grant (if refresh_token is already set in the environment). It stores the resulting access_token and refresh_token directly in process.env, making them available to all request handlers without any additional state management. A setInterval fires every 55 minutes (3,300,000 ms) to silently obtain a fresh token before the current one expires.
// Simplified token refresh loop (bc-v1/src/auth/token.js)
id_interval = setInterval(() => {
  query(); // re-runs the OAuth POST to /oauth/token
}, 3300000); // every 55 minutes

Database

The database layer is a PostgreSQL instance accessed through a pg.Pool configured in bc-v1/src/database.js. Connection parameters are read from environment variables at startup:
const db = new pg.Pool({
  client_encoding: 'utf8',
  user: ENV.DB_USER,
  host: ENV.DB_HOST,
  database: ENV.DB_NAME,
  password: ENV.DB_PASSWORD,
  ssl: ENV.DB_SSL,
});
The pool is imported by querys.controller.js and used for all local data operations. The database stores:
  • Customers — client records referenced when building invoice bodies
  • Products — product/service line items included in invoices
  • Payment methods — lookup data for invoice payment configuration
  • Other lookup tables — supporting configuration tables for the challenge’s CRUD requirements
In the reference deployment, the PostgreSQL database is hosted on Azure Database for PostgreSQL with SSL enforced (DB_SSL=true).

Frontend (fr-v1/)

The frontend is a completely static application — there is no bundler, no build step, and no server-side rendering. It consists of:
  • HTML — structural markup in fr-v1/index.html
  • Vanilla JavaScript modules — ES6 files that handle UI interaction, form submission, and HTTP requests to the backend
  • Bootstrap 5.3.3 (Vapor dark theme) — bundled locally in fr-v1/resources/utils/bootstrap-5.3.3/ for responsive layout and UI components
  • Tabulator 6.3 — bundled locally in fr-v1/resources/utils/tabulator-6.3/ for interactive, sortable data tables (invoices, customers, products)
  • config.json — a single configuration file at fr-v1/resources/assets/config.json that tells the frontend where the backend lives:
{
  "url": "http://localhost:4500"
}
The frontend never communicates directly with the Factus API or PostgreSQL. All data flows through the backend.

External API — Factus

The Factus API (api-sandbox.factus.com.co for sandbox, or the production equivalent) is the authoritative source for all electronic invoice data. The backend interacts with two categories of endpoints:
CategoryEndpointUsed for
AuthenticationPOST /oauth/tokenObtaining and refreshing access tokens
Invoice operationsGET /v1/bills/Listing recent invoices
GET /v1/bills/show/:numberFetching a single invoice
GET /v1/bills/download-pdf/:numberDownloading an invoice as Base64 PDF
POST /v1/bills/validateCreating and validating a new invoice
DELETE /v1/bills/destroy/reference/:reference_codeDeleting an unvalidated invoice
All requests to /v1/bills/* include an Authorization: Bearer <access_token> header supplied by the token manager.

Request Flow

Browser → Backend → Factus API (for invoice operations): The frontend sends an HTTP request to the Express backend. The backend attaches the OAuth Bearer token and forwards the request to the Factus API, then returns the normalized response to the frontend.Browser → Backend → PostgreSQL (for local data operations): The frontend sends an HTTP request to a /get-data, /add-data, /update-data, or /delete endpoint. The backend queries the PostgreSQL pool and returns the result — the Factus API is not involved.
Browser (fr-v1)

     │  HTTP (fetch/XHR)

Express Backend (bc-v1, port 4500)
     │                    │
     │  Bearer token       │  pg.Pool
     ▼                    ▼
Factus API           PostgreSQL
(/v1/bills/*)        (customers,
                      products,
                      lookup tables)

Explore Further

Backend Setup

Configure the Express server, environment variables, and start the backend locally.

Authentication

Deep-dive into the OAuth 2.0 token manager and how tokens are refreshed automatically.

Database

Learn how the PostgreSQL pool is configured and how the generic CRUD routes work.

Frontend Overview

Explore the static frontend structure, Tabulator integration, and config.json setup.

Build docs developers (and LLMs) love