Backend-Integration für eigene Clients

Nutzen Sie die Backend-Verträge, wenn Sie eine eigene Oberfläche, einen Headless-Client oder eine spezialisierte Arbeitsoberfläche gegen Workspace bauen. Starten Sie mit Discovery und Ressourcen-Metadaten, und behandeln Sie Readiness-Antworten als Maschinenvertrag, nicht als fertige UI.

Discovery zuerst lesen

Lesen Sie zuerst die öffentlichen und tenantgebundenen Einstiegspunkte:

bash
nucli --host https://workspace.example discovery --json
nucli --tenant <tenant> resources list
nucli --tenant <tenant> resources meta <entrypoint-id>

Verwenden Sie veröffentlichte URLs, Methoden und Felder aus den Antworten. Bauen Sie Fachpfade nicht aus Annahmen zusammen, wenn der Server einen Einstiegspunkt oder eine Ressourcen-Meta-Fläche bereitstellt.

Readiness-Antworten auswerten

Readiness-Endpunkte helfen Clients, fehlende Voraussetzungen vor einer Aktion sichtbar zu machen. Sie ändern keine Daten und ersetzen keine Validierung im Schreibpfad.

Werten Sie diese Felder aus:

FeldVerwendung im Client
statusEntscheidet, ob der Vorgang bereit oder blockiert ist.
checks[]Enthält alle geprüften Bedingungen. Nutzen Sie die Liste für Diagnose- oder Detailansichten.
blockers[]Enthält die aktuell blockierenden Punkte. Nutzen Sie diese Liste für Hinweise und nächste Schritte.
codeStabiler technischer Schlüssel für Fallbacks, Tests und Telemetrie.
reasonKeyStabiler fachlicher Schlüssel für den Nutzertext im Client.
detailKeys[]Optionale Unterschlüssel für genauere Hinweise.
fieldFachliches Feld oder Bereich, der den Blocker ausgelöst hat.
ownerAreaZuständiger Produktbereich, zum Beispiel documents, positions oder commerce.
categoryArt des Blockers, zum Beispiel user_data, configuration, template oder system_state.
responsibilityZuständigkeit, zum Beispiel user, admin, template_owner oder system.
actionabilitySteuert die Darstellung: direct, escalate oder none.
actionRouteKeyBevorzugter logischer Navigationsschlüssel für andere Seiten oder Module.
actionUrlFallback oder lokales Ziel innerhalb einer Detailansicht.

Erzeugen Sie Nutzertexte aus reasonKey, detailKeys[] und optional code. Verlassen Sie sich nicht auf serverseitige Freitexte.

Aktionsziele mappen

Behandeln Sie actionRouteKey als bevorzugten Navigationsvertrag. Pflegen Sie in Ihrem Client eine eigene Routen-Tabelle:

js
const routeMap = {
  "commerce-document-template-mappings": "/settings/document-template-mappings",
  "commerce-profiles": "/settings/commerce-profiles",
  "pim-price-lists": "/pim/price-lists",
  "warehouses": "/inventory/warehouses",
};

Wenn actionRouteKey fehlt, kann actionUrl ein lokales Ziel enthalten. Lokale Ziele beginnen typischerweise mit # und verweisen auf einen Bereich der aktuellen Detailansicht. Übernehmen Sie diese Werte nicht ungeprüft als eigene Tab-IDs. Mappen Sie sie auf Ihre eigene Oberfläche:

js
const localReadinessTargets = {
  "#quotes-tab-items": { resource: "quotes", panel: "items" },
  "#quotes-tab-details": { resource: "quotes", panel: "details" },
  "#quotes-tab-documents": { resource: "quotes", panel: "documents" },
  "#quotes-tab-workflow": { resource: "quotes", panel: "workflow" },
  "#quotes-tab-service-context": { resource: "quotes", panel: "serviceContext" },
  "#quotes-tab-finance": { resource: "quotes", panel: "finance" },
  "#commerce-orders-tab-details": { resource: "orders", panel: "details" },
  "#commerce-orders-tab-profile": { resource: "orders", panel: "profile" },
};

OpenAPI beschreibt die Antwortstruktur. Konkrete actionUrl-Werte sind fachliche Laufzeitwerte und können mit neuen Readiness-Pfaden wachsen. Schreiben Sie Ihren Client deshalb tolerant:

  • Öffnen Sie bei bekanntem actionRouteKey die gemappte Seite.
  • Öffnen Sie bei bekannter lokaler actionUrl den gemappten Bereich.
  • Öffnen Sie bei unbekannter lokaler actionUrl die Detailansicht und zeigen Sie den Blocker trotzdem an.
  • Zeigen Sie Blocker mit actionability: "none" ohne Pflichtlink an.

