InvoFuse
Multi‑tenant e‑invoicing platform built and operated by us
PINT‑AE
Peppol PINT-AE v1.0.3 as the compliance target
~0.18s
To accept and queue a 1,200-invoice ingestion payload
3 layers
Independent tenant-isolation controls, not one check
The problem
E-invoicing is a data problem wearing a format’s clothes.
How it was built.
Each phase fixed something the previous version of the platform got wrong in production, not in theory.
- 01
Model the compliance target first
The PINT-AE field list and rule set were pulled apart before any code: which rules are presence checks, which are arithmetic, which are code lists, and which fields the source systems do not currently carry at all — Peppol routing identifiers and legal registration IDs were a real gap, not a mapping detail.
rule tiers + field-gap list - 02
Make ingestion asynchronous
Ingestion used to validate and write the whole payload inside the webhook request — a database connection held per in-flight call and a transaction as long as the biggest payload anyone sent. Now the endpoint resolves the connection, persists the job and its envelope, queues it and returns 202 with a status URL.
202 + status_url, ~0.18s - 03
Make the work resumable
A worker resolves tax and unit-of-measure mappings, evaluates compliance and upserts in batches of 500 — about ten statements for a payload that previously took twelve hundred. Every write is an upsert keyed on tenant, source system and external id, so a retry finishes the job instead of starting a second copy.
checkpointed, idempotent jobs - 04
Give every key an owner
Ingestion was authenticated by one secret shared across every tenant and every pipeline: it could not be revoked for one customer, could not be rotated without changing every workflow at once, and left no trail. Keys now belong to a tenant and optionally a single connection.
scoped, revocable keys
The part that cannot be wrong once
One tenant’s invoice book, invisible to every other.
Invoices are commercial records: who buys what, at what price, how often. A platform that holds several companies’ books has to treat isolation as an architecture decision rather than a filter applied late in a query.
Running it
A platform that explains itself at 3am.
API & worker
NestJS, two processes, one codebase
Data
PostgreSQL with TypeORM migrations
Queues
BullMQ on Redis, per-queue dashboards
Web
Next.js 15, React 19, localised UI
Compliance
PINT-AE rules engine + UBL generation
Operations
Prometheus metrics, OpenTelemetry traces
What changed.
Figures above are measured on our own platform under the payload described, not a benchmark claim for every workload. Compliance coverage tracks the published PINT-AE v1.0.3 rule set; the specification is the authority, not our implementation of it.