Platform and services¶
The canonical description of what esz-backend is and where an external system fits. Other pages link here rather than restating it.
What esz-backend is¶
esz-backend is the internal backend platform of ESZ. It holds the company's canonical business data — customers, employees, products, procurements and certificates — and keeps that data in sync with the external systems the business actually runs on (HR software, ERP, CRM, procurement and mail).
It is not a single application. It is a set of independent services, each owning one business domain and its own database.
| Service | Owns | Talks to today |
|---|---|---|
auth |
Login, identity, sessions | Microsoft Entra / Microsoft OAuth |
certificates |
Certificate records and document files | S3-compatible object storage |
customers |
Customer master data | Büro+ (Microtech), Salesforce, Business Central |
employees |
Employee master data | Personio, Microsoft 365 |
products |
Sellable products, technical models and prices | Büro+, Salesforce |
procurements |
Suppliers, purchased items, supply options, and catalogue reconciliation | Büro+, Hivebuy |
integrations |
Cross-cutting flows: inbound webhooks, generated documents, outbound e-mail | Hivebuy, mail relay |
logging |
Central audit + external-call log | — |
Three rules explain most of the design:
- Each service is independent. Separate database, separate deployment.
A broken release in
customerscannot take downauth. Services do not read each other's databases. - External systems never own our data. Every external system is mirrored into a quarantined layer, then written into our canonical model. Our model never depends on theirs.
- esz-backend is the hub. Connected systems receive the data they need for their own function — never data whose only purpose is to be forwarded to a third system. Routing between systems is our job, not the partner's. If system B needs data that system A holds, that flows A → core → B, both hops ours — a second integration, not a wider feed through the first.
Where a new external system fits¶
An external system ("vendor" in our terminology, regardless of whether money
changes hands) is added as a vendor app inside an existing service — not
as a new service. If your system carries employee data, it lives inside
employees. Sellable catalogue data → products. Purchasing catalogue data →
procurements. Customer data → customers. Webhook and document flows that
span domains live in integrations. The vendor app is an anti-corruption
layer: a translation buffer between your data model and ours.
flowchart LR
subgraph external["YOUR SYSTEM"]
yourapi["Your REST / GraphQL API"]
yourhook["Your webhook emitter"]
end
subgraph service["esz-backend service — e.g. employees"]
direction TB
subgraph vendorapp["vendor app — quarantine zone"]
direction TB
inbound["POST /v1/yourvendor/sync/<br/><i>auth: Bearer access token</i>"]
hookep["POST /v1/webhooks/yourvendor/event-name<br/><i>auth: signed payload</i>"]
mirror[("mirror table<br/>keyed on YOUR id<br/>YOUR field names")]
client["outbound client<br/><i>auth: OAuth2 client credentials</i>"]
inbound --> mirror
hookep --> mirror
end
core[("core<br/>canonical ESZ model<br/>vendor-agnostic<br/><b>source of truth</b>")]
mirror -- "upsert — ALLOWED" --> core
core -- "import — FORBIDDEN" --> mirror
core --> client
end
subgraph platform["Rest of platform"]
others["customers · products · procurements<br/>read core, never your mirror"]
logsvc[("logging<br/>every external call:<br/>request · response · latency")]
end
yourhook -- "HTTPS + signature headers" --> hookep
client -- "HTTPS + Bearer access_token" --> yourapi
yourapi -. "optional: you trigger a pull —<br/>'something changed, come look'" .-> inbound
core --> others
client --> logsvc
linkStyle 2 stroke:#0d9488,stroke-width:2px
linkStyle 3 stroke:#e11d48,stroke-width:2px,stroke-dasharray:4 4
classDef ext fill:#f9d6d6,stroke:#b04,color:#000
classDef vend fill:#fde8e8,stroke:#b04,color:#000
classDef corebox fill:#cfeec9,stroke:#2a6,color:#000
classDef plat fill:#e0f0ff,stroke:#268,color:#000
class yourapi,yourhook ext
class inbound,hookep,mirror,client vend
class core corebox
class others,logsvc plat
Read the diagram as two claims:
- The green edge (
mirror → core) is the only path vendor data takes into ours. The red edge is a rule the codebase enforces mechanically —coreimporting from a vendor app fails the build, not just review. - Vendor identifiers and field names stop at the mirror. If the vendor system is replaced in three years, we delete the vendor app; the canonical model does not change.
The design rules behind the mirror boundary — bounded contexts, field authority, the vendor-removal test — are in Domain modelling.