The Document System Behind a Multi-Entity Company
The Situation
Klevar is not one legal shape. It has an FZE path, a US LLC path, and a UK Ltd path, each with its own identity, banking data, document numbering, tax posture, retention rules, and audit exposure.
That sounds like paperwork until the first real document has to leave the company. A Sterling letterhead needs the FZE identity. A German invoice may need EN16931 Factur-X or XRechnung. A board resolution needs officer signatures. A vendor bill needs AP tracking. A credit note needs to inherit the right terms from the invoice it corrects. A receipt needs to prove which payment it came from.
The dangerous version is letting every internal tool generate its own PDF. The Client Portal renders one format. The CLI renders another. A one-off script writes a letterhead. The payment flow sends a receipt from somewhere else. Each piece looks small until the company has to prove what happened six months later.
I built Klevar Docs as the central document substrate: one headless API for every legal document the group issues or stores.
The Cost of Doing Nothing
The cost was not a software license. It was control.
If each system generated its own documents, every new document type would copy the same legal identity fields, the same banking details, the same numbering logic, the same storage rules, and the same delivery hooks. The first time one copy drifted, the business would have a document that looked legitimate but carried the wrong entity, wrong bank details, or wrong compliance artifact.
For a small group company, that risk is expensive. One wrongly issued invoice can cost a client relationship. One missing audit trail can cost days of accountant time. A conservative estimate of senior finance and engineering cleanup time puts one serious document incident in the €3K to €8K range before any regulatory or client damage.
The system was built to make that class of drift harder to create.
What I Built
Klevar Docs is a TypeScript and Fastify service backed by PostgreSQL 16, Redis, Supabase Storage, Puppeteer, Ghostscript, veraPDF, mustangproject, and EU DSS. It generates 14 document types across 42 template bundles: letterhead, invoices, pro-forma invoices, credit notes, board resolutions, contract covers, proposals, engagement letters, receipts, statements, quotes, reference letters, minutes, and compliance letters.
The hard part was not making PDFs. The hard part was making PDFs that can be defended later.
One batch exposed the shape of the problem. The FZE templates originally looked correct because they hardcoded FZE identity strings in the footer. That passed visual inspection. It also meant an LLC render could leak FZE identity into a legal document. The fix widened the entity schema, captured richer entity snapshots, rewired the templates to read from the snapshot, and added a regression gate that renders templates against different entities to catch cross-entity leakage.
That correction shaped the rest of the system. The database owns the legal state. The renderer consumes frozen snapshots. The compliance sidecars produce the XML and signing outputs. The hash chain proves order. The shared ecosystem services handle notifications, webhooks, and schedules.
System Flow
Data Model
Architecture Layers
The Decision Log
| Decision | Alternative Rejected | Why |
|---|---|---|
| One document engine for all entities | Per-entity generators | Adding FZE, LLC, Ltd, or a future entity must be data work, not a deploy. |
| Frozen entity snapshot on document rows | Live entity lookup during re-render | Old documents need to match the identity and banking data used when they were issued. |
| 14 schema-gated document types | Free-form PDF payloads | Each document family has different required fields. Bad payloads should fail before rendering starts. |
| Two-phase numbering with gaps | PostgreSQL sequences | Rollbacks create sequence gaps. The service needs documented gaps and safe reclaim. |
| Java sidecars for compliance | Rewriting EN16931 and PAdES in TypeScript | The compliance libraries already exist. The value is orchestration and fail-closed behavior, not reimplementation. |
| Shared ecosystem engines | Build email, webhooks, and schedules locally | Klevar Docs should produce proof. Hub, Webhook Engine, and Workflow Engine already own delivery and orchestration. |
Ecosystem Integration
Klevar Docs sits behind the Client Portal instead of exposing a client UI. Generated invoices and documents flow back to the Portal as cached project artifacts, while operational alerts route through the notification hub. Webhook delivery goes through the webhook ingestion engine, and selected schedules run through the workflow automation engine so the document service keeps the business function without owning every timer. All integrations are feature-flagged, the system runs standalone with no ecosystem dependency.
Results
Before Klevar Docs, each new legal document started as a separate implementation decision: which tool renders it, where the entity identity comes from, how the number is assigned, where the file is stored, and what proof survives later. After the service landed, 14 canonical document types, 42 template bundles, 40 table schema files, and 59 OpenAPI path groups run through one API surface.
The most important result is not the count. It is that a new Klevar document no longer starts as a custom script. It starts inside a system that already knows which entity is issuing it, which fields are allowed, which number sequence it belongs to, which compliance path applies, which events need to leave, and which audit proof must remain.
The project also changed the operating baseline. Sterling letters, invoices, proposals, engagement letters, receipts, statements, credit notes, board resolutions, vendor bills, intercompany records, reconciliation reports, and audit packets now sit on the same substrate. The next constraint is external conformance breadth, not internal sprawl.