Skip to main content
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): 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.
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.

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:
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:
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: 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.

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.