Tech Stack
Architecture
Data Flow
- 1
Background processor runs on schedule (Task Scheduler or PM2 interval)
- 2
For each tenant: queries Sage 300 MSSQL tables for new POs, payments, and vendor data
- 3
Builds and validates payloads using Joi schemas and custom transformers
- 4
Pushes purchase orders, payments, and supplier data to Portal de Proveedores REST API
- 5
Downloads CFDIs and provider data from Portal API back to local storage
- 6
Spawns external CFDI importer process to load invoices into Sage 300
Code Patterns
Multi-Tenant Sequential Processing
Processes multiple companies sequentially in a single Node.js process. Each tenant has its own Sage 300 database, Portal API credentials, and RFC — configured via comma-separated environment variables.
Dual-Mode Runtime
A single application runs in three modes: web-only (Express dashboard on port 3030), background-only (8 sync controllers), or combined. PM2 or Windows Task Scheduler orchestrates execution cycles.
Controller Pipeline Architecture
Eight specialized controllers execute sequentially per tenant: Provider Sync, CFDI Download, Payment Check, Payment Upload, PO Creation, PO Updates, PO Closure, and PO Cancellation — each handling one sync responsibility.
System Metrics
What's Next
The current system relies on an external Windows executable (ImportaFacturasFocaltec.exe) to import CFDIs into Sage 300 — a black box with no structured error feedback, no per-invoice tracking, and no correlation between processed XMLs and created batches.
The next evolution replaces this executable entirely by integrating directly with Sage 300's REST Web API. This eliminates the dependency on Windows, enables granular error handling per invoice, and makes the entire data flow observable and testable from Node.js.
This migration also addresses critical reliability gaps: payments that upload to the portal before confirming CFDI import, silent failures in control table inserts, and XML corruption from race conditions in the addenda injection pipeline.
Want similar results for your project?