Beispiel: Angebots-Readiness

Ein Angebots-Readiness-Blocker für fehlende Positionen kann so aussehen:

json
{
  "code": "items_val_required",
  "status": "blocked",
  "field": "items",
  "reasonKey": "items",
  "actionUrl": "#quotes-tab-items",
  "ownerArea": "positions",
  "category": "user_data",
  "responsibility": "user",
  "actionability": "direct"
}

Ihr Client sollte daraus nicht ableiten, dass Ihre Oberfläche einen Tab mit der ID quotes-tab-items braucht. Leiten Sie stattdessen aus field, reasonKey oder Ihrer actionUrl-Adapter-Tabelle ab, dass der Nutzer die Positionen des Angebots öffnen soll.

Fallbacks gestalten

Zeigen Sie Readiness-Blocker auch dann an, wenn Sie das Aktionsziel nicht kennen. Nutzen Sie einen neutralen Fallback:

js
function resolveReadinessTarget(blocker) {
  const routeKey = String(blocker?.actionRouteKey || "").trim();
  if (routeKey && routeMap[routeKey]) return routeMap[routeKey];

  const actionUrl = String(blocker?.actionUrl || "").trim();
  if (actionUrl && localReadinessTargets[actionUrl]) {
    return localReadinessTargets[actionUrl];
  }

  return { resource: "current", panel: "details" };
}

Protokollieren Sie unbekannte actionRouteKey- und actionUrl-Werte in Ihrer Client-Telemetrie. So erkennen Sie neue Backend-Verträge früh, ohne Nutzer zu blockieren.

Bestell-Dokumentempfänger integrieren

Behandeln Sie customerEmailSnapshot bei Bestellungen als revisionsfesten Snapshot. Senden Sie dieses Feld nicht in Update-Payloads. Der Server lehnt Update-Versuche mit VAL_PROTECTED_FIELD ab, auch wenn der gesendete Wert dem aktuellen Snapshot entspricht.

Wenn ein Client den Empfänger einer Auftragsbestätigung ändern soll, verwenden Sie den dokumenttypbezogenen Override der Bestellung:

text
GET    /api/v1/commerce/orders/{id}/document-recipient-overrides
PUT    /api/v1/commerce/orders/{id}/document-recipient-overrides/order_confirmation/email
DELETE /api/v1/commerce/orders/{id}/document-recipient-overrides/order_confirmation/email

Für PUT senden Sie nur die operative Zieladresse:

json
{
  "recipientEmail": "rechnung@example.test"
}

Der effektive Empfänger der Auftragsbestätigung folgt dieser Reihenfolge:

  1. aktiver Override für order_confirmation und email,
  2. E-Mail im Rechnungsadress-Snapshot der Bestellung,
  3. customerEmailSnapshot.

Zeigen Sie diese drei Ebenen getrennt an. Schreiben Sie Override-Felder nicht in den normalen Order-Update-Payload. Checkout-Eingangsbestätigungen und andere Dokumenttypen verwenden diesen Override-Vertrag nicht automatisch.

Physische Fulfillment-Strategien integrieren

Lesen und schreiben Sie die Erfüllungsstrategie bei Produktvarianten nur im Logistikmodul. Das Feld heißt physicalFulfillmentStrategy und gilt nur für Varianten mit isPhysical: true.

Zulässige Werte sind:

  • stock
  • nos
  • dropship
  • finish_to_order
  • assemble_to_order
  • make_to_order
  • procure_to_order

Behandeln Sie standard nur als alten Eingabewert für stock. Verwenden Sie die Strategie nicht als Ersatz für Produkt-Capabilities wie Lizenz, Service oder Digitalprodukt. Senden Sie kein modules.logistics für nicht-physische Varianten; der Server lehnt diese Capability-Kombination ab.

Wenn Ihr Client Bestellungen, Fulfillment oder operative Übersichten anzeigt, werten Sie den OrderItem-Typ als serverseitigen Snapshot aus. Schreiben Sie ihn nicht selbst. stock kann im OrderItem weiterhin als standard erscheinen. Nicht lagerwirksame Strategien bestätigen die Position, erzeugen aber keine fertige Warenreservierung. Zeigen Sie dafür einen Folgeprozess an, statt eine fehlende Reservierung als Lagerfehler zu behandeln.

