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.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.
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:
- Calls
token()to immediately fetch an OAuth 2.0 access token from the Factus API - Begins listening for HTTP connections
- Registers all route groups and global middleware
| Middleware | Purpose |
|---|---|
| CORS headers | Allows * 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 |
- factura routes
- querys routes
- page routes
Defined in
bc-v1/src/routes/factura.routes.js. These routes proxy operations directly to the Factus API using the in-memory access_token.| Method | Path | Description |
|---|---|---|
GET | /factura | Retrieve the latest list of invoices from Factus (/v1/bills/) |
GET | /factura/:number | Retrieve a single invoice by bill number (/v1/bills/show/:number) |
GET | /factura-download/:number | Download the Base64-encoded PDF of an invoice (/v1/bills/download-pdf/:number) |
POST | /factura | Validate and create a new invoice (/v1/bills/validate) |
DELETE | /factura/:reference_code | Delete an unvalidated invoice by reference code (/v1/bills/destroy/reference/:reference_code) |
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 apg.Pool configured in bc-v1/src/database.js. Connection parameters are read from environment variables at startup:
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 atfr-v1/resources/assets/config.jsonthat tells the frontend where the backend lives:
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:
| Category | Endpoint | Used for |
|---|---|---|
| Authentication | POST /oauth/token | Obtaining and refreshing access tokens |
| Invoice operations | GET /v1/bills/ | Listing recent invoices |
GET /v1/bills/show/:number | Fetching a single invoice | |
GET /v1/bills/download-pdf/:number | Downloading an invoice as Base64 PDF | |
POST /v1/bills/validate | Creating and validating a new invoice | |
DELETE /v1/bills/destroy/reference/:reference_code | Deleting an unvalidated invoice |
/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.
