Project
An access point for the European e-invoicing network — the piece that puts a company on Peppol and moves documents in and out of it.

What it is
Peppol Suite is an access point for the Peppol network, the European system public bodies and their suppliers use to exchange invoices, orders, and credit notes as structured documents instead of PDFs. Joining that network means running real infrastructure: an AS4 endpoint that speaks the protocol, validation that proves a document conforms before it leaves, and somewhere for a human to see what happened. The portal gives an organisation exactly that — send a document, watch what arrives, manage the participants and certificates behind it, and browse the specification itself. It runs as a working test-stage deployment: the full send and receive path is wired end to end against a sandbox rather than live production traffic.
Architecture
One hostname fronts everything. The ingress terminates TLS and hands off to the portal's own nginx, which serves the React app and reverse-proxies the API, the AS4 engine, and the SMP behind a single origin — so the browser, the machine clients, and the protocol all arrive at the same door. Behind it: a Node service holding the domain API and PostgreSQL persistence, phase4 as the AS4 engine, a .NET service for schema and customization-ID validation, Redis, and PostgreSQL outside the cluster. Jenkins builds every image in parallel, pushes them to a self-hosted registry, applies the manifests to Kubernetes, and health-checks the real hostname from inside the cluster before calling it a deploy — with ingress and certificates deliberately owned by a separate infrastructure pipeline.
Notable engineering
The interesting seam is where the protocol meets the application. The AS4 engine receives Peppol messages and writes them to disk; a sidecar in the same pod watches that directory, posts each file to an internal endpoint behind a shared secret, and deletes it. The API then reads the raw envelope — lifting the sender and receiver party identifiers out of the ebMS headers, the document and process identifiers out of the business header, and the UBL document out of the payload — hashes it, and works out which tenant it belongs to from the participant identifier. Outbound runs the mirror: a friendly document type is expanded into its full Peppol identifier, validated before it leaves, and only handed to the AS4 engine once it passes. A rejection is stored as a first-class record with its reasons, not a dropped request.
Making the specification navigable
Peppol publishes its code lists as XML meant for machines — every document type, participant scheme, process, and transport profile the network recognises. Scripts parse the published version into the database, decomposing each document-type identifier into its schema namespace, root element, customization ID, and UBL version on the way in. The portal turns those into searchable reference pages, and the same table drives enforcement: a document is checked against the schema registered for its type, and its customization ID against the one the specification expects. Reference data and validation share one source of truth instead of drifting apart.
Working to someone else's specification
Most of the work in a project like this is not code you would choose to write. The network defines the identifiers, the envelope, the signatures, the validation rules, and the statistics reports you are obliged to produce — conformance is the product. What is left to engineer is the plumbing between a protocol you do not control and a system your own users can actually operate, and that plumbing is where the real decisions live.
Building against a standard?
Regulated formats, conformance rules, and networks nobody lets you redesign — tell me what you have to interoperate with.