Für finish_to_order, assemble_to_order und make_to_order kann der Folgeprozess auf einen Fertigungsauftrag verweisen. Leiten Sie daraus keine automatische Fertigmeldung oder Bestandsbuchung ab. Ein positiver Fertigungsfolgeprozess setzt voraus, dass ein freigegebener Fertigungsplan die bestellte Variante als primäres Ergebnis führt. Fehlt diese Voraussetzung, zeigen Sie den Blocker als Konfigurations- oder Stammdatenproblem an.

Behandeln Sie nos und procure_to_order unterschiedlich. nos ist ein lagernaher Backorder-Pfad für reguläre Sortimentsartikel und kann Pending- oder Backorder-Reservationen nutzen. procure_to_order ist auftragsbezogene Beschaffung; der aktuelle Vertrag erzeugt dafür keine Reservation, keine PurchaseOrder und keine automatische Bestandsbewegung.

Compliance und Contracts integrieren

Compliance-Ressourcen sind tenantgebunden, workflow-nah und teilweise vertragsgebunden. Lesen Sie zuerst die Ressourcen-Metadaten, bevor Sie eigene Formulare oder Automationen bauen. Der Server veröffentlicht unter anderem Ressourcen für Anforderungen, Vertragspflicht-Verknüpfungen, Kontrollen, Prüfungen und Nachweise, wenn die aktuelle Session die nötigen Rechte hat.

Behandeln Sie Contracts als Quelle für Vertragsstatus, Vertragsattribute, Sichtbarkeit und Fristen. Compliance dupliziert diese Daten nicht. Eine Vertragspflicht verknüpft eine requirementId mit einer contractId und trägt Rolle, Löschregel, Nachweisstärke und Gültigkeitszeitraum.

Wichtige Integrationsregeln:

  • Schreiben Sie Status- und Workflow-Felder von Anforderungen und Prüfungen nicht direkt. Nutzen Sie die veröffentlichten Workflow-Transitionen.
  • Legen Sie Nachweise an der konkreten Prüfung an, nicht nur an einer Anforderung oder einem Vertrag.
  • Laden Sie Dateien über den veröffentlichten Evidence-Upload hoch, wenn Ihr Client Dateiinhalt übertragen soll. Der Server berechnet den Hash und verknüpft optional ein Storage-Objekt.
  • Werten Sie Sichtbarkeit so aus, wie der Server sie liefert. Verknüpfte Compliance-Daten können durch den sichtbaren Contract-Kontext eingeschränkt sein.
  • Zeigen Sie Contract-Fristen aus Compliance-Berichten als abgeleitete Berichtswerte an. Korrigieren Sie Fristen über den Contract und seine strukturierten Attribute.
  • Exportieren Sie Evidence-Snapshots nur in freigegebene Storage-Ziele und behandeln Sie Prüfsummen als Audit-Metadaten.

Typische Statuswerte für Prüfungen sind open, in_progress, in_review, closed und failed. Typische Anforderungsstatus sind draft, active, retired und deprecated. Diese Werte sind fachliche Verträge; behandeln Sie unbekannte künftige Werte fail-closed oder mit einem neutralen Fallback.

Seriennummern und Chargen integrieren

Lesen und schreiben Sie Tracking-Felder über die veröffentlichten Ressourcen-Metadaten. Verwenden Sie keine internen Inventory- oder Fulfillment-Pfade als Ersatz, wenn eine Ressource im aktuellen Kontext nicht veröffentlicht ist.

Für Produktvarianten sind diese Felder relevant:

FeldVerwendung im Client
trackingTypeEntscheidet, ob eine Variante ohne Tracking, chargengeführt oder seriennummerngeführt ist.
serialNumberSourceBeschreibt bei Seriennummern, ob Nummern extern übernommen oder intern erzeugt werden.

Behandeln Sie Tracking als Prozessvertrag:

  • Wareneingänge müssen Tracking-Nummern liefern, wenn die Variante batch oder serial_number verlangt.
  • Picking und Versand dürfen trackingpflichtige Positionen erst abschließen, wenn die konkrete Nummer oder Charge zugeordnet ist.
  • Seriennummern stehen für einzelne Einheiten; Chargen können Mengen tragen und bei Teilversand Restmengen behalten.
  • Korrekturen, Sperrungen und Retouren brauchen einen nachvollziehbaren fachlichen Grund.

Zeigen Sie Konflikte wie fehlende, bereits verwendete oder nicht verfügbare Nummern als fachlichen Zustand an. Geben Sie keine internen Tabellennamen, Datenbankfehler, Rohfehler oder Lagerpfad-Details an Benutzer weiter.