Skip to content

Connecting a system to esz-backend — project brief

Audience: partners & internalStatus: reference

For whoever runs the project on the other side. This page is what you need to plan and staff the work; it stays deliberately short and self-contained. The technical reference is the Partner overview and the pages it links — hand those to the engineers.

The platform in three sentences

esz-backend is ESZ's internal backend: eight documented domain services (auth, certificates, customers, employees, integrations, logging, procurements, products), each owning one business domain and its own database. It holds the company's canonical data and keeps it in sync with the systems the business runs on — Personio, Büro+, Business Central, Salesforce, Hivebuy and Microsoft 365. A new external system is added inside the service that owns its data — employee data lands in employees, sellable catalogue data in products, purchasing catalogue data in procurements, and customer data in customers. Detail: Platform and services.

How data flows

The external system is mirrored into a quarantined layer inside the owning service; the mirror is then translated into ESZ's canonical model. The canonical model never depends on the vendor's shape — if the vendor system is replaced in three years, the mirror is deleted and nothing else changes.

flowchart LR
  you["EXTERNAL SYSTEM"]:::ext
  subgraph svc["esz-backend service"]
    direction TB
    mirror[("vendor app<br/>mirror — vendor's ids,<br/>vendor's field names")]:::vend
    core[("core<br/>canonical ESZ model<br/>source of truth")]:::corebox
    mirror -- "translate — ALLOWED" --> core
    core -- "import — FORBIDDEN" --> mirror
  end
  you <-- "webhooks · pulls · pushes ·<br/>published reads" --> mirror

  linkStyle 0 stroke:#0d9488,stroke-width:2px
  linkStyle 1 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

One principle to know before scoping: esz-backend is the hub. A connected system receives the data it needs for its own function — never data whose only purpose is forwarding to a third system. If your system needs data that another system holds, that is a second integration on our side, not a wider feed through the first one.

The five steps

  1. Discovery and domain modelling. The six questions below and the Partner overview §5 checklist get answered; sandbox credentials are exchanged in both directions. Output: a written data contract, not code.
  2. Mirror. Read-only sync against the sandbox. Canonical data untouched.
  3. Upsert. The mirror writes into the canonical model; conflict rules become code.
  4. Outbound. Only where the external system consumes ESZ changes — we push, or it reads an agreed field list.
  5. Cutover. Production credentials, initial full load, reconciliation, monitoring.

Day counts vary with the quality of the vendor API; the ordering does not. Step 1 is where schedules slip, and almost always on field authority — "who wins when two systems both hold a phone number?" is a business decision, not an engineering one. Plan for the business owner to be in the room.

The six questions

These are answered in step 1, per entity, with a business owner present. Full explanations in Domain modelling.

  1. What is the entity, in ESZ's words?
  2. What identifies it permanently? (Not a name, not an e-mail address.)
  3. Do two systems describe the same real thing?
  4. For each field held on both sides, which side wins? ("Both ways" is not an answer.)
  5. What happens when a vendor record matches nothing on our side?
  6. What does deletion mean?

Where the external system reads from us, step 1 additionally produces the exact list of fields it may read. That list is a contract — a field a partner already consumes cannot be quietly withdrawn later — so it starts minimal: each field needs a named consumer and a stated purpose.

Secrets and owners

Up to four secrets are exchanged, in opposite directions — ESZ-issued OAuth client credentials the vendor stores, and vendor-issued credentials ESZ stores. Each needs a named rotation owner on both sides; that naming is a step-1 deliverable, and finding those owners is project work, not engineering work. The mechanisms — which hop uses which, and why webhooks carry a signature instead of a token — are in Authentication.

Where personal data crosses the boundary, a data processing agreement must be signed before production cutover. Raise it with legal during step 1; legal turnaround is the long pole. See Data protection.

What ESZ provides

A mirrored, inspectable copy of the vendor's data with per-record sync errors and single-row re-sync; central logging of every call in both directions; an OpenAPI spec for everything we expose; a staging environment to test against; retry with backoff on transient failures and a visible error state on permanent ones.

What the vendor side must produce

The full checklist is Partner overview §5. The short version: a sandbox, credentials and a rotation contact, a field-level schema with stable identifiers, a field-authority answer per shared field, deletion semantics, expected volumes, and API documentation. Missing documentation does not block the project, but it converts discovery time into reverse-engineering